mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
7005 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e10163a9d | ||
|
|
5fcf20ee9d | ||
|
|
fc72d2b771 | ||
|
|
b7ea3fcd19 | ||
|
|
9cb7529ba6 | ||
|
|
55ad8757ec | ||
|
|
3e4b01173a | ||
|
|
2f1d1d5cac | ||
|
|
4c0a4067df | ||
|
|
8550142804 | ||
|
|
97f40754ba | ||
|
|
cff8f04477 | ||
|
|
db8034f12e | ||
|
|
c86763dc38 | ||
|
|
5ce575b157 | ||
|
|
fabef23bea | ||
|
|
685bf58046 | ||
|
|
9e2921fce8 | ||
|
|
80d8f7c7cb | ||
|
|
38e1b075b4 | ||
|
|
d659610afc | ||
|
|
6cafc1f8bf | ||
|
|
788f11ea6a | ||
|
|
b7fdc9ef0e | ||
|
|
0d8cc26044 | ||
|
|
2955888468 | ||
|
|
0773cecc1f | ||
|
|
8e33586359 | ||
|
|
da5c72da4b | ||
|
|
2f7c583143 | ||
|
|
51fd4993ba | ||
|
|
e37bfdb445 | ||
|
|
3d7015afa2 | ||
|
|
7e5424b806 | ||
|
|
43f70b961e | ||
|
|
b7231c7d02 | ||
|
|
15c34f0a8c | ||
|
|
d1e42ffa16 | ||
|
|
36f489c211 | ||
|
|
defe2287aa | ||
|
|
112bef11ad | ||
|
|
b38780f3fd | ||
|
|
5f33238f06 | ||
|
|
3592ac3c02 | ||
|
|
c897b16f32 | ||
|
|
4f741addbd | ||
|
|
355b81d8bc | ||
|
|
6f35553372 | ||
|
|
71090b7e2c | ||
|
|
2ab2ee166e | ||
|
|
1e858e39e6 | ||
|
|
664639e349 | ||
|
|
517b9d91fc | ||
|
|
0ac7ebceef | ||
|
|
85c56b2603 | ||
|
|
10aeb75cea | ||
|
|
d41bb98c09 | ||
|
|
2fda51692b | ||
|
|
1de71e8a78 | ||
|
|
60dd42be60 | ||
|
|
d821e4cbfb | ||
|
|
8aa465117f | ||
|
|
8977815f5d | ||
|
|
a48c20c97c | ||
|
|
601f47436f | ||
|
|
ef76d6cfa5 | ||
|
|
96ed4b47b9 | ||
|
|
13c4019e94 | ||
|
|
b7b387b1f7 | ||
|
|
7569edfaef | ||
|
|
55b2a06812 | ||
|
|
b81a509556 | ||
|
|
26f4dbe12c | ||
|
|
b3f1970f18 | ||
|
|
c51da9174f | ||
|
|
81f71f6f29 | ||
|
|
48e7005554 | ||
|
|
2b3e68814b | ||
|
|
cc83294316 | ||
|
|
08c8375acb | ||
|
|
824a057935 | ||
|
|
d91ddb97d1 | ||
|
|
5bb637ca04 | ||
|
|
142aba00d5 | ||
|
|
8687e44d10 | ||
|
|
0bd8e85185 | ||
|
|
00a5ab2364 | ||
|
|
f44e76b65c | ||
|
|
1174d97072 | ||
|
|
d9eaffe564 | ||
|
|
6197385d1f | ||
|
|
d07272d631 | ||
|
|
e2a011d9d0 | ||
|
|
76dc7d0a76 | ||
|
|
7e94e52144 | ||
|
|
5ef7e3c9c5 | ||
|
|
d2cc1149b3 | ||
|
|
c3b553a93f | ||
|
|
eb0b41587c | ||
|
|
3c0bb7ff51 | ||
|
|
995ce7198b | ||
|
|
38ffa522f6 | ||
|
|
8898aecb21 | ||
|
|
f08505e92b | ||
|
|
c1e8809a8f | ||
|
|
6130c4fa3c | ||
|
|
8c4ceb3b86 | ||
|
|
30a5909544 | ||
|
|
e841944b47 | ||
|
|
635d8c0632 | ||
|
|
6b8db0f644 | ||
|
|
3b2804c815 | ||
|
|
ff1792edf1 | ||
|
|
b985123d2e | ||
|
|
c983279020 | ||
|
|
ee9199b542 | ||
|
|
f1a6998df2 | ||
|
|
3e44bbd313 | ||
|
|
4adfdaaf12 | ||
|
|
4a7ba3cfaf | ||
|
|
ffbca80ca2 | ||
|
|
c11467af36 | ||
|
|
13cfe6406f | ||
|
|
8e77ece0ee | ||
|
|
ffec7fe109 | ||
|
|
e07f8fb863 | ||
|
|
8cf9dbb742 | ||
|
|
3008e7c226 | ||
|
|
a2b630c0bb | ||
|
|
5b1baa7a2e | ||
|
|
7f8cf771b7 | ||
|
|
b00e99c529 | ||
|
|
a76e32f949 | ||
|
|
512acd125e | ||
|
|
72adf49ba8 | ||
|
|
73ceea6ad2 | ||
|
|
39c3ae0ea3 | ||
|
|
ed19ea05fe | ||
|
|
dc1b9febf1 | ||
|
|
d9015da151 | ||
|
|
1f0e62f139 | ||
|
|
7d830ff52f | ||
|
|
8f383e8987 | ||
|
|
ca538965d8 | ||
|
|
e4669b81ae | ||
|
|
1b9308b727 | ||
|
|
80c64dc3b3 | ||
|
|
be3d6c0fbb | ||
|
|
7956070f2b | ||
|
|
d0f34b5a76 | ||
|
|
84498104bf | ||
|
|
378a0a634f | ||
|
|
ac08fa74f3 | ||
|
|
d5d4ae51ee | ||
|
|
0f87eafa2f | ||
|
|
3af00277ee | ||
|
|
b774dbc1c0 | ||
|
|
296352ecb0 | ||
|
|
11a9b62322 | ||
|
|
452ef78517 | ||
|
|
0d1b48893a | ||
|
|
ec8a05f653 | ||
|
|
78b5bc6629 | ||
|
|
f41cdc75a1 | ||
|
|
c8e7c4b352 | ||
|
|
bff084c10a | ||
|
|
16c8b05f11 | ||
|
|
15dd2058fd | ||
|
|
c27180c044 | ||
|
|
050fdd4126 | ||
|
|
ae1f002999 | ||
|
|
3911c23866 | ||
|
|
3814dbb0f4 | ||
|
|
82f023d7e3 | ||
|
|
ec57c57baf | ||
|
|
354fa581c1 | ||
|
|
d881814a35 | ||
|
|
ad048d78ac | ||
|
|
109dbc0b75 | ||
|
|
745ecf2825 | ||
|
|
265785b7b9 | ||
|
|
97f4d48a07 | ||
|
|
3cc7f0ba43 | ||
|
|
dde4695136 | ||
|
|
3337930292 | ||
|
|
44cc148907 | ||
|
|
b2e16facd4 | ||
|
|
4fd662fea9 | ||
|
|
12c058698b | ||
|
|
33095916ec | ||
|
|
5818cf8596 | ||
|
|
1fa0bd1e87 | ||
|
|
592c6bc3e5 | ||
|
|
efc81c93a9 | ||
|
|
35d4f6737a | ||
|
|
291a042b3e | ||
|
|
9dad3721a9 | ||
|
|
dbb1c2d10c | ||
|
|
e8e34ed6fb | ||
|
|
c529782a8d | ||
|
|
2dfd48492e | ||
|
|
a6bdf313f2 | ||
|
|
915685e01b | ||
|
|
05540220a9 | ||
|
|
75158e1086 | ||
|
|
676537cf29 | ||
|
|
d857fd42ac | ||
|
|
5856b71eb7 | ||
|
|
57adb2973a | ||
|
|
ead44adcd3 | ||
|
|
d3085f7add | ||
|
|
1da64c37e8 | ||
|
|
ef36b097bf | ||
|
|
ec3833c96e | ||
|
|
25dfc2c41d | ||
|
|
d5b7889d40 | ||
|
|
74561d70b5 | ||
|
|
83f7372369 | ||
|
|
8c3de35b0b | ||
|
|
ec1d5d564c | ||
|
|
26befd9c6c | ||
|
|
a28c4558c5 | ||
|
|
ed6a0dc7c2 | ||
|
|
9dd62525f3 | ||
|
|
ada588a7a8 | ||
|
|
286e164ed6 | ||
|
|
85b8dc8aba | ||
|
|
0748800118 | ||
|
|
b7fab6f285 | ||
|
|
9fc7deab0d | ||
|
|
b115bc8a5d | ||
|
|
cd018c7a4c | ||
|
|
9fce0eb5ab | ||
|
|
33e94849b1 | ||
|
|
8f1511184a | ||
|
|
acca9d43d3 | ||
|
|
58f464f4da | ||
|
|
7eb59a9152 | ||
|
|
740ed11aa8 | ||
|
|
d2a97a7ab4 | ||
|
|
15bc7ded39 | ||
|
|
f0810068a6 | ||
|
|
7aa2f36317 | ||
|
|
9cd85b8496 | ||
|
|
f8dcd7d452 | ||
|
|
69530b406e | ||
|
|
122b0fdc4f | ||
|
|
b990d97d35 | ||
|
|
fd6839b746 | ||
|
|
a79d9b22b1 | ||
|
|
2613c9d98a | ||
|
|
27aff880a9 | ||
|
|
7b53e67d64 | ||
|
|
da956469a1 | ||
|
|
9c59632d8b | ||
|
|
d1f458d383 | ||
|
|
a35a900ac0 | ||
|
|
f4c3969b63 | ||
|
|
ee75e51f2f | ||
|
|
9f9240b661 | ||
|
|
48885309c7 | ||
|
|
203b3d0143 | ||
|
|
25526eb3fe | ||
|
|
c3f7414c45 | ||
|
|
4c4fce5107 | ||
|
|
6816b31378 | ||
|
|
e94bad1c15 | ||
|
|
617d726a3d | ||
|
|
020eda887f | ||
|
|
b5f8021a12 | ||
|
|
7b6947576a | ||
|
|
9375a8c4c2 | ||
|
|
7f5c4084c7 | ||
|
|
6c89f00d1b | ||
|
|
dee0993286 | ||
|
|
47351c2b16 | ||
|
|
16b7670614 | ||
|
|
72b2a81f90 | ||
|
|
d73c26d2b7 | ||
|
|
e83bbeb673 | ||
|
|
b6aa9c5cfe | ||
|
|
dfe3b77cb5 | ||
|
|
cbe3b2bfe5 | ||
|
|
b1ae7fc941 | ||
|
|
8695bcc2b1 | ||
|
|
4ae6f708b1 | ||
|
|
14c4656fb8 | ||
|
|
13cec31f7f | ||
|
|
5db7e4b1ee | ||
|
|
54693fa992 | ||
|
|
3f83bcb4af | ||
|
|
e1e546d67e | ||
|
|
3714084f48 | ||
|
|
eb2c3a5e18 | ||
|
|
f6967eca58 | ||
|
|
8455bf66c2 | ||
|
|
00e59e01e3 | ||
|
|
91eaffe13f | ||
|
|
2066024981 | ||
|
|
d274b2096f | ||
|
|
0327a2526b | ||
|
|
f43412f1d5 | ||
|
|
b9010ec617 | ||
|
|
21ecc833ea | ||
|
|
f9bb8f76ee | ||
|
|
a5a9f268fe | ||
|
|
0a255771f4 | ||
|
|
e07d79ad50 | ||
|
|
2f74eb7584 | ||
|
|
39741c7d50 | ||
|
|
3f016888fd | ||
|
|
e5a012c959 | ||
|
|
c3cf174e5e | ||
|
|
a0a7c9f2e3 | ||
|
|
a8f61ba937 | ||
|
|
842d6edfdc | ||
|
|
92a8855ff3 | ||
|
|
def96fd7c4 | ||
|
|
f624a73bbc | ||
|
|
93a373f6ba | ||
|
|
01742c07e6 | ||
|
|
e00662f263 | ||
|
|
491ddb08a4 | ||
|
|
918cb39fed | ||
|
|
1369fe43e1 | ||
|
|
150f3416ac | ||
|
|
d8941be8cb | ||
|
|
592059c8fd | ||
|
|
37f4a23f60 | ||
|
|
27be94c889 | ||
|
|
974f49e22a | ||
|
|
9f7506ac1b | ||
|
|
8779d6c8bb | ||
|
|
96be713fd2 | ||
|
|
13d8fc9542 | ||
|
|
f74473b151 | ||
|
|
5eda68f11b | ||
|
|
f635207347 | ||
|
|
64f7e893f3 | ||
|
|
31556ec7a8 | ||
|
|
9ad3f4385f | ||
|
|
e9899dbdb4 | ||
|
|
18cffa8aa9 | ||
|
|
7e07a32504 | ||
|
|
be11a496bb | ||
|
|
c6f5f0b505 | ||
|
|
f553da1730 | ||
|
|
40753bcbf7 | ||
|
|
33df361d52 | ||
|
|
f4db970718 | ||
|
|
ab3928898f | ||
|
|
13f274fd02 | ||
|
|
b51fe50e7f | ||
|
|
1829a2ee0d | ||
|
|
65370a0f56 | ||
|
|
23213099e9 | ||
|
|
25e08110d5 | ||
|
|
95f683039d | ||
|
|
129d7195ff | ||
|
|
044339d6b4 | ||
|
|
4c4fc7462a | ||
|
|
22cb57ee20 | ||
|
|
4c0be4da13 | ||
|
|
4549855126 | ||
|
|
284c28c773 | ||
|
|
d2406ae372 | ||
|
|
1e9c34972a | ||
|
|
116bd19324 | ||
|
|
883de22c29 | ||
|
|
18f500a7a4 | ||
|
|
d14b0ca4db | ||
|
|
4156e7d464 | ||
|
|
9e48da65c1 | ||
|
|
2cdf9416ee | ||
|
|
cd0c83e485 | ||
|
|
0e814e956c | ||
|
|
f47e5a7732 | ||
|
|
91fff802b9 | ||
|
|
3c8ac20d63 | ||
|
|
38a521defd | ||
|
|
2f13049600 | ||
|
|
af531cf787 | ||
|
|
d495e343c0 | ||
|
|
de7e4d00ab | ||
|
|
374cc1be74 | ||
|
|
8b25488fe9 | ||
|
|
4f5742baa0 | ||
|
|
2b416de4ca | ||
|
|
1f41b7dca1 | ||
|
|
486e7852db | ||
|
|
a68a92793c | ||
|
|
a84e8aced7 | ||
|
|
3bc2d9aeaa | ||
|
|
6214c26bd3 | ||
|
|
da7a350667 | ||
|
|
66ca4fc97b | ||
|
|
7d63f8b249 | ||
|
|
bb1365dd77 | ||
|
|
bcc273d460 | ||
|
|
a6da3c67f8 | ||
|
|
ab110fc8fb | ||
|
|
7265d96116 | ||
|
|
560b63b051 | ||
|
|
0eb82a7c90 | ||
|
|
f92a5182fc | ||
|
|
fb6fabc116 | ||
|
|
c3269275a8 | ||
|
|
7e47855d47 | ||
|
|
d2d6ad481a | ||
|
|
5dcb49c7dd | ||
|
|
19d8550cf4 | ||
|
|
7610f76aea | ||
|
|
59cb358fda | ||
|
|
bb16db1747 | ||
|
|
d6f0342a34 | ||
|
|
6f6e5b51cc | ||
|
|
28de25a664 | ||
|
|
052b34dceb | ||
|
|
748b5c5d53 | ||
|
|
e1e4ffe057 | ||
|
|
1b53b2ff4b | ||
|
|
da45cecfc8 | ||
|
|
87b5d233e9 | ||
|
|
194cee671d | ||
|
|
b7c5520add | ||
|
|
2bee307592 | ||
|
|
85e62c330d | ||
|
|
0add026a5d | ||
|
|
f4184849c4 | ||
|
|
565cde84a7 | ||
|
|
f0e670b4c6 | ||
|
|
ef8951779d | ||
|
|
e285f8f9d2 | ||
|
|
cb383673f6 | ||
|
|
0768d620a5 | ||
|
|
d640d78f91 | ||
|
|
544b3d8b3b | ||
|
|
ce12142c45 | ||
|
|
c83a81ca38 | ||
|
|
d88db22ae8 | ||
|
|
a1cc50ba96 | ||
|
|
feb2fff894 | ||
|
|
7d30490ef4 | ||
|
|
317beebef8 | ||
|
|
7a413c9722 | ||
|
|
5be7363297 | ||
|
|
646784f0e5 | ||
|
|
18ed3f0279 | ||
|
|
00dd50a00c | ||
|
|
7039d14616 | ||
|
|
ec3c9f2f5a | ||
|
|
3b4f5fb891 | ||
|
|
76064b1bf2 | ||
|
|
8df766917e | ||
|
|
299430a6c1 | ||
|
|
dcbe005a6a | ||
|
|
af57b55bdb | ||
|
|
967e6426b9 | ||
|
|
61971acbe1 | ||
|
|
5bd0b6cf71 | ||
|
|
0eec25f75b | ||
|
|
3a6f06003c | ||
|
|
f805d1a7f7 | ||
|
|
ab29ee9c44 | ||
|
|
d07c2992d1 | ||
|
|
b1a8b09c21 | ||
|
|
fe2ef556d9 | ||
|
|
11eb67eec9 | ||
|
|
39a083b16b | ||
|
|
202b7b18af | ||
|
|
20934382e3 | ||
|
|
1bdf68b905 | ||
|
|
89827e49bc | ||
|
|
f157ff3b3a | ||
|
|
d15cfef935 | ||
|
|
28f9c960d5 | ||
|
|
323c42d51e | ||
|
|
d1fdf9ff8d | ||
|
|
e93f40d8b4 | ||
|
|
4df1b1d4fe | ||
|
|
1af58f6b77 | ||
|
|
a8fc8fc2d2 | ||
|
|
b8b7f1f3d0 | ||
|
|
622a116917 | ||
|
|
b51b0b3236 | ||
|
|
8cb1c99563 | ||
|
|
597a751466 | ||
|
|
5a9e4ae5e7 | ||
|
|
3094552311 | ||
|
|
e4c9ff5873 | ||
|
|
9b13bcf185 | ||
|
|
8f6d6bcb08 | ||
|
|
300fd3055a | ||
|
|
f6df3708c2 | ||
|
|
785cb938ec | ||
|
|
246d117df0 | ||
|
|
3f776f582b | ||
|
|
d8d2d71663 | ||
|
|
6a9adabfbb | ||
|
|
2564f25114 | ||
|
|
7fb08531e0 | ||
|
|
9dba0bb7fb | ||
|
|
87bca719c3 | ||
|
|
f3439944ea | ||
|
|
a7c1690d62 | ||
|
|
662fedd74b | ||
|
|
128139c66a | ||
|
|
2b439c1fc8 | ||
|
|
e16b22751a | ||
|
|
7587e20cf4 | ||
|
|
2e1b46db39 | ||
|
|
f4e6fe54c9 | ||
|
|
f86ceb5539 | ||
|
|
dfa34b4792 | ||
|
|
e9e9fd0cca | ||
|
|
7e95ba8787 | ||
|
|
66fd34ed84 | ||
|
|
f8c6f9f4f3 | ||
|
|
e6cfebb578 | ||
|
|
5d2379d93f | ||
|
|
6884ccbd2f | ||
|
|
bad97961dc | ||
|
|
b0ab07cdac | ||
|
|
68c4583693 | ||
|
|
6b237b0fe9 | ||
|
|
b37a136314 | ||
|
|
c9c8c64506 | ||
|
|
c5d502dc5f | ||
|
|
1629b803cb | ||
|
|
29c7a4558a | ||
|
|
b7dc2ca25c | ||
|
|
f525f2c818 | ||
|
|
1b5819efbd | ||
|
|
a56a0bc7d6 | ||
|
|
bd7bd5ff0c | ||
|
|
f9aece899f | ||
|
|
63508f1518 | ||
|
|
9ac22062af | ||
|
|
73faaab26d | ||
|
|
9467c1f9b9 | ||
|
|
04653dabc8 | ||
|
|
19617f7b4a | ||
|
|
b218de2702 | ||
|
|
d4764934c3 | ||
|
|
c225330aaf | ||
|
|
3c56896d21 | ||
|
|
deb8353d2c | ||
|
|
73053f26bc | ||
|
|
0c13e1b3f8 | ||
|
|
9da38f2f99 | ||
|
|
a93ffb1ae9 | ||
|
|
e08f600378 | ||
|
|
e406845542 | ||
|
|
a93eb4cf38 | ||
|
|
7fd24bef0f | ||
|
|
1a9a184145 | ||
|
|
4965ccf283 | ||
|
|
c6f89cbf9c | ||
|
|
2921779c1f | ||
|
|
cbed522ef4 | ||
|
|
4f539ccf21 | ||
|
|
b5e539fc5a | ||
|
|
88c18ef648 | ||
|
|
7dc9431f60 | ||
|
|
07a3e1f939 | ||
|
|
93223719c9 | ||
|
|
0b2d5fe494 | ||
|
|
d3c7cfad22 | ||
|
|
9ec777faf8 | ||
|
|
69f445fd09 | ||
|
|
643b9d0183 | ||
|
|
2c681b874e | ||
|
|
e44e79cedb | ||
|
|
beaf19c3e7 | ||
|
|
0b2a394cbc | ||
|
|
27e88dec04 | ||
|
|
929f136b3b | ||
|
|
6a22f4fee1 | ||
|
|
d90990d6ac | ||
|
|
111225a996 | ||
|
|
7dfcbf7df6 | ||
|
|
38ecf188d9 | ||
|
|
29be5eddde | ||
|
|
54b1ddc45d | ||
|
|
8cd9aa326c | ||
|
|
cd50745e1c | ||
|
|
ae94e3db4b | ||
|
|
6efaa74dd3 | ||
|
|
5496eda5d1 | ||
|
|
353dec1102 | ||
|
|
d80da9e674 | ||
|
|
6f0c56304f | ||
|
|
2452ad3663 | ||
|
|
1fa38546a0 | ||
|
|
249e28c75a | ||
|
|
6273153c5f | ||
|
|
628dcceb8d | ||
|
|
00ec415a69 | ||
|
|
ec8035cef9 | ||
|
|
775f64f4b8 | ||
|
|
660274bfb7 | ||
|
|
59cf9ff797 | ||
|
|
ff272503b0 | ||
|
|
43a939e3f2 | ||
|
|
b65b6db304 | ||
|
|
7b1f8f57c3 | ||
|
|
c32012d199 | ||
|
|
9ba6ce1b67 | ||
|
|
ca9e247762 | ||
|
|
f27a630e46 | ||
|
|
243a9d9be0 | ||
|
|
c528f8d5c8 | ||
|
|
1d1c0f14e1 | ||
|
|
e63ff70eae | ||
|
|
8a70f1420b | ||
|
|
cdf58a7aba | ||
|
|
1d6c9676f9 | ||
|
|
3d29fa99ec | ||
|
|
d167935874 | ||
|
|
d326961290 | ||
|
|
7dec4029ee | ||
|
|
ab0189c813 | ||
|
|
bb484a799e | ||
|
|
ad9f1571ce | ||
|
|
f800557824 | ||
|
|
13f81f4aa7 | ||
|
|
d3ae752c53 | ||
|
|
e3437244b5 | ||
|
|
1efeb59166 | ||
|
|
d4fc18f375 | ||
|
|
58680edb12 | ||
|
|
34141954c7 | ||
|
|
cba00be622 | ||
|
|
de78dd685b | ||
|
|
88abb50229 | ||
|
|
6d6b8595df | ||
|
|
66bd4774a8 | ||
|
|
c117fa4bf9 | ||
|
|
b040825b86 | ||
|
|
3c793ef153 | ||
|
|
cff0764b7f | ||
|
|
a3377921eb | ||
|
|
a61ffbafe5 | ||
|
|
190b474610 | ||
|
|
85e90b0f80 | ||
|
|
516ca6a442 | ||
|
|
fe993ca94d | ||
|
|
f8683063fb | ||
|
|
7c83eb6e63 | ||
|
|
58e8ecf48f | ||
|
|
c5e44330a5 | ||
|
|
ae82762c31 | ||
|
|
2ac7401b44 | ||
|
|
44af79223e | ||
|
|
03fc62ad2f | ||
|
|
68c865c9e6 | ||
|
|
6dc94e39a7 | ||
|
|
8146b04ffb | ||
|
|
5b19cf7875 | ||
|
|
53fae55652 | ||
|
|
bd66a92e7c | ||
|
|
165ef61de3 | ||
|
|
7dbbde8c5e | ||
|
|
888f4f9503 | ||
|
|
2c6f0581ac | ||
|
|
916faecb83 | ||
|
|
5d7b71b7a7 | ||
|
|
0dde65a26b | ||
|
|
b177311aee | ||
|
|
778f0dff9b | ||
|
|
342579aa6f | ||
|
|
01b9bbb0f9 | ||
|
|
852a0b29c3 | ||
|
|
55290c8584 | ||
|
|
e633091d23 | ||
|
|
4c9fdb9f74 | ||
|
|
e0d30a22d7 | ||
|
|
42ec4e3090 | ||
|
|
3735002751 | ||
|
|
d47a80c05e | ||
|
|
9dd9952138 | ||
|
|
71c4ae2336 | ||
|
|
c0268d9217 | ||
|
|
da448cdc99 | ||
|
|
d619a87aa5 | ||
|
|
a931301bef | ||
|
|
265b0bc9bb | ||
|
|
13f249a826 | ||
|
|
c66e08acb3 | ||
|
|
f5446552f3 | ||
|
|
364d302bca | ||
|
|
60e71c1b8b | ||
|
|
342921eb97 | ||
|
|
df0ed76a76 | ||
|
|
d7521f5428 | ||
|
|
c7f10de442 | ||
|
|
f60bd811e9 | ||
|
|
cd0637a953 | ||
|
|
8809f65b13 | ||
|
|
c906619620 | ||
|
|
5710d2fe2e | ||
|
|
32fe5fbc11 | ||
|
|
bcb0a24a8f | ||
|
|
96ed96dabd | ||
|
|
8ad2ca9ae2 | ||
|
|
23a37ecac4 | ||
|
|
47bae3abf6 | ||
|
|
dff9dd56a0 | ||
|
|
7182508a75 | ||
|
|
cb0fe9e195 | ||
|
|
87f2984df0 | ||
|
|
24ce3e9d54 | ||
|
|
98cddfaf7a | ||
|
|
d1fcb8ce9d | ||
|
|
b4ace35304 | ||
|
|
888ce058d8 | ||
|
|
c394e86184 | ||
|
|
4aaadc2f29 | ||
|
|
abef92c037 | ||
|
|
87019d7721 | ||
|
|
fc265c5a92 | ||
|
|
d999efe6e5 | ||
|
|
97e8c55ee8 | ||
|
|
739fa96737 | ||
|
|
d474f2986e | ||
|
|
a863c62cd1 | ||
|
|
5ac353d845 | ||
|
|
faecd066a6 | ||
|
|
6efc43cc0a | ||
|
|
4496e0e8e7 | ||
|
|
64d5ea39c0 | ||
|
|
4af8403aa2 | ||
|
|
2f84a6bd73 | ||
|
|
eda15d52a8 | ||
|
|
741d5f10c6 | ||
|
|
4f92fd8ddd | ||
|
|
7f2359a5cc | ||
|
|
6e942e5898 | ||
|
|
1c9bb168bb | ||
|
|
799de21af6 | ||
|
|
1cb1edeb68 | ||
|
|
15c1162b24 | ||
|
|
a7175ee029 | ||
|
|
68516f91be | ||
|
|
531ffa8104 | ||
|
|
d7212df0f1 | ||
|
|
a28bc3ebf6 | ||
|
|
55bb4dab7a | ||
|
|
5fa4209ca0 | ||
|
|
4f6c8c6652 | ||
|
|
a7303a3d3d | ||
|
|
70c6b408dc | ||
|
|
be7af36c51 | ||
|
|
3b36bde953 | ||
|
|
c3986d4c5a | ||
|
|
b3a1a0ca9d | ||
|
|
e448d31d63 | ||
|
|
37de48979e | ||
|
|
08f955e17b | ||
|
|
3435ae9bd0 | ||
|
|
7a9295778c | ||
|
|
f7746d0000 | ||
|
|
96a6ea0f26 | ||
|
|
6242786158 | ||
|
|
b430ceec7a | ||
|
|
3a7bf54ad5 | ||
|
|
c1cb307b4b | ||
|
|
af6118d98b | ||
|
|
ea3337a210 | ||
|
|
035a13f7e4 | ||
|
|
f14adfd75e | ||
|
|
d218be3482 | ||
|
|
f4c077e85e | ||
|
|
1c7785ab1e | ||
|
|
87257f869c | ||
|
|
b936741032 | ||
|
|
2b2a3c87b6 | ||
|
|
6e962ac51e | ||
|
|
991ab811cb | ||
|
|
3249824264 | ||
|
|
1c465dc33a | ||
|
|
2a87d78f69 | ||
|
|
3ba4db7030 | ||
|
|
d29702134a | ||
|
|
1c82a1e1e5 | ||
|
|
2d0c7adba9 | ||
|
|
0b4b31a960 | ||
|
|
8a21e5a8c6 | ||
|
|
fa9c8d04d4 | ||
|
|
c5fabfb068 | ||
|
|
e2aee6c4af | ||
|
|
2598ca668b | ||
|
|
cd7ad50bc8 | ||
|
|
5e4a1441cb | ||
|
|
9dea2ae87c | ||
|
|
795268bb7c | ||
|
|
70cbc66b7f | ||
|
|
b63276e70f | ||
|
|
b0c03e2be9 | ||
|
|
8475e0e492 | ||
|
|
7f06cc7ed0 | ||
|
|
10d40508e6 | ||
|
|
daf8f7a669 | ||
|
|
15fa9ab06d | ||
|
|
7e70e4842b | ||
|
|
9e9d33a2db | ||
|
|
b32aa4797d | ||
|
|
826ddc5403 | ||
|
|
3bd4e1e8cd | ||
|
|
51e23e0ab7 | ||
|
|
08650cb14c | ||
|
|
24c28cd715 | ||
|
|
c0c6a97c35 | ||
|
|
d47d379216 | ||
|
|
eb1b138ec2 | ||
|
|
13f596433b | ||
|
|
3fe4469bfa | ||
|
|
8eb50bce43 | ||
|
|
fc10fafa25 | ||
|
|
efcbec3df5 | ||
|
|
3e2e4b5a33 | ||
|
|
79332c0d66 | ||
|
|
bdfc296faf | ||
|
|
2ad1c4e800 | ||
|
|
0da7ba57b5 | ||
|
|
b3d12c5a3d | ||
|
|
bc7402aa3a | ||
|
|
f233dffbd6 | ||
|
|
c2da3809f7 | ||
|
|
48346c878f | ||
|
|
a0274c08b5 | ||
|
|
f627e27749 | ||
|
|
0b6cae6792 | ||
|
|
e5610f1877 | ||
|
|
c376170644 | ||
|
|
48163179eb | ||
|
|
b4c1b27e03 | ||
|
|
c90b87e021 | ||
|
|
ad17b21889 | ||
|
|
a366868535 | ||
|
|
f55d35c5a0 | ||
|
|
6af8e11450 | ||
|
|
1a288c06d9 | ||
|
|
4aeb093206 | ||
|
|
1eb7a7061a | ||
|
|
eec6ab7615 | ||
|
|
5df9847f06 | ||
|
|
fb7a162f53 | ||
|
|
d73762eea3 | ||
|
|
d58405a353 | ||
|
|
0f8e9e2d86 | ||
|
|
c4a3f55be3 | ||
|
|
473108ae6e | ||
|
|
e401959b89 | ||
|
|
7706303828 | ||
|
|
f5e8a17e09 | ||
|
|
5509597dec | ||
|
|
70aeb5fddd | ||
|
|
3e06d40029 | ||
|
|
416e719bea | ||
|
|
9f5dc9309d | ||
|
|
b984e9dbd4 | ||
|
|
c60d9fcab1 | ||
|
|
47a63d90e7 | ||
|
|
bc112b0e7f | ||
|
|
8a82feeb7c | ||
|
|
0350f95e7b | ||
|
|
9a480deec4 | ||
|
|
c252546cee | ||
|
|
7b8a4ecd6f | ||
|
|
17b849c97a | ||
|
|
276a9836bd | ||
|
|
c140b2e749 | ||
|
|
b547302943 | ||
|
|
136c6c7734 | ||
|
|
3fb1634f21 | ||
|
|
881addc9e1 | ||
|
|
b7799aaefe | ||
|
|
ce854cf021 | ||
|
|
9e7b8ab7cf | ||
|
|
87bc224011 | ||
|
|
a4e8b552d6 | ||
|
|
62652202c4 | ||
|
|
001adf5096 | ||
|
|
ff66fd4bb6 | ||
|
|
e02b89d0d3 | ||
|
|
d1a1fec134 | ||
|
|
f3873b3d88 | ||
|
|
6e3b2102bc | ||
|
|
cc29b94d0f | ||
|
|
6eb71beaff | ||
|
|
39d7e3ec25 | ||
|
|
ac97bc14f6 | ||
|
|
31e93c3228 | ||
|
|
a720d81d0a | ||
|
|
359758d611 | ||
|
|
1f83b51d71 | ||
|
|
a5a7d3a297 | ||
|
|
4fc78878e0 | ||
|
|
b973bffa94 | ||
|
|
d1c80404fe | ||
|
|
9a12959ab6 | ||
|
|
070c810e2d | ||
|
|
71ec4609eb | ||
|
|
0f7db203fb | ||
|
|
4e25abc9a9 | ||
|
|
839dbff2aa | ||
|
|
f6f5ea4173 | ||
|
|
9a37d9cb1e | ||
|
|
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 | ||
|
|
7a6fd4c1c7 | ||
|
|
8395d24616 | ||
|
|
7d085960eb | ||
|
|
3884317181 | ||
|
|
089a2435f8 | ||
|
|
8ed16deb24 | ||
|
|
a577af9067 | ||
|
|
59af13651b | ||
|
|
787568f371 | ||
|
|
f0019fc506 | ||
|
|
9f639210ca | ||
|
|
deec574421 | ||
|
|
04657e42d5 | ||
|
|
1b88775534 | ||
|
|
7f6537557d | ||
|
|
518233ca79 | ||
|
|
bc72130d71 | ||
|
|
855decd3a7 | ||
|
|
0090cbdba6 | ||
|
|
73ff720972 | ||
|
|
c561e1378d | ||
|
|
aa2c47d835 | ||
|
|
536b84680b | ||
|
|
7508b795bf | ||
|
|
76ee1d18bf | ||
|
|
379bc86547 | ||
|
|
066696644f | ||
|
|
755bcd3722 | ||
|
|
1985aa9666 | ||
|
|
f4663a36da | ||
|
|
521e6fdcfc | ||
|
|
61ab574e38 | ||
|
|
660cb6a085 | ||
|
|
4274208833 | ||
|
|
34db05b421 | ||
|
|
1657be22a3 | ||
|
|
3636b9ffaa | ||
|
|
e3cd264571 | ||
|
|
69555b0943 | ||
|
|
522c05cf9a | ||
|
|
f0b4fdaf5e | ||
|
|
ac6ce98375 | ||
|
|
1b3cadaa39 | ||
|
|
61ca7d596c | ||
|
|
688d573295 | ||
|
|
ec6e0bf0c0 | ||
|
|
184dede92f | ||
|
|
d2cc0323fb | ||
|
|
3a1eefd331 | ||
|
|
824f1c7944 | ||
|
|
7bc8218d81 | ||
|
|
a405cda63c | ||
|
|
7afa3a4a48 | ||
|
|
c80b3d8c3f | ||
|
|
ef6122c622 | ||
|
|
75fb17b891 | ||
|
|
2abbf2498f | ||
|
|
b91b50c01f | ||
|
|
06891710f2 | ||
|
|
b765ec32b9 | ||
|
|
a70d070cc5 | ||
|
|
1f1fbe187e | ||
|
|
fc63847406 | ||
|
|
f58677d123 | ||
|
|
7ab1538861 | ||
|
|
7ad0f94de9 | ||
|
|
8af534a52c | ||
|
|
7447419266 | ||
|
|
5216de37a4 | ||
|
|
ccc0d1eb1d | ||
|
|
7fc0890881 | ||
|
|
b17f1d76c0 | ||
|
|
451b5fc969 | ||
|
|
1e678fcab1 | ||
|
|
48bcc6ee2b | ||
|
|
32734c7c3c | ||
|
|
aaf375d0a5 | ||
|
|
9680f811f6 | ||
|
|
bda41fa509 | ||
|
|
7ea84b6890 | ||
|
|
cc234d944a | ||
|
|
ac84096d1f | ||
|
|
a1cc591b29 | ||
|
|
da0405080e | ||
|
|
0c0a3e2dd3 | ||
|
|
ad301e487c | ||
|
|
b5ae4aba38 | ||
|
|
8d2aad49e3 | ||
|
|
bc2b4963a0 | ||
|
|
ee7118a816 | ||
|
|
95dd949c09 | ||
|
|
9326552e66 | ||
|
|
1e34e4b7cd | ||
|
|
06464f55e2 | ||
|
|
1b85e3f1a0 | ||
|
|
eac9dc63e3 | ||
|
|
30e8c8e1e4 | ||
|
|
d53d7795ee | ||
|
|
59c95e4243 | ||
|
|
f8a94f0de8 | ||
|
|
3b5f6214a6 | ||
|
|
542ad675b9 | ||
|
|
1e736b8ff7 | ||
|
|
a6d8c3f336 | ||
|
|
bb4aa89c10 | ||
|
|
09021eabb5 | ||
|
|
8d69d57113 | ||
|
|
eaa4c150ab | ||
|
|
a125c82ad2 | ||
|
|
93eff16a6a | ||
|
|
d2d9fe184d | ||
|
|
2d4ca358db | ||
|
|
39993af514 | ||
|
|
bef4934045 | ||
|
|
1312d9fc47 | ||
|
|
75aeac44e8 | ||
|
|
68f40ebba9 | ||
|
|
973007daac | ||
|
|
8060514230 | ||
|
|
b1a2f37a6e | ||
|
|
7c66b86028 | ||
|
|
cc248aae9b | ||
|
|
ca23c51aeb | ||
|
|
fca9a9b0f0 | ||
|
|
1ea15dbe05 | ||
|
|
8e34cd41f0 | ||
|
|
9ef1cc7cdf | ||
|
|
411acbbc2a | ||
|
|
32e83406c4 | ||
|
|
7e28fca126 | ||
|
|
e4ffb53900 | ||
|
|
7c2d381c28 | ||
|
|
bde47ca7c5 | ||
|
|
ea7f8108b0 | ||
|
|
98393ae2e2 | ||
|
|
759ac87019 | ||
|
|
a1e0e45e01 | ||
|
|
54170a084d | ||
|
|
1bbf83c07d | ||
|
|
ccd2b499ed | ||
|
|
1de50993a7 | ||
|
|
786c36876b | ||
|
|
8bd1a73e14 | ||
|
|
c7d692c3c3 | ||
|
|
f9b9e2f067 | ||
|
|
dafe63ca98 | ||
|
|
f49a7b227f | ||
|
|
f5e4eadb74 | ||
|
|
717eb9b883 | ||
|
|
5ba268efa8 | ||
|
|
25ff30e804 | ||
|
|
bdae761ee1 | ||
|
|
5af50297be | ||
|
|
32f761755e | ||
|
|
c4fea82ff9 | ||
|
|
6ded1170ac | ||
|
|
991f90f296 | ||
|
|
c979dad54a | ||
|
|
136ac7ecec | ||
|
|
3e8369b6dc | ||
|
|
a7dc44d27d | ||
|
|
07a874fd9b | ||
|
|
e35080cede | ||
|
|
ce8149b6fe | ||
|
|
a86179f429 | ||
|
|
56cf38ac98 | ||
|
|
b0f451eb3b | ||
|
|
d0829892c6 | ||
|
|
fdf88d7574 | ||
|
|
595f2d4d97 | ||
|
|
cae95647a4 | ||
|
|
a254fd9798 | ||
|
|
805edf9d7d | ||
|
|
eca2adb4b3 | ||
|
|
4eea7793ea | ||
|
|
67684d038d | ||
|
|
98b332edea | ||
|
|
e681e82066 | ||
|
|
08571358b1 | ||
|
|
8901a07fdb | ||
|
|
880da0072e | ||
|
|
a83600cc82 | ||
|
|
dd0628f85f | ||
|
|
e66dfd1879 | ||
|
|
bf2daeaf2d | ||
|
|
bd0ad74f4b | ||
|
|
79f671cc7c | ||
|
|
0f9c48b1d2 | ||
|
|
538ba24fd7 | ||
|
|
d37d8d7b69 | ||
|
|
f4a0483ab8 | ||
|
|
f5f95a38c4 | ||
|
|
3e7053ac59 | ||
|
|
420ef2c419 | ||
|
|
9fb3f7a9ab | ||
|
|
734a94a20c | ||
|
|
b44be3e944 | ||
|
|
fc0302cf07 | ||
|
|
4fdc39dde8 | ||
|
|
9a933bc2ce | ||
|
|
524dc9afd6 | ||
|
|
e4d709cbf8 | ||
|
|
48c1586cd1 | ||
|
|
7bd0cf5b8f | ||
|
|
fcb69e5cdc | ||
|
|
96557d23a3 | ||
|
|
4e5db0ad4a | ||
|
|
c81a32f071 | ||
|
|
6f2623fd69 | ||
|
|
b4235b3165 | ||
|
|
d25c0e42c7 | ||
|
|
0ecfbf27c3 | ||
|
|
fb4c98c2c8 | ||
|
|
cd8e38b13f | ||
|
|
b35d0d8e9a | ||
|
|
c948e309f2 | ||
|
|
d1f83bcc81 | ||
|
|
e0fde757fd | ||
|
|
25d34a5c80 | ||
|
|
610364e3a6 | ||
|
|
036e70b024 | ||
|
|
ac13ad106a | ||
|
|
bd9e9eccbd | ||
|
|
8ff9d697c9 | ||
|
|
62b68c8046 | ||
|
|
e4724e5c1c | ||
|
|
559e727bf7 | ||
|
|
126642b633 | ||
|
|
cca4e06786 | ||
|
|
2f1faea89b | ||
|
|
3d90ec146f | ||
|
|
1bc209b441 | ||
|
|
1433e6da69 | ||
|
|
f8f4c862e8 | ||
|
|
226df8e717 | ||
|
|
6c92af2067 | ||
|
|
54c7298ce4 | ||
|
|
642a979a27 | ||
|
|
e733c93423 | ||
|
|
ffdb58a51a | ||
|
|
c053133207 | ||
|
|
9098bbf3b3 | ||
|
|
68618b8810 | ||
|
|
e553d27f41 | ||
|
|
d092924c63 | ||
|
|
34027489e0 | ||
|
|
d1239eae92 | ||
|
|
331050969b | ||
|
|
259c3e72b0 | ||
|
|
8f7a38336d | ||
|
|
999dfffc9b | ||
|
|
527a51cec5 | ||
|
|
20c15aead5 | ||
|
|
fb859e5674 | ||
|
|
4f2dcb1714 | ||
|
|
64e74631e0 | ||
|
|
fba31efb74 | ||
|
|
435f1ed70d | ||
|
|
94f34ca10a | ||
|
|
b0633744fa | ||
|
|
c127e8aaec | ||
|
|
bf4e725d5d | ||
|
|
663717f465 | ||
|
|
12b159ac41 | ||
|
|
9299c8f0b4 | ||
|
|
dfef3f1099 | ||
|
|
fa3690f488 | ||
|
|
4acbfa2ade | ||
|
|
ef86d74736 | ||
|
|
118f39d45b | ||
|
|
77867907ed | ||
|
|
98c1b32565 | ||
|
|
7a176e87d5 | ||
|
|
79c9d8a180 | ||
|
|
7d8219327b | ||
|
|
4ac4bdbb38 | ||
|
|
f494f2864c | ||
|
|
017f22b47f | ||
|
|
dec41b556b | ||
|
|
be2961da2c | ||
|
|
914cc65c9d | ||
|
|
6479c2ed3f | ||
|
|
c1a04ecbfd | ||
|
|
69b06c50c4 | ||
|
|
6aaf8d8c10 | ||
|
|
4cf64834ed | ||
|
|
b8709f5046 | ||
|
|
24448f741f | ||
|
|
76533c52dc | ||
|
|
3ff984d7a7 | ||
|
|
7a52790b50 | ||
|
|
7b329a2d79 | ||
|
|
599dc93c64 | ||
|
|
8b54f00466 | ||
|
|
8469faef03 | ||
|
|
bceec82f35 | ||
|
|
ed521de525 | ||
|
|
d157de203a | ||
|
|
1bfbf40bd5 | ||
|
|
6d19c6742c | ||
|
|
a628b06977 | ||
|
|
6b2d24de2c | ||
|
|
e23d790fa7 | ||
|
|
2a5904a580 | ||
|
|
4610ac79c2 | ||
|
|
142f5be922 | ||
|
|
b17dd0c435 | ||
|
|
3669201179 | ||
|
|
a5c48193c7 | ||
|
|
4366275bab | ||
|
|
c579310a00 | ||
|
|
96553aa7ef | ||
|
|
2094283b80 | ||
|
|
4c631ac621 | ||
|
|
d96d3893dd | ||
|
|
b73b51a9e4 | ||
|
|
3c1edccb7b | ||
|
|
b23c290630 | ||
|
|
c7b562becf | ||
|
|
5648a81936 | ||
|
|
daa3d0e2da | ||
|
|
c9a66d41fe | ||
|
|
0ee1bd82c5 | ||
|
|
53e1f937bc | ||
|
|
604f343c49 | ||
|
|
e9c4c3018b | ||
|
|
db1babe6a9 | ||
|
|
f1abcc7a4c | ||
|
|
97e1254a2d | ||
|
|
89b0a3d963 | ||
|
|
3a79260d3a | ||
|
|
43a4dc1053 | ||
|
|
e53fe9a278 | ||
|
|
f5a95bb50b | ||
|
|
0e23e41d48 | ||
|
|
ac69049ec2 | ||
|
|
b2a2dd1154 | ||
|
|
31837783c0 | ||
|
|
d40fb72395 | ||
|
|
1c548d5e59 | ||
|
|
be59d0ec23 | ||
|
|
0bc467516a | ||
|
|
844f11f284 | ||
|
|
1cf1e7b3b4 | ||
|
|
18b72cc829 | ||
|
|
271f87e5d4 | ||
|
|
2e6c7f4549 | ||
|
|
6819304740 | ||
|
|
a795ab99c7 | ||
|
|
567e56313a | ||
|
|
9e95e92bdf | ||
|
|
be60c7b9d1 | ||
|
|
7d81641065 | ||
|
|
17d8573ef0 | ||
|
|
e2dd78f744 | ||
|
|
06b91d8eb9 | ||
|
|
9ec5422c37 | ||
|
|
1935e11c3c | ||
|
|
ec14031abd | ||
|
|
024a9bafbd | ||
|
|
27741d9fd9 | ||
|
|
e3bdb76326 | ||
|
|
9369576459 | ||
|
|
8a405c6ca1 | ||
|
|
94ad1c6477 | ||
|
|
6f039cc2ac | ||
|
|
6216ca2c70 | ||
|
|
c6e27b608e | ||
|
|
f76584a57c | ||
|
|
7bea78ced6 | ||
|
|
1264288cb5 | ||
|
|
0f0ea7f779 | ||
|
|
0b4af330ce | ||
|
|
6dd41b67fb | ||
|
|
1521eefb62 | ||
|
|
a036a0e818 | ||
|
|
7583ded808 | ||
|
|
78818f4465 | ||
|
|
7a49cb5667 | ||
|
|
23212669ac | ||
|
|
3ce0f9a653 | ||
|
|
d834adc14f | ||
|
|
b84ba8967a | ||
|
|
79845f2834 | ||
|
|
78ece130a4 | ||
|
|
bd37c66630 | ||
|
|
371d1c36b3 | ||
|
|
d0f821ad3d | ||
|
|
ded8347d6b | ||
|
|
c4a5c57dc3 | ||
|
|
404e813c52 | ||
|
|
90d0a8db38 | ||
|
|
956ff9ff72 | ||
|
|
1eca49c6ed | ||
|
|
34758d5c15 | ||
|
|
befbfe6115 | ||
|
|
900748fca1 | ||
|
|
87ee248169 | ||
|
|
bb7c4fa361 | ||
|
|
c613d37048 | ||
|
|
d52a22e4db | ||
|
|
6dfb45bcdf | ||
|
|
145794936f | ||
|
|
301c680fd7 | ||
|
|
d27cbec598 | ||
|
|
f5be54d6ab | ||
|
|
1e19f7ba5f | ||
|
|
db719fb0d7 | ||
|
|
b0d4f4c10e | ||
|
|
238d23d775 | ||
|
|
c019068f06 | ||
|
|
715d1f4504 | ||
|
|
4f092bee9f | ||
|
|
1bbd10fe07 | ||
|
|
088aac8597 | ||
|
|
81c652d5d2 | ||
|
|
d7761c1480 | ||
|
|
93689aa51a | ||
|
|
46e6ad492a | ||
|
|
97efa5c36c | ||
|
|
0b1ffe2755 | ||
|
|
8c35542d1f | ||
|
|
0e9480317d | ||
|
|
b695d088cf | ||
|
|
81dc5750ca | ||
|
|
d82434cf27 | ||
|
|
cd6058f3d4 | ||
|
|
9be3ba223c | ||
|
|
a261989cda | ||
|
|
7b5c3eb05e | ||
|
|
0feec72eee | ||
|
|
be8bd99aa4 | ||
|
|
355b8bcd73 | ||
|
|
d58e4c273c | ||
|
|
a217ad3095 | ||
|
|
3d6feada8a | ||
|
|
5f78da2025 | ||
|
|
a05e4fa512 | ||
|
|
2119a4c462 | ||
|
|
1d5a1da9f8 | ||
|
|
2e7d19945c | ||
|
|
5d2c5c4c73 | ||
|
|
8694312695 | ||
|
|
d9d6bc5278 | ||
|
|
ebed4c3af0 | ||
|
|
172875cf15 | ||
|
|
4d26e9e4f4 | ||
|
|
8f4455f296 | ||
|
|
2e1d43deb2 | ||
|
|
6780f72000 | ||
|
|
39e01d2d4b | ||
|
|
f75502950b | ||
|
|
974f27e7e9 | ||
|
|
af32f69eb0 | ||
|
|
0cd2f40764 | ||
|
|
0d95824995 | ||
|
|
bbc09ffba9 | ||
|
|
a4677968cf | ||
|
|
03b1cddc31 | ||
|
|
9c2dd04993 | ||
|
|
a84a93fafe | ||
|
|
5fdcc397b1 | ||
|
|
5664871e5f | ||
|
|
55d9e0fada | ||
|
|
929e3011c6 | ||
|
|
07d70ff560 | ||
|
|
58c2960960 | ||
|
|
00d943d513 | ||
|
|
71c780da06 | ||
|
|
3b18cba889 | ||
|
|
2974e20550 | ||
|
|
430d841a2c | ||
|
|
31ec50d7da | ||
|
|
5ad0e46f08 | ||
|
|
1b5814e338 | ||
|
|
255810c0d6 | ||
|
|
5d2640376e | ||
|
|
d02984bbb7 | ||
|
|
0f9555207a | ||
|
|
885448d74c | ||
|
|
b14545b3ff | ||
|
|
9a5a86734f | ||
|
|
d1d1505045 | ||
|
|
144ce1dc21 | ||
|
|
aa126974ba | ||
|
|
707de53457 | ||
|
|
10f83cf43d | ||
|
|
59ee743c5f | ||
|
|
d54765c442 | ||
|
|
91262d5d3e | ||
|
|
1c09c743b1 | ||
|
|
06ce139fcc | ||
|
|
fae5bb3183 | ||
|
|
6fe25398d6 | ||
|
|
909ce14fc4 | ||
|
|
935b920120 | ||
|
|
b31427cd4a | ||
|
|
e2e3379d79 | ||
|
|
6b1ef85dd8 | ||
|
|
92325ada0c | ||
|
|
1707e0f9e2 | ||
|
|
7ff701e816 | ||
|
|
2e3c141795 | ||
|
|
76f79ba748 | ||
|
|
9dd891bb28 | ||
|
|
99f106d1cf | ||
|
|
3816cae745 | ||
|
|
759c0627e1 | ||
|
|
e03dfae507 | ||
|
|
c7677b892a | ||
|
|
da7b63972d | ||
|
|
499957d9ba | ||
|
|
582250008b | ||
|
|
a9b31409d5 | ||
|
|
98355b8086 | ||
|
|
70ed474b38 | ||
|
|
4775934364 | ||
|
|
25f2cb3d6b | ||
|
|
154f9a3aca | ||
|
|
b9df3bf20c | ||
|
|
6abd193fe3 | ||
|
|
362099a512 | ||
|
|
fdfc3dc9f3 | ||
|
|
4937459225 | ||
|
|
be2f866b4c | ||
|
|
f08aacf7d6 | ||
|
|
4fa6112efe | ||
|
|
1623ba6889 | ||
|
|
766526c791 | ||
|
|
5c15e29f2b | ||
|
|
0413e1605f | ||
|
|
0e5a1f8352 | ||
|
|
e5a2b8544d | ||
|
|
736a6a291c | ||
|
|
6e69cff118 | ||
|
|
cf72f20426 | ||
|
|
d479210cee | ||
|
|
b781537597 | ||
|
|
ea1438dad8 | ||
|
|
d2e9d069b4 | ||
|
|
58379559cc | ||
|
|
b3e6c81565 | ||
|
|
a6a3c3df45 | ||
|
|
6e3d4c4045 | ||
|
|
ca60b701ee | ||
|
|
e24c0b98d7 | ||
|
|
f389ac80a9 | ||
|
|
50f2f002d9 | ||
|
|
9ec7528475 | ||
|
|
a8e2a43a09 | ||
|
|
eb06fa95e4 | ||
|
|
1db8b61de7 | ||
|
|
38c66db8d6 | ||
|
|
f8be7d4219 | ||
|
|
13e29995f5 | ||
|
|
7c583c7316 | ||
|
|
9fecec5e85 | ||
|
|
9e696bd468 | ||
|
|
6ab6d4bfc1 | ||
|
|
cb1bcc7ebb | ||
|
|
19ba7d6318 | ||
|
|
7753ca1f49 | ||
|
|
d52a796c39 | ||
|
|
60514d457c | ||
|
|
5bc00efe42 | ||
|
|
c45f3133bc | ||
|
|
fb47591de0 | ||
|
|
514d129c49 | ||
|
|
db843fc12d | ||
|
|
63787382d8 | ||
|
|
85d4d142d8 | ||
|
|
3cd2af41e4 | ||
|
|
b214eda4f0 | ||
|
|
0771727d41 | ||
|
|
a5d74a1876 | ||
|
|
23bf32f767 | ||
|
|
87a819edee | ||
|
|
27a1234874 | ||
|
|
51f289d1e6 | ||
|
|
d0d6dc61e8 | ||
|
|
d91c8c50d2 | ||
|
|
e20a4f84d6 | ||
|
|
bbd6f4ba8e | ||
|
|
2a951cd2f9 | ||
|
|
a538066d5a | ||
|
|
c10b0bdd50 | ||
|
|
431efc8979 | ||
|
|
2d6dbe290c | ||
|
|
c33e3e3967 | ||
|
|
71b3374bd5 | ||
|
|
de343e3cce | ||
|
|
384958ed3d | ||
|
|
1cd5beeb06 | ||
|
|
4c70e359d0 | ||
|
|
f9c3005bff | ||
|
|
9147074d8b | ||
|
|
7007bddaef | ||
|
|
2f8dc29182 | ||
|
|
6066594bbe | ||
|
|
40c0289176 | ||
|
|
acf1af0cd9 | ||
|
|
62791bdfa2 | ||
|
|
47f1218d69 | ||
|
|
1179355dab | ||
|
|
3d807132e4 | ||
|
|
42d0b4c280 | ||
|
|
d313ae7d23 | ||
|
|
28a69e25ea | ||
|
|
ad911a7ac3 | ||
|
|
5575de140d | ||
|
|
a5ce1eb1af | ||
|
|
76a78cd8bc | ||
|
|
0b25efc12a | ||
|
|
64cae087b6 | ||
|
|
b7cc59c503 | ||
|
|
7eb8d18a99 | ||
|
|
e7bf3e5e87 | ||
|
|
5aafd07b37 | ||
|
|
053f3a831d | ||
|
|
a2d2e5c047 | ||
|
|
dd3a922035 | ||
|
|
0e916c6038 | ||
|
|
87fcb63975 | ||
|
|
68b2cc5538 | ||
|
|
4dcf3697ff | ||
|
|
ea77525546 | ||
|
|
17d5a07ec2 | ||
|
|
3966b9c609 | ||
|
|
1c47fbd96b | ||
|
|
1691bdcafc | ||
|
|
6a5ef41fb3 | ||
|
|
09b6f4b00d | ||
|
|
7067b0aa28 | ||
|
|
112e731150 | ||
|
|
1336e41460 | ||
|
|
7c1b7890d3 | ||
|
|
dd0700b025 | ||
|
|
04d8e8b25f | ||
|
|
3723efcb1d | ||
|
|
054b40b6fa | ||
|
|
6773a7798f | ||
|
|
2d4c8e5945 | ||
|
|
087173c887 | ||
|
|
57835c00ad | ||
|
|
4ed886ae6e | ||
|
|
740819ef7b | ||
|
|
829230689e | ||
|
|
77ba4cc2f9 | ||
|
|
e94989fe4d | ||
|
|
c11b88061f | ||
|
|
647c5433f8 | ||
|
|
8f694072a5 | ||
|
|
9a689986c6 | ||
|
|
3174b31d96 | ||
|
|
4eb61975b7 | ||
|
|
76e26e1042 | ||
|
|
9069dfd005 | ||
|
|
2be5d2daad | ||
|
|
22cd0063e5 | ||
|
|
3d2e458a4d | ||
|
|
a57568d716 | ||
|
|
61f543cade | ||
|
|
b8771f9615 | ||
|
|
d5d4b28220 | ||
|
|
a037edaccd | ||
|
|
356bbb8351 | ||
|
|
1f0fa9318a | ||
|
|
15c1707887 | ||
|
|
9dec7aa9c1 | ||
|
|
bc3d7454e0 | ||
|
|
56901bc7c3 | ||
|
|
5c7f570b16 | ||
|
|
4f6e5fe323 | ||
|
|
7d682ffea7 | ||
|
|
cef40af209 | ||
|
|
a358449ab1 | ||
|
|
8ef6b72514 | ||
|
|
620bbabc61 | ||
|
|
7ef6aa6405 | ||
|
|
7ad1d4fd66 | ||
|
|
bf5c2bf604 | ||
|
|
b8fe70a516 | ||
|
|
06963d0fca | ||
|
|
b964901f7d | ||
|
|
b52c1d9d3a | ||
|
|
a24e12e6dd | ||
|
|
3c6cd53b23 | ||
|
|
4f69fe59c7 | ||
|
|
d2e02b7d96 | ||
|
|
a57873b710 | ||
|
|
30ce7e8a64 | ||
|
|
f0af1e5ec6 | ||
|
|
f7ca98bdc4 | ||
|
|
7df0935a51 | ||
|
|
f22ee86517 | ||
|
|
8f98c608b9 | ||
|
|
32c58f06e0 | ||
|
|
040f7b6595 | ||
|
|
d2476f0db3 | ||
|
|
952cf8f4f3 | ||
|
|
a138e47560 | ||
|
|
7d6916547f | ||
|
|
6cd7888e46 | ||
|
|
1d54358e52 | ||
|
|
4c80c473ed | ||
|
|
571a4b2654 | ||
|
|
501972bf72 | ||
|
|
99cdaff70d | ||
|
|
c36b5017b8 | ||
|
|
a4cf6bec19 | ||
|
|
0154b302ce | ||
|
|
ec99e9da81 | ||
|
|
e052b21f32 | ||
|
|
b2f0246498 | ||
|
|
c1659c79ef | ||
|
|
4a7cb3e8a8 | ||
|
|
0de40240bb | ||
|
|
d79c77caca | ||
|
|
2b106d0b3a | ||
|
|
8fef024528 | ||
|
|
6963e540db | ||
|
|
3ef526f5fa | ||
|
|
eecd22ff7b | ||
|
|
add7e8fb6b | ||
|
|
f6e09367a7 | ||
|
|
3aae15ecfb | ||
|
|
f5ad6eb18d | ||
|
|
7f1b717ac7 | ||
|
|
55bdb41632 | ||
|
|
7c06e407ec | ||
|
|
c13ad7ec47 | ||
|
|
d2094cc33d | ||
|
|
c3469aed19 | ||
|
|
232ce2b2c8 | ||
|
|
882582b307 | ||
|
|
ebaa0489b4 | ||
|
|
1a1c244dc3 | ||
|
|
320989b05d | ||
|
|
9d682a8dc1 | ||
|
|
37c3cf430d | ||
|
|
751411c40d | ||
|
|
6a46226b3a | ||
|
|
42e66aa24c | ||
|
|
5cb1f5c795 | ||
|
|
12b9c8409e | ||
|
|
e8ca590142 | ||
|
|
863dff5179 | ||
|
|
3fedd74ba2 | ||
|
|
78ffe4787f | ||
|
|
a4b4af889b | ||
|
|
d286ee98b9 | ||
|
|
42be591878 | ||
|
|
3a4c683f04 | ||
|
|
e7d29902a6 | ||
|
|
64bd756832 | ||
|
|
8642efd0d6 | ||
|
|
063393d62d | ||
|
|
7a55d06e0d | ||
|
|
6f82f7a6f6 | ||
|
|
33d213bb37 | ||
|
|
a426e396c4 | ||
|
|
fafeb69cb6 | ||
|
|
b9277bdb6a | ||
|
|
b53713d322 | ||
|
|
2f22174f21 | ||
|
|
d820215b35 | ||
|
|
ea4a03762a | ||
|
|
46ef7d1dc8 | ||
|
|
e340a8203e | ||
|
|
3459d319d1 | ||
|
|
09ec75a629 | ||
|
|
4df7868d39 | ||
|
|
bc888e05da | ||
|
|
26c7f120e6 | ||
|
|
5b7be6ee4a | ||
|
|
951351a537 | ||
|
|
0b21c485ec | ||
|
|
068a7221ce | ||
|
|
a4772a4dbc | ||
|
|
2ee91aedb1 | ||
|
|
d95447229b | ||
|
|
40ec33b604 | ||
|
|
35e3b2d555 | ||
|
|
aa9c2df9d9 | ||
|
|
f472cdf017 | ||
|
|
1dc587af1b | ||
|
|
aeb6292d0d | ||
|
|
7d91d5a619 | ||
|
|
7169bb4aa9 | ||
|
|
2db52650fc | ||
|
|
c1f62a573a | ||
|
|
08a740ff43 | ||
|
|
b67381d0dc | ||
|
|
07e9500818 | ||
|
|
c77cf82206 | ||
|
|
f8014b864e | ||
|
|
d58911fb37 | ||
|
|
b335d74565 | ||
|
|
3405fe45f4 | ||
|
|
095efec1d6 | ||
|
|
7ca6e85649 | ||
|
|
74be4fc399 | ||
|
|
3b4b1984ef | ||
|
|
6902ed178b | ||
|
|
fab9a9c547 | ||
|
|
376acbfad5 | ||
|
|
12458878c2 | ||
|
|
546434f867 | ||
|
|
ac2a1a449d | ||
|
|
e1bd49d6f3 | ||
|
|
ab94af5c6f | ||
|
|
c88ca682ef | ||
|
|
fc990e81cb | ||
|
|
e2ba16ccea | ||
|
|
76d4988d06 | ||
|
|
25ea348bd1 | ||
|
|
8ca5756339 | ||
|
|
029c171330 | ||
|
|
8f04bb36e7 | ||
|
|
b7334b4c31 | ||
|
|
a7f8404ecd | ||
|
|
6c65e14634 | ||
|
|
ddd491d45e | ||
|
|
5d78a10232 | ||
|
|
4d66e00afa | ||
|
|
531d06b824 | ||
|
|
c6a7f2f48a | ||
|
|
d4e4cbe105 | ||
|
|
41bd28fee3 | ||
|
|
a1a440c23e | ||
|
|
089e73f8d6 | ||
|
|
2c5548d25e | ||
|
|
65c2a918d4 | ||
|
|
8950ac03f8 | ||
|
|
26ef00bd3c | ||
|
|
efe3037cf5 | ||
|
|
f62c17e378 | ||
|
|
0f62178580 | ||
|
|
81c99202d3 | ||
|
|
3473b5b4d8 | ||
|
|
ba35824322 | ||
|
|
6afe7f23b0 | ||
|
|
19b27a485e | ||
|
|
ff81e809f4 | ||
|
|
fd2dd2aa23 | ||
|
|
82ed910630 | ||
|
|
90ba34e27c | ||
|
|
8ee3d639b2 | ||
|
|
0c5a792ac7 | ||
|
|
2af27ad9aa | ||
|
|
3b2b534567 | ||
|
|
3fa64fd008 | ||
|
|
b557c4c7eb | ||
|
|
0882faa2b2 | ||
|
|
3cd5eb3b3b | ||
|
|
4ff3d9d6b4 | ||
|
|
26c08b6c21 | ||
|
|
4db4149283 | ||
|
|
1ac15cd8ad | ||
|
|
b348deae3d | ||
|
|
18c71e96f8 | ||
|
|
f0f5767f15 | ||
|
|
15b7b73d7d | ||
|
|
e420b9d854 | ||
|
|
2855f61f4a | ||
|
|
2d1ebe9c72 | ||
|
|
c485a357cc | ||
|
|
5013576705 | ||
|
|
8886f8d0e6 | ||
|
|
fcb6d28d0b | ||
|
|
62402cb14b | ||
|
|
305ab1331b | ||
|
|
8212336aaa | ||
|
|
3e3dcd624f | ||
|
|
b30b3bb899 | ||
|
|
55b64e4b5e | ||
|
|
e411463442 | ||
|
|
660c6fbdaa | ||
|
|
ce6c7c6318 | ||
|
|
fa994de488 | ||
|
|
2348926995 | ||
|
|
735a816e54 | ||
|
|
a1b1b1da46 | ||
|
|
c3563c46ed | ||
|
|
0c80cd8ee9 | ||
|
|
b79f79e3aa | ||
|
|
af642a61b3 | ||
|
|
ef1aa91039 | ||
|
|
1960e2280c | ||
|
|
7c1b4daa6f | ||
|
|
7a24c346b0 | ||
|
|
64c2cf8fea | ||
|
|
81d538ce23 | ||
|
|
e327acece4 | ||
|
|
4e40377ac2 | ||
|
|
eeb1568fd5 | ||
|
|
0ba481368c | ||
|
|
38bf526fc5 | ||
|
|
bc363ea983 | ||
|
|
84f69dad19 | ||
|
|
4a13b9d57a | ||
|
|
a039749b4c | ||
|
|
15b84e142a | ||
|
|
45a8354004 | ||
|
|
c32d024071 | ||
|
|
205c27ac67 | ||
|
|
f5c2081302 | ||
|
|
e6c64e7933 | ||
|
|
a036580649 | ||
|
|
796d484b44 | ||
|
|
1f52f4c407 | ||
|
|
d567322fbc | ||
|
|
3ff1e677a1 | ||
|
|
ef325f0cf4 | ||
|
|
3d8810c928 | ||
|
|
d153974ee2 | ||
|
|
5b56cc19fb | ||
|
|
c48b22c858 | ||
|
|
65d0a49f5c | ||
|
|
6a48ca56eb | ||
|
|
a20aa42ac4 | ||
|
|
e92ee12893 | ||
|
|
5c66303ad6 | ||
|
|
27e3e9c906 | ||
|
|
f0b36a48c8 | ||
|
|
25cf88936f | ||
|
|
ae682c3e11 | ||
|
|
99994aef3e | ||
|
|
78043d1969 | ||
|
|
43e46b4cf6 | ||
|
|
9ec16c83be | ||
|
|
a24c687094 | ||
|
|
60cb2f9016 | ||
|
|
ac1a0994b6 | ||
|
|
f2cbf44ba5 | ||
|
|
dab552237e | ||
|
|
2201ba580e | ||
|
|
b7c33e3bde | ||
|
|
82980a2384 | ||
|
|
b6a30afc98 | ||
|
|
ed91f3e418 | ||
|
|
60c8d7bc7f | ||
|
|
5783c065ba | ||
|
|
adc19c987b | ||
|
|
3d38277706 | ||
|
|
64c704f0b9 | ||
|
|
69c6522734 | ||
|
|
0f8f98c8ff | ||
|
|
e384bfbdcb | ||
|
|
08e5094d7f | ||
|
|
4b3977bf00 | ||
|
|
c80ccabb0c | ||
|
|
ef5d23ebcd | ||
|
|
27b9a19be0 | ||
|
|
14175f1e77 | ||
|
|
269833af78 | ||
|
|
fca3ef06cd | ||
|
|
07a14ef8b2 | ||
|
|
21cde2888c | ||
|
|
4a7481889c | ||
|
|
0adb99b9dc | ||
|
|
36349ea0be | ||
|
|
ec3f7d1b61 | ||
|
|
f0359dd00d | ||
|
|
ef55c686bc | ||
|
|
5f7ce2041c | ||
|
|
328fcf113a | ||
|
|
24c857f1de | ||
|
|
a784e10d00 | ||
|
|
7eb6bf0397 | ||
|
|
49d6fdc036 | ||
|
|
8b35435f7c | ||
|
|
8ada751890 | ||
|
|
1a52e84874 | ||
|
|
53c5cbed23 | ||
|
|
4a81463880 | ||
|
|
09b7f5dbb1 | ||
|
|
6d7b6081ac | ||
|
|
31b7d79afe | ||
|
|
b2999e457f | ||
|
|
0f3203c312 | ||
|
|
a2edb26cd6 | ||
|
|
9bec528606 | ||
|
|
2f0e3b30a9 | ||
|
|
ff41a59f58 | ||
|
|
08f15335b5 | ||
|
|
bd36966bed | ||
|
|
f76933b149 | ||
|
|
378a074c82 | ||
|
|
c36cd31713 | ||
|
|
5e12ce1186 | ||
|
|
166aa72332 | ||
|
|
f9f6184f38 | ||
|
|
f625af9400 | ||
|
|
fc7952e7f3 | ||
|
|
cbce490e13 | ||
|
|
74a7f81d57 | ||
|
|
5b5591d8a8 | ||
|
|
c55f70218c | ||
|
|
6957ae33a9 | ||
|
|
8a5d6bba09 | ||
|
|
1d2c275fff | ||
|
|
d0fd26aa16 | ||
|
|
e20c5e9521 | ||
|
|
66203a982b | ||
|
|
b315601ce0 | ||
|
|
5f808dfbd7 | ||
|
|
0b73ca12fa | ||
|
|
03e2d0e329 | ||
|
|
182517e692 | ||
|
|
554e0a8dd0 | ||
|
|
b0f3f5784c | ||
|
|
3060d4aa1d | ||
|
|
1347d5126a | ||
|
|
5d1e1dcf4b | ||
|
|
74f5442401 | ||
|
|
c08bb0fb73 | ||
|
|
e30f065766 | ||
|
|
9dce9b45b3 | ||
|
|
60be6acf46 | ||
|
|
a5827a28d2 | ||
|
|
dcc875e41e | ||
|
|
128cf58433 | ||
|
|
7e0ca8e2f0 | ||
|
|
d79d1c69f7 | ||
|
|
a7d068abff | ||
|
|
7f931a0002 | ||
|
|
07b7c86c06 | ||
|
|
1f5c6343e6 | ||
|
|
290b615a16 | ||
|
|
57df171bc0 | ||
|
|
f08baea3dd | ||
|
|
2fb139c11b | ||
|
|
3420c8e6e0 | ||
|
|
b17bc22bb3 | ||
|
|
3adffb52e6 | ||
|
|
4df9f36841 | ||
|
|
5c9730a46c | ||
|
|
d9fcc198cf | ||
|
|
c831379436 | ||
|
|
d73ee7b70e | ||
|
|
cda2ae84b3 | ||
|
|
e7d6e0aa0c | ||
|
|
8c9fd200f9 | ||
|
|
79f118d859 | ||
|
|
7b10f91d8f | ||
|
|
3d19b4c83e | ||
|
|
79452d4693 | ||
|
|
cb13abfed0 | ||
|
|
0503f06089 | ||
|
|
f855a7d01a | ||
|
|
4c3b4b2557 | ||
|
|
79b5aa09a0 | ||
|
|
9bd6597666 | ||
|
|
6fe076b3d7 | ||
|
|
cec8aa7724 | ||
|
|
4c36a13ef2 | ||
|
|
24986abd07 | ||
|
|
8dfac376b5 | ||
|
|
e78733d975 | ||
|
|
dffba35e01 | ||
|
|
bd4ed7f719 | ||
|
|
752eaba41f | ||
|
|
ad517ce5b3 | ||
|
|
1f8413449d | ||
|
|
d0a7c8a487 | ||
|
|
ebb00c8e29 | ||
|
|
6543dc0c4c | ||
|
|
e459239d27 | ||
|
|
651443a7ff | ||
|
|
79fc6bdb45 | ||
|
|
245fbb5129 | ||
|
|
c7c11a0d4c | ||
|
|
c27f25922e | ||
|
|
af21c12fbc | ||
|
|
32b1f1de0e | ||
|
|
529e60864f | ||
|
|
972a3619c4 | ||
|
|
8458724d25 | ||
|
|
9422bb3fdf | ||
|
|
5afd8aedce | ||
|
|
86692050b5 | ||
|
|
460f6b990a | ||
|
|
896bd482c0 | ||
|
|
53f821f1e6 | ||
|
|
b33b791e6b | ||
|
|
17d31b380b | ||
|
|
a8b9d4edec | ||
|
|
f83f054875 | ||
|
|
15800c7e89 | ||
|
|
b531360763 | ||
|
|
b567933566 | ||
|
|
52d7d78865 | ||
|
|
23c5aef18e | ||
|
|
e19452a96c | ||
|
|
9ef5390714 | ||
|
|
fd0abefa43 | ||
|
|
19c14f987e | ||
|
|
122f19a615 | ||
|
|
3ca8e68f58 | ||
|
|
d41c7d025c | ||
|
|
b86f0cefa2 | ||
|
|
c226b7c2fd | ||
|
|
5865fcdd63 | ||
|
|
e68f34816f | ||
|
|
716baed7ff | ||
|
|
b882b49747 | ||
|
|
1f0610ef82 | ||
|
|
379e689dac | ||
|
|
65575e9670 | ||
|
|
5e71c4446e | ||
|
|
94a7fce217 | ||
|
|
3bc67f0c4f | ||
|
|
117af10225 | ||
|
|
536541d52b | ||
|
|
496d9272c1 | ||
|
|
34d3eed462 | ||
|
|
923fa97808 | ||
|
|
4440b8aa3f | ||
|
|
5a554d5b14 | ||
|
|
2cfeab21ce | ||
|
|
2b086e033c | ||
|
|
241fc706a9 | ||
|
|
7fadb4bc58 | ||
|
|
6c7c2ef372 | ||
|
|
86a2dd0a0a | ||
|
|
63f0774f75 | ||
|
|
d47741cac6 | ||
|
|
5d5811f7d9 | ||
|
|
dcc3a131d1 | ||
|
|
7212be9237 | ||
|
|
44e2e57837 | ||
|
|
d1be231290 | ||
|
|
a926daecbf | ||
|
|
53dd3135f1 | ||
|
|
cd64343a7a | ||
|
|
9e3c856a39 | ||
|
|
1e8ae5ede6 | ||
|
|
83fff1aa60 | ||
|
|
055af77666 | ||
|
|
cd8185f2bd | ||
|
|
6bd98f0617 | ||
|
|
14d43f1fcf | ||
|
|
3a64ad1fd0 | ||
|
|
5557c8e3e0 | ||
|
|
baf3e5049e | ||
|
|
b389939f87 | ||
|
|
af77cc6b57 | ||
|
|
1309d90dde | ||
|
|
a9766ef147 | ||
|
|
5a788adec1 | ||
|
|
50abd20bb3 | ||
|
|
37f9805dab | ||
|
|
b5f9e67d57 | ||
|
|
ed06894a01 | ||
|
|
d532c0f569 | ||
|
|
ec9df38086 | ||
|
|
81791cfccb | ||
|
|
2fb27e9146 | ||
|
|
946347b8ff | ||
|
|
c239825783 | ||
|
|
33e817e37e | ||
|
|
1b8e662a24 | ||
|
|
2acf81eb00 | ||
|
|
654175798b | ||
|
|
3e578a1909 | ||
|
|
b606265491 | ||
|
|
263cf2ed55 | ||
|
|
ab7104da8f | ||
|
|
1b7c47cb55 | ||
|
|
039faa8660 | ||
|
|
f7632fc60d | ||
|
|
2f098547ea | ||
|
|
c7c056410c | ||
|
|
e803090538 | ||
|
|
6265551a5a | ||
|
|
958f373550 | ||
|
|
2c51d5deec | ||
|
|
97cb8dc29b | ||
|
|
cd957c70c4 | ||
|
|
7b3d425783 | ||
|
|
b24203b323 | ||
|
|
3472009789 | ||
|
|
f27b53f5b5 | ||
|
|
e08bfe1248 | ||
|
|
74e708d85a | ||
|
|
7597e1a96a | ||
|
|
692da0b555 | ||
|
|
67ea0d4844 | ||
|
|
9b73d1c0e9 | ||
|
|
f3737e0648 | ||
|
|
19a013837e | ||
|
|
d730b113f4 | ||
|
|
7ae359c331 | ||
|
|
8de330a387 | ||
|
|
27d3cdbc94 | ||
|
|
106005004e | ||
|
|
92ad2c90c4 | ||
|
|
11a5a3c704 | ||
|
|
8bb5aa8fe8 | ||
|
|
4040be4d60 | ||
|
|
a9685611e2 | ||
|
|
b280a1f47e | ||
|
|
f8be5ef4cb | ||
|
|
587cb08dc4 | ||
|
|
8638dd48f7 | ||
|
|
2bca43f627 | ||
|
|
375a4556c7 | ||
|
|
b41c3f9273 | ||
|
|
35bdd146e4 | ||
|
|
8d249b635c | ||
|
|
932be9aa52 | ||
|
|
c6b81a9865 | ||
|
|
e0414f4202 | ||
|
|
6e4fb64e61 | ||
|
|
37863201ad | ||
|
|
4f6325c362 | ||
|
|
f98df1d9b7 | ||
|
|
3d913675a1 | ||
|
|
2f9af90118 | ||
|
|
3eb388185b | ||
|
|
858fb9ebad | ||
|
|
2f03f956f4 | ||
|
|
0199b05f25 | ||
|
|
e2d1033d5d | ||
|
|
c46ded4621 | ||
|
|
8cd9fd4e8c | ||
|
|
41979ff87c | ||
|
|
b11ed3b150 | ||
|
|
42245f1b56 | ||
|
|
c29ee43dbd | ||
|
|
d310a212f7 | ||
|
|
ca6c93f817 | ||
|
|
72914a606e | ||
|
|
4b957c2238 | ||
|
|
d853783f21 | ||
|
|
298c10d5bb | ||
|
|
6608462cac | ||
|
|
ca8e96946e | ||
|
|
6ed67e6dd5 | ||
|
|
1f658d4207 | ||
|
|
d3bc0b68ab | ||
|
|
1a0de6c68b | ||
|
|
eb601ffeb8 | ||
|
|
8d72ef6e52 | ||
|
|
bcf5b1335d | ||
|
|
bd7e05d799 | ||
|
|
c95f1aa9d3 | ||
|
|
86ffe37f11 | ||
|
|
b536f47e3c | ||
|
|
43b06eeae9 | ||
|
|
067857e0ac | ||
|
|
b3e10ed75b | ||
|
|
a353d56337 | ||
|
|
eb86d661d7 | ||
|
|
fe055c718a | ||
|
|
31f440e68b | ||
|
|
c95da96a0c | ||
|
|
bf9f01689f | ||
|
|
da81e21536 | ||
|
|
46831d6fcf | ||
|
|
b58ad6c569 | ||
|
|
22b1933287 | ||
|
|
5a03f68a5a | ||
|
|
e81da93e86 | ||
|
|
f578043391 | ||
|
|
e8f5b936ad | ||
|
|
667e72a195 | ||
|
|
e1b3d5c4be | ||
|
|
f7b9377863 | ||
|
|
a5343e765b | ||
|
|
704f908eae | ||
|
|
de2fd20eb7 | ||
|
|
100e5241b0 | ||
|
|
ddecf7060b | ||
|
|
56cdbccb92 | ||
|
|
fc8a6b9705 | ||
|
|
143384f367 | ||
|
|
8c3b04730b | ||
|
|
aa9b77a56c | ||
|
|
b72f24c719 | ||
|
|
a800434a82 | ||
|
|
3b3c3d4390 | ||
|
|
d846b09874 | ||
|
|
1d3754aede | ||
|
|
e44f9a12c4 | ||
|
|
5243c216d6 | ||
|
|
79a51e7ee6 | ||
|
|
cad2bba7d8 | ||
|
|
fe8c0a9824 | ||
|
|
6cdc6b1344 | ||
|
|
05848a2cc7 | ||
|
|
528bfcd79a | ||
|
|
a1e13a937c | ||
|
|
e3fe383aaa | ||
|
|
43bd68e5dd | ||
|
|
ea2111d10a | ||
|
|
4c36ddbeec | ||
|
|
2b6b4d539b | ||
|
|
35f69d8ad9 | ||
|
|
7b1ce0d746 | ||
|
|
54816348d1 | ||
|
|
49d11b78c1 | ||
|
|
bb0f7089fe | ||
|
|
1ff5450d31 | ||
|
|
2f7512b006 | ||
|
|
943882a289 | ||
|
|
6c82f74b6f | ||
|
|
8a5b8b263b | ||
|
|
d47a7fcf0f | ||
|
|
e24c850818 | ||
|
|
6c612747e3 | ||
|
|
505c7ea2bc | ||
|
|
9add51f18e | ||
|
|
f7bd44eb32 | ||
|
|
e3ac52f2e1 | ||
|
|
06e27ef78e | ||
|
|
23e43fceeb | ||
|
|
f900f5fe71 | ||
|
|
db199cfae0 | ||
|
|
5914bf15d2 | ||
|
|
45f133b976 | ||
|
|
c5eb365011 | ||
|
|
2f326946a1 | ||
|
|
754d120c98 | ||
|
|
8e9871303b | ||
|
|
de5fb3744d | ||
|
|
6e47bda08e | ||
|
|
130b4ae447 | ||
|
|
ba5e128d23 |
23
.cirrus.yml
Normal file
23
.cirrus.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
freebsd_task:
|
||||
name: FreeBSD
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-0
|
||||
env:
|
||||
PATH: /usr/local/bin:$PATH
|
||||
prep_script:
|
||||
- dd if=/dev/zero of=/tmp/zpool bs=1M count=1024
|
||||
- zpool create -m `pwd`/testtmp zpool /tmp/zpool
|
||||
- pkg install -y bash autotools m4 xxhash zstd liblz4 wget
|
||||
- wget -O git-version.h https://gist.githubusercontent.com/WayneD/c11243fa374fc64d4e42f2855c8e3827/raw/rsync-git-version.h
|
||||
configure_script:
|
||||
- CPPFLAGS=-I/usr/local/include/ LDFLAGS=-L/usr/local/lib/ ./configure --disable-md2man
|
||||
make_script:
|
||||
- make
|
||||
install_script:
|
||||
- make install
|
||||
info_script:
|
||||
- rsync --version
|
||||
test_script:
|
||||
- RSYNC_EXPECT_SKIPPED=acls-default,acls,crtimes,protected-regular make check
|
||||
ssl_file_list_script:
|
||||
- rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
21
.cvsignore
21
.cvsignore
@@ -1,21 +0,0 @@
|
||||
.ignore
|
||||
.cvsignore
|
||||
Makefile
|
||||
a
|
||||
b
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
dist.tar.gz
|
||||
rsync
|
||||
rsync-*
|
||||
rsync.aux
|
||||
rsync.dvi
|
||||
rsync.log
|
||||
tech_report.aux
|
||||
tech_report.dvi
|
||||
tech_report.log
|
||||
tech_report.ps
|
||||
test
|
||||
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
125
.github/workflows/build.yml
vendored
Normal file
125
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore: [ .cirrus.yml ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore: [ .cirrus.yml ]
|
||||
schedule:
|
||||
- cron: '42 8 * * *'
|
||||
|
||||
jobs:
|
||||
|
||||
ubuntu-build:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: prep
|
||||
run: |
|
||||
sudo apt-get install acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm openssl wget
|
||||
wget -O git-version.h https://gist.githubusercontent.com/WayneD/c11243fa374fc64d4e42f2855c8e3827/raw/rsync-git-version.h
|
||||
echo "/usr/local/bin" >>$GITHUB_PATH
|
||||
- name: configure
|
||||
run: ./configure --with-rrsync
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: info
|
||||
run: rsync --version
|
||||
- name: check
|
||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check
|
||||
- name: check30
|
||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check30
|
||||
- name: check29
|
||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check29
|
||||
- name: ssl file list
|
||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ubuntu-bin
|
||||
path: |
|
||||
rsync
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
rrsync.1
|
||||
rrsync
|
||||
|
||||
macos-build:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: prep
|
||||
run: |
|
||||
brew install automake openssl xxhash zstd lz4 wget
|
||||
sudo pip3 install commonmark
|
||||
wget -O git-version.h https://gist.githubusercontent.com/WayneD/c11243fa374fc64d4e42f2855c8e3827/raw/rsync-git-version.h
|
||||
echo "/usr/local/bin" >>$GITHUB_PATH
|
||||
- name: configure
|
||||
run: CPPFLAGS=-I/usr/local/opt/openssl/include/ LDFLAGS=-L/usr/local/opt/openssl/lib/ ./configure --with-rrsync
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: info
|
||||
run: rsync --version
|
||||
- name: check
|
||||
run: sudo RSYNC_EXPECT_SKIPPED=acls-default,chmod-temp-dir,chown-fake,devices-fake,dir-sgid,protected-regular,xattrs-hlink,xattrs make check
|
||||
- name: ssl file list
|
||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macos-bin
|
||||
path: |
|
||||
rsync
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
rrsync.1
|
||||
rrsync
|
||||
|
||||
cygwin-build:
|
||||
runs-on: windows-2022
|
||||
if: (github.event_name == 'schedule' || contains(github.event.head_commit.message, '[buildall]'))
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: cygwin
|
||||
run: choco install -y --no-progress cygwin cyg-get
|
||||
- name: prep
|
||||
run: |
|
||||
cyg-get make autoconf automake gcc-core attr libattr-devel python39 python39-pip libzstd-devel liblz4-devel libssl-devel libxxhash0 libxxhash-devel
|
||||
curl.exe -o git-version.h https://gist.githubusercontent.com/WayneD/c11243fa374fc64d4e42f2855c8e3827/raw/rsync-git-version.h
|
||||
echo "C:/tools/cygwin/bin" >>$Env:GITHUB_PATH
|
||||
- name: commonmark
|
||||
run: bash -c 'python3 -mpip install --user commonmark'
|
||||
- name: configure
|
||||
run: bash -c './configure --with-rrsync'
|
||||
- name: make
|
||||
run: bash -c 'make'
|
||||
- name: install
|
||||
run: bash -c 'make install'
|
||||
- name: info
|
||||
run: bash -c '/usr/local/bin/rsync --version'
|
||||
- name: check
|
||||
run: bash -c 'RSYNC_EXPECT_SKIPPED=acls-default,acls,chown,devices,dir-sgid,protected-regular make check'
|
||||
- name: ssl file list
|
||||
run: bash -c 'PATH="/usr/local/bin:$PATH" rsync-ssl --no-motd download.samba.org::rsyncftp/ || true'
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cygwin-bin
|
||||
path: |
|
||||
rsync.exe
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
rrsync.1
|
||||
rrsync
|
||||
60
.gitignore
vendored
Normal file
60
.gitignore
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
*.[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*.[15]
|
||||
/rrsync
|
||||
/rrsync*.1
|
||||
/rsync*.html
|
||||
/rrsync*.html
|
||||
/help-rsync*.h
|
||||
/default-cvsignore.h
|
||||
/default-dont-compress.h
|
||||
/daemon-parm.h
|
||||
/.md2man-works
|
||||
/autom4te*.cache
|
||||
/confdefs.h
|
||||
/conftest*
|
||||
/dox
|
||||
/getgroups
|
||||
/gists
|
||||
/gmon.out
|
||||
/rsync
|
||||
/stunnel-rsyncd.conf
|
||||
/shconfig
|
||||
/git-version.h
|
||||
/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
|
||||
/patches.gen
|
||||
/build
|
||||
/auto-build-save
|
||||
.deps
|
||||
/*.exe
|
||||
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
|
||||
858
COPYING
858
COPYING
@@ -1,285 +1,635 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
REGARDING OPENSSL AND XXHASH
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to dynamically link rsync with the OpenSSL and xxhash
|
||||
libraries when those libraries are being distributed in compliance
|
||||
with their license terms, and to distribute a dynamically linked
|
||||
combination of rsync and these libraries. This is also considered
|
||||
to be covered under the GPL's System Libraries exception.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://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 +637,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 +654,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 <https://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
|
||||
<https://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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
187
Doxyfile
Normal file
187
Doxyfile
Normal file
@@ -0,0 +1,187 @@
|
||||
# Doxyfile 1.2.15
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = rsync
|
||||
PROJECT_NUMBER = HEAD
|
||||
OUTPUT_DIRECTORY = dox
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH = *source
|
||||
INTERNAL_DOCS = YES
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = YES
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = NO
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = .
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = proto.h \
|
||||
zlib \
|
||||
popt
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 3
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 3
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = NO
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME = search.cgi
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
EXT_DOC_PATHS =
|
||||
242
INSTALL.md
Normal file
242
INSTALL.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# How to build and install rsync
|
||||
|
||||
When building rsync, you'll want to install various libraries in order to get
|
||||
all the features enabled. The configure script will alert you when the
|
||||
newest libraries are missing and tell you the appropriate `--disable-LIB`
|
||||
option to use if you want to just skip that feature. What follows are various
|
||||
support libraries that you may want to install to build rsync with the maximum
|
||||
features (the impatient can skip down to the package summary):
|
||||
|
||||
## The basic setup
|
||||
|
||||
You need to have a C compiler installed and optionally a C++ compiler in order
|
||||
to try to build some hardware-accelerated checksum routines. Rsync also needs
|
||||
a modern awk, which might be provided via gawk or nawk on some OSes.
|
||||
|
||||
## Autoconf & manpages
|
||||
|
||||
If you're installing from the git repo (instead of a release tar file) you'll
|
||||
also need the GNU autotools (autoconf & automake) and your choice of 2 python3
|
||||
markdown libraries: cmarkgfm or commonmark (needed to generate the manpages).
|
||||
If your OS doesn't provide a python3-cmarkgfm or python3-commonmark package,
|
||||
you can run the following to install the commonmark python library for your
|
||||
build user (after installing python3's pip package):
|
||||
|
||||
> python3 -mpip install --user commonmark
|
||||
|
||||
You can test if you've got it fixed by running (from the rsync checkout):
|
||||
|
||||
> ./md-convert --test rsync-ssl.1.md
|
||||
|
||||
Alternately, you can avoid generating the manpages by fetching the very latest
|
||||
versions (that match the latest git source) from the [generated-files][6] dir.
|
||||
One way to do that is to run:
|
||||
|
||||
> ./prepare-source fetchgen
|
||||
|
||||
[6]: https://download.samba.org/pub/rsync/generated-files/
|
||||
|
||||
## ACL support
|
||||
|
||||
To support copying ACL file information, make sure you have an acl
|
||||
development library installed. It also helps to have the helper programs
|
||||
installed to manipulate ACLs and to run the rsync testsuite.
|
||||
|
||||
## Xattr support
|
||||
|
||||
To support copying xattr file information, make sure you have an attr
|
||||
development library installed. It also helps to have the helper programs
|
||||
installed to manipulate xattrs and to run the rsync testsuite.
|
||||
|
||||
## xxhash
|
||||
|
||||
The [xxHash library][1] provides extremely fast checksum functions that can
|
||||
make the "rsync algorithm" run much more quickly, especially when matching
|
||||
blocks in large files. Installing this development library adds xxhash
|
||||
checksums as the default checksum algorithm. You'll need at least v0.8.0
|
||||
if you want rsync to include the full range of its checksum algorithms.
|
||||
|
||||
[1]: https://cyan4973.github.io/xxHash/
|
||||
|
||||
## zstd
|
||||
|
||||
The [zstd library][2] compression algorithm that uses less CPU than
|
||||
the default zlib algorithm at the same compression level. Note that you
|
||||
need at least version 1.4, so you might need to skip the zstd compression if
|
||||
you can only install a 1.3 release. Installing this development library
|
||||
adds zstd compression as the default compression algorithm.
|
||||
|
||||
[2]: http://facebook.github.io/zstd/
|
||||
|
||||
## lz4
|
||||
|
||||
The [lz4 library][3] compression algorithm that uses very little CPU, though
|
||||
it also has the smallest compression ratio of other algorithms. Installing
|
||||
this development library adds lz4 compression as an available compression
|
||||
algorithm.
|
||||
|
||||
[3]: https://lz4.github.io/lz4/
|
||||
|
||||
## openssl crypto
|
||||
|
||||
The [openssl crypto library][4] provides some hardware accelerated checksum
|
||||
algorithms for MD4 and MD5. Installing this development library makes rsync
|
||||
use the (potentially) faster checksum routines when computing MD4 & MD5
|
||||
checksums.
|
||||
|
||||
[4]: https://www.openssl.org/docs/man1.0.2/man3/crypto.html
|
||||
|
||||
## Package summary
|
||||
|
||||
To help you get the libraries installed, here are some package install commands
|
||||
for various OSes. The commands are split up to correspond with the above
|
||||
items, but feel free to combine the package names into a single install, if you
|
||||
like.
|
||||
|
||||
- For Debian and Ubuntu (Debian Buster users may want to briefly(?) enable
|
||||
buster-backports to update zstd from 1.3 to 1.4):
|
||||
|
||||
> sudo apt install -y gcc g++ gawk autoconf automake python3-cmarkgfm
|
||||
> sudo apt install -y acl libacl1-dev
|
||||
> sudo apt install -y attr libattr1-dev
|
||||
> sudo apt install -y libxxhash-dev
|
||||
> sudo apt install -y libzstd-dev
|
||||
> sudo apt install -y liblz4-dev
|
||||
> sudo apt install -y libssl-dev
|
||||
|
||||
- For CentOS (use EPEL for python3-pip):
|
||||
|
||||
> sudo yum -y install epel-release
|
||||
> sudo yum -y install gcc g++ gawk autoconf automake python3-pip
|
||||
> sudo yum -y install acl libacl-devel
|
||||
> sudo yum -y install attr libattr-devel
|
||||
> sudo yum -y install xxhash-devel
|
||||
> sudo yum -y install libzstd-devel
|
||||
> sudo yum -y install lz4-devel
|
||||
> sudo yum -y install openssl-devel
|
||||
> python3 -mpip install --user commonmark
|
||||
|
||||
- For Fedora 33:
|
||||
|
||||
> sudo dnf -y install acl libacl-devel
|
||||
> sudo dnf -y install attr libattr-devel
|
||||
> sudo dnf -y install xxhash-devel
|
||||
> sudo dnf -y install libzstd-devel
|
||||
> sudo dnf -y install lz4-devel
|
||||
> sudo dnf -y install openssl-devel
|
||||
|
||||
- For FreeBSD (this assumes that the python3 version is 3.7):
|
||||
|
||||
> sudo pkg install -y autotools python3 py37-CommonMark
|
||||
> sudo pkg install -y xxhash
|
||||
> sudo pkg install -y zstd
|
||||
> sudo pkg install -y liblz4
|
||||
|
||||
- For macOS:
|
||||
|
||||
> brew install automake
|
||||
> brew install xxhash
|
||||
> brew install zstd
|
||||
> brew install lz4
|
||||
> brew install openssl
|
||||
|
||||
- For Cygwin (with all cygwin programs stopped, run the appropriate setup program from a cmd shell):
|
||||
|
||||
> setup-x86_64 --quiet-mode -P make,gawk,autoconf,automake,gcc-core,python38,python38-pip
|
||||
> setup-x86_64 --quiet-mode -P attr,libattr-devel
|
||||
> setup-x86_64 --quiet-mode -P libzstd-devel
|
||||
> setup-x86_64 --quiet-mode -P liblz4-devel
|
||||
> setup-x86_64 --quiet-mode -P libssl-devel
|
||||
|
||||
Sometimes cygwin has commonmark packaged and sometimes it doesn't. Now that
|
||||
its python38 has stabilized, you could install python38-commonmark. Or just
|
||||
avoid the issue by running this from a bash shell as your build user:
|
||||
|
||||
> python3 -mpip install --user commonmark
|
||||
|
||||
## Build and install
|
||||
|
||||
After installing the various libraries, you need to configure, build, and
|
||||
install the source:
|
||||
|
||||
> ./configure
|
||||
> make
|
||||
> sudo make install
|
||||
|
||||
The default install path is /usr/local/bin, but you can set the installation
|
||||
directory and other parameters using options 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 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.
|
||||
|
||||
If you want to automatically use a separate "build" directory based on
|
||||
the current git branch name, start with a pristine git checkout and run
|
||||
"mkdir auto-build-save" before you run the first ./configure command.
|
||||
That will cause a fresh build dir to spring into existence along with a
|
||||
special Makefile symlink that allows you to run "make" and "./configure"
|
||||
from the source dir (the "build" dir gets auto switched based on branch).
|
||||
This is helpful when using the branch-from-patch and patch-update scripts
|
||||
to maintain the official rsync patches. If you ever need to build from
|
||||
a "detached head" git position then you'll need to manually chdir into
|
||||
the build dir to run make. I also like to create 2 more symlinks in the
|
||||
source dir: `ln -s build/rsync . ; ln -s build/testtmp .`
|
||||
|
||||
## 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
|
||||
|
||||
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
|
||||
ANSI C. You may see this error message in config.log if ./configure
|
||||
fails:
|
||||
|
||||
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
|
||||
|
||||
Install gcc or HP's "ANSI/C Compiler".
|
||||
|
||||
## Mac OS X notes
|
||||
|
||||
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
|
||||
not completely implement the "New Sockets" API.
|
||||
|
||||
[This site][5] says that Apple started to support IPv6 in 10.2 (Jaguar). If
|
||||
your build fails, try again after running configure with `--disable-ipv6`.
|
||||
|
||||
[5]: http://www.ipv6.org/impl/mac.html
|
||||
|
||||
## IBM AIX notes
|
||||
|
||||
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
|
||||
The workaround is to append the following to config.h:
|
||||
|
||||
> #ifdef _LARGE_FILES
|
||||
> #undef HAVE_SECURE_MKSTEMP
|
||||
> #endif
|
||||
375
Makefile.in
375
Makefile.in
@@ -1,66 +1,367 @@
|
||||
# Makefile for rsync. This is processed by configure to produce the final
|
||||
# Makefile
|
||||
# The Makefile for rsync (configure creates it from Makefile.in).
|
||||
|
||||
prefix=@prefix@
|
||||
datarootdir=@datarootdir@
|
||||
exec_prefix=@exec_prefix@
|
||||
INSTALL_BIN=$(exec_prefix)/bin
|
||||
INSTALL_MAN=$(prefix)/man
|
||||
bindir=@bindir@
|
||||
libdir=@libdir@/rsync
|
||||
mandir=@mandir@
|
||||
with_rrsync=@with_rrsync@
|
||||
|
||||
LIBS=@LIBS@
|
||||
CC=@CC@
|
||||
AWK=@AWK@
|
||||
CFLAGS=@CFLAGS@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
CXX=@CXX@
|
||||
CXXFLAGS=@CXXFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBOBJDIR=lib/
|
||||
|
||||
INSTALLCMD=@INSTALL@
|
||||
INSTALLMAN=@INSTALL@
|
||||
|
||||
VPATH=@srcdir@
|
||||
srcdir=@srcdir@
|
||||
MKDIR_P=@MKDIR_P@
|
||||
VPATH=$(srcdir)
|
||||
SHELL=/bin/sh
|
||||
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/getopt.o lib/fnmatch.o lib/zlib.o lib/compat.o
|
||||
OBJS1=rsync.o exclude.o util.o md4.o main.o checksum.o match.o syscall.o log.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o
|
||||
ROLL_SIMD_x86_64=simd-checksum-x86_64.o
|
||||
ROLL_ASM_x86_64=simd-checksum-avx2.o
|
||||
MD5_ASM_x86_64=lib/md5-asm-x86_64.o
|
||||
|
||||
GENFILES=configure.sh aclocal.m4 config.h.in rsync.1 rsync.1.html \
|
||||
rsync-ssl.1 rsync-ssl.1.html rsyncd.conf.5 rsyncd.conf.5.html \
|
||||
@GEN_RRSYNC@
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
|
||||
lib/pool_alloc.h lib/mdigest.h lib/md-defines.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 \
|
||||
util1.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 \
|
||||
usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
|
||||
OBJS3=progress.o pipe.o @MD5_ASM@ @ROLL_SIMD@ @ROLL_ASM@
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ)
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
|
||||
|
||||
TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
|
||||
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
|
||||
|
||||
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
|
||||
|
||||
# Objects for CHECK_PROGS to clean
|
||||
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
|
||||
|
||||
# note that the -I. is needed to handle config.h when using VPATH
|
||||
.c.o:
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
|
||||
@OBJ_SAVE@
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
@OBJ_RESTORE@
|
||||
|
||||
all: rsync
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_RRSYNC@ @MAKE_MAN@
|
||||
.PHONY: all
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
-mkdir -p ${INSTALL_BIN}
|
||||
${INSTALLCMD} -m 755 rsync ${INSTALL_BIN}
|
||||
-mkdir -p ${INSTALL_MAN}/man1
|
||||
-mkdir -p ${INSTALL_MAN}/man5
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsync.1 ${INSTALL_MAN}/man1
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsyncd.conf.5 ${INSTALL_MAN}/man5
|
||||
-$(MKDIR_P) $(DESTDIR)$(bindir)
|
||||
$(INSTALLCMD) $(INSTALL_STRIP) -m 755 rsync$(EXEEXT) $(DESTDIR)$(bindir)
|
||||
$(INSTALLCMD) -m 755 $(srcdir)/rsync-ssl $(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 rsync-ssl.1; then $(INSTALLMAN) -m 644 rsync-ssl.1 $(DESTDIR)$(mandir)/man1; fi
|
||||
if test -f rsyncd.conf.5; then $(INSTALLMAN) -m 644 rsyncd.conf.5 $(DESTDIR)$(mandir)/man5; fi
|
||||
if test "$(with_rrsync)" = yes; then \
|
||||
$(INSTALLCMD) -m 755 rrsync $(DESTDIR)$(bindir); \
|
||||
if test -f rrsync.1; then $(INSTALLMAN) -m 644 rrsync.1 $(DESTDIR)$(mandir)/man1; fi; \
|
||||
fi
|
||||
|
||||
rsync: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
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
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
install-all: install install-ssl-daemon
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_STRIP='-s' install
|
||||
|
||||
proto:
|
||||
cat *.c | awk -f mkproto.awk > proto.h
|
||||
rsync$(EXEEXT): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync config.cache config.log config.status
|
||||
rrsync: support/rrsync
|
||||
cp -p $(srcdir)/support/rrsync rrsync
|
||||
|
||||
dist:
|
||||
tar --exclude-from .ignore -czf dist.tar.gz .
|
||||
-mkdir rsync-$(VERSION)
|
||||
(cd rsync-$(VERSION) ; tar xzf ../dist.tar.gz)
|
||||
tar -czf rsync-$(VERSION).tar.gz rsync-$(VERSION)
|
||||
rm -f dist.tar.gz
|
||||
echo rsync-$(VERSION) >> .cvsignore
|
||||
$(OBJS): $(HEADERS)
|
||||
$(CHECK_OBJS): $(HEADERS)
|
||||
tls.o xattrs.o: lib/sysxattrs.h
|
||||
usage.o: version.h latest-year.h help-rsync.h help-rsyncd.h git-version.h default-cvsignore.h
|
||||
loadparm.o: default-dont-compress.h daemon-parm.h
|
||||
|
||||
flist.o: rounding.h
|
||||
|
||||
default-cvsignore.h default-dont-compress.h: rsync.1.md define-from-md.awk
|
||||
$(AWK) -f $(srcdir)/define-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
|
||||
|
||||
help-rsync.h help-rsyncd.h: rsync.1.md help-from-md.awk
|
||||
$(AWK) -f $(srcdir)/help-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
|
||||
|
||||
daemon-parm.h: daemon-parm.txt daemon-parm.awk
|
||||
$(AWK) -f $(srcdir)/daemon-parm.awk $(srcdir)/daemon-parm.txt
|
||||
|
||||
rounding.h: rounding.c rsync.h proto.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
|
||||
|
||||
git-version.h: ALWAYS_RUN
|
||||
$(srcdir)/mkgitver
|
||||
|
||||
.PHONY: ALWAYS_RUN
|
||||
ALWAYS_RUN:
|
||||
|
||||
simd-checksum-x86_64.o: simd-checksum-x86_64.cpp
|
||||
@$(srcdir)/cmd-or-msg disable-roll-simd $(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $(srcdir)/simd-checksum-x86_64.cpp
|
||||
|
||||
simd-checksum-avx2.o: simd-checksum-avx2.S
|
||||
@$(srcdir)/cmd-or-msg disable-roll-asm $(CC) $(CFLAGS) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/simd-checksum-avx2.S
|
||||
|
||||
lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.S lib/md-defines.h
|
||||
@$(srcdir)/cmd-or-msg disable-md5-asm $(CC) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/lib/md5-asm-x86_64.S
|
||||
|
||||
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)
|
||||
|
||||
getfsdev$(EXEEXT): getfsdev.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
|
||||
|
||||
TRIMSLASH_OBJ = trimslash.o syscall.o util2.o t_stub.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 util1.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)
|
||||
|
||||
.PHONY: conf
|
||||
conf: configure.sh config.h.in
|
||||
|
||||
.PHONY: gen
|
||||
gen: conf proto.h man git-version.h
|
||||
|
||||
.PHONY: gensend
|
||||
gensend: gen
|
||||
if ! diff git-version.h $(srcdir)/gists/rsync-git-version.h >/dev/null; then \
|
||||
./rsync -ai git-version.h $(srcdir)/gists/rsync-git-version.h && \
|
||||
(cd $(srcdir)/gists && git commit --allow-empty-message -m '' rsync-git-version.h && git push) ; \
|
||||
fi
|
||||
rsync -aic $(GENFILES) git-version.h $${SAMBA_HOST-samba.org}:/home/ftp/pub/rsync/generated-files/ || true
|
||||
|
||||
aclocal.m4: $(srcdir)/m4/*.m4
|
||||
aclocal -I $(srcdir)/m4
|
||||
|
||||
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 || test -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
|
||||
|
||||
.PHONY: reconfigure
|
||||
reconfigure: configure.sh
|
||||
./config.status --recheck
|
||||
./config.status
|
||||
|
||||
.PHONY: restatus
|
||||
restatus:
|
||||
./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
|
||||
|
||||
stunnel-rsyncd.conf: $(srcdir)/stunnel-rsyncd.conf.in Makefile
|
||||
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/stunnel-rsyncd.conf.in >stunnel-rsyncd.conf
|
||||
|
||||
.PHONY: proto
|
||||
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 daemon-parm.h
|
||||
$(AWK) -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
|
||||
|
||||
.PHONY: man
|
||||
man: rsync.1 rsync-ssl.1 rsyncd.conf.5 @MAKE_RRSYNC_1@
|
||||
|
||||
rsync.1: rsync.1.md md-convert version.h Makefile
|
||||
@$(srcdir)/maybe-make-man rsync.1.md
|
||||
|
||||
rsync-ssl.1: rsync-ssl.1.md md-convert version.h Makefile
|
||||
@$(srcdir)/maybe-make-man rsync-ssl.1.md
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.5.md md-convert version.h Makefile
|
||||
@$(srcdir)/maybe-make-man rsyncd.conf.5.md
|
||||
|
||||
rrsync.1: support/rrsync.1.md md-convert Makefile
|
||||
@$(srcdir)/maybe-make-man support/rrsync.1.md
|
||||
|
||||
.PHONY: clean
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
|
||||
git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
|
||||
*.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
|
||||
|
||||
.PHONY: cleantests
|
||||
cleantests:
|
||||
rm -rf ./testtmp*
|
||||
|
||||
# We try to delete built files from both the source and build
|
||||
# directories, just in case somebody previously configured things in
|
||||
# the source directory.
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
for dir in $(srcdir) . ; do \
|
||||
(cd "$$dir" && rm -rf Makefile config.h config.status stunnel-rsyncd.conf \
|
||||
lib/dummy popt/dummy zlib/dummy config.cache config.log shconfig \
|
||||
$(GENFILES) autom4te.cache) ; \
|
||||
done
|
||||
|
||||
# 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
|
||||
# dead (ie. unused) functions in the code. (tridge)
|
||||
.PHONY: finddead
|
||||
finddead:
|
||||
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
|
||||
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
@rm nmused.txt nmfns.txt
|
||||
|
||||
# 'check' is the GNU name, 'test' is the name for everybody else :-)
|
||||
.PHONY: test
|
||||
test: check
|
||||
|
||||
# There seems to be no standard way to specify some variables as
|
||||
# exported from a Makefile apart from listing them like this.
|
||||
|
||||
# This depends on building rsync; if we need any helper programs it
|
||||
# should depend on them too.
|
||||
|
||||
# We try to run the scripts with POSIX mode on, in the hope that will
|
||||
# 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.
|
||||
|
||||
.PHONY: check
|
||||
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
|
||||
|
||||
.PHONY: check29
|
||||
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
|
||||
|
||||
.PHONY: check30
|
||||
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
|
||||
|
||||
wildtest.o: wildtest.c t_stub.o 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.
|
||||
|
||||
.PHONY: installcheck
|
||||
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
|
||||
|
||||
# Run the SPLINT (Secure Programming Lint) tool. <www.splint.org>
|
||||
.PHONY: splint
|
||||
splint:
|
||||
splint +unixlib +gnuextensions -weak rsync.c
|
||||
|
||||
.PHONY: doxygen
|
||||
doxygen:
|
||||
cd $(srcdir) && rm dox/html/* && doxygen
|
||||
|
||||
# for maintainers only
|
||||
.PHONY: doxygen-upload
|
||||
doxygen-upload:
|
||||
rsync -avzv $(srcdir)/dox/html/ --delete \
|
||||
$${SAMBA_HOST-samba.org}:/home/httpd/html/rsync/doxygen/head/
|
||||
|
||||
159
README
159
README
@@ -1,159 +0,0 @@
|
||||
WHAT IS RSYNC?
|
||||
--------------
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Basically you use rsync just like rcp, but rsync has many additional options.
|
||||
|
||||
Here is a brief description of available options:
|
||||
|
||||
Options:
|
||||
-v, --verbose increase verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode (same as -rlptDog)
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ extension)
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
-H, --hard-links preserve hard links
|
||||
-p, --perms preserve permissions
|
||||
-o, --owner preserve owner (root only)
|
||||
-g, --group preserve group
|
||||
-D, --devices preserve devices (root only)
|
||||
-t, --times preserve times
|
||||
-S, --sparse handle sparse files efficiently
|
||||
-n, --dry-run show what would have been transferred
|
||||
-W, --whole-file copy whole files, no incremental checks
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size SIZE checksum blocking size
|
||||
-e, --rsh COMMAND specify rsh replacement
|
||||
--rsync-path PATH specify path to rsync on the remote machine
|
||||
-C, --cvs-exclude auto ignore files in the same way CVS does
|
||||
--delete delete files that don't exist on the sending side
|
||||
--force force deletion of directories even if not empty
|
||||
--numeric-ids don't map uid/gid values by user/group name
|
||||
--timeout TIME set IO timeout in seconds
|
||||
-I, --ignore-times don't exclude files that match length and time
|
||||
-T --temp-dir DIR create temporary files in directory DIR
|
||||
-z, --compress compress file data
|
||||
--exclude FILE exclude file FILE
|
||||
--exclude-from FILE exclude files listed in FILE
|
||||
--suffix SUFFIX override backup suffix
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--config FILE specify alternate rsyncd.conf file
|
||||
--port PORT specify alternate rsyncd port number
|
||||
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
Rsync uses rsh or ssh for communication. It does not need to be setuid
|
||||
and requires no special privilages for installation. It does not
|
||||
require a inetd entry or a daemon. You must, however, have a working
|
||||
rsh or ssh system. Using ssh is recommended for its security
|
||||
features.
|
||||
|
||||
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
|
||||
to the name of your native compiler before running configure in this
|
||||
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!
|
||||
|
||||
RSYNC SERVERS
|
||||
-------------
|
||||
|
||||
rsync can also talk to "rsync servers" which can provide anonymous or
|
||||
authenticated rsync. See the rsync.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.
|
||||
|
||||
|
||||
MAILING LIST
|
||||
------------
|
||||
|
||||
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.
|
||||
|
||||
To join the mailing list send mail to listproc@samba.anu.edu.au with
|
||||
no subject and a body of "subscribe rsync Your Name".
|
||||
|
||||
To send mail to everyone on the list send it to rsync@samba.anu.edu.au
|
||||
|
||||
|
||||
BUG REPORTS
|
||||
-----------
|
||||
|
||||
If you have web access then please look at
|
||||
http://samba.anu.edu.au/rsync/
|
||||
|
||||
This will give you access to the bug tracking system used by the
|
||||
developers of rsync and will allow you to look at other bug reports or
|
||||
submit a new bug report.
|
||||
|
||||
If you don't have web access then mail bug reports to
|
||||
rsync-bugs@samba.anu.edu.au or (if you think it will be of interest to
|
||||
lots of people) send it to rsync@samba.anu.edu.au
|
||||
|
||||
|
||||
CVS TREE
|
||||
--------
|
||||
|
||||
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:
|
||||
|
||||
cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot login
|
||||
Password: cvs
|
||||
|
||||
cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot co rsync
|
||||
|
||||
Look at the cvs documentation for more details.
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
---------
|
||||
|
||||
Rsync was written by Andrew Tridgell and Paul Mackerras, and is
|
||||
available under the Gnu Public License.
|
||||
|
||||
tridge@samba.anu.edu.au
|
||||
paulus@cs.anu.edu.au
|
||||
|
||||
|
||||
AVAILABILITY
|
||||
------------
|
||||
|
||||
The main ftp site for rsync is ftp://samba.anu.edu.au/pub/rsync
|
||||
This is also available as rsync://samba.anu.edu.au/rsyncftp/
|
||||
|
||||
Mirrors are available at:
|
||||
|
||||
ftp://sunsite.auc.dk/pub/unix/rsync
|
||||
ftp://ftp.sunet.se/pub/unix/admin/rsync
|
||||
ftp://ftp.fu-berlin.de/pub/unix/network/rsync/
|
||||
144
README.md
Normal file
144
README.md
Normal file
@@ -0,0 +1,144 @@
|
||||
WHAT IS RSYNC?
|
||||
--------------
|
||||
|
||||
Rsync is a fast and extraordinarily versatile file copying tool for
|
||||
both remote and local files.
|
||||
|
||||
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.
|
||||
|
||||
A technical report describing the rsync algorithm is included with this
|
||||
package.
|
||||
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Basically you use rsync just like scp, but rsync has many additional
|
||||
options. To get a complete list of supported options type:
|
||||
|
||||
rsync --help
|
||||
|
||||
See the [manpage][0] for more detailed information.
|
||||
|
||||
[0]: https://download.samba.org/pub/rsync/rsync.1
|
||||
|
||||
BUILDING AND INSTALLING
|
||||
-----------------------
|
||||
|
||||
If you need to build rsync yourself, check out the [INSTALL][1] page for
|
||||
information on what libraries and packages you can use to get the maximum
|
||||
features in your build.
|
||||
|
||||
[1]: https://github.com/WayneD/rsync/blob/master/INSTALL.md
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
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".
|
||||
|
||||
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
|
||||
to the name of your native compiler before running configure in this
|
||||
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!
|
||||
|
||||
|
||||
RSYNC DAEMONS
|
||||
-------------
|
||||
|
||||
Rsync can also talk to "rsync daemons" which can provide anonymous or
|
||||
authenticated rsync. See the rsyncd.conf(5) manpage for details on how
|
||||
to setup an rsync daemon. See the rsync(1) manpage for info on how to
|
||||
connect to an rsync daemon.
|
||||
|
||||
|
||||
WEB SITE
|
||||
--------
|
||||
|
||||
For more information, visit the [main rsync web site][2].
|
||||
|
||||
[2]: https://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][3] for full
|
||||
details.
|
||||
|
||||
[3]: https://rsync.samba.org/lists.html
|
||||
|
||||
|
||||
BUG REPORTS
|
||||
-----------
|
||||
|
||||
The [bug-tracking web page][4] has full details on bug reporting.
|
||||
|
||||
[4]: https://rsync.samba.org/bug-tracking.html
|
||||
|
||||
That page contains links to the current bug list, and information on how to
|
||||
do a good job when reporting a bug. You might also like to try searching
|
||||
the Internet for the error message you've received, or looking in the
|
||||
[mailing list archives][5].
|
||||
|
||||
[5]: https://mail-archive.com/rsync@lists.samba.org/
|
||||
|
||||
To send a bug report, follow the instructions on the bug-tracking
|
||||
page of the web site.
|
||||
|
||||
Alternately, email your bug report to <rsync@lists.samba.org>.
|
||||
|
||||
|
||||
GIT REPOSITORY
|
||||
--------------
|
||||
|
||||
If you want to get the very latest version of rsync direct from the
|
||||
source code repository, then you will need to use git. The git repo
|
||||
is hosted [on GitHub][6] and [on Samba's site][7].
|
||||
|
||||
[6]: https://github.com/WayneD/rsync
|
||||
[7]: https://git.samba.org/?p=rsync.git;a=summary
|
||||
|
||||
See [the download page][8] for full details on all the ways to grab the
|
||||
source.
|
||||
|
||||
[8]: https://rsync.samba.org/download.html
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
---------
|
||||
|
||||
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.
|
||||
|
||||
Rsync may be used, modified and redistributed only under the terms of
|
||||
the GNU General Public License, found in the file [COPYING][9] in this
|
||||
distribution, or at [the Free Software Foundation][10].
|
||||
|
||||
[9]: https://github.com/WayneD/rsync/blob/master/COPYING
|
||||
[10]: https://www.fsf.org/licenses/gpl.html
|
||||
12
SECURITY.md
Normal file
12
SECURITY.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the current release of the software is actively supported. If you need
|
||||
help backporting fixes into an older release, feel free to ask.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Email your vulnerability information to rsync's maintainer:
|
||||
|
||||
Wayne Davison <wayne@opencoder.net>
|
||||
528
TODO
Normal file
528
TODO
Normal file
@@ -0,0 +1,528 @@
|
||||
-*- indented-text -*-
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
Use chroot only if supported
|
||||
Allow supplementary groups in rsyncd.conf 2002/04/09
|
||||
Handling IPv6 on old machines
|
||||
Other IPv6 stuff
|
||||
Add ACL support 2001/12/02
|
||||
proxy authentication 2002/01/23
|
||||
SOCKS 2002/01/23
|
||||
FAT support
|
||||
--diff david.e.sewell 2002/03/15
|
||||
Add daemon --no-fork option
|
||||
Create more granular verbosity 2003/05/15
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
Keep list of open issues and todos on the web site
|
||||
Perhaps redo manual as SGML
|
||||
|
||||
LOGGING --------------------------------------------------------------
|
||||
Memory accounting
|
||||
Improve error messages
|
||||
Better statistics Rasmus 2002/03/08
|
||||
Perhaps flush stdout like syslog
|
||||
Log child death on signal
|
||||
verbose output David Stein 2001/12/20
|
||||
internationalization
|
||||
|
||||
DEVELOPMENT --------------------------------------------------------
|
||||
Handling duplicate names
|
||||
Use generic zlib 2002/02/25
|
||||
TDB 2002/03/12
|
||||
Splint 2002/03/12
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
Traverse just one directory at a time
|
||||
Allow skipping MD4 file_sum 2002/04/08
|
||||
Accelerate MD4
|
||||
|
||||
TESTING --------------------------------------------------------------
|
||||
Torture test
|
||||
Cross-test versions 2001/08/22
|
||||
Test on kernel source
|
||||
Test large files
|
||||
Create mutator program for testing
|
||||
Create configure option to enable dangerous tests
|
||||
Create pipe program for testing
|
||||
Create test makefile target for some tests
|
||||
|
||||
RELATED PROJECTS -----------------------------------------------------
|
||||
rsyncsh
|
||||
https://rsync.samba.org/rsync-and-debian/
|
||||
rsyncable gzip patch
|
||||
rsyncsplit as alternative to real integration with gzip?
|
||||
reverse rsync over HTTP Range
|
||||
|
||||
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
|
||||
|
||||
Use chroot only if supported
|
||||
|
||||
If the platform doesn't support it, then don't even try.
|
||||
|
||||
If running as non-root, then don't fail, just give a warning.
|
||||
(There was a thread about this a while ago?)
|
||||
|
||||
https://lists.samba.org/pipermail/rsync/2001-August/thread.html
|
||||
https://lists.samba.org/pipermail/rsync/2001-September/thread.html
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Allow supplementary groups in rsyncd.conf 2002/04/09
|
||||
|
||||
Perhaps allow supplementary groups to be specified in rsyncd.conf;
|
||||
then make the first one the primary gid and all the rest be
|
||||
supplementary gids.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Handling IPv6 on old machines
|
||||
|
||||
The KAME IPv6 patch is nice in theory but has proved a bit of a
|
||||
nightmare in practice. The basic idea of their patch is that rsync
|
||||
is rewritten to use the new getaddrinfo()/getnameinfo() interface,
|
||||
rather than gethostbyname()/gethostbyaddr() as in rsync 2.4.6.
|
||||
Systems that don't have the new interface are handled by providing
|
||||
our own implementation in lib/, which is selectively linked in.
|
||||
|
||||
The problem with this is that it is really hard to get right on
|
||||
platforms that have a half-working implementation, so redefining
|
||||
these functions clashes with system headers, and leaving them out
|
||||
breaks. This affects at least OSF/1, RedHat 5, and Cobalt, which
|
||||
are moderately important.
|
||||
|
||||
Perhaps the simplest solution would be to have two different files
|
||||
implementing the same interface, and choose either the new or the
|
||||
old API. This is probably necessary for systems that e.g. have
|
||||
IPv6, but gethostbyaddr() can't handle it. The Linux manpage claims
|
||||
this is currently the case.
|
||||
|
||||
In fact, our internal sockets interface (things like
|
||||
open_socket_out(), etc) is much narrower than the getaddrinfo()
|
||||
interface, and so probably simpler to get right. In addition, the
|
||||
old code is known to work well on old machines.
|
||||
|
||||
We could drop the rather large lib/getaddrinfo files.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Other IPv6 stuff
|
||||
|
||||
Implement suggestions from http://www.kame.net/newsletter/19980604/
|
||||
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
|
||||
|
||||
If a host has multiple addresses, then listen try to connect to all
|
||||
in order until we get through. (getaddrinfo may return multiple
|
||||
addresses.) This is kind of implemented already.
|
||||
|
||||
Possibly also when starting as a server we may need to listen on
|
||||
multiple passive addresses. This might be a bit harder, because we
|
||||
may need to select on all of them. Hm.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Add ACL support 2001/12/02
|
||||
|
||||
Transfer ACLs. Need to think of a standard representation.
|
||||
Probably better not to even try to convert between NT and POSIX.
|
||||
Possibly can share some code with Samba.
|
||||
NOTE: there is a patch that implements this in the "patches" subdir.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
proxy authentication 2002/01/23
|
||||
|
||||
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
|
||||
HTTP Basic Proxy-Authentication.
|
||||
|
||||
Multiple schemes are possible, up to and including the insanity that
|
||||
is NTLM, but Basic probably covers most cases.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
SOCKS 2002/01/23
|
||||
|
||||
Add --with-socks, and then perhaps a command-line option to put them
|
||||
on or off. This might be more reliable than LD_PRELOAD hacks.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
FAT support
|
||||
|
||||
rsync to a FAT partition on a Unix machine doesn't work very well at
|
||||
the moment. I think we get errors about invalid filenames and
|
||||
perhaps also trying to do atomic renames.
|
||||
|
||||
I guess the code to do this is currently #ifdef'd on Windows;
|
||||
perhaps we ought to intelligently fall back to it on Unix too.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
--diff david.e.sewell 2002/03/15
|
||||
|
||||
Allow people to specify the diff command. (Might want to use wdiff,
|
||||
gnudiff, etc.)
|
||||
|
||||
Just diff the temporary file with the destination file, and delete
|
||||
the tmp file rather than moving it into place.
|
||||
|
||||
Interaction with --partial.
|
||||
|
||||
Security interactions with daemon mode?
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Add daemon --no-fork option
|
||||
|
||||
Very useful for debugging. Also good when running under a
|
||||
daemon-monitoring process that tries to restart the service when the
|
||||
parent exits.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create more granular verbosity 2003/05/15
|
||||
|
||||
Control output with the --report option.
|
||||
|
||||
The option takes as a single argument (no whitespace) a
|
||||
comma delimited lists of keywords.
|
||||
|
||||
This would separate debugging from "logging" as well as
|
||||
fine grained selection of statistical reporting and what
|
||||
actions are logged.
|
||||
|
||||
https://lists.samba.org/archive/rsync/2003-May/006059.html
|
||||
|
||||
-- --
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
|
||||
|
||||
Keep list of open issues and todos on the web site
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Perhaps redo manual as SGML
|
||||
|
||||
The man page is getting rather large, and there is more information
|
||||
that ought to be added.
|
||||
|
||||
TexInfo source is probably a dying format.
|
||||
|
||||
Linuxdoc looks like the most likely contender. I know DocBook is
|
||||
favoured by some people, but it's so bloody verbose, even with emacs
|
||||
support.
|
||||
|
||||
-- --
|
||||
|
||||
LOGGING --------------------------------------------------------------
|
||||
|
||||
|
||||
Memory accounting
|
||||
|
||||
At exit, show how much memory was used for the file list, etc.
|
||||
|
||||
We also do a weird exponential-growth allocation in flist.c. I'm
|
||||
not sure this makes sense with modern mallocs. At any rate it will
|
||||
make us allocate a huge amount of memory for large file lists.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Improve error messages
|
||||
|
||||
If we hang or get SIGINT, then explain where we were up to. Perhaps
|
||||
have a static buffer that contains the current function name, or
|
||||
some kind of description of what we were trying to do. This is a
|
||||
little easier on people than needing to run strace/truss.
|
||||
|
||||
"The dungeon collapses! You are killed." Rather than "unexpected
|
||||
eof" give a message that is more detailed if possible and also more
|
||||
helpful.
|
||||
|
||||
If we get an error writing to a socket, then we should perhaps
|
||||
continue trying to read to see if an error message comes across
|
||||
explaining why the socket is closed. I'm not sure if this would
|
||||
work, but it would certainly make our messages more helpful.
|
||||
|
||||
What happens if a directory is missing -x attributes. Do we lose
|
||||
our load? (Debian #28416) Probably fixed now, but a test case would
|
||||
be good.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Better statistics Rasmus 2002/03/08
|
||||
|
||||
<Rasmus>
|
||||
hey, how about an rsync option that just gives you the
|
||||
summary without the list of files? And perhaps gives
|
||||
more information like the number of new files, number
|
||||
of changed, deleted, etc. ?
|
||||
|
||||
<mbp>
|
||||
nice idea there is --stats but at the moment it's very
|
||||
tridge-oriented rather than user-friendly it would be
|
||||
nice to improve it that would also work well with
|
||||
--dryrun
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Perhaps flush stdout like syslog
|
||||
|
||||
Perhaps flush stdout after each filename, so that people trying to
|
||||
monitor progress in a log file can do so more easily. See
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Log child death on signal
|
||||
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
that when we reap it and log a message.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
verbose output David Stein 2001/12/20
|
||||
|
||||
At end of transfer, show how many files were or were not transferred
|
||||
correctly.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
internationalization
|
||||
|
||||
Change to using gettext(). Probably need to ship this for platforms
|
||||
that don't have it.
|
||||
|
||||
Solicit translations.
|
||||
|
||||
Does anyone care? Before we bother modifying the code, we ought to
|
||||
get the manual translated first, because that's possibly more useful
|
||||
and at any rate demonstrates desire.
|
||||
|
||||
-- --
|
||||
|
||||
DEVELOPMENT --------------------------------------------------------
|
||||
|
||||
Handling duplicate names
|
||||
|
||||
Some folks would like rsync to be deterministic in how it handles
|
||||
duplicate names that come from mering multiple source directories
|
||||
into a single destination directory; e.g. the last name wins. We
|
||||
could do this by switching our sort algorithm to one that will
|
||||
guarantee that the names won't be reordered. Alternately, we could
|
||||
assign an ever-increasing number to each item as we insert it into
|
||||
the list and then make sure that we leave the largest number when
|
||||
cleaning the file list (see clean_flist()). Another solution would
|
||||
be to add a hash table, and thus never put any duplicate names into
|
||||
the file list (and bump the protocol to handle this).
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Use generic zlib 2002/02/25
|
||||
|
||||
Perhaps don't use our own zlib.
|
||||
|
||||
Advantages:
|
||||
|
||||
- will automatically be up to date with bugfixes in zlib
|
||||
|
||||
- can leave it out for small rsync on e.g. recovery disks
|
||||
|
||||
- can use a shared library
|
||||
|
||||
- avoids people breaking rsync by trying to do this themselves and
|
||||
messing up
|
||||
|
||||
Should we ship zlib for systems that don't have it, or require
|
||||
people to install it separately?
|
||||
|
||||
Apparently this will make us incompatible with versions of rsync
|
||||
that use the patched version of rsync. Probably the simplest way to
|
||||
do this is to just disable gzip (with a warning) when talking to old
|
||||
versions.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Splint 2002/03/12
|
||||
|
||||
Build rsync with SPLINT to try to find security holes. Add
|
||||
annotations as necessary. Keep track of the number of warnings
|
||||
found initially, and see how many of them are real bugs, or real
|
||||
security bugs. Knowing the percentage of likely hits would be
|
||||
really interesting for other projects.
|
||||
|
||||
-- --
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
|
||||
Allow skipping MD4 file_sum 2002/04/08
|
||||
|
||||
If we're doing a local transfer, or using -W, then perhaps don't
|
||||
send the file checksum. If we're doing a local transfer, then
|
||||
calculating MD4 checksums uses 90% of CPU and is unlikely to be
|
||||
useful.
|
||||
|
||||
We should not allow it to be disabled separately from -W, though
|
||||
as it is the only thing that lets us know when the rsync algorithm
|
||||
got out of sync and messed the file up (i.e. if the basis file
|
||||
changed between checksum generation and reception).
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Accelerate MD4
|
||||
|
||||
Perhaps borrow an assembler MD4 from someone?
|
||||
|
||||
Make sure we call MD4 with properly-sized blocks whenever possible
|
||||
to avoid copying into the residue region?
|
||||
|
||||
-- --
|
||||
|
||||
TESTING --------------------------------------------------------------
|
||||
|
||||
Torture test
|
||||
|
||||
Something that just keeps running rsync continuously over a data set
|
||||
likely to generate problems.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Cross-test versions 2001/08/22
|
||||
|
||||
Part of the regression suite should be making sure that we
|
||||
don't break backwards compatibility: old clients vs new
|
||||
servers and so on. Ideally we would test both up and down
|
||||
from the current release to all old versions.
|
||||
|
||||
Run current rsync versions against significant past releases.
|
||||
|
||||
We might need to omit broken old versions, or versions in which
|
||||
particular functionality is broken
|
||||
|
||||
It might be sufficient to test downloads from well-known public
|
||||
rsync servers running different versions of rsync. This will give
|
||||
some testing and also be the most common case for having different
|
||||
versions and not being able to upgrade.
|
||||
|
||||
The new --protocol option may help in this.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Test on kernel source
|
||||
|
||||
Download all versions of kernel; unpack, sync between them. Also
|
||||
sync between uncompressed tarballs. Compare directories after
|
||||
transfer.
|
||||
|
||||
Use local mode; ssh; daemon; --whole-file and --no-whole-file.
|
||||
|
||||
Use awk to pull out the 'speedup' number for each transfer. Make
|
||||
sure it is >= x.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Test large files
|
||||
|
||||
Sparse and non-sparse
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create mutator program for testing
|
||||
|
||||
Insert bytes, delete bytes, swap blocks, ...
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create configure option to enable dangerous tests
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create pipe program for testing
|
||||
|
||||
Create pipe program that makes slow/jerky connections for
|
||||
testing Versions of read() and write() that corrupt the
|
||||
stream, or abruptly fail
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create test makefile target for some tests
|
||||
|
||||
Separate makefile target to run rough tests -- or perhaps
|
||||
just run them every time?
|
||||
|
||||
-- --
|
||||
|
||||
RELATED PROJECTS -----------------------------------------------------
|
||||
|
||||
rsyncsh
|
||||
|
||||
Write a small emulation of interactive ftp as a Pythonn program
|
||||
that calls rsync. Commands such as "cd", "ls", "ls *.c" etc map
|
||||
fairly directly into rsync commands: it just needs to remember the
|
||||
current host, directory and so on. We can probably even do
|
||||
completion of remote filenames.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
https://rsync.samba.org/rsync-and-debian/
|
||||
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
rsyncable gzip patch
|
||||
|
||||
Exhaustive, tortuous testing
|
||||
|
||||
Cleanups?
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
rsyncsplit as alternative to real integration with gzip?
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
reverse rsync over HTTP Range
|
||||
|
||||
Goswin Brederlow suggested this on Debian; I think tridge and I
|
||||
talked about it previous in relation to rproxy.
|
||||
|
||||
Addendum: It looks like someone is working on a version of this:
|
||||
|
||||
http://zsync.moria.org.uk/
|
||||
|
||||
-- --
|
||||
|
||||
344
access.c
344
access.c
@@ -1,96 +1,257 @@
|
||||
/*
|
||||
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-2022 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"
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
#include <netgroup.h>
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
|
||||
static int match_address(char *addr, char *tok)
|
||||
{
|
||||
char *p;
|
||||
unsigned long a, t, mask = ~0;
|
||||
|
||||
if (!addr || !*addr) return 0;
|
||||
|
||||
if (!isdigit(tok[0])) return 0;
|
||||
|
||||
p = strchr(tok,'/');
|
||||
if (p) *p = 0;
|
||||
|
||||
a = inet_addr(addr);
|
||||
t = inet_addr(tok);
|
||||
|
||||
if (p) {
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
if (t == INADDR_NONE) {
|
||||
rprintf(FERROR,"malformed address %s\n", tok);
|
||||
if (!host || !*host)
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = ntohl(a);
|
||||
t = ntohl(t);
|
||||
#ifdef HAVE_INNETGR
|
||||
if (*tok == '@' && tok[1])
|
||||
return innetgr(tok + 1, host, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (p) {
|
||||
if (strchr(p+1,'.')) {
|
||||
mask = inet_addr(p+1);
|
||||
if (mask == INADDR_NONE) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
return 0;
|
||||
}
|
||||
mask = ntohl(mask);
|
||||
} else {
|
||||
int bits = atoi(p+1);
|
||||
if (bits <= 0 || bits > 32) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
return 0;
|
||||
}
|
||||
mask &= (mask << (32-bits));
|
||||
/* 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)
|
||||
*host_ptr = strdup(tok);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ((a&mask) == (t&mask));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int access_match(char *list, char *addr, char *host)
|
||||
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])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void make_mask(char *mask, int plen, int addrlen)
|
||||
{
|
||||
int w, b;
|
||||
|
||||
w = plen >> 3;
|
||||
b = plen & 0x7;
|
||||
|
||||
if (w)
|
||||
memset(mask, 0xff, w);
|
||||
if (w < addrlen)
|
||||
mask[w] = 0xff & (0xff<<(8-b));
|
||||
if (w+1 < addrlen)
|
||||
memset(mask+w+1, 0, addrlen-w-1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int match_address(const char *addr, const char *tok)
|
||||
{
|
||||
char *p;
|
||||
struct addrinfo hints, *resa, *rest;
|
||||
int gai;
|
||||
int ret = 0;
|
||||
int addrlen = 0;
|
||||
#ifdef HAVE_STRTOL
|
||||
long int bits;
|
||||
#else
|
||||
int bits;
|
||||
#endif
|
||||
char mask[16];
|
||||
char *a = NULL, *t = NULL;
|
||||
|
||||
if (!addr || !*addr)
|
||||
return 0;
|
||||
|
||||
p = strchr(tok,'/');
|
||||
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;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifdef AI_NUMERICHOST
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
|
||||
if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
|
||||
if (p)
|
||||
*p = '/';
|
||||
return 0;
|
||||
}
|
||||
|
||||
gai = getaddrinfo(tok, NULL, &hints, &rest);
|
||||
if (p)
|
||||
*p++ = '/';
|
||||
if (gai != 0) {
|
||||
rprintf(FLOG, "error matching address %s: %s\n",
|
||||
tok, gai_strerror(gai));
|
||||
freeaddrinfo(resa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rest->ai_family != resa->ai_family) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch(resa->ai_family) {
|
||||
case PF_INET:
|
||||
a = (char *)&((struct sockaddr_in *)resa->ai_addr)->sin_addr;
|
||||
t = (char *)&((struct sockaddr_in *)rest->ai_addr)->sin_addr;
|
||||
addrlen = 4;
|
||||
|
||||
break;
|
||||
|
||||
#ifdef INET6
|
||||
case PF_INET6: {
|
||||
struct sockaddr_in6 *sin6a, *sin6t;
|
||||
|
||||
sin6a = (struct sockaddr_in6 *)resa->ai_addr;
|
||||
sin6t = (struct sockaddr_in6 *)rest->ai_addr;
|
||||
|
||||
a = (char *)&sin6a->sin6_addr;
|
||||
t = (char *)&sin6t->sin6_addr;
|
||||
|
||||
addrlen = 16;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
if (sin6t->sin6_scope_id && sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
rprintf(FLOG, "unknown family %u\n", rest->ai_family);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bits = -1;
|
||||
if (p) {
|
||||
if (inet_pton(resa->ai_addr->sa_family, p, mask) <= 0) {
|
||||
#ifdef HAVE_STRTOL
|
||||
char *ep = NULL;
|
||||
#else
|
||||
unsigned char *pp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRTOL
|
||||
bits = strtol(p, &ep, 10);
|
||||
if (!*p || *ep) {
|
||||
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(FLOG, "malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
bits = atoi(p);
|
||||
#endif
|
||||
if (bits == 0) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
if (bits < 0 || bits > (addrlen << 3)) {
|
||||
rprintf(FLOG, "malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bits = 128;
|
||||
}
|
||||
|
||||
if (bits >= 0)
|
||||
make_mask(mask, bits, addrlen);
|
||||
|
||||
ret = match_binary(a, t, mask, addrlen);
|
||||
|
||||
out:
|
||||
freeaddrinfo(resa);
|
||||
freeaddrinfo(rest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -100,31 +261,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;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#undef HAVE_BROKEN_READDIR
|
||||
#undef HAVE_ERRNO_DECL
|
||||
#undef HAVE_LONGLONG
|
||||
#undef HAVE_OFF64_T
|
||||
#undef HAVE_REMSH
|
||||
#undef HAVE_UNSIGNED_CHAR
|
||||
#undef HAVE_UTIMBUF
|
||||
#undef ino_t
|
||||
#undef HAVE_CONNECT
|
||||
426
authenticate.c
426
authenticate.c
@@ -1,38 +1,42 @@
|
||||
/*
|
||||
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 rsync daemon authentication.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2002-2020 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"
|
||||
#include "ifuncs.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) {
|
||||
@@ -45,171 +49,325 @@ 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, 16);
|
||||
gettimeofday(&tv, NULL);
|
||||
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(-1, 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;
|
||||
|
||||
if (!fname || !*fname) return 0;
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
while (!found) {
|
||||
int i = 0;
|
||||
memset(line, 0, sizeof(line));
|
||||
while (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++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
if (!found) return 0;
|
||||
|
||||
strlcpy(secret, pass, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* generate a 16 byte hash from a password and challenge */
|
||||
void generate_hash(char *in, char *challenge, char *out)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
sum_init();
|
||||
sum_init(-1, 0);
|
||||
sum_update(in, strlen(in));
|
||||
sum_update(challenge, strlen(challenge));
|
||||
sum_end(buf);
|
||||
len = sum_end(buf);
|
||||
|
||||
base64_encode(buf, 16, out);
|
||||
base64_encode(buf, len, out, 0);
|
||||
}
|
||||
|
||||
/* possible negotiate authentication with the client. Use "leader" to
|
||||
start off the auth if necessary
|
||||
/* 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;
|
||||
int user_len = strlen(user);
|
||||
int group_len = group ? strlen(group) : 0;
|
||||
char *err;
|
||||
FILE *fh;
|
||||
|
||||
return NULL if authentication failed
|
||||
if (!fname || !*fname || (fh = fopen(fname, "r")) == NULL)
|
||||
return "no secrets file";
|
||||
|
||||
return "" if anonymous access
|
||||
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(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
fclose(fh);
|
||||
return "ignoring secrets file";
|
||||
}
|
||||
|
||||
otherwise return username
|
||||
*/
|
||||
char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
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;
|
||||
}
|
||||
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. */
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
|
||||
force_memzero(line, sizeof line);
|
||||
force_memzero(pass2, sizeof pass2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const char *getpassf(const char *filename)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
char buffer[512], *p;
|
||||
int n;
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
n = fgets(buffer, sizeof buffer, stdin) == NULL ? -1 : (int)strlen(buffer);
|
||||
} else {
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename,O_RDONLY)) < 0) {
|
||||
rsyserr(FERROR, errno, "could not open password file %s", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
rsyserr(FERROR, errno, "stat(%s)", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
|
||||
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
n = read(fd, buffer, sizeof buffer - 1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
buffer[n] = '\0';
|
||||
if ((p = strtok(buffer, "\n\r")) != NULL)
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
rprintf(FERROR, "ERROR: failed to read a password from %s\n", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
/* Possibly negotiate authentication with the client. Use "leader" to
|
||||
* start off the auth if necessary.
|
||||
*
|
||||
* 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];
|
||||
const 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(fd,"%s%s\n", leader, b64_challenge);
|
||||
io_printf(f_out, "%s%s\n", leader, challenge);
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(user, 0, sizeof(user));
|
||||
memset(pass, 0, sizeof(pass));
|
||||
|
||||
if (sscanf(line,"%99s %29s", user, pass) != 2) {
|
||||
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';
|
||||
|
||||
users = strdup(users);
|
||||
if (!users) return NULL;
|
||||
|
||||
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
|
||||
if (strcmp(tok, user) == 0) break;
|
||||
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;
|
||||
auth_uid_groups = new_array(const char *, auth_uid_groups_cnt);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
free(users);
|
||||
|
||||
if (!tok) {
|
||||
return NULL;
|
||||
if (!tok)
|
||||
err = "no matching rule";
|
||||
else if (opt_ch == 'd')
|
||||
err = "denied by rule";
|
||||
else {
|
||||
const 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));
|
||||
|
||||
force_memzero(challenge, sizeof challenge);
|
||||
force_memzero(pass, strlen(pass));
|
||||
|
||||
if (auth_uid_groups) {
|
||||
int j;
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j])
|
||||
free((char*)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];
|
||||
const char *pass;
|
||||
char pass2[MAX_DIGEST_LEN*2];
|
||||
|
||||
if (!user || !*user) return;
|
||||
if (!user || !*user)
|
||||
user = "nobody";
|
||||
|
||||
if (!(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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
355
backup.c
Normal file
355
backup.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Backup handling code.
|
||||
*
|
||||
* Copyright (C) 1999 Andrew Tridgell
|
||||
* Copyright (C) 2003-2022 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 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;
|
||||
|
||||
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
|
||||
static int validate_backup_dir(void)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (do_lstat(backup_dir_buf, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
|
||||
if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a backup path from the given fname, putting the result into
|
||||
* backup_dir_buf. Any new directories (compared to the prior backup
|
||||
* path) are ensured to exist as directories, replacing anything else
|
||||
* that may be in the way (e.g. a symlink). */
|
||||
static BOOL copy_valid_path(const char *fname)
|
||||
{
|
||||
const char *f;
|
||||
int val;
|
||||
BOOL ret = True;
|
||||
stat_x sx;
|
||||
char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;
|
||||
|
||||
for (f = fname, b = rel; *f && *f == *b; f++, b++) {
|
||||
if (*b == '/')
|
||||
name = b + 1;
|
||||
}
|
||||
|
||||
if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
for ( ; ; name = b + 1) {
|
||||
if ((b = strchr(name, '/')) == NULL)
|
||||
return True;
|
||||
*b = '\0';
|
||||
|
||||
val = validate_backup_dir();
|
||||
if (val == 0)
|
||||
break;
|
||||
if (val < 0) {
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
init_stat_x(&sx);
|
||||
|
||||
for ( ; b; name = b + 1, b = strchr(name, '/')) {
|
||||
*b = '\0';
|
||||
|
||||
while (do_mkdir(backup_dir_buf, ACCESSPERMS) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
val = validate_backup_dir();
|
||||
if (val > 0)
|
||||
break;
|
||||
if (val == 0)
|
||||
continue;
|
||||
} else
|
||||
rsyserr(FERROR, errno, "backup mkdir %s failed", backup_dir_buf);
|
||||
*name = '\0';
|
||||
ret = False;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Try to transfer the directory settings of the actual dir
|
||||
* that the files are coming from. */
|
||||
if (x_stat(rel, &sx.st, NULL) < 0)
|
||||
rsyserr(FERROR, errno, "backup stat %s failed", full_fname(rel));
|
||||
else {
|
||||
struct file_struct *file;
|
||||
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
|
||||
continue;
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(rel, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(rel, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);
|
||||
unmake_file(file);
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make a complete pathname for backup file and verify any new path elements. */
|
||||
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)) {
|
||||
if (INFO_GTE(NONREG, 1))
|
||||
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, ATTRS_ACCURATE_TIME);
|
||||
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;
|
||||
}
|
||||
312
batch.c
Normal file
312
batch.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Support for the batch-file options.
|
||||
*
|
||||
* Copyright (C) 1999 Weiss
|
||||
* Copyright (C) 2004 Chris Shoemaker
|
||||
* Copyright (C) 2004-2022 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 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 write_batch;
|
||||
extern int protocol_version;
|
||||
extern int raw_argc, cooked_argc;
|
||||
extern char **raw_argv, **cooked_argv;
|
||||
extern char *batch_name;
|
||||
#ifdef ICONV_OPTION
|
||||
extern char *iconv_opt;
|
||||
#endif
|
||||
|
||||
extern filter_rule_list filter_list;
|
||||
|
||||
int batch_fd = -1;
|
||||
int batch_sh_fd = -1;
|
||||
int batch_stream_flags;
|
||||
|
||||
static int tweaked_append;
|
||||
static int tweaked_append_verify;
|
||||
static int tweaked_iconv;
|
||||
|
||||
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)
|
||||
{
|
||||
int i, flags;
|
||||
|
||||
tweaked_append = append_mode == 1;
|
||||
tweaked_append_verify = append_mode == 2;
|
||||
#ifdef ICONV_OPTION
|
||||
tweaked_iconv = iconv_opt != NULL;
|
||||
#endif
|
||||
|
||||
/* 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 read_stream_flags(int fd)
|
||||
{
|
||||
batch_stream_flags = read_int(fd);
|
||||
}
|
||||
|
||||
void check_batch_flags(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
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);
|
||||
}
|
||||
if (INFO_GTE(MISC, 1)) {
|
||||
rprintf(FINFO,
|
||||
"%sing the %s option to match the batchfile.\n",
|
||||
set ? "Sett" : "Clear", flag_name[i]);
|
||||
}
|
||||
*flag_ptr[i] = set;
|
||||
}
|
||||
}
|
||||
if (protocol_version < 29) {
|
||||
if (recurse)
|
||||
xfer_dirs |= 1;
|
||||
else if (xfer_dirs < 2)
|
||||
xfer_dirs = 0;
|
||||
}
|
||||
|
||||
if (tweaked_append)
|
||||
append_mode = 1;
|
||||
else if (tweaked_append_verify)
|
||||
append_mode = 2;
|
||||
}
|
||||
|
||||
static int write_arg(const char *arg)
|
||||
{
|
||||
const char *x, *s;
|
||||
int len, err = 0;
|
||||
|
||||
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
|
||||
err |= write(batch_sh_fd, arg, x - arg + 1) != x - arg + 1;
|
||||
arg += x - arg + 1;
|
||||
}
|
||||
|
||||
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
|
||||
err |= write(batch_sh_fd, "'", 1) != 1;
|
||||
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
|
||||
err |= write(batch_sh_fd, s, x - s + 1) != x - s + 1;
|
||||
err |= write(batch_sh_fd, "'", 1) != 1;
|
||||
}
|
||||
len = strlen(s);
|
||||
err |= write(batch_sh_fd, s, len) != len;
|
||||
err |= write(batch_sh_fd, "'", 1) != 1;
|
||||
return err;
|
||||
}
|
||||
|
||||
len = strlen(arg);
|
||||
err |= write(batch_sh_fd, arg, len) != len;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Writes out a space and then an option (or other string) with an optional "=" + arg suffix. */
|
||||
static int write_opt(const char *opt, const char *arg)
|
||||
{
|
||||
int len = strlen(opt);
|
||||
int err = write(batch_sh_fd, " ", 1) != 1;
|
||||
err = write(batch_sh_fd, opt, len) != len ? 1 : 0;
|
||||
if (arg) {
|
||||
err |= write(batch_sh_fd, "=", 1) != 1;
|
||||
err |= write_arg(arg);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void write_filter_rules(int fd)
|
||||
{
|
||||
filter_rule *ent;
|
||||
|
||||
write_sbuf(fd, " <<'#E#'\n");
|
||||
for (ent = filter_list.head; ent; ent = ent->next) {
|
||||
unsigned int plen;
|
||||
char *p = get_rule_prefix(ent, "- ", 0, &plen);
|
||||
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#");
|
||||
}
|
||||
|
||||
/* This sets batch_fd and (for --write-batch) batch_sh_fd. */
|
||||
void open_batch_files(void)
|
||||
{
|
||||
if (write_batch) {
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
stringjoin(filename, sizeof filename, batch_name, ".sh", NULL);
|
||||
|
||||
batch_sh_fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
if (batch_sh_fd < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(filename));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
batch_fd = do_open(batch_name, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
} else if (strcmp(batch_name, "-") == 0)
|
||||
batch_fd = STDIN_FILENO;
|
||||
else
|
||||
batch_fd = do_open(batch_name, O_RDONLY, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (batch_fd < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s open error", full_fname(batch_name));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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(void)
|
||||
{
|
||||
int i, j, len, err = 0;
|
||||
char *p, *p2;
|
||||
|
||||
/* Write argvs info to BATCH.sh file */
|
||||
err |= write_arg(raw_argv[0]);
|
||||
if (filter_list.head) {
|
||||
if (protocol_version >= 29)
|
||||
err |= write_opt("--filter", "._-");
|
||||
else
|
||||
err |= write_opt("--exclude-from", "-");
|
||||
}
|
||||
|
||||
/* Elide the filename args from the option list, but scan for them in reverse. */
|
||||
for (i = raw_argc-1, j = cooked_argc-1; i > 0 && j >= 0; i--) {
|
||||
if (strcmp(raw_argv[i], cooked_argv[j]) == 0) {
|
||||
raw_argv[i] = NULL;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < raw_argc; i++) {
|
||||
if (!(p = raw_argv[i]))
|
||||
continue;
|
||||
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 (strncmp(p, "--write-batch", len = 13) == 0
|
||||
|| strncmp(p, "--only-write-batch", len = 18) == 0)
|
||||
err |= write_opt("--read-batch", p[len] == '=' ? p + len + 1 : NULL);
|
||||
else {
|
||||
err |= write(batch_sh_fd, " ", 1) != 1;
|
||||
err |= write_arg(p);
|
||||
}
|
||||
}
|
||||
if (!(p = check_for_hostspec(cooked_argv[cooked_argc - 1], &p2, &i)))
|
||||
p = cooked_argv[cooked_argc - 1];
|
||||
err |= write_opt("${1:-", NULL);
|
||||
err |= write_arg(p);
|
||||
err |= write(batch_sh_fd, "}", 1) != 1;
|
||||
if (filter_list.head)
|
||||
write_filter_rules(batch_sh_fd);
|
||||
if (write(batch_sh_fd, "\n", 1) != 1 || close(batch_sh_fd) < 0 || err) {
|
||||
rsyserr(FERROR, errno, "Batch file %s.sh write error", batch_name);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
batch_sh_fd = -1;
|
||||
}
|
||||
155
byteorder.h
155
byteorder.h
@@ -1,27 +1,28 @@
|
||||
/*
|
||||
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-2022 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
|
||||
|
||||
/* 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 +31,101 @@
|
||||
#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 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 IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
|
||||
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
|
||||
#endif
|
||||
|
||||
static inline uint32
|
||||
IVALu(const uchar *buf, int pos)
|
||||
{
|
||||
return UVAL(buf, pos)
|
||||
| UVAL(buf, pos + 1) << 8
|
||||
| UVAL(buf, pos + 2) << 16
|
||||
| UVAL(buf, pos + 3) << 24;
|
||||
}
|
||||
|
||||
static inline void
|
||||
SIVALu(uchar *buf, int pos, uint32 val)
|
||||
{
|
||||
CVAL(buf, pos) = val;
|
||||
CVAL(buf, pos + 1) = val >> 8;
|
||||
CVAL(buf, pos + 2) = val >> 16;
|
||||
CVAL(buf, pos + 3) = val >> 24;
|
||||
}
|
||||
|
||||
static inline int64
|
||||
IVAL64(const char *buf, int pos)
|
||||
{
|
||||
return IVALu((uchar*)buf, pos) | (int64)IVALu((uchar*)buf, pos + 4) << 32;
|
||||
}
|
||||
|
||||
static inline void
|
||||
SIVAL64(char *buf, int pos, int64 val)
|
||||
{
|
||||
SIVALu((uchar*)buf, pos, val);
|
||||
SIVALu((uchar*)buf, pos + 4, val >> 32);
|
||||
}
|
||||
|
||||
#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. */
|
||||
|
||||
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 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 /* !CAREFUL_ALIGNMENT */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
92
case_N.h
Normal file
92
case_N.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Allow an arbitrary sequence of case labels.
|
||||
*
|
||||
* Copyright (C) 2006-2020 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 segment 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
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
#elif !defined CASE_N_STATE_2
|
||||
#define CASE_N_STATE_2
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
#elif !defined CASE_N_STATE_3
|
||||
#define CASE_N_STATE_3
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
#elif !defined CASE_N_STATE_4
|
||||
#define CASE_N_STATE_4
|
||||
/* FALLTHROUGH */
|
||||
case 4:
|
||||
#elif !defined CASE_N_STATE_5
|
||||
#define CASE_N_STATE_5
|
||||
/* FALLTHROUGH */
|
||||
case 5:
|
||||
#elif !defined CASE_N_STATE_6
|
||||
#define CASE_N_STATE_6
|
||||
/* FALLTHROUGH */
|
||||
case 6:
|
||||
#elif !defined CASE_N_STATE_7
|
||||
#define CASE_N_STATE_7
|
||||
/* FALLTHROUGH */
|
||||
case 7:
|
||||
#elif !defined CASE_N_STATE_8
|
||||
#define CASE_N_STATE_8
|
||||
/* FALLTHROUGH */
|
||||
case 8:
|
||||
#elif !defined CASE_N_STATE_9
|
||||
#define CASE_N_STATE_9
|
||||
/* FALLTHROUGH */
|
||||
case 9:
|
||||
#elif !defined CASE_N_STATE_10
|
||||
#define CASE_N_STATE_10
|
||||
/* FALLTHROUGH */
|
||||
case 10:
|
||||
#elif !defined CASE_N_STATE_11
|
||||
#define CASE_N_STATE_11
|
||||
/* FALLTHROUGH */
|
||||
case 11:
|
||||
#elif !defined CASE_N_STATE_12
|
||||
#define CASE_N_STATE_12
|
||||
/* FALLTHROUGH */
|
||||
case 12:
|
||||
#elif !defined CASE_N_STATE_13
|
||||
#define CASE_N_STATE_13
|
||||
/* FALLTHROUGH */
|
||||
case 13:
|
||||
#elif !defined CASE_N_STATE_14
|
||||
#define CASE_N_STATE_14
|
||||
/* FALLTHROUGH */
|
||||
case 14:
|
||||
#elif !defined CASE_N_STATE_15
|
||||
#define CASE_N_STATE_15
|
||||
/* FALLTHROUGH */
|
||||
case 15:
|
||||
#elif !defined CASE_N_STATE_16
|
||||
#define CASE_N_STATE_16
|
||||
/* FALLTHROUGH */
|
||||
case 16:
|
||||
#else
|
||||
#error Need to add more case statements!
|
||||
#endif
|
||||
787
checksum.c
787
checksum.c
@@ -1,195 +1,658 @@
|
||||
/*
|
||||
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-2022 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.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to dynamically link rsync with the OpenSSL and xxhash
|
||||
* libraries when those libraries are being distributed in compliance
|
||||
* with their license terms, and to distribute a dynamically linked
|
||||
* combination of rsync and these libraries. This is also considered
|
||||
* to be covered under the GPL's System Libraries exception.
|
||||
*
|
||||
* 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 */
|
||||
#ifdef SUPPORT_XXHASH
|
||||
#include <xxhash.h>
|
||||
# if XXH_VERSION_NUMBER >= 800
|
||||
# define SUPPORT_XXH3 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define CSUM_CHUNK 64
|
||||
extern int am_server;
|
||||
extern int whole_file;
|
||||
extern int checksum_seed;
|
||||
extern int protocol_version;
|
||||
extern int proper_seed_order;
|
||||
extern const char *checksum_choice;
|
||||
|
||||
int checksum_seed = 0;
|
||||
extern int remote_version;
|
||||
struct name_num_obj valid_checksums = {
|
||||
"checksum", NULL, NULL, 0, 0, {
|
||||
#ifdef SUPPORT_XXH3
|
||||
{ CSUM_XXH3_128, "xxh128", NULL },
|
||||
{ CSUM_XXH3_64, "xxh3", NULL },
|
||||
#endif
|
||||
#ifdef SUPPORT_XXHASH
|
||||
{ CSUM_XXH64, "xxh64", NULL },
|
||||
{ CSUM_XXH64, "xxhash", NULL },
|
||||
#endif
|
||||
{ CSUM_MD5, "md5", NULL },
|
||||
{ CSUM_MD4, "md4", NULL },
|
||||
{ CSUM_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
}
|
||||
};
|
||||
|
||||
int xfersum_type = 0; /* used for the file transfer checksums */
|
||||
int checksum_type = 0; /* used for the pre-transfer (--checksum) checksums */
|
||||
|
||||
static int initialized_choices = 0;
|
||||
|
||||
int parse_csum_name(const char *name, int len)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
|
||||
if (len < 0 && name)
|
||||
len = strlen(name);
|
||||
|
||||
if (!name || (len == 4 && strncasecmp(name, "auto", 4) == 0)) {
|
||||
if (protocol_version >= 30)
|
||||
return CSUM_MD5;
|
||||
if (protocol_version >= 27)
|
||||
return CSUM_MD4_OLD;
|
||||
if (protocol_version >= 21)
|
||||
return CSUM_MD4_BUSTED;
|
||||
return CSUM_MD4_ARCHAIC;
|
||||
}
|
||||
|
||||
if (!initialized_choices)
|
||||
init_checksum_choices();
|
||||
|
||||
nni = get_nni_by_name(&valid_checksums, name, len);
|
||||
|
||||
if (!nni) {
|
||||
rprintf(FERROR, "unknown checksum name: %s\n", name);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
return nni->num;
|
||||
}
|
||||
|
||||
static const char *checksum_name(int num)
|
||||
{
|
||||
struct name_num_item *nni = get_nni_by_num(&valid_checksums, num);
|
||||
|
||||
return nni ? nni->name : num < CSUM_MD4 ? "md4" : "UNKNOWN";
|
||||
}
|
||||
|
||||
void parse_checksum_choice(int final_call)
|
||||
{
|
||||
if (valid_checksums.negotiated_name)
|
||||
xfersum_type = checksum_type = valid_checksums.negotiated_num;
|
||||
else {
|
||||
char *cp = checksum_choice ? strchr(checksum_choice, ',') : NULL;
|
||||
if (cp) {
|
||||
xfersum_type = parse_csum_name(checksum_choice, cp - checksum_choice);
|
||||
checksum_type = parse_csum_name(cp+1, -1);
|
||||
} else
|
||||
xfersum_type = checksum_type = parse_csum_name(checksum_choice, -1);
|
||||
if (am_server && checksum_choice)
|
||||
validate_choice_vs_env(NSTR_CHECKSUM, xfersum_type, checksum_type);
|
||||
}
|
||||
|
||||
if (xfersum_type == CSUM_NONE)
|
||||
whole_file = 1;
|
||||
|
||||
/* Snag the checksum name for both write_batch's option output & the following debug output. */
|
||||
if (valid_checksums.negotiated_name)
|
||||
checksum_choice = valid_checksums.negotiated_name;
|
||||
else if (checksum_choice == NULL)
|
||||
checksum_choice = checksum_name(xfersum_type);
|
||||
|
||||
if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)) {
|
||||
rprintf(FINFO, "%s%s checksum: %s\n",
|
||||
am_server ? "Server" : "Client",
|
||||
valid_checksums.negotiated_name ? " negotiated" : "",
|
||||
checksum_choice);
|
||||
}
|
||||
}
|
||||
|
||||
int csum_len_for_type(int cst, BOOL flist_csum)
|
||||
{
|
||||
switch (cst) {
|
||||
case CSUM_NONE:
|
||||
return 1;
|
||||
case CSUM_MD4_ARCHAIC:
|
||||
/* The oldest checksum code is rather weird: the file-list code only sent
|
||||
* 2-byte checksums, but all other checksums were full MD4 length. */
|
||||
return flist_csum ? 2 : MD4_DIGEST_LEN;
|
||||
case CSUM_MD4:
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
return MD4_DIGEST_LEN;
|
||||
case CSUM_MD5:
|
||||
return MD5_DIGEST_LEN;
|
||||
case CSUM_XXH64:
|
||||
case CSUM_XXH3_64:
|
||||
return 64/8;
|
||||
case CSUM_XXH3_128:
|
||||
return 128/8;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 0 if the checksum is not canonical (i.e. it includes a seed value).
|
||||
* Returns 1 if the public sum order matches our internal sum order.
|
||||
* Returns -1 if the public sum order is the reverse of our internal sum order.
|
||||
*/
|
||||
int canonical_checksum(int csum_type)
|
||||
{
|
||||
switch (csum_type) {
|
||||
case CSUM_NONE:
|
||||
case CSUM_MD4_ARCHAIC:
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
break;
|
||||
case CSUM_MD4:
|
||||
case CSUM_MD5:
|
||||
return -1;
|
||||
case CSUM_XXH64:
|
||||
case CSUM_XXH3_64:
|
||||
case CSUM_XXH3_128:
|
||||
return 1;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef USE_ROLL_SIMD /* See simd-checksum-*.cpp. */
|
||||
/*
|
||||
a simple 32 bit checksum that can be upadted from either end
|
||||
a simple 32 bit checksum that can be updated 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;
|
||||
uint32 s1, s2;
|
||||
schar *buf = (schar *)buf1;
|
||||
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] +
|
||||
10*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;
|
||||
}
|
||||
return (s1 & 0xffff) + (s2 << 16);
|
||||
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] + 10*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;
|
||||
}
|
||||
return (s1 & 0xffff) + (s2 << 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
void get_checksum2(char *buf, int32 len, char *sum)
|
||||
{
|
||||
switch (xfersum_type) {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
SIVAL64(sum, 0, XXH3_64bits_withSeed(buf, len, checksum_seed));
|
||||
break;
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest = XXH3_128bits_withSeed(buf, len, checksum_seed);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5: {
|
||||
md5_context m5;
|
||||
uchar seedbuf[4];
|
||||
md5_begin(&m5);
|
||||
if (proper_seed_order) {
|
||||
if (checksum_seed) {
|
||||
SIVALu(seedbuf, 0, checksum_seed);
|
||||
md5_update(&m5, seedbuf, 4);
|
||||
}
|
||||
md5_update(&m5, (uchar *)buf, len);
|
||||
} else {
|
||||
md5_update(&m5, (uchar *)buf, len);
|
||||
if (checksum_seed) {
|
||||
SIVALu(seedbuf, 0, checksum_seed);
|
||||
md5_update(&m5, seedbuf, 4);
|
||||
}
|
||||
}
|
||||
md5_result(&m5, (uchar *)sum);
|
||||
break;
|
||||
}
|
||||
case CSUM_MD4:
|
||||
#ifdef USE_OPENSSL
|
||||
{
|
||||
MD4_CTX m4;
|
||||
MD4_Init(&m4);
|
||||
MD4_Update(&m4, (uchar *)buf, len);
|
||||
if (checksum_seed) {
|
||||
uchar seedbuf[4];
|
||||
SIVALu(seedbuf, 0, checksum_seed);
|
||||
MD4_Update(&m4, seedbuf, 4);
|
||||
}
|
||||
MD4_Final((uchar *)sum, &m4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
case CSUM_MD4_ARCHAIC: {
|
||||
md_context m;
|
||||
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;
|
||||
}
|
||||
|
||||
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 || xfersum_type > CSUM_MD4_BUSTED)
|
||||
mdfour_update(&m, (uchar *)(buf1+i), len-i);
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
break;
|
||||
}
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void sum_put(MDstruct *md,char *sum)
|
||||
void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
|
||||
{
|
||||
SIVAL(sum,0,md->buffer[0]);
|
||||
if (csum_length <= 4) return;
|
||||
SIVAL(sum,4,md->buffer[1]);
|
||||
if (csum_length <= 8) return;
|
||||
SIVAL(sum,8,md->buffer[2]);
|
||||
if (csum_length <= 12) return;
|
||||
SIVAL(sum,12,md->buffer[3]);
|
||||
struct map_struct *buf;
|
||||
OFF_T i, len = st_p->st_size;
|
||||
int32 remainder;
|
||||
int fd;
|
||||
|
||||
memset(sum, 0, MAX_DIGEST_LEN);
|
||||
|
||||
fd = do_open(fname, O_RDONLY, 0);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
buf = map_file(fd, len, MAX_MAP_SIZE, CHUNK_SIZE);
|
||||
|
||||
switch (checksum_type) {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64: {
|
||||
static XXH64_state_t* state = NULL;
|
||||
if (!state && !(state = XXH64_createState()))
|
||||
out_of_memory("file_checksum");
|
||||
|
||||
XXH64_reset(state, 0);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
XXH64_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
XXH64_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
SIVAL64(sum, 0, XXH64_digest(state));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64: {
|
||||
static XXH3_state_t* state = NULL;
|
||||
if (!state && !(state = XXH3_createState()))
|
||||
out_of_memory("file_checksum");
|
||||
|
||||
XXH3_64bits_reset(state);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
SIVAL64(sum, 0, XXH3_64bits_digest(state));
|
||||
break;
|
||||
}
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest;
|
||||
static XXH3_state_t* state = NULL;
|
||||
if (!state && !(state = XXH3_createState()))
|
||||
out_of_memory("file_checksum");
|
||||
|
||||
XXH3_128bits_reset(state);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
digest = XXH3_128bits_digest(state);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5: {
|
||||
md5_context m5;
|
||||
|
||||
md5_begin(&m5);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
md5_update(&m5, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
md5_update(&m5, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
md5_result(&m5, (uchar *)sum);
|
||||
break;
|
||||
}
|
||||
case CSUM_MD4:
|
||||
#ifdef USE_OPENSSL
|
||||
{
|
||||
MD4_CTX m4;
|
||||
|
||||
MD4_Init(&m4);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
MD4_Update(&m4, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
MD4_Update(&m4, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
MD4_Final((uchar *)sum, &m4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
case CSUM_MD4_ARCHAIC: {
|
||||
md_context m;
|
||||
|
||||
mdfour_begin(&m);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
/* 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 || checksum_type > CSUM_MD4_BUSTED)
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rprintf(FERROR, "Invalid checksum-choice for --checksum: %s (%d)\n",
|
||||
checksum_name(checksum_type), checksum_type);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
unmap_file(buf);
|
||||
}
|
||||
|
||||
static int32 sumresidue;
|
||||
static union {
|
||||
md_context md;
|
||||
#ifdef USE_OPENSSL
|
||||
MD4_CTX m4;
|
||||
#endif
|
||||
md5_context m5;
|
||||
} ctx;
|
||||
#ifdef SUPPORT_XXHASH
|
||||
static XXH64_state_t* xxh64_state;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
static XXH3_state_t* xxh3_state;
|
||||
#endif
|
||||
static int cursum_type;
|
||||
|
||||
void get_checksum2(char *buf,int len,char *sum)
|
||||
void sum_init(int csum_type, int seed)
|
||||
{
|
||||
int i;
|
||||
MDstruct MD;
|
||||
static char *buf1;
|
||||
static int len1;
|
||||
char s[4];
|
||||
|
||||
if (len > len1) {
|
||||
if (buf1) free(buf1);
|
||||
buf1 = (char *)malloc(len+4);
|
||||
len1 = len;
|
||||
if (!buf1) out_of_memory("get_checksum2");
|
||||
}
|
||||
if (csum_type < 0)
|
||||
csum_type = parse_csum_name(NULL, 0);
|
||||
cursum_type = csum_type;
|
||||
|
||||
MDbegin(&MD);
|
||||
|
||||
bcopy(buf,buf1,len);
|
||||
if (checksum_seed) {
|
||||
SIVAL(buf1,len,checksum_seed);
|
||||
len += 4;
|
||||
}
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
MDupdate(&MD, buf1+i, CSUM_CHUNK*8);
|
||||
}
|
||||
if (len - i > 0)
|
||||
MDupdate(&MD, buf1+i, (len-i)*8);
|
||||
|
||||
sum_put(&MD,sum);
|
||||
switch (csum_type) {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
if (!xxh64_state && !(xxh64_state = XXH64_createState()))
|
||||
out_of_memory("sum_init");
|
||||
XXH64_reset(xxh64_state, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
|
||||
out_of_memory("sum_init");
|
||||
XXH3_64bits_reset(xxh3_state);
|
||||
break;
|
||||
case CSUM_XXH3_128:
|
||||
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
|
||||
out_of_memory("sum_init");
|
||||
XXH3_128bits_reset(xxh3_state);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
md5_begin(&ctx.m5);
|
||||
break;
|
||||
case CSUM_MD4:
|
||||
#ifdef USE_OPENSSL
|
||||
MD4_Init(&ctx.m4);
|
||||
#else
|
||||
mdfour_begin(&ctx.md);
|
||||
sumresidue = 0;
|
||||
#endif
|
||||
break;
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
case CSUM_MD4_ARCHAIC:
|
||||
mdfour_begin(&ctx.md);
|
||||
sumresidue = 0;
|
||||
SIVAL(s, 0, seed);
|
||||
sum_update(s, 4);
|
||||
break;
|
||||
case CSUM_NONE:
|
||||
break;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void file_checksum(char *fname,char *sum,OFF_T size)
|
||||
/**
|
||||
* Feed data into an MD4 accumulator, md. The results may be
|
||||
* retrieved using sum_end(). md is used for different purposes at
|
||||
* different points during execution.
|
||||
*
|
||||
* @todo Perhaps get rid of md and just pass in the address each time.
|
||||
* Very slightly clearer and slower.
|
||||
**/
|
||||
void sum_update(const char *p, int32 len)
|
||||
{
|
||||
OFF_T i;
|
||||
MDstruct MD;
|
||||
struct map_struct *buf;
|
||||
int fd;
|
||||
OFF_T len = size;
|
||||
char tmpchunk[CSUM_CHUNK];
|
||||
switch (cursum_type) {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
XXH64_update(xxh64_state, p, len);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
XXH3_64bits_update(xxh3_state, p, len);
|
||||
break;
|
||||
case CSUM_XXH3_128:
|
||||
XXH3_128bits_update(xxh3_state, p, len);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
md5_update(&ctx.m5, (uchar *)p, len);
|
||||
break;
|
||||
case CSUM_MD4:
|
||||
#ifdef USE_OPENSSL
|
||||
MD4_Update(&ctx.m4, (uchar *)p, len);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD4_OLD:
|
||||
case CSUM_MD4_BUSTED:
|
||||
case CSUM_MD4_ARCHAIC:
|
||||
if (len + sumresidue < CSUM_CHUNK) {
|
||||
memcpy(ctx.md.buffer + sumresidue, p, len);
|
||||
sumresidue += len;
|
||||
break;
|
||||
}
|
||||
|
||||
bzero(sum,csum_length);
|
||||
if (sumresidue) {
|
||||
int32 i = CSUM_CHUNK - sumresidue;
|
||||
memcpy(ctx.md.buffer + sumresidue, p, i);
|
||||
mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, CSUM_CHUNK);
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) return;
|
||||
while (len >= CSUM_CHUNK) {
|
||||
mdfour_update(&ctx.md, (uchar *)p, CSUM_CHUNK);
|
||||
len -= CSUM_CHUNK;
|
||||
p += CSUM_CHUNK;
|
||||
}
|
||||
|
||||
buf = map_file(fd,size);
|
||||
|
||||
MDbegin(&MD);
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
bcopy(map_ptr(buf,i,CSUM_CHUNK),tmpchunk,CSUM_CHUNK);
|
||||
MDupdate(&MD, tmpchunk, CSUM_CHUNK*8);
|
||||
}
|
||||
|
||||
if (len - i > 0) {
|
||||
bcopy(map_ptr(buf,i,len-i),tmpchunk,len-i);
|
||||
MDupdate(&MD, tmpchunk, (len-i)*8);
|
||||
}
|
||||
|
||||
sum_put(&MD,sum);
|
||||
|
||||
close(fd);
|
||||
unmap_file(buf);
|
||||
sumresidue = len;
|
||||
if (sumresidue)
|
||||
memcpy(ctx.md.buffer, p, sumresidue);
|
||||
break;
|
||||
case CSUM_NONE:
|
||||
break;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checksum_init(void)
|
||||
/* NOTE: all the callers of sum_end() pass in a pointer to a buffer that is
|
||||
* MAX_DIGEST_LEN in size, so even if the csum-len is shorter than that (i.e.
|
||||
* CSUM_MD4_ARCHAIC), we don't have to worry about limiting the data we write
|
||||
* into the "sum" buffer. */
|
||||
int sum_end(char *sum)
|
||||
{
|
||||
if (remote_version >= 14)
|
||||
csum_length = 2; /* adaptive */
|
||||
else
|
||||
csum_length = SUM_LENGTH;
|
||||
switch (cursum_type) {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
SIVAL64(sum, 0, XXH64_digest(xxh64_state));
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
SIVAL64(sum, 0, XXH3_64bits_digest(xxh3_state));
|
||||
break;
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest = XXH3_128bits_digest(xxh3_state);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
md5_result(&ctx.m5, (uchar *)sum);
|
||||
break;
|
||||
case CSUM_MD4:
|
||||
#ifdef USE_OPENSSL
|
||||
MD4_Final((uchar *)sum, &ctx.m4);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD4_OLD:
|
||||
mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, sumresidue);
|
||||
mdfour_result(&ctx.md, (uchar *)sum);
|
||||
break;
|
||||
case CSUM_MD4_BUSTED:
|
||||
case CSUM_MD4_ARCHAIC:
|
||||
if (sumresidue)
|
||||
mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, sumresidue);
|
||||
mdfour_result(&ctx.md, (uchar *)sum);
|
||||
break;
|
||||
case CSUM_NONE:
|
||||
*sum = '\0';
|
||||
break;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
return csum_len_for_type(cursum_type, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static MDstruct sumMD;
|
||||
static int sumresidue;
|
||||
static char sumrbuf[CSUM_CHUNK];
|
||||
|
||||
void sum_init(void)
|
||||
void init_checksum_choices()
|
||||
{
|
||||
char s[4];
|
||||
MDbegin(&sumMD);
|
||||
sumresidue=0;
|
||||
SIVAL(s,0,checksum_seed);
|
||||
sum_update(s,4);
|
||||
#ifdef SUPPORT_XXH3
|
||||
char buf[32816];
|
||||
int j;
|
||||
for (j = 0; j < (int)sizeof buf; j++) {
|
||||
buf[j] = ' ' + (j % 96);
|
||||
}
|
||||
sum_init(CSUM_XXH3_64, 0);
|
||||
sum_update(buf, 32816);
|
||||
sum_update(buf, 31152);
|
||||
sum_update(buf, 32474);
|
||||
sum_update(buf, 9322);
|
||||
if (XXH3_64bits_digest(xxh3_state) != 0xadbcf16d4678d1de) {
|
||||
int t, f;
|
||||
struct name_num_item *nni = valid_checksums.list;
|
||||
for (t = f = 0; nni[f].name; f++) {
|
||||
if (nni[f].num == CSUM_XXH3_64 || nni[f].num == CSUM_XXH3_128)
|
||||
continue;
|
||||
if (t != f)
|
||||
nni[t++] = nni[f];
|
||||
}
|
||||
nni[t].name = NULL;
|
||||
}
|
||||
#endif
|
||||
initialized_choices = 1;
|
||||
}
|
||||
|
||||
void sum_update(char *p,int len)
|
||||
{
|
||||
int i;
|
||||
if (len + sumresidue < CSUM_CHUNK) {
|
||||
bcopy(p,sumrbuf+sumresidue,len);
|
||||
sumresidue += len;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sumresidue) {
|
||||
i = MIN(CSUM_CHUNK-sumresidue,len);
|
||||
bcopy(p,sumrbuf+sumresidue,i);
|
||||
MDupdate(&sumMD, sumrbuf, (i+sumresidue)*8);
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
bcopy(p+i,sumrbuf,CSUM_CHUNK);
|
||||
MDupdate(&sumMD, sumrbuf, CSUM_CHUNK*8);
|
||||
}
|
||||
|
||||
if (len - i > 0) {
|
||||
sumresidue = len-i;
|
||||
bcopy(p+i,sumrbuf,sumresidue);
|
||||
} else {
|
||||
sumresidue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sum_end(char *sum)
|
||||
{
|
||||
if (sumresidue)
|
||||
MDupdate(&sumMD, sumrbuf, sumresidue*8);
|
||||
|
||||
SIVAL(sum,0,sumMD.buffer[0]);
|
||||
SIVAL(sum,4,sumMD.buffer[1]);
|
||||
SIVAL(sum,8,sumMD.buffer[2]);
|
||||
SIVAL(sum,12,sumMD.buffer[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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-2020 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 success
|
||||
* (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;
|
||||
}
|
||||
298
cleanup.c
Normal file
298
cleanup.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* End-of-run cleanup routines.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2020 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 am_sender;
|
||||
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;
|
||||
|
||||
int called_from_signal_handler = 0;
|
||||
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)
|
||||
{
|
||||
#ifdef SHUTDOWN_ALL_SOCKETS
|
||||
int max_fd;
|
||||
int fd;
|
||||
int ret;
|
||||
STRUCT_STAT st;
|
||||
|
||||
max_fd = sysconf(_SC_OPEN_MAX) - 1;
|
||||
for (fd = max_fd; fd >= 0; fd--) {
|
||||
if ((ret = do_fstat(fd, &st)) == 0) {
|
||||
if (is_a_socket(fd))
|
||||
ret = shutdown(fd, 2);
|
||||
ret = close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @file cleanup.c
|
||||
*
|
||||
* Code for handling interrupted transfers. Depending on the @c
|
||||
* --partial option, we may either delete the temporary file, or go
|
||||
* ahead and overwrite the destination. This second behaviour only
|
||||
* occurs if we've sent literal data and therefore hopefully made
|
||||
* progress on the transfer.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Set to True once literal data has been sent across the link for the
|
||||
* current file. (????)
|
||||
*
|
||||
* Handling the cleanup when a transfer is interrupted is tricky when
|
||||
* --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;
|
||||
|
||||
static const char *cleanup_fname;
|
||||
static const char *cleanup_new_fname;
|
||||
static struct file_struct *cleanup_file;
|
||||
static int cleanup_fd_r = -1, cleanup_fd_w = -1;
|
||||
static pid_t cleanup_pid = 0;
|
||||
|
||||
pid_t cleanup_child_pid = -1;
|
||||
|
||||
/**
|
||||
* Eventually calls exit(), passing @p code, therefore does not return.
|
||||
*
|
||||
* @param code one of the RERR_* codes from errcode.h.
|
||||
**/
|
||||
NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
static int switch_step = 0;
|
||||
static int exit_code = 0, exit_line = 0;
|
||||
static const char *exit_file = NULL;
|
||||
static int first_code = 0;
|
||||
|
||||
SIGACTION(SIGUSR1, SIG_IGN);
|
||||
SIGACTION(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (!exit_code) { /* Preserve first error exit info when recursing. */
|
||||
exit_code = code;
|
||||
exit_file = file;
|
||||
exit_line = line < 0 ? -line : line;
|
||||
}
|
||||
|
||||
/* If 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;
|
||||
|
||||
/* 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++;
|
||||
|
||||
first_code = code;
|
||||
|
||||
if (output_needs_newline) {
|
||||
fputc('\n', stdout);
|
||||
output_needs_newline = 0;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(EXIT, 2)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
who_am_i(), code, src_file(file), line);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#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)" : "");
|
||||
}
|
||||
|
||||
#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) {
|
||||
if (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);
|
||||
}
|
||||
if (!am_sender)
|
||||
io_flush(MSG_FLUSH); /* Be sure to send all messages */
|
||||
noop_io_until_death();
|
||||
}
|
||||
else if (!am_sender)
|
||||
io_flush(MSG_FLUSH); /* Be sure to send all messages */
|
||||
}
|
||||
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (am_server && exit_code)
|
||||
msleep(100);
|
||||
close_all();
|
||||
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (called_from_signal_handler)
|
||||
_exit(exit_code);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
void cleanup_disable(void)
|
||||
{
|
||||
cleanup_fname = cleanup_new_fname = NULL;
|
||||
cleanup_fd_r = cleanup_fd_w = -1;
|
||||
cleanup_got_literal = 0;
|
||||
}
|
||||
|
||||
|
||||
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; /* can be NULL on a partial-dir failure */
|
||||
cleanup_file = file;
|
||||
cleanup_fd_r = fd_r;
|
||||
cleanup_fd_w = fd_w;
|
||||
}
|
||||
|
||||
void cleanup_set_pid(pid_t pid)
|
||||
{
|
||||
cleanup_pid = pid;
|
||||
}
|
||||
538
clientname.c
Normal file
538
clientname.c
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* 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-2022 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"
|
||||
#include "itypes.h"
|
||||
|
||||
extern int am_daemon;
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
static const char proxyv2sig[] = "\r\n\r\n\0\r\nQUIT\n";
|
||||
|
||||
static char ipaddr_buf[100];
|
||||
|
||||
#define PROXY_V2_SIG_SIZE ((int)sizeof proxyv2sig - 1)
|
||||
#define PROXY_V2_HEADER_SIZE (PROXY_V2_SIG_SIZE + 1 + 1 + 2)
|
||||
|
||||
#define CMD_LOCAL 0
|
||||
#define CMD_PROXY 1
|
||||
|
||||
#define PROXY_FAM_TCPv4 0x11
|
||||
#define PROXY_FAM_TCPv6 0x21
|
||||
|
||||
#define GET_SOCKADDR_FAMILY(ss) ((struct sockaddr*)ss)->sa_family
|
||||
|
||||
static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len);
|
||||
static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, char *name_buf, size_t name_buf_size);
|
||||
static int valid_ipaddr(const char *s, int allow_scope);
|
||||
|
||||
/* Return the IP addr of the client as a string. */
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
|
||||
if (*ipaddr_buf)
|
||||
return ipaddr_buf;
|
||||
|
||||
if (am_daemon < 0) { /* daemon over --rsh mode */
|
||||
char *env_str;
|
||||
strlcpy(ipaddr_buf, "0.0.0.0", sizeof ipaddr_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(ipaddr_buf, env_str, sizeof ipaddr_buf);
|
||||
/* Truncate the value to just the IP address. */
|
||||
if ((p = strchr(ipaddr_buf, ' ')) != NULL)
|
||||
*p = '\0';
|
||||
}
|
||||
if (valid_ipaddr(ipaddr_buf, True))
|
||||
return ipaddr_buf;
|
||||
}
|
||||
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
getnameinfo((struct sockaddr *)&ss, length, ipaddr_buf, sizeof ipaddr_buf, NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
return ipaddr_buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the DNS name of the client.
|
||||
*
|
||||
* The name is statically cached so that repeated lookups are quick,
|
||||
* so there is a limit of one lookup per customer.
|
||||
*
|
||||
* If anything goes wrong, including the name->addr->name check, then
|
||||
* we just use "UNKNOWN", so you can use that value in hosts allow
|
||||
* lines.
|
||||
*
|
||||
* After translation from sockaddr to name we do a forward lookup to
|
||||
* make sure nobody is spoofing PTR records.
|
||||
**/
|
||||
char *client_name(const char *ipaddr)
|
||||
{
|
||||
static char name_buf[100];
|
||||
char port_buf[100];
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len;
|
||||
struct addrinfo hint, *answer;
|
||||
int err;
|
||||
|
||||
if (*name_buf)
|
||||
return name_buf;
|
||||
|
||||
strlcpy(name_buf, default_name, sizeof name_buf);
|
||||
|
||||
if (strcmp(ipaddr, "0.0.0.0") == 0)
|
||||
return name_buf;
|
||||
|
||||
memset(&ss, 0, sizeof ss);
|
||||
memset(&hint, 0, sizeof hint);
|
||||
|
||||
#ifdef AI_NUMERICHOST
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if ((err = getaddrinfo(ipaddr, NULL, &hint, &answer)) != 0) {
|
||||
rprintf(FLOG, "malformed address %s: %s\n", ipaddr, 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:
|
||||
NOISY_DEATH("Unknown ai_family value");
|
||||
}
|
||||
freeaddrinfo(answer);
|
||||
|
||||
/* reverse lookup */
|
||||
err = getnameinfo((struct sockaddr*)&ss, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf, NI_NAMEREQD | NI_NUMERICSERV);
|
||||
if (err) {
|
||||
strlcpy(name_buf, default_name, sizeof name_buf);
|
||||
rprintf(FLOG, "name lookup failed for %s: %s\n", ipaddr, gai_strerror(err));
|
||||
} else
|
||||
check_name(ipaddr, &ss, name_buf, sizeof name_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
|
||||
/* Try to read a proxy protocol header (V1 or V2). Returns 1 on success or 0 on failure. */
|
||||
int read_proxy_protocol_header(int fd)
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
char line[108];
|
||||
} v1;
|
||||
struct {
|
||||
char sig[PROXY_V2_SIG_SIZE];
|
||||
char ver_cmd;
|
||||
char fam;
|
||||
char len[2];
|
||||
union {
|
||||
struct {
|
||||
char src_addr[4];
|
||||
char dst_addr[4];
|
||||
char src_port[2];
|
||||
char dst_port[2];
|
||||
} ip4;
|
||||
struct {
|
||||
char src_addr[16];
|
||||
char dst_addr[16];
|
||||
char src_port[2];
|
||||
char dst_port[2];
|
||||
} ip6;
|
||||
struct {
|
||||
char src_addr[108];
|
||||
char dst_addr[108];
|
||||
} unx;
|
||||
} addr;
|
||||
} v2;
|
||||
} hdr;
|
||||
|
||||
read_buf(fd, (char*)&hdr, PROXY_V2_SIG_SIZE);
|
||||
|
||||
if (memcmp(hdr.v2.sig, proxyv2sig, PROXY_V2_SIG_SIZE) == 0) { /* Proxy V2 */
|
||||
int ver, cmd, size;
|
||||
|
||||
read_buf(fd, (char*)&hdr + PROXY_V2_SIG_SIZE, PROXY_V2_HEADER_SIZE - PROXY_V2_SIG_SIZE);
|
||||
|
||||
ver = (hdr.v2.ver_cmd & 0xf0) >> 4;
|
||||
cmd = (hdr.v2.ver_cmd & 0x0f);
|
||||
size = (hdr.v2.len[0] << 8) + hdr.v2.len[1];
|
||||
|
||||
if (ver != 2 || size + PROXY_V2_HEADER_SIZE > (int)sizeof hdr)
|
||||
return 0;
|
||||
|
||||
/* Grab all the remaining data in the binary request. */
|
||||
read_buf(fd, (char*)&hdr + PROXY_V2_HEADER_SIZE, size);
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_PROXY:
|
||||
switch (hdr.v2.fam) {
|
||||
case PROXY_FAM_TCPv4:
|
||||
if (size != sizeof hdr.v2.addr.ip4)
|
||||
return 0;
|
||||
inet_ntop(AF_INET, hdr.v2.addr.ip4.src_addr, ipaddr_buf, sizeof ipaddr_buf);
|
||||
return valid_ipaddr(ipaddr_buf, False);
|
||||
#ifdef INET6
|
||||
case PROXY_FAM_TCPv6:
|
||||
if (size != sizeof hdr.v2.addr.ip6)
|
||||
return 0;
|
||||
inet_ntop(AF_INET6, hdr.v2.addr.ip6.src_addr, ipaddr_buf, sizeof ipaddr_buf);
|
||||
return valid_ipaddr(ipaddr_buf, False);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* For an unsupported protocol we'll ignore the proxy data (leaving ipaddr_buf unset)
|
||||
* and accept the connection, which will get handled as a normal socket addr. */
|
||||
return 1;
|
||||
case CMD_LOCAL:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(hdr.v1.line, "PROXY", 5) == 0) { /* Proxy V1 */
|
||||
char *endc, *sp, *p = hdr.v1.line + PROXY_V2_SIG_SIZE;
|
||||
int port_chk;
|
||||
|
||||
*p = '\0';
|
||||
if (!strchr(hdr.v1.line, '\n')) {
|
||||
while (1) {
|
||||
read_buf(fd, p, 1);
|
||||
if (*p++ == '\n')
|
||||
break;
|
||||
if (p - hdr.v1.line >= (int)sizeof hdr.v1.line - 1)
|
||||
return 0;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
endc = strchr(hdr.v1.line, '\r');
|
||||
if (!endc || endc[1] != '\n' || endc[2])
|
||||
return 0;
|
||||
*endc = '\0';
|
||||
|
||||
p = hdr.v1.line + 5;
|
||||
|
||||
if (!isSpace(p++))
|
||||
return 0;
|
||||
if (strncmp(p, "TCP4", 4) == 0)
|
||||
p += 4;
|
||||
else if (strncmp(p, "TCP6", 4) == 0)
|
||||
p += 4;
|
||||
else if (strncmp(p, "UNKNOWN", 7) == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (!isSpace(p++))
|
||||
return 0;
|
||||
|
||||
if ((sp = strchr(p, ' ')) == NULL)
|
||||
return 0;
|
||||
*sp = '\0';
|
||||
if (!valid_ipaddr(p, False))
|
||||
return 0;
|
||||
strlcpy(ipaddr_buf, p, sizeof ipaddr_buf); /* It will always fit when valid. */
|
||||
|
||||
p = sp + 1;
|
||||
if ((sp = strchr(p, ' ')) == NULL)
|
||||
return 0;
|
||||
*sp = '\0';
|
||||
if (!valid_ipaddr(p, False))
|
||||
return 0;
|
||||
/* Ignore destination address. */
|
||||
|
||||
p = sp + 1;
|
||||
if ((sp = strchr(p, ' ')) == NULL)
|
||||
return 0;
|
||||
*sp = '\0';
|
||||
port_chk = strtol(p, &endc, 10);
|
||||
if (*endc || port_chk == 0)
|
||||
return 0;
|
||||
/* Ignore source port. */
|
||||
|
||||
p = sp + 1;
|
||||
port_chk = strtol(p, &endc, 10);
|
||||
if (*endc || port_chk == 0)
|
||||
return 0;
|
||||
/* Ignore destination port. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the sockaddr for the client.
|
||||
*
|
||||
* If it comes in as an ipv4 address mapped into IPv6 format then we
|
||||
* convert it back to a regular IPv4.
|
||||
**/
|
||||
static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len)
|
||||
{
|
||||
memset(ss, 0, sizeof *ss);
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rsyserr(FLOG, errno, "getpeername on fd%d failed", fd);
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
if (GET_SOCKADDR_FAMILY(ss) == AF_INET6
|
||||
&& IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
|
||||
/* OK, so ss is in the IPv6 family, but it is really
|
||||
* an IPv4 address: something like
|
||||
* "::ffff:10.130.1.2". If we use it as-is, then the
|
||||
* reverse lookup might fail or perhaps something else
|
||||
* bad might happen. So instead we convert it to an
|
||||
* equivalent address in the IPv4 address family. */
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
memcpy(&sin6, ss, sizeof sin6);
|
||||
sin = (struct sockaddr_in *)ss;
|
||||
memset(sin, 0, sizeof *sin);
|
||||
sin->sin_family = AF_INET;
|
||||
*ss_len = sizeof (struct sockaddr_in);
|
||||
#ifdef HAVE_SOCKADDR_IN_LEN
|
||||
sin->sin_len = *ss_len;
|
||||
#endif
|
||||
sin->sin_port = sin6.sin6_port;
|
||||
|
||||
/* There is a macro to extract the mapped part
|
||||
* (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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare an addrinfo from the resolver to a sockinfo.
|
||||
*
|
||||
* Like strcmp, returns 0 for identical.
|
||||
**/
|
||||
static int compare_addrinfo_sockaddr(const struct addrinfo *ai, const struct sockaddr_storage *ss)
|
||||
{
|
||||
int ss_family = GET_SOCKADDR_FAMILY(ss);
|
||||
const char fn[] = "compare_addrinfo_sockaddr";
|
||||
|
||||
if (ai->ai_family != ss_family) {
|
||||
rprintf(FLOG, "%s: response family %d != %d\n",
|
||||
fn, ai->ai_family, ss_family);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The comparison method depends on the particular AF. */
|
||||
if (ss_family == AF_INET) {
|
||||
const struct sockaddr_in *sin1, *sin2;
|
||||
|
||||
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
|
||||
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 < (int)sizeof (struct sockaddr_in6)) {
|
||||
rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
|
||||
fn, (int)ai->ai_addrlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof sin1->sin6_addr))
|
||||
return 1;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
if (sin1->sin6_scope_id != sin2->sin6_scope_id)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
/* don't know */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do a forward lookup on @p name_buf and make sure it corresponds to
|
||||
* @p ss -- otherwise we may be being spoofed. If we suspect we are,
|
||||
* then we don't abort the connection but just emit a warning, and
|
||||
* change @p name_buf to be "UNKNOWN".
|
||||
*
|
||||
* We don't do anything with the service when checking the name,
|
||||
* because it doesn't seem that it could be spoofed in any way, and
|
||||
* getaddrinfo on random service names seems to cause problems on AIX.
|
||||
**/
|
||||
static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, 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);
|
||||
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(FLOG, "forward name lookup for %s failed: %s\n",
|
||||
name_buf, gai_strerror(error));
|
||||
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) {
|
||||
if (!compare_addrinfo_sockaddr(res, ss))
|
||||
break; /* OK, identical */
|
||||
}
|
||||
|
||||
if (!res0) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
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(FLOG, "%s is not a known address for \"%s\": "
|
||||
"spoofed address?\n", ipaddr, name_buf);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */
|
||||
static int valid_ipaddr(const char *s, int allow_scope)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strchr(s, ':') != NULL) { /* Only IPv6 has a colon. */
|
||||
int count, saw_double_colon = 0;
|
||||
int ipv4_at_end = 0;
|
||||
|
||||
if (*s == ':') { /* A colon at the start must be a :: */
|
||||
if (*++s != ':')
|
||||
return 0;
|
||||
saw_double_colon = 1;
|
||||
s++;
|
||||
}
|
||||
|
||||
for (count = 0; count < 8; count++) {
|
||||
if (!*s)
|
||||
return saw_double_colon;
|
||||
if (allow_scope && *s == '%') {
|
||||
if (saw_double_colon)
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strchr(s, ':') == NULL && strchr(s, '.') != NULL) {
|
||||
if ((!saw_double_colon && count != 6) || (saw_double_colon && count > 6))
|
||||
return 0;
|
||||
ipv4_at_end = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isHexDigit(s++)) /* Need 1-4 hex digits */
|
||||
return 0;
|
||||
if (isHexDigit(s) && isHexDigit(++s) && isHexDigit(++s) && isHexDigit(++s))
|
||||
return 0;
|
||||
|
||||
if (*s == ':') {
|
||||
if (!*++s)
|
||||
return 0;
|
||||
if (*s == ':') {
|
||||
if (saw_double_colon)
|
||||
return 0;
|
||||
saw_double_colon = 1;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ipv4_at_end) {
|
||||
if (allow_scope && *s == '%')
|
||||
for (s++; isAlNum(s); s++) { }
|
||||
return !*s && s[-1] != '%';
|
||||
}
|
||||
}
|
||||
|
||||
/* IPv4 */
|
||||
for (i = 0; i < 4; i++) {
|
||||
long n;
|
||||
char *end;
|
||||
|
||||
if (i && *s++ != '.')
|
||||
return 0;
|
||||
n = strtol(s, &end, 10);
|
||||
if (n > 255 || n < 0 || end <= s || end > s+3)
|
||||
return 0;
|
||||
s = end;
|
||||
}
|
||||
|
||||
return !*s;
|
||||
}
|
||||
1664
clientserver.c
1664
clientserver.c
File diff suppressed because it is too large
Load Diff
11
cmd-or-msg
Executable file
11
cmd-or-msg
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
opt="$1"
|
||||
shift
|
||||
|
||||
echo "$*"
|
||||
if ! "${@}"; then
|
||||
echo "If you can't fix the issue, re-run $srcdir/configure with --$opt."
|
||||
exit 1
|
||||
fi
|
||||
857
compat.c
857
compat.c
@@ -1,76 +1,813 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/* compatability routines for older rsync protocol versions */
|
||||
/*
|
||||
* Compatibility routines for older rsync protocol versions.
|
||||
*
|
||||
* Copyright (C) Andrew Tridgell 1996
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2004-2022 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"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int am_server;
|
||||
|
||||
extern int csum_length;
|
||||
|
||||
extern int preserve_links;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_devices;
|
||||
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 write_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_atimes;
|
||||
extern int preserve_crtimes;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int xfer_flags_as_varint;
|
||||
extern int need_messages_from_generator;
|
||||
extern int delete_mode, delete_before, delete_during, delete_after;
|
||||
extern int do_compression;
|
||||
extern int do_compression_level;
|
||||
extern int saw_stderr_opt;
|
||||
extern int msgs2stderr;
|
||||
extern char *shell_cmd;
|
||||
extern char *partial_dir;
|
||||
extern char *files_from;
|
||||
extern char *filesfrom_host;
|
||||
extern const char *checksum_choice;
|
||||
extern const char *compress_choice;
|
||||
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
|
||||
extern struct name_num_obj valid_checksums;
|
||||
|
||||
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;
|
||||
int inplace_partial = 0;
|
||||
int do_negotiated_strings = 0;
|
||||
int xmit_id0_names = 0;
|
||||
|
||||
extern int remote_version;
|
||||
extern int verbose;
|
||||
/* These index values are for the file-list's extra-attribute array. */
|
||||
int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
|
||||
|
||||
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
|
||||
int sender_symlink_iconv = 0; /* sender should convert symlink content */
|
||||
|
||||
#ifdef ICONV_OPTION
|
||||
int filesfrom_convert = 0;
|
||||
#endif
|
||||
|
||||
#define MAX_NSTR_STRLEN 256
|
||||
|
||||
struct name_num_obj valid_compressions = {
|
||||
"compress", NULL, NULL, 0, 0, {
|
||||
#ifdef SUPPORT_ZSTD
|
||||
{ CPRES_ZSTD, "zstd", NULL },
|
||||
#endif
|
||||
#ifdef SUPPORT_LZ4
|
||||
{ CPRES_LZ4, "lz4", NULL },
|
||||
#endif
|
||||
{ CPRES_ZLIBX, "zlibx", NULL },
|
||||
{ CPRES_ZLIB, "zlib", NULL },
|
||||
{ CPRES_NONE, "none", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
}
|
||||
};
|
||||
|
||||
#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)
|
||||
#define CF_INPLACE_PARTIAL_DIR (1<<6)
|
||||
#define CF_VARINT_FLIST_FLAGS (1<<7)
|
||||
#define CF_ID0_NAMES (1<<8)
|
||||
|
||||
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)
|
||||
{
|
||||
if (!local_server)
|
||||
client_info = shell_cmd ? shell_cmd : "";
|
||||
else if (am_server) {
|
||||
char buf[64];
|
||||
maybe_add_e_option(buf, sizeof buf);
|
||||
client_info = *buf ? strdup(buf+1) : ""; /* The +1 skips the leading "e". */
|
||||
}
|
||||
|
||||
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 && strchr(client_info, 'i') == NULL)
|
||||
allow_inc_recurse = 0;
|
||||
}
|
||||
|
||||
void parse_compress_choice(int final_call)
|
||||
{
|
||||
if (valid_compressions.negotiated_name)
|
||||
do_compression = valid_compressions.negotiated_num;
|
||||
else if (compress_choice) {
|
||||
struct name_num_item *nni = get_nni_by_name(&valid_compressions, compress_choice, -1);
|
||||
if (!nni) {
|
||||
rprintf(FERROR, "unknown compress name: %s\n", compress_choice);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
do_compression = nni->num;
|
||||
if (am_server)
|
||||
validate_choice_vs_env(NSTR_COMPRESS, do_compression, -1);
|
||||
} else if (do_compression)
|
||||
do_compression = CPRES_ZLIB;
|
||||
else
|
||||
do_compression = CPRES_NONE;
|
||||
|
||||
if (do_compression != CPRES_NONE && final_call)
|
||||
init_compression_level(); /* There's a chance this might turn compression off! */
|
||||
|
||||
if (do_compression == CPRES_NONE)
|
||||
compress_choice = NULL;
|
||||
|
||||
/* Snag the compression name for both write_batch's option output & the following debug output. */
|
||||
if (valid_compressions.negotiated_name)
|
||||
compress_choice = valid_compressions.negotiated_name;
|
||||
else if (compress_choice == NULL) {
|
||||
struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression);
|
||||
compress_choice = nni ? nni->name : "UNKNOWN";
|
||||
}
|
||||
|
||||
if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)
|
||||
&& (do_compression != CPRES_NONE || do_compression_level != CLVL_NOT_SPECIFIED)) {
|
||||
rprintf(FINFO, "%s%s compress: %s (level %d)\n",
|
||||
am_server ? "Server" : "Client",
|
||||
valid_compressions.negotiated_name ? " negotiated" : "",
|
||||
compress_choice, do_compression_level);
|
||||
}
|
||||
}
|
||||
|
||||
struct name_num_item *get_nni_by_name(struct name_num_obj *nno, const char *name, int len)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen(name);
|
||||
|
||||
for (nni = nno->list; nni->name; nni++) {
|
||||
if (strncasecmp(name, nni->name, len) == 0 && nni->name[len] == '\0')
|
||||
return nni;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct name_num_item *get_nni_by_num(struct name_num_obj *nno, int num)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
|
||||
for (nni = nno->list; nni->name; nni++) {
|
||||
if (num == nni->num)
|
||||
return nni;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void init_nno_saw(struct name_num_obj *nno, int val)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
int cnt;
|
||||
|
||||
if (!nno->saw_len) {
|
||||
for (nni = nno->list; nni->name; nni++) {
|
||||
if (nni->num >= nno->saw_len)
|
||||
nno->saw_len = nni->num + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nno->saw) {
|
||||
nno->saw = new_array0(uchar, nno->saw_len);
|
||||
|
||||
/* We'll take this opportunity to make sure that the main_name values are set right. */
|
||||
for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {
|
||||
if (nno->saw[nni->num])
|
||||
nni->main_name = nno->list[nno->saw[nni->num]-1].name;
|
||||
else
|
||||
nno->saw[nni->num] = cnt;
|
||||
}
|
||||
}
|
||||
|
||||
memset(nno->saw, val, nno->saw_len);
|
||||
}
|
||||
|
||||
/* Simplify the user-provided string so that it contains valid names without any duplicates.
|
||||
* It also sets the "saw" flags to a 1-relative count of which name was seen first. */
|
||||
static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf, int tobuf_len)
|
||||
{
|
||||
char *to = tobuf, *tok = NULL;
|
||||
int saw_tok = 0, cnt = 0;
|
||||
|
||||
while (1) {
|
||||
int at_space = isSpace(from);
|
||||
char ch = *from++;
|
||||
if (ch == '&')
|
||||
ch = '\0';
|
||||
if (!ch || at_space) {
|
||||
if (tok) {
|
||||
struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
|
||||
if (nni && !nno->saw[nni->num]) {
|
||||
nno->saw[nni->num] = ++cnt;
|
||||
if (nni->main_name) {
|
||||
to = tok + strlcpy(tok, nni->main_name, tobuf_len - (tok - tobuf));
|
||||
if (to - tobuf >= tobuf_len) {
|
||||
to = tok - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
to = tok - (tok != tobuf);
|
||||
saw_tok = 1;
|
||||
tok = NULL;
|
||||
}
|
||||
if (!ch)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (!tok) {
|
||||
if (to != tobuf)
|
||||
*to++ = ' ';
|
||||
tok = to;
|
||||
}
|
||||
if (to - tobuf >= tobuf_len - 1) {
|
||||
to = tok - (tok != tobuf);
|
||||
break;
|
||||
}
|
||||
*to++ = ch;
|
||||
}
|
||||
*to = '\0';
|
||||
|
||||
if (saw_tok && to == tobuf)
|
||||
return strlcpy(tobuf, "INVALID", MAX_NSTR_STRLEN);
|
||||
|
||||
return to - tobuf;
|
||||
}
|
||||
|
||||
/* This routine is always called with a tmpbuf of MAX_NSTR_STRLEN length, but the
|
||||
* buffer may be pre-populated with a "len" length string to use OR a len of -1
|
||||
* to tell us to read a string from the fd. */
|
||||
static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf, int len)
|
||||
{
|
||||
struct name_num_item *ret = NULL;
|
||||
|
||||
if (len < 0)
|
||||
len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN);
|
||||
|
||||
if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
|
||||
if (am_server)
|
||||
rprintf(FINFO, "Client %s list (on server): %s\n", nno->type, tmpbuf);
|
||||
else
|
||||
rprintf(FINFO, "Server %s list (on client): %s\n", nno->type, tmpbuf);
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
struct name_num_item *nni;
|
||||
int best = nno->saw_len; /* We want best == 1 from the client list, so start with a big number. */
|
||||
char *space, *tok = tmpbuf;
|
||||
while (tok) {
|
||||
while (*tok == ' ') tok++; /* Should be unneeded... */
|
||||
if (!*tok)
|
||||
break;
|
||||
if ((space = strchr(tok, ' ')) != NULL)
|
||||
*space = '\0';
|
||||
nni = get_nni_by_name(nno, tok, -1);
|
||||
if (space) {
|
||||
*space = ' ';
|
||||
tok = space + 1;
|
||||
} else
|
||||
tok = NULL;
|
||||
if (!nni || !nno->saw[nni->num] || best <= nno->saw[nni->num])
|
||||
continue;
|
||||
ret = nni;
|
||||
best = nno->saw[nni->num];
|
||||
if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
free(nno->saw);
|
||||
nno->saw = NULL;
|
||||
nno->negotiated_name = ret->main_name ? ret->main_name : ret->name;
|
||||
nno->negotiated_num = ret->num;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!am_server || !do_negotiated_strings) {
|
||||
char *cp = tmpbuf;
|
||||
int j;
|
||||
rprintf(FERROR, "Failed to negotiate a %s choice.\n", nno->type);
|
||||
rprintf(FERROR, "%s list: %s\n", am_server ? "Client" : "Server", tmpbuf);
|
||||
/* Recreate our original list from the saw values. This can't overflow our huge
|
||||
* buffer because we don't have enough valid entries to get anywhere close. */
|
||||
for (j = 1, *cp = '\0'; j <= nno->saw_len; j++) {
|
||||
struct name_num_item *nni;
|
||||
for (nni = nno->list; nni->name; nni++) {
|
||||
if (nno->saw[nni->num] == j) {
|
||||
*cp++ = ' ';
|
||||
cp += strlcpy(cp, nni->name, MAX_NSTR_STRLEN - (cp - tmpbuf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!*tmpbuf)
|
||||
strlcpy(cp, " INVALID", MAX_NSTR_STRLEN);
|
||||
rprintf(FERROR, "%s list:%s\n", am_server ? "Server" : "Client", tmpbuf);
|
||||
}
|
||||
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
static const char *getenv_nstr(int ntype)
|
||||
{
|
||||
const char *env_str = getenv(ntype == NSTR_COMPRESS ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
|
||||
|
||||
/* When writing a batch file, we always negotiate an old-style choice. */
|
||||
if (write_batch)
|
||||
env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
|
||||
|
||||
if (am_server && env_str) {
|
||||
char *cp = strchr(env_str, '&');
|
||||
if (cp)
|
||||
env_str = cp + 1;
|
||||
}
|
||||
|
||||
return env_str;
|
||||
}
|
||||
|
||||
void validate_choice_vs_env(int ntype, int num1, int num2)
|
||||
{
|
||||
struct name_num_obj *nno = ntype == NSTR_COMPRESS ? &valid_compressions : &valid_checksums;
|
||||
const char *list_str = getenv_nstr(ntype);
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
|
||||
if (!list_str)
|
||||
return;
|
||||
|
||||
while (isSpace(list_str)) list_str++;
|
||||
|
||||
if (!*list_str)
|
||||
return;
|
||||
|
||||
init_nno_saw(nno, 0);
|
||||
parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
|
||||
|
||||
if (ntype == NSTR_CHECKSUM) /* If "md4" is in the env list, all the old MD4 choices are OK too. */
|
||||
nno->saw[CSUM_MD4_ARCHAIC] = nno->saw[CSUM_MD4_BUSTED] = nno->saw[CSUM_MD4_OLD] = nno->saw[CSUM_MD4];
|
||||
|
||||
if (!nno->saw[num1] || (num2 >= 0 && !nno->saw[num2])) {
|
||||
rprintf(FERROR, "Your --%s-choice value (%s) was refused by the server.\n",
|
||||
ntype == NSTR_COMPRESS ? "compress" : "checksum",
|
||||
ntype == NSTR_COMPRESS ? compress_choice : checksum_choice);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
free(nno->saw);
|
||||
nno->saw = NULL;
|
||||
}
|
||||
|
||||
/* The saw buffer is initialized and used to store ordinal values from 1 to N
|
||||
* for the order of the args in the array. If dup_markup == '\0', duplicates
|
||||
* are removed otherwise the char is prefixed to the duplicate term and, if it
|
||||
* is an opening paren/bracket/brace, the matching closing char is suffixed.
|
||||
* "none" is removed on the client side unless dup_markup != '\0'. */
|
||||
int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len, char dup_markup)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
int len = 0, cnt = 0;
|
||||
char delim = '\0', post_delim;
|
||||
|
||||
switch (dup_markup) {
|
||||
case '(': post_delim = ')'; break;
|
||||
case '[': post_delim = ']'; break;
|
||||
case '{': post_delim = '}'; break;
|
||||
default: post_delim = '\0'; break;
|
||||
}
|
||||
|
||||
init_nno_saw(nno, 0);
|
||||
|
||||
for (nni = nno->list, len = 0; nni->name; nni++) {
|
||||
if (nni->main_name) {
|
||||
if (!dup_markup)
|
||||
continue;
|
||||
delim = dup_markup;
|
||||
}
|
||||
if (nni->num == 0 && !am_server && !dup_markup)
|
||||
continue;
|
||||
if (len)
|
||||
to_buf[len++]= ' ';
|
||||
if (delim) {
|
||||
to_buf[len++]= delim;
|
||||
delim = post_delim;
|
||||
}
|
||||
len += strlcpy(to_buf+len, nni->name, to_buf_len - len);
|
||||
if (len >= to_buf_len - 3)
|
||||
exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE... */
|
||||
if (delim) {
|
||||
to_buf[len++]= delim;
|
||||
delim = '\0';
|
||||
}
|
||||
nno->saw[nni->num] = ++cnt;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void send_negotiate_str(int f_out, struct name_num_obj *nno, int ntype)
|
||||
{
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
const char *list_str = getenv_nstr(ntype);
|
||||
int len;
|
||||
|
||||
if (list_str && *list_str) {
|
||||
init_nno_saw(nno, 0);
|
||||
len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
|
||||
list_str = tmpbuf;
|
||||
} else
|
||||
list_str = NULL;
|
||||
|
||||
if (!list_str || !*list_str)
|
||||
len = get_default_nno_list(nno, tmpbuf, MAX_NSTR_STRLEN, '\0');
|
||||
|
||||
if (DEBUG_GTE(NSTR, am_server ? 3 : 2)) {
|
||||
if (am_server)
|
||||
rprintf(FINFO, "Server %s list (on server): %s\n", nno->type, tmpbuf);
|
||||
else
|
||||
rprintf(FINFO, "Client %s list (on client): %s\n", nno->type, tmpbuf);
|
||||
}
|
||||
|
||||
/* Each side sends their list of valid names to the other side and then both sides
|
||||
* pick the first name in the client's list that is also in the server's list. */
|
||||
if (do_negotiated_strings)
|
||||
write_vstring(f_out, tmpbuf, len);
|
||||
}
|
||||
|
||||
static void negotiate_the_strings(int f_in, int f_out)
|
||||
{
|
||||
/* We send all the negotiation strings before we start to read them to help avoid a slow startup. */
|
||||
|
||||
init_checksum_choices();
|
||||
|
||||
if (!checksum_choice)
|
||||
send_negotiate_str(f_out, &valid_checksums, NSTR_CHECKSUM);
|
||||
|
||||
if (do_compression && !compress_choice)
|
||||
send_negotiate_str(f_out, &valid_compressions, NSTR_COMPRESS);
|
||||
|
||||
if (valid_checksums.saw) {
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
int len;
|
||||
if (do_negotiated_strings)
|
||||
len = -1;
|
||||
else
|
||||
len = strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
|
||||
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, len);
|
||||
}
|
||||
|
||||
if (valid_compressions.saw) {
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
int len;
|
||||
if (do_negotiated_strings)
|
||||
len = -1;
|
||||
else
|
||||
len = strlcpy(tmpbuf, "zlib", MAX_NSTR_STRLEN);
|
||||
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, len);
|
||||
}
|
||||
|
||||
/* If the other side is too old to negotiate, the above steps just made sure that
|
||||
* the env didn't disallow the old algorithm. Mark things as non-negotiated. */
|
||||
if (!do_negotiated_strings)
|
||||
valid_checksums.negotiated_name = valid_compressions.negotiated_name = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
write_flush(f_out);
|
||||
} else {
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
write_flush(f_out);
|
||||
remote_version = read_int(f_in);
|
||||
assert(file_extra_cnt == 0);
|
||||
assert(EXTRA64_CNT == 2 || EXTRA64_CNT == 1);
|
||||
|
||||
/* All int64 values must be set first so that they are guaranteed to be
|
||||
* aligned for direct int64-pointer memory access. */
|
||||
if (preserve_atimes)
|
||||
atimes_ndx = (file_extra_cnt += EXTRA64_CNT);
|
||||
if (preserve_crtimes)
|
||||
crtimes_ndx = (file_extra_cnt += EXTRA64_CNT);
|
||||
if (am_sender) /* This is most likely in the file_extras64 union as well. */
|
||||
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
|
||||
else
|
||||
depth_ndx = ++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 (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 manpage for an explanation)\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
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();
|
||||
|
||||
if (!saw_stderr_opt && protocol_version <= 28 && am_server)
|
||||
msgs2stderr = 0; /* The client side may not have stderr setup for us. */
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
if (remote_version < MIN_PROTOCOL_VERSION ||
|
||||
remote_version > MAX_PROTOCOL_VERSION) {
|
||||
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "local_version=%d remote_version=%d\n",
|
||||
PROTOCOL_VERSION, remote_version);
|
||||
|
||||
if (remote_version >= 12) {
|
||||
if (am_server) {
|
||||
checksum_seed = time(NULL);
|
||||
write_int(f_out,checksum_seed);
|
||||
} else {
|
||||
checksum_seed = read_int(f_in);
|
||||
}
|
||||
if (delete_mode && !(delete_before+delete_during+delete_after)) {
|
||||
if (protocol_version < 30)
|
||||
delete_before = 1;
|
||||
else
|
||||
delete_during = 1;
|
||||
}
|
||||
|
||||
checksum_init();
|
||||
|
||||
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",
|
||||
alt_dest_opt(0), 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",
|
||||
alt_dest_opt(0), 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 (strchr(client_info, 'f') != NULL)
|
||||
compat_flags |= CF_SAFE_FLIST;
|
||||
if (strchr(client_info, 'x') != NULL)
|
||||
compat_flags |= CF_AVOID_XATTR_OPTIM;
|
||||
if (strchr(client_info, 'C') != NULL)
|
||||
compat_flags |= CF_CHKSUM_SEED_FIX;
|
||||
if (strchr(client_info, 'I') != NULL)
|
||||
compat_flags |= CF_INPLACE_PARTIAL_DIR;
|
||||
if (strchr(client_info, 'u') != NULL)
|
||||
compat_flags |= CF_ID0_NAMES;
|
||||
if (strchr(client_info, 'v') != NULL) {
|
||||
do_negotiated_strings = 1;
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
}
|
||||
if (strchr(client_info, 'V') != NULL) { /* Support a pre-release 'V' that got superseded */
|
||||
if (!write_batch)
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
write_byte(f_out, compat_flags);
|
||||
} else
|
||||
write_varint(f_out, compat_flags);
|
||||
} else { /* read_varint() is compatible with the older write_byte() when the 0x80 bit isn't on. */
|
||||
compat_flags = read_varint(f_in);
|
||||
if (compat_flags & CF_VARINT_FLIST_FLAGS)
|
||||
do_negotiated_strings = 1;
|
||||
}
|
||||
/* 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;
|
||||
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
|
||||
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
|
||||
if (!xfer_flags_as_varint && preserve_crtimes) {
|
||||
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
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
|
||||
? 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;
|
||||
if (compat_flags & CF_INPLACE_PARTIAL_DIR)
|
||||
inplace_partial = 1;
|
||||
#ifdef CAN_SET_SYMLINK_TIMES
|
||||
} else if (!am_sender) {
|
||||
receiver_symlink_times = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (read_batch)
|
||||
do_negotiated_strings = 0;
|
||||
|
||||
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
|
||||
|
||||
negotiate_the_strings(f_in, f_out);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
parse_checksum_choice(1); /* Sets checksum_type & xfersum_type */
|
||||
parse_compress_choice(1); /* Sets do_compression */
|
||||
|
||||
if (write_batch && !am_server)
|
||||
write_batch_shell_file();
|
||||
|
||||
init_flist();
|
||||
}
|
||||
|
||||
|
||||
1684
config.guess
vendored
Normal file
1684
config.guess
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1793
config.sub
vendored
Normal file
1793
config.sub
vendored
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`
|
||||
if test x"$dir" = x; then
|
||||
dir=.
|
||||
fi
|
||||
|
||||
if test "$dir" = '.'; then
|
||||
branch=`packaging/prep-auto-dir` || exit 1
|
||||
if test x"$branch" != x; then
|
||||
cd build || exit 1
|
||||
dir=..
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ! -f configure.sh; then
|
||||
if ! "$dir/prepare-source" build; then
|
||||
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
|
||||
rm -f configure.sh
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exec ./configure.sh --srcdir="$dir" "${@}"
|
||||
1452
configure.ac
Normal file
1452
configure.ac
Normal file
File diff suppressed because it is too large
Load Diff
120
configure.in
120
configure.in
@@ -1,120 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(byteorder.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
|
||||
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH)
|
||||
|
||||
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)
|
||||
|
||||
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_STRUCT_ST_RDEV
|
||||
AC_CHECK_TYPE(ino_t,unsigned)
|
||||
|
||||
echo $ac_n "checking for errno in errno.h... $ac_c"
|
||||
AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
|
||||
echo yes; AC_DEFINE(HAVE_ERRNO_DECL),
|
||||
echo no)
|
||||
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_MMAP
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid strtok pipe getcwd mkdir strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr bcopy bzero readlink link utime utimes)
|
||||
AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf setsid glob)
|
||||
|
||||
echo $ac_n "checking for working fnmatch... $ac_c"
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
main() { exit(fnmatch("*.o", "x.o", 0) == 0? 0: 1); }],
|
||||
echo yes;AC_DEFINE(HAVE_FNMATCH),
|
||||
echo no)
|
||||
|
||||
echo $ac_n "checking for long long ... $ac_c"
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
|
||||
echo yes;AC_DEFINE(HAVE_LONGLONG),
|
||||
echo no)
|
||||
|
||||
echo $ac_n "checking for off64_t ... $ac_c"
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) return 1; exit((lstat64("/dev/null", &st)==0)?0:1); }],
|
||||
echo yes;AC_DEFINE(HAVE_OFF64_T),
|
||||
echo no)
|
||||
|
||||
echo $ac_n "checking for unsigned char ... $ac_c"
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
main() { char c; c=250; exit((c > 0)?0:1); }],
|
||||
echo yes;AC_DEFINE(HAVE_UNSIGNED_CHAR),
|
||||
echo no)
|
||||
|
||||
echo $ac_n "checking for broken readdir ... $ac_c"
|
||||
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) return 0; return 1;} ],
|
||||
echo yes - you are using the broken /usr/ucb/cc;AC_DEFINE(HAVE_BROKEN_READDIR),
|
||||
echo no)
|
||||
|
||||
echo $ac_n "checking for utimbuf ... $ac_c"
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <utime.h>],
|
||||
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; return utime("foo.c",&tbuf);],
|
||||
echo yes;AC_DEFINE(HAVE_UTIMBUF),
|
||||
echo no)
|
||||
|
||||
# The following test taken from the cvs sources
|
||||
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
|
||||
# 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_FUNC(connect, :,
|
||||
[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 "$ac_cv_lib_socket_connect" = "yes" ||
|
||||
test "$ac_cv_lib_inet_connect" = "yes"; then
|
||||
ac_cv_func_connect=yes
|
||||
AC_DEFINE(HAVE_CONNECT)
|
||||
fi])
|
||||
|
||||
|
||||
AC_OUTPUT(Makefile lib/dummy)
|
||||
65
connection.c
65
connection.c
@@ -1,46 +1,47 @@
|
||||
/*
|
||||
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
|
||||
* Copyright (C) 2006-2020 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 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;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
/* A lock failure needs to return an errno of 0. */
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
88
csprotocol.txt
Normal file
88
csprotocol.txt
Normal file
@@ -0,0 +1,88 @@
|
||||
This is kind of informal and may be wrong, but it helped me. It's
|
||||
basically a summary of clientserver.c and authenticate.c.
|
||||
|
||||
-- Martin Pool <mbp@samba.org>
|
||||
|
||||
|
||||
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>.<subprotocol>
|
||||
|
||||
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
|
||||
|
||||
#list
|
||||
|
||||
to get a listing of modules, or the name of a module. After this, the
|
||||
connection is now bound to a particular module. Access per host for
|
||||
this module is now checked, as is per-module connection limits.
|
||||
|
||||
If authentication is required to use this module, the server will say
|
||||
|
||||
@RSYNCD: AUTHREQD <challenge>
|
||||
|
||||
where <challenge> is a random string of base64 characters. The client
|
||||
must respond with
|
||||
|
||||
<user> <response>
|
||||
|
||||
where <user> is the username they claim to be, and <response> is the
|
||||
base64 form of the MD4 hash of challenge+password.
|
||||
|
||||
At this point the server applies all remaining constraints before
|
||||
handing control to the client, including switching uid/gid, setting up
|
||||
include and exclude lists, moving to the root of the module, and doing
|
||||
chroot.
|
||||
|
||||
If the login is acceptable, then the server will respond with
|
||||
|
||||
@RSYNCD: OK
|
||||
|
||||
The client now writes some rsync options, as if it were remotely
|
||||
executing the command. The server parses these arguments as if it had
|
||||
just been invoked with them, but they're added to the existing state.
|
||||
So if the client specifies a list of files to be included or excluded,
|
||||
they'll defer to existing limits specified in the server
|
||||
configuration.
|
||||
|
||||
At this point the client and server both switch to using a
|
||||
multiplexing layer across the socket. The main point of this is to
|
||||
allow the server to asynchronously pass errors back, while still
|
||||
allowing streamed and pipelined data.
|
||||
|
||||
Unfortunately, the multiplex protocol is not used at every stage. We
|
||||
start up in plain socket mode and then change over by calling
|
||||
io_start_buffering. Of course both the client and the server have to
|
||||
do this at the same point.
|
||||
|
||||
The server then talks to the client as normal across the socket,
|
||||
passing checksums, file lists and so on. For documentation of that,
|
||||
stay tuned (or write it yourself!).
|
||||
|
||||
|
||||
|
||||
------------
|
||||
Protocol version changes
|
||||
|
||||
30 (2007-10-04, 3.0.0pre1)
|
||||
|
||||
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.
|
||||
114
daemon-parm.awk
Executable file
114
daemon-parm.awk
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# The caller must pass arg: daemon-parm.txt
|
||||
# The resulting code is output into daemon-parm.h
|
||||
|
||||
BEGIN {
|
||||
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n"
|
||||
sect = psect = defines = accessors = prior_ptype = ""
|
||||
parms = "\nstatic struct parm_struct parm_table[] = {"
|
||||
comment_fmt = "\n/********** %s **********/\n"
|
||||
tdstruct = "typedef struct {"
|
||||
}
|
||||
|
||||
/^\s*$/ { next }
|
||||
/^#/ { next }
|
||||
|
||||
/^Globals:/ {
|
||||
if (defines != "") {
|
||||
print "The Globals section must come first!"
|
||||
defines = ""
|
||||
exit
|
||||
}
|
||||
defines = tdstruct
|
||||
values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n"
|
||||
exps = exp_values = sprintf(comment_fmt, "EXP")
|
||||
sect = "GLOBAL"
|
||||
psect = ", P_GLOBAL, &Vars.g."
|
||||
next
|
||||
}
|
||||
|
||||
/^Locals:/ {
|
||||
if (sect == "") {
|
||||
print "The Locals section must come after the Globals!"
|
||||
exit
|
||||
}
|
||||
defines = defines exps "} global_vars;\n\n" tdstruct
|
||||
values = values exp_values "\n }, { /* Locals: */\n"
|
||||
exps = exp_values = sprintf(comment_fmt, "EXP")
|
||||
sect = "LOCAL"
|
||||
psect = ", P_LOCAL, &Vars.l."
|
||||
next
|
||||
}
|
||||
|
||||
/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
|
||||
ptype = $1
|
||||
name = $2
|
||||
$1 = $2 = ""
|
||||
sub(/^[ \t]+/, "")
|
||||
|
||||
if (ptype != prior_ptype) {
|
||||
comment = sprintf(comment_fmt, ptype)
|
||||
defines = defines comment
|
||||
values = values comment
|
||||
parms = parms "\n"
|
||||
accessors = accessors "\n"
|
||||
prior_ptype = ptype
|
||||
}
|
||||
|
||||
if (ptype == "STRING" || ptype == "PATH") {
|
||||
atype = "STRING"
|
||||
vtype = "char*"
|
||||
} else if (ptype ~ /BOOL/) {
|
||||
atype = vtype = "BOOL"
|
||||
} else if (ptype == "CHAR") {
|
||||
atype = "CHAR"
|
||||
vtype = "char"
|
||||
} else {
|
||||
atype = "INTEGER"
|
||||
vtype = "int"
|
||||
}
|
||||
|
||||
# The name might be var_name|public_name
|
||||
pubname = name
|
||||
sub(/\|.*/, "", name)
|
||||
sub(/.*\|/, "", pubname)
|
||||
gsub(/_/, " ", pubname)
|
||||
gsub(/-/, "", name)
|
||||
|
||||
if (ptype == "ENUM")
|
||||
enum = "enum_" name
|
||||
else
|
||||
enum = "NULL"
|
||||
|
||||
defines = defines "\t" vtype " " name ";\n"
|
||||
values = values "\t" $0 ", /* " name " */\n"
|
||||
parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n"
|
||||
accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n"
|
||||
|
||||
if (vtype == "char*") {
|
||||
exps = exps "\tBOOL " name "_EXP;\n"
|
||||
exp_values = exp_values "\tFalse, /* " name "_EXP */\n"
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
/./ {
|
||||
print "Extraneous line:" $0
|
||||
defines = ""
|
||||
exit
|
||||
}
|
||||
|
||||
END {
|
||||
if (sect != "" && defines != "") {
|
||||
defines = defines exps "} local_vars;\n\n"
|
||||
defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n"
|
||||
values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n"
|
||||
parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n"
|
||||
print heading defines values parms accessors > "daemon-parm.h"
|
||||
} else {
|
||||
print "Failed to parse the data in " ARGV[1]
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
68
daemon-parm.txt
Normal file
68
daemon-parm.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
Globals: ================================================================
|
||||
|
||||
STRING bind_address|address NULL
|
||||
STRING daemon_chroot NULL
|
||||
STRING daemon_gid NULL
|
||||
STRING daemon_uid NULL
|
||||
STRING motd_file NULL
|
||||
STRING pid_file NULL
|
||||
STRING socket_options NULL
|
||||
|
||||
INTEGER listen_backlog 5
|
||||
INTEGER rsync_port|port 0
|
||||
|
||||
BOOL proxy_protocol False
|
||||
|
||||
Locals: =================================================================
|
||||
|
||||
STRING auth_users NULL
|
||||
STRING charset NULL
|
||||
STRING comment NULL
|
||||
STRING dont_compress DEFAULT_DONT_COMPRESS
|
||||
STRING early_exec NULL
|
||||
STRING exclude NULL
|
||||
STRING exclude_from NULL
|
||||
STRING filter NULL
|
||||
STRING gid NULL
|
||||
STRING hosts_allow NULL
|
||||
STRING hosts_deny NULL
|
||||
STRING include NULL
|
||||
STRING include_from NULL
|
||||
STRING incoming_chmod NULL
|
||||
STRING lock_file DEFAULT_LOCK_FILE
|
||||
STRING log_file NULL
|
||||
STRING log_format "%o %h [%a] %m (%u) %f %l"
|
||||
STRING name NULL
|
||||
STRING name_converter NULL
|
||||
STRING outgoing_chmod NULL
|
||||
STRING post-xfer_exec NULL
|
||||
STRING pre-xfer_exec NULL
|
||||
STRING refuse_options NULL
|
||||
STRING secrets_file NULL
|
||||
STRING syslog_tag "rsyncd"
|
||||
STRING uid NULL
|
||||
|
||||
PATH path NULL
|
||||
PATH temp_dir NULL
|
||||
|
||||
INTEGER max_connections 0
|
||||
INTEGER max_verbosity 1
|
||||
INTEGER timeout 0
|
||||
|
||||
ENUM syslog_facility LOG_DAEMON
|
||||
|
||||
BOOL fake_super False
|
||||
BOOL forward_lookup True
|
||||
BOOL ignore_errors False
|
||||
BOOL ignore_nonreadable False
|
||||
BOOL list True
|
||||
BOOL read_only True
|
||||
BOOL reverse_lookup True
|
||||
BOOL strict_modes True
|
||||
BOOL transfer_logging False
|
||||
BOOL use_chroot True
|
||||
BOOL write_only False
|
||||
|
||||
BOOL3 munge_symlinks Unset
|
||||
BOOL3 numeric_ids Unset
|
||||
BOOL3 open_noatime Unset
|
||||
41
define-from-md.awk
Executable file
41
define-from-md.awk
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# The caller must pass args: -v hfile=NAME rsync.1.md
|
||||
|
||||
BEGIN {
|
||||
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */"
|
||||
if (hfile ~ /compress/) {
|
||||
define = "#define DEFAULT_DONT_COMPRESS"
|
||||
prefix = "*."
|
||||
} else {
|
||||
define = "#define DEFAULT_CVSIGNORE"
|
||||
prefix = ""
|
||||
}
|
||||
value_list = ""
|
||||
}
|
||||
|
||||
/^ > [^ ]+$/ {
|
||||
gsub(/`/, "")
|
||||
if (value_list != "") value_list = value_list " "
|
||||
value_list = value_list prefix $2
|
||||
next
|
||||
}
|
||||
|
||||
value_list ~ /\.gz / && hfile ~ /compress/ {
|
||||
exit
|
||||
}
|
||||
|
||||
value_list ~ /SCCS / && hfile ~ /cvsignore/ {
|
||||
exit
|
||||
}
|
||||
|
||||
value_list = ""
|
||||
|
||||
END {
|
||||
if (value_list != "")
|
||||
print heading "\n\n" define " \"" value_list "\"" > hfile
|
||||
else {
|
||||
print "Failed to find a value list in " ARGV[1] " for " hfile
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
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-2020 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 */
|
||||
}
|
||||
20
doc/README-SGML
Normal file
20
doc/README-SGML
Normal file
@@ -0,0 +1,20 @@
|
||||
Handling the rsync SGML documentation
|
||||
|
||||
rsync documentation is now primarily in Docbook format. Docbook is an
|
||||
SGML/XML documentation format that is becoming standard on free
|
||||
operating systems. It's also used for Samba documentation.
|
||||
|
||||
The SGML files are source code that can be translated into various
|
||||
useful output formats, primarily PDF, HTML, Postscript and plain text.
|
||||
|
||||
To do this transformation on Debian, you should install the
|
||||
docbook-utils package. Having done that, you can say
|
||||
|
||||
docbook2pdf rsync.sgml
|
||||
|
||||
and so on.
|
||||
|
||||
On other systems you probably need James Clark's "sp" and "JadeTeX"
|
||||
packages. Work it out for yourself and send a note to the mailing
|
||||
list.
|
||||
|
||||
42
doc/profile.txt
Normal file
42
doc/profile.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
Notes on rsync profiling
|
||||
|
||||
strlcpy is hot:
|
||||
|
||||
0.00 0.00 1/7735635 push_dir [68]
|
||||
0.00 0.00 1/7735635 pop_dir [71]
|
||||
0.00 0.00 1/7735635 send_file_list [15]
|
||||
0.01 0.00 18857/7735635 send_files [4]
|
||||
0.04 0.00 129260/7735635 send_file_entry [18]
|
||||
0.04 0.00 129260/7735635 make_file [20]
|
||||
0.04 0.00 141666/7735635 send_directory <cycle 1> [36]
|
||||
2.29 0.00 7316589/7735635 f_name [13]
|
||||
[14] 11.7 2.42 0.00 7735635 strlcpy [14]
|
||||
|
||||
|
||||
Here's the top few functions:
|
||||
|
||||
46.23 9.57 9.57 13160929 0.00 0.00 mdfour64
|
||||
14.78 12.63 3.06 13160929 0.00 0.00 copy64
|
||||
11.69 15.05 2.42 7735635 0.00 0.00 strlcpy
|
||||
10.05 17.13 2.08 41438 0.05 0.38 sum_update
|
||||
4.11 17.98 0.85 13159996 0.00 0.00 mdfour_update
|
||||
1.50 18.29 0.31 file_compare
|
||||
1.45 18.59 0.30 129261 0.00 0.01 send_file_entry
|
||||
1.23 18.84 0.26 2557585 0.00 0.00 f_name
|
||||
1.11 19.07 0.23 1483750 0.00 0.00 u_strcmp
|
||||
1.11 19.30 0.23 118129 0.00 0.00 writefd_unbuffered
|
||||
0.92 19.50 0.19 1085011 0.00 0.00 writefd
|
||||
0.43 19.59 0.09 156987 0.00 0.00 read_timeout
|
||||
0.43 19.68 0.09 129261 0.00 0.00 clean_fname
|
||||
0.39 19.75 0.08 32887 0.00 0.38 matched
|
||||
0.34 19.82 0.07 1 70.00 16293.92 send_files
|
||||
0.29 19.89 0.06 129260 0.00 0.00 make_file
|
||||
0.29 19.95 0.06 75430 0.00 0.00 read_unbuffered
|
||||
|
||||
|
||||
|
||||
mdfour could perhaps be made faster:
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast! */
|
||||
|
||||
There might be an optimized version somewhere that we can borrow.
|
||||
351
doc/rsync.sgml
Normal file
351
doc/rsync.sgml
Normal file
@@ -0,0 +1,351 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
||||
<book id="rsync">
|
||||
<bookinfo>
|
||||
<title>rsync</title>
|
||||
<copyright>
|
||||
<year>1996 -- 2002</year>
|
||||
<holder>Martin Pool</holder>
|
||||
<holder>Andrew Tridgell</holder>
|
||||
</copyright>
|
||||
<author>
|
||||
<firstname>Martin</firstname>
|
||||
<surname>Pool</surname>
|
||||
</author>
|
||||
</bookinfo>
|
||||
|
||||
<chapter>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>rsync is a flexible program for efficiently copying files or
|
||||
directory trees.
|
||||
|
||||
<para>rsync has many options to select which files will be copied
|
||||
and how they are to be transferred. It may be used as an
|
||||
alternative to ftp, http, scp or rcp.
|
||||
|
||||
<para>The rsync remote-update protocol allows rsync to transfer just
|
||||
the differences between two sets of files across the network link,
|
||||
using an efficient checksum-search algorithm described in the
|
||||
technical report that accompanies this package.</para>
|
||||
|
||||
<para>Some of the additional features of rsync are:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>support for copying links, devices, owners, groups and
|
||||
permissions
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
exclude and exclude-from options similar to GNU tar
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
a CVS exclude mode for ignoring the same files that CVS would ignore
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
can use any transparent remote shell, including rsh or ssh
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
does not require root privileges
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
pipelining of file transfers to minimize latency costs
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
support for anonymous or authenticated rsync servers (ideal for
|
||||
mirroring)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</chapter>
|
||||
|
||||
|
||||
|
||||
<chapter>
|
||||
<title>Using rsync</title>
|
||||
<section>
|
||||
<title>
|
||||
Introductory example
|
||||
</title>
|
||||
|
||||
<para>
|
||||
Probably the most common case of rsync usage is to copy files
|
||||
to or from a remote machine using
|
||||
<application>ssh</application> as a network transport. In
|
||||
this situation rsync is a good alternative to
|
||||
<application>scp</application>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The most commonly used arguments for rsync are
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-v</option></term>
|
||||
<listitem>
|
||||
<para>Be verbose. Primarily, display the name of each file as it is copied.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-a</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Reproduce the structure and attributes of the origin files as exactly
|
||||
as possible: this includes copying subdirectories, symlinks, special
|
||||
files, ownership and permissions. (@xref{Attributes to
|
||||
copy}.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
|
||||
|
||||
<para><option>-v </option>
|
||||
|
||||
<para><option>-z</option>
|
||||
Compress network traffic, using a modified version of the
|
||||
@command{zlib} library.</para>
|
||||
|
||||
<para><option>-P</option>
|
||||
Display a progress indicator while files are transferred. This should
|
||||
normally be omitted if rsync is not run on a terminal.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<title>Local and remote</title>
|
||||
|
||||
<para>There are six different ways of using rsync. They
|
||||
are:</para>
|
||||
|
||||
|
||||
|
||||
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM REFENTRY SECTION) -->
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
for copying local files. This is invoked when neither
|
||||
source nor destination path contains a @code{:} separator
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
for copying from the local machine to a remote machine using
|
||||
a remote shell program as the transport (such as rsh or
|
||||
ssh). This is invoked when the destination path contains a
|
||||
single @code{:} separator.
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
for copying from a remote machine to the local machine
|
||||
using a remote shell program. This is invoked when the source
|
||||
contains a @code{:} separator.
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
for copying from a remote rsync server to the local
|
||||
machine. This is invoked when the source path contains a @code{::}
|
||||
separator or a @code{rsync://} URL.
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
for copying from the local machine to a remote rsync
|
||||
server. This is invoked when the destination path contains a @code{::}
|
||||
separator.
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
for listing files on a remote machine. This is done the
|
||||
same way as rsync transfers except that you leave off the
|
||||
local destination.
|
||||
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
Note that in all cases (other than listing) at least one of the source
|
||||
and destination paths must be local.
|
||||
|
||||
<para>
|
||||
Any one invocation of rsync makes a copy in a single direction. rsync
|
||||
currently has no equivalent of @command{ftp}'s interactive mode.
|
||||
|
||||
@cindex @sc{nfs}
|
||||
@cindex network filesystems
|
||||
@cindex remote filesystems
|
||||
|
||||
<para>
|
||||
rsync's network protocol is generally faster at copying files than
|
||||
network filesystems such as @sc{nfs} or @sc{cifs}. It is better to
|
||||
run rsync on the file server either as a daemon or over ssh than
|
||||
running rsync giving the network directory.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
|
||||
|
||||
<chapter>
|
||||
<title>Frequently asked questions</title>
|
||||
|
||||
|
||||
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM SECTION SIMPLESECT REFENTRY SECT1) -->
|
||||
<qandaset>
|
||||
<!-- one of (QANDADIV QANDAENTRY) -->
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST
|
||||
SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE
|
||||
TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO
|
||||
SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS
|
||||
CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS
|
||||
DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA
|
||||
ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT
|
||||
MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE
|
||||
INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE
|
||||
PROCEDURE ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS INDEXTERM) -->
|
||||
<para>Are there mailing lists for rsync?
|
||||
</question>
|
||||
|
||||
<answer>
|
||||
<para>Yes, and you can subscribe and unsubscribe through a
|
||||
web interface at
|
||||
<ulink
|
||||
url="http://lists.samba.org/">http://lists.samba.org/</ulink>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you are having trouble with the mailing list, please
|
||||
send mail to the administrator
|
||||
|
||||
<email>rsync-admin@lists.samba.org</email>
|
||||
|
||||
not to the list itself.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The mailing list archives are searchable. Use
|
||||
<ulink url="http://google.com/">Google</ulink> and prepend
|
||||
the search with <userinput>site:lists.samba.org
|
||||
rsync</userinput>, plus relevant keywords.
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Why is rsync so much bigger when I build it with
|
||||
<command>gcc</command>?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
On gcc, rsync builds by default with debug symbols
|
||||
included. If you strip both executables, they should end
|
||||
up about the same size. (Use <command>make
|
||||
install-strip</command>.)
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Is rsync useful for a single large file like an ISO image?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
Yes, but note the following:
|
||||
|
||||
<para>
|
||||
Background: A common use of rsync is to update a file (or set of files) in one location from a more
|
||||
correct or up-to-date copy in another location, taking advantage of portions of the files that are
|
||||
identical to speed up the process. (Note that rsync will transfer a file in its entirety if no copy
|
||||
exists at the destination.)
|
||||
|
||||
<para>
|
||||
(This discussion is written in terms of updating a local copy of a file from a correct file in a
|
||||
remote location, although rsync can work in either direction.)
|
||||
|
||||
<para>
|
||||
The file to be updated (the local file) must be in a destination directory that has enough space for
|
||||
two copies of the file. (In addition, keep an extra copy of the file to be updated in a different
|
||||
location for safety -- see the discussion (below) about rsync's behavior when the rsync process is
|
||||
interrupted before completion.)
|
||||
|
||||
<para>
|
||||
The local file must have the same name as the remote file being sync'd to (I think?). If you are
|
||||
trying to upgrade an iso from, for example, beta1 to beta2, rename the local file to the same name
|
||||
as the beta2 file. *(This is a useful thing to do -- only the changed portions will be
|
||||
transmitted.)*
|
||||
|
||||
<para>
|
||||
The extra copy of the local file kept in a different location is because of rsync's behavior if
|
||||
interrupted before completion:
|
||||
|
||||
<para>
|
||||
* If you specify the --partial option and rsync is interrupted, rsync will save the partially
|
||||
rsync'd file and throw away the original local copy. (The partially rsync'd file is correct but
|
||||
truncated.) If rsync is restarted, it will not have a local copy of the file to check for duplicate
|
||||
blocks beyond the section of the file that has already been rsync'd, thus the remainder of the rsync
|
||||
process will be a "pure transfer" of the file rather than taking advantage of the rsync algorithm.
|
||||
|
||||
<para>
|
||||
* If you don't specify the --partial option and rsync is interrupted, rsync will throw away the
|
||||
partially rsync'd file, and, when rsync is restarted starts the rsync process over from the
|
||||
beginning.
|
||||
|
||||
<para>
|
||||
Which of these is most desirable depends on the degree of commonality between the local and remote
|
||||
copies of the file *and how much progress was made before the interruption*.
|
||||
|
||||
<para>
|
||||
The ideal approach after an interruption would be to create a new file by taking the original file
|
||||
and deleting a portion equal in size to the portion already rsync'd and then appending *the
|
||||
remaining* portion to the portion of the file that has already been rsync'd. (There has been some
|
||||
discussion about creating an option to do this automatically.)
|
||||
|
||||
The --compare-dest option is useful when transferring multiple files, but is of no benefit in
|
||||
transferring a single file. (AFAIK)
|
||||
|
||||
*Other potentially useful information can be found at:
|
||||
-[3]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFile
|
||||
|
||||
This answer, formatted with "real" bullets, can be found at:
|
||||
-[4]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFileFAQ*
|
||||
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
</chapter>
|
||||
|
||||
|
||||
<appendix>
|
||||
<title>Other Resources</title>
|
||||
|
||||
<para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
|
||||
</appendix>
|
||||
</book>
|
||||
64
errcode.h
Normal file
64
errcode.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Error codes returned by rsync.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2003-2019 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_STARTCLIENT 5 /* error starting client-server protocol */
|
||||
|
||||
#define RERR_SOCKETIO 10 /* error in socket IO */
|
||||
#define RERR_FILEIO 11 /* error in file IO */
|
||||
#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_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:
|
||||
*
|
||||
* 124 if the command exited with status 255
|
||||
* 125 if the command is killed by a signal
|
||||
* 126 if the command cannot be run
|
||||
* 127 if the command is not found
|
||||
*
|
||||
* and we could use this to give a better explanation if the remote
|
||||
* command is not found.
|
||||
*/
|
||||
#define RERR_CMD_FAILED 124
|
||||
#define RERR_CMD_KILLED 125
|
||||
#define RERR_CMD_RUN 126
|
||||
#define RERR_CMD_NOTFOUND 127
|
||||
328
fileio.c
Normal file
328
fileio.c
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* File IO utilities used in rsync.
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004-2020 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 boundaries. */
|
||||
#define ALIGN_BOUNDARY 1024
|
||||
/* How far past the boundary is an offset? */
|
||||
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDARY-1))
|
||||
/* Round up a length to the next boundary */
|
||||
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDARY-1)) + 1)
|
||||
|
||||
extern int sparse_files;
|
||||
|
||||
OFF_T preallocated_len = 0;
|
||||
|
||||
static OFF_T sparse_seek = 0;
|
||||
static OFF_T sparse_past_write = 0;
|
||||
|
||||
int sparse_end(int f, OFF_T size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sparse_past_write = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
sparse_seek = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Note that the offset is just the caller letting us know where
|
||||
* the current file position is in the file. The use_seek arg tells
|
||||
* us that we should seek over matching data instead of writing it. */
|
||||
static int write_sparse(int f, int use_seek, OFF_T offset, const char *buf, int len)
|
||||
{
|
||||
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++) {}
|
||||
|
||||
sparse_seek += l1;
|
||||
|
||||
if (l1 == len)
|
||||
return len;
|
||||
|
||||
if (sparse_seek) {
|
||||
if (sparse_past_write >= preallocated_len) {
|
||||
if (do_lseek(f, sparse_seek, SEEK_CUR) < 0)
|
||||
return -1;
|
||||
} else if (do_punch_hole(f, sparse_past_write, sparse_seek) < 0) {
|
||||
sparse_seek = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
sparse_seek = l2;
|
||||
sparse_past_write = offset + len - l2;
|
||||
|
||||
if (use_seek) {
|
||||
/* The in-place data already matches. */
|
||||
if (do_lseek(f, len - (l1+l2), SEEK_CUR) < 0)
|
||||
return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
sparse_seek = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret != (int)(len - (l1+l2))) {
|
||||
sparse_seek = 0;
|
||||
return l1+ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static char *wf_writeBuf;
|
||||
static size_t wf_writeBufSize;
|
||||
static size_t wf_writeBufCnt;
|
||||
|
||||
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. Note that use_seek and
|
||||
* offset are only used in sparse processing (see write_sparse()). */
|
||||
int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len > 0) {
|
||||
int r1;
|
||||
if (sparse_files > 0) {
|
||||
int len1 = MIN(len, SPARSE_WRITE_SIZE);
|
||||
r1 = write_sparse(f, use_seek, offset, buf, len1);
|
||||
offset += r1;
|
||||
} else {
|
||||
if (!wf_writeBuf) {
|
||||
wf_writeBufSize = WRITE_SIZE * 8;
|
||||
wf_writeBufCnt = 0;
|
||||
wf_writeBuf = new_array(char, wf_writeBufSize);
|
||||
}
|
||||
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;
|
||||
return r1;
|
||||
}
|
||||
len -= r1;
|
||||
buf += r1;
|
||||
ret += r1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* An in-place update found identical data at an identical location. We either
|
||||
* just seek past it, or (for an in-place sparse update), we give the data to
|
||||
* the sparse processor with the use_seek flag set. */
|
||||
int skip_matched(int fd, OFF_T offset, const char *buf, int len)
|
||||
{
|
||||
OFF_T pos;
|
||||
|
||||
if (sparse_files > 0) {
|
||||
if (write_file(fd, 1, offset, buf, len) != len)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flush_write_file(fd) < 0)
|
||||
return -1;
|
||||
|
||||
if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset + len) {
|
||||
rsyserr(FERROR_XFER, errno, "lseek returned %s, not %s",
|
||||
big_num(pos), big_num(offset));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 = new0(struct map_struct);
|
||||
|
||||
if (blk_size && (read_size % blk_size))
|
||||
read_size += blk_size - (read_size % blk_size);
|
||||
|
||||
map->fd = fd;
|
||||
map->file_size = len;
|
||||
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, int32 len)
|
||||
{
|
||||
OFF_T window_start, read_start;
|
||||
int32 window_size, read_size, read_offset, align_fudge;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
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);
|
||||
|
||||
/* nope, we are going to have to do a read. Work out our desired window */
|
||||
align_fudge = (int32)ALIGNED_OVERSHOOT(offset);
|
||||
window_start = offset - align_fudge;
|
||||
window_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 = realloc_array(map->p, char, window_size);
|
||||
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) {
|
||||
read_start = map->p_offset + map->p_len;
|
||||
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 {
|
||||
read_start = window_start;
|
||||
read_size = window_size;
|
||||
read_offset = 0;
|
||||
}
|
||||
|
||||
if (read_size <= 0) {
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int unmap_file(struct map_struct *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
ret = map->status;
|
||||
#if 0 /* I don't think we really need this. */
|
||||
force_memzero(map, sizeof map[0]);
|
||||
#endif
|
||||
free(map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
2431
generator.c
Normal file
2431
generator.c
Normal file
File diff suppressed because it is too large
Load Diff
22
getfsdev.c
Normal file
22
getfsdev.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#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;
|
||||
}
|
||||
61
getgroups.c
Normal file
61
getgroups.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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-2020 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3 as
|
||||
* 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, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
{
|
||||
int n, i;
|
||||
gid_t *list;
|
||||
gid_t gid = MY_GID();
|
||||
int gid_in_list = 0;
|
||||
|
||||
#ifdef HAVE_GETGROUPS
|
||||
if ((n = getgroups(0, NULL)) < 0) {
|
||||
perror("getgroups");
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
n = 0;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
498
hashtable.c
Normal file
498
hashtable.c
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* Routines to provide a memory-efficient hashtable.
|
||||
*
|
||||
* Copyright (C) 2007-2020 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;
|
||||
}
|
||||
|
||||
tbl = new(struct hashtable);
|
||||
tbl->nodes = new_array0(char, size * node_size);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Returns the node that holds the indicated key if it exists. When it does not
|
||||
* exist, it returns either NULL (when data_when_new is NULL), or it returns a
|
||||
* new node with its node->data set to the indicated value.
|
||||
*
|
||||
* If your code doesn't know the data value for a new node in advance (usually
|
||||
* because it doesn't know if a node is new or not) you should pass in a unique
|
||||
* (non-0) value that you can use to check if the returned node is new. You can
|
||||
* then overwrite the data with any value you want (even 0) since it only needs
|
||||
* to be different than whatever data_when_new value you use later on.
|
||||
*
|
||||
* This return is a void* just because it might be pointing at a ht_int32_node
|
||||
* or a ht_int64_node, and that makes the caller's assignment a little easier. */
|
||||
void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
|
||||
{
|
||||
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 (data_when_new && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
|
||||
void *old_nodes = tbl->nodes;
|
||||
int size = tbl->size * 2;
|
||||
int i;
|
||||
|
||||
tbl->nodes = new_array0(char, size * tbl->node_size);
|
||||
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;
|
||||
if (move_node->data)
|
||||
hashtable_find(tbl, move_key, move_node->data);
|
||||
else {
|
||||
node = hashtable_find(tbl, move_key, "");
|
||||
node->data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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 (!data_when_new)
|
||||
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;
|
||||
node->data = data_when_new;
|
||||
tbl->entries++;
|
||||
return node;
|
||||
}
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
# define HASH_LITTLE_ENDIAN 1
|
||||
# define HASH_BIG_ENDIAN 0
|
||||
#else
|
||||
# define HASH_LITTLE_ENDIAN 0
|
||||
# define HASH_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
lookup3.c, by Bob Jenkins, May 2006, Public Domain.
|
||||
|
||||
These are functions for producing 32-bit hashes for hash table lookup.
|
||||
hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
|
||||
are externally useful functions. Routines to test the hash are included
|
||||
if SELF_TEST is defined. You can use this free for any purpose. It's in
|
||||
the public domain. It has no warranty.
|
||||
|
||||
You probably want to use hashlittle(). hashlittle() and hashbig()
|
||||
hash byte arrays. hashlittle() is is faster than hashbig() on
|
||||
little-endian machines. Intel and AMD are little-endian machines.
|
||||
On second thought, you probably want hashlittle2(), which is identical to
|
||||
hashlittle() except it returns two 32-bit hashes for the price of one.
|
||||
You could implement hashbig2() if you wanted but I haven't bothered here.
|
||||
|
||||
If you want to find a hash of, say, exactly 7 integers, do
|
||||
a = i1; b = i2; c = i3;
|
||||
mix(a,b,c);
|
||||
a += i4; b += i5; c += i6;
|
||||
mix(a,b,c);
|
||||
a += i7;
|
||||
final(a,b,c);
|
||||
then use c as the hash value. If you have a variable length array of
|
||||
4-byte integers to hash, use hash_word(). If you have a byte array (like
|
||||
a character string), use hashlittle(). If you have several byte arrays, or
|
||||
a mix of things, see the comments above hashlittle().
|
||||
|
||||
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
|
||||
then mix those integers. This is fast (you can do a lot more thorough
|
||||
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
|
||||
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||
*/
|
||||
|
||||
#define hashsize(n) ((uint32_t)1<<(n))
|
||||
#define hashmask(n) (hashsize(n)-1)
|
||||
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
mix -- mix 3 32-bit values reversibly.
|
||||
|
||||
This is reversible, so any information in (a,b,c) before mix() is
|
||||
still in (a,b,c) after mix().
|
||||
|
||||
If four pairs of (a,b,c) inputs are run through mix(), or through
|
||||
mix() in reverse, there are at least 32 bits of the output that
|
||||
are sometimes the same for one pair and different for another pair.
|
||||
This was tested for:
|
||||
* pairs that differed by one bit, by two bits, in any combination
|
||||
of top bits of (a,b,c), or in any combination of bottom bits of
|
||||
(a,b,c).
|
||||
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
||||
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
||||
is commonly produced by subtraction) look like a single 1-bit
|
||||
difference.
|
||||
* the base values were pseudorandom, all zero but one bit set, or
|
||||
all zero plus a counter that starts at zero.
|
||||
|
||||
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
|
||||
satisfy this are
|
||||
4 6 8 16 19 4
|
||||
9 15 3 18 27 15
|
||||
14 9 3 7 17 3
|
||||
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
|
||||
for "differ" defined as + with a one-bit base and a two-bit delta. I
|
||||
used http://burtleburtle.net/bob/hash/avalanche.html to choose
|
||||
the operations, constants, and arrangements of the variables.
|
||||
|
||||
This does not achieve avalanche. There are input bits of (a,b,c)
|
||||
that fail to affect some output bits of (a,b,c), especially of a. The
|
||||
most thoroughly mixed value is c, but it doesn't really even achieve
|
||||
avalanche in c.
|
||||
|
||||
This allows some parallelism. Read-after-writes are good at doubling
|
||||
the number of bits affected, so the goal of mixing pulls in the opposite
|
||||
direction as the goal of parallelism. I did what I could. Rotates
|
||||
seem to cost as much as shifts on every machine I could lay my hands
|
||||
on, and rotates are much kinder to the top and bottom bits, so I used
|
||||
rotates.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
#define mix(a,b,c) \
|
||||
{ \
|
||||
a -= c; a ^= rot(c, 4); c += b; \
|
||||
b -= a; b ^= rot(a, 6); a += c; \
|
||||
c -= b; c ^= rot(b, 8); b += a; \
|
||||
a -= c; a ^= rot(c,16); c += b; \
|
||||
b -= a; b ^= rot(a,19); a += c; \
|
||||
c -= b; c ^= rot(b, 4); b += a; \
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
final -- final mixing of 3 32-bit values (a,b,c) into c
|
||||
|
||||
Pairs of (a,b,c) values differing in only a few bits will usually
|
||||
produce values of c that look totally different. This was tested for
|
||||
* pairs that differed by one bit, by two bits, in any combination
|
||||
of top bits of (a,b,c), or in any combination of bottom bits of
|
||||
(a,b,c).
|
||||
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
||||
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
||||
is commonly produced by subtraction) look like a single 1-bit
|
||||
difference.
|
||||
* the base values were pseudorandom, all zero but one bit set, or
|
||||
all zero plus a counter that starts at zero.
|
||||
|
||||
These constants passed:
|
||||
14 11 25 16 4 14 24
|
||||
12 14 25 16 4 14 24
|
||||
and these came close:
|
||||
4 8 15 26 3 22 24
|
||||
10 8 15 26 3 22 24
|
||||
11 8 15 26 3 22 24
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
#define final(a,b,c) \
|
||||
{ \
|
||||
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); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
hashlittle() -- hash a variable-length key into a 32-bit value
|
||||
k : the key (the unaligned variable-length array of bytes)
|
||||
length : the length of the key, counting by bytes
|
||||
val2 : IN: can be any 4-byte value OUT: second 32 bit hash.
|
||||
Returns a 32-bit value. Every bit of the key affects every bit of
|
||||
the return value. Two keys differing by one or two bits will have
|
||||
totally different hash values. Note that the return value is better
|
||||
mixed than val2, so use that first.
|
||||
|
||||
The best hash table sizes are powers of 2. There is no need to do
|
||||
mod a prime (mod is sooo slow!). If you need less than 32 bits,
|
||||
use a bitmask. For example, if you need only 10 bits, do
|
||||
h = (h & hashmask(10));
|
||||
In which case, the hash table should have hashsize(10) elements.
|
||||
|
||||
If you are hashing n strings (uint8_t **)k, do it like this:
|
||||
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
|
||||
|
||||
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
|
||||
code any way you wish, private, educational, or commercial. It's free.
|
||||
|
||||
Use for hash table lookup, or anything where one collision in 2^^32 is
|
||||
acceptable. Do NOT use for cryptographic purposes.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t hashlittle(const void *key, size_t length)
|
||||
{
|
||||
uint32_t a,b,c; /* internal state */
|
||||
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
|
||||
|
||||
/* Set up the internal state */
|
||||
a = b = c = 0xdeadbeef + ((uint32_t)length);
|
||||
|
||||
u.ptr = key;
|
||||
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
||||
const uint8_t *k8;
|
||||
|
||||
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
||||
while (length > 12)
|
||||
{
|
||||
a += k[0];
|
||||
b += k[1];
|
||||
c += k[2];
|
||||
mix(a,b,c);
|
||||
length -= 12;
|
||||
k += 3;
|
||||
}
|
||||
|
||||
/*----------------------------- handle the last (probably partial) block */
|
||||
k8 = (const uint8_t *)k;
|
||||
switch(length)
|
||||
{
|
||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||
case 9 : c+=k8[8]; /* fall through */
|
||||
case 8 : b+=k[1]; a+=k[0]; break;
|
||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||
case 5 : b+=k8[4]; /* fall through */
|
||||
case 4 : a+=k[0]; break;
|
||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||
case 1 : a+=k8[0]; break;
|
||||
case 0 : return c;
|
||||
}
|
||||
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
||||
const uint8_t *k8;
|
||||
|
||||
/*--------------- all but last block: aligned reads and different mixing */
|
||||
while (length > 12)
|
||||
{
|
||||
a += k[0] + (((uint32_t)k[1])<<16);
|
||||
b += k[2] + (((uint32_t)k[3])<<16);
|
||||
c += k[4] + (((uint32_t)k[5])<<16);
|
||||
mix(a,b,c);
|
||||
length -= 12;
|
||||
k += 6;
|
||||
}
|
||||
|
||||
/*----------------------------- handle the last (probably partial) block */
|
||||
k8 = (const uint8_t *)k;
|
||||
switch(length)
|
||||
{
|
||||
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10: c+=k[4];
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 9 : c+=k8[8]; /* fall through */
|
||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 : b+=k[2];
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 5 : b+=k8[4]; /* fall through */
|
||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 : a+=k[0];
|
||||
break;
|
||||
case 1 : a+=k8[0];
|
||||
break;
|
||||
case 0 : return c; /* zero length requires no mixing */
|
||||
}
|
||||
|
||||
} else { /* need to read the key one byte at a time */
|
||||
const uint8_t *k = (const uint8_t *)key;
|
||||
|
||||
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
||||
while (length > 12)
|
||||
{
|
||||
a += k[0];
|
||||
a += ((uint32_t)k[1])<<8;
|
||||
a += ((uint32_t)k[2])<<16;
|
||||
a += ((uint32_t)k[3])<<24;
|
||||
b += k[4];
|
||||
b += ((uint32_t)k[5])<<8;
|
||||
b += ((uint32_t)k[6])<<16;
|
||||
b += ((uint32_t)k[7])<<24;
|
||||
c += k[8];
|
||||
c += ((uint32_t)k[9])<<8;
|
||||
c += ((uint32_t)k[10])<<16;
|
||||
c += ((uint32_t)k[11])<<24;
|
||||
mix(a,b,c);
|
||||
length -= 12;
|
||||
k += 12;
|
||||
}
|
||||
|
||||
/*-------------------------------- last block: affect all 32 bits of (c) */
|
||||
switch(length) /* all the case statements fall through */
|
||||
{
|
||||
case 12: c+=((uint32_t)k[11])<<24;
|
||||
/* FALLTHROUGH */
|
||||
case 11: c+=((uint32_t)k[10])<<16;
|
||||
/* FALLTHROUGH */
|
||||
case 10: c+=((uint32_t)k[9])<<8;
|
||||
/* FALLTHROUGH */
|
||||
case 9 : c+=k[8];
|
||||
/* FALLTHROUGH */
|
||||
case 8 : b+=((uint32_t)k[7])<<24;
|
||||
/* FALLTHROUGH */
|
||||
case 7 : b+=((uint32_t)k[6])<<16;
|
||||
/* FALLTHROUGH */
|
||||
case 6 : b+=((uint32_t)k[5])<<8;
|
||||
/* FALLTHROUGH */
|
||||
case 5 : b+=k[4];
|
||||
/* FALLTHROUGH */
|
||||
case 4 : a+=((uint32_t)k[3])<<24;
|
||||
/* FALLTHROUGH */
|
||||
case 3 : a+=((uint32_t)k[2])<<16;
|
||||
/* FALLTHROUGH */
|
||||
case 2 : a+=((uint32_t)k[1])<<8;
|
||||
/* FALLTHROUGH */
|
||||
case 1 : a+=k[0];
|
||||
break;
|
||||
case 0 : return c;
|
||||
}
|
||||
}
|
||||
|
||||
final(a,b,c);
|
||||
return c;
|
||||
}
|
||||
40
help-from-md.awk
Executable file
40
help-from-md.awk
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# The caller must pass args: -v hfile=help-NAME.h NAME.NUM.md
|
||||
|
||||
BEGIN {
|
||||
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from the option list in " ARGV[1] "! */"
|
||||
findcomment = hfile
|
||||
sub("\\.", "\\.", findcomment)
|
||||
findcomment = "\\[comment\\].*" findcomment
|
||||
backtick_cnt = 0
|
||||
prints = ""
|
||||
}
|
||||
|
||||
/^```/ {
|
||||
backtick_cnt++
|
||||
next
|
||||
}
|
||||
|
||||
foundcomment {
|
||||
if (backtick_cnt > 1) exit
|
||||
if (backtick_cnt == 1) {
|
||||
gsub(/"/, "\\\"")
|
||||
prints = prints "\n rprintf(F,\"" $0 "\\n\");"
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
$0 ~ findcomment {
|
||||
foundcomment = 1
|
||||
backtick_cnt = 0
|
||||
}
|
||||
|
||||
END {
|
||||
if (foundcomment && backtick_cnt > 1)
|
||||
print heading "\n" prints > hfile
|
||||
else {
|
||||
print "Failed to find " hfile " section in " ARGV[1]
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
686
hlink.c
686
hlink.c
@@ -1,156 +1,566 @@
|
||||
/*
|
||||
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 hard-linking.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2020 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 alt_dest_type;
|
||||
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 void *data_when_new = "";
|
||||
|
||||
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, HT_KEY64);
|
||||
else if (inc_recurse)
|
||||
prior_hlinks = hashtable_create(1024, HT_KEY32);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
if (flist->count < 2) return;
|
||||
static struct ht_int64_node *dev_node = NULL;
|
||||
|
||||
if (hlink_list) free(hlink_list);
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
for (i = 0; i < flist->count; i++)
|
||||
bcopy(flist->files[i], &hlink_list[i], sizeof(hlink_list[0]));
|
||||
|
||||
qsort(hlink_list,flist->count,
|
||||
sizeof(hlink_list[0]),
|
||||
(int (*)())hlink_compare);
|
||||
|
||||
hlink_count=flist->count;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int low=0,high=hlink_count-1;
|
||||
int ret=0;
|
||||
|
||||
if (!hlink_list || !S_ISREG(file->mode)) return 0;
|
||||
|
||||
while (low != high) {
|
||||
int mid = (low+high)/2;
|
||||
ret = hlink_compare(&hlink_list[mid],file);
|
||||
if (ret == 0) {
|
||||
low = mid;
|
||||
break;
|
||||
}
|
||||
if (ret > 0)
|
||||
high=mid;
|
||||
else
|
||||
low=mid+1;
|
||||
}
|
||||
|
||||
if (hlink_compare(&hlink_list[low],file) != 0) return 0;
|
||||
|
||||
if (low > 0 &&
|
||||
S_ISREG(hlink_list[low-1].mode) &&
|
||||
file->dev == hlink_list[low-1].dev &&
|
||||
file->inode == hlink_list[low-1].inode)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static void hard_link_one(int i)
|
||||
{
|
||||
STRUCT_STAT st1,st2;
|
||||
|
||||
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 (do_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));
|
||||
return;
|
||||
/* 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, data_when_new);
|
||||
if (dev_node->data == data_when_new) {
|
||||
dev_node->data = hashtable_create(512, HT_KEY64);
|
||||
if (DEBUG_GTE(HLINK, 3)) {
|
||||
rprintf(FINFO, "[%s] created hashtable for dev %s\n",
|
||||
who_am_i(), big_num(dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
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 flist */
|
||||
void do_hard_links(struct file_list *flist)
|
||||
return hashtable_find(dev_node->data, ino, (void*)-1L);
|
||||
}
|
||||
|
||||
void idev_destroy(void)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
|
||||
if (!hlink_list) return;
|
||||
|
||||
for (i=1;i<hlink_count;i++) {
|
||||
if (S_ISREG(hlink_list[i].mode) &&
|
||||
S_ISREG(hlink_list[i-1].mode) &&
|
||||
hlink_list[i].basename && hlink_list[i-1].basename &&
|
||||
hlink_list[i].dev == hlink_list[i-1].dev &&
|
||||
hlink_list[i].inode == hlink_list[i-1].inode) {
|
||||
hard_link_one(i);
|
||||
}
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
hashtable_destroy(dev_tbl);
|
||||
}
|
||||
|
||||
static int hlink_compare_gnum(int *int1, int *int2)
|
||||
{
|
||||
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 (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, data_when_new);
|
||||
if (node->data == data_when_new) {
|
||||
node->data = new_array0(char, 5);
|
||||
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;
|
||||
|
||||
ndx_list = new_array(int32, flist->used);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
F_HL_PREV(file) = prev_ndx = F_HL_PREV(fp);
|
||||
}
|
||||
|
||||
if (inc_recurse
|
||||
&& (node = hashtable_find(prior_hlinks, gnum, NULL)) != 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 (alt_dest_type == 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 (!quick_check_ok(FT_REG, 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;
|
||||
}
|
||||
|
||||
file->flags |= FLAG_HLINK_DONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 (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, NULL);
|
||||
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);
|
||||
node->data = strdup(our_name);
|
||||
}
|
||||
}
|
||||
|
||||
int skip_hard_link(struct file_struct *file, struct file_list **flist_p)
|
||||
{
|
||||
struct file_list *flist;
|
||||
int prev_ndx;
|
||||
|
||||
file->flags |= FLAG_SKIP_HLINK;
|
||||
if (!(file->flags & FLAG_HLINK_LAST))
|
||||
return -1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return prev_ndx;
|
||||
}
|
||||
#endif
|
||||
|
||||
112
ifuncs.h
Normal file
112
ifuncs.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2022 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)
|
||||
{
|
||||
xb->buf = new_array(char, sz);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
sx_p->crtime = 0;
|
||||
#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
|
||||
}
|
||||
|
||||
static inline char *my_strdup(const char *str, const char *file, int line)
|
||||
{
|
||||
int len = strlen(str)+1;
|
||||
char *buf = my_alloc(NULL, len, 1, file, line);
|
||||
memcpy(buf, str, len);
|
||||
return buf;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ else
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
if [ -f $src ] || [ -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
@@ -208,7 +208,7 @@ else
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
|
||||
57
inums.h
Normal file
57
inums.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2008-2019 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-2019 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);
|
||||
}
|
||||
71
itypes.h
Normal file
71
itypes.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2022 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
|
||||
isHexDigit(const char *ptr)
|
||||
{
|
||||
return isxdigit(*(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
|
||||
isAlNum(const char *ptr)
|
||||
{
|
||||
return isalnum(*(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
latest-year.h
Normal file
1
latest-year.h
Normal file
@@ -0,0 +1 @@
|
||||
#define LATEST_YEAR "2022"
|
||||
@@ -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 */
|
||||
278
lib/compat.c
278
lib/compat.c
@@ -1,42 +1,50 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
compatibility functions - replacing 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-2020 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)
|
||||
char get_number_separator(void)
|
||||
{
|
||||
int l = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(l);
|
||||
if (ret)
|
||||
strcpy(ret,s);
|
||||
return ret;
|
||||
if (!number_separator) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof buf, "%f", 3.14);
|
||||
if (strchr(buf, '.') != NULL)
|
||||
number_separator = ',';
|
||||
else
|
||||
number_separator = '.';
|
||||
}
|
||||
|
||||
return number_separator;
|
||||
}
|
||||
|
||||
char get_decimal_point(void)
|
||||
{
|
||||
return get_number_separator() == ',' ? '.' : ',';
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETCWD
|
||||
char *getcwd(char *buf, int size)
|
||||
char *getcwd(char *buf, int size)
|
||||
{
|
||||
return getwd(buf);
|
||||
}
|
||||
@@ -44,17 +52,221 @@ char *getcwd(char *buf, int size)
|
||||
|
||||
|
||||
#ifndef HAVE_WAITPID
|
||||
pid_t waitpid(pid_t pid, int *statptr, int options)
|
||||
pid_t waitpid(pid_t pid, int *statptr, int options)
|
||||
{
|
||||
#ifdef HAVE_WAIT4
|
||||
return wait4(pid, statptr, options, NULL);
|
||||
#else
|
||||
/* If wait4 is also not available, try wait3 for SVR3 variants */
|
||||
/* Less ideal because can't actually request a specific pid */
|
||||
/* At least the WNOHANG option is supported */
|
||||
/* Code borrowed from apache fragment written by dwd@bell-labs.com */
|
||||
int tmp_pid, dummystat;;
|
||||
if (kill(pid, 0) == -1) {
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
if (statptr == NULL)
|
||||
statptr = &dummystat;
|
||||
while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
|
||||
(tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
|
||||
;
|
||||
return tmp_pid;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_MEMMOVE
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
bcopy(src, dest, n);
|
||||
bcopy((char *) src, (char *) dest, n);
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRPBRK
|
||||
/**
|
||||
* Find the first occurrence in @p s of any character in @p accept.
|
||||
*
|
||||
* Derived from glibc
|
||||
**/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
const char *a = accept;
|
||||
while (*a != '\0') {
|
||||
if (*a++ == *s) return (char *)s;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/**
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize is the size of the destination buffer.
|
||||
*
|
||||
* @return index of the terminating byte.
|
||||
**/
|
||||
size_t strlcpy(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
size_t ret = len;
|
||||
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
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize length of the buffer, which should be one more than
|
||||
* the maximum resulting string length.
|
||||
**/
|
||||
size_t strlcat(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len1 = strlen(d);
|
||||
size_t len2 = strlen(s);
|
||||
size_t ret = len1 + len2;
|
||||
|
||||
if (len1 < bufsize - 1) {
|
||||
if (len2 >= bufsize - len1)
|
||||
len2 = bufsize - len1 - 1;
|
||||
memcpy(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* some systems don't take the 2nd argument */
|
||||
int sys_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
#ifdef HAVE_GETTIMEOFDAY_TZ
|
||||
return gettimeofday(tv, NULL);
|
||||
#else
|
||||
return gettimeofday(tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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)
|
||||
(void)get_number_separator();
|
||||
|
||||
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
|
||||
|
||||
if (human_flag > 1) {
|
||||
int mult = human_flag == 2 ? 1000 : 1024;
|
||||
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 if ((dnum /= mult) < mult)
|
||||
units = 'T';
|
||||
else {
|
||||
dnum /= mult;
|
||||
units = 'P';
|
||||
}
|
||||
if (num < 0)
|
||||
dnum = -dnum;
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units);
|
||||
return bufs[n];
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
204
lib/fnmatch.c
204
lib/fnmatch.c
@@ -1,204 +0,0 @@
|
||||
#include "../rsync.h"
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined (STDC_HEADERS) || !defined (isascii)
|
||||
#define ISASCII(c) 1
|
||||
#else
|
||||
#define ISASCII(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
|
||||
|
||||
/* 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 !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register char c;
|
||||
|
||||
/* Note that this evalutes C many times. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_FILE_NAME) && *n == '/')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (*n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||
if (((flags & FNM_FILE_NAME) && *n == '/') ||
|
||||
(c == '?' && *n == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '\0')
|
||||
return 0;
|
||||
|
||||
{
|
||||
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; *n != '\0'; ++n)
|
||||
if ((c == '[' || FOLD (*n) == c1) &&
|
||||
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
register int not;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
register char cstart = c, cend = c;
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
cstart = cend = *p++;
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_FILE_NAME) && c == '/')
|
||||
/* [/] can never match. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
|
||||
goto matched;
|
||||
|
||||
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 == '\\')
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD (*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;
|
||||
}
|
||||
|
||||
#else /* HAVE_FNMATCH */
|
||||
void fnmatch_dummy(void) {}
|
||||
#endif
|
||||
@@ -1,69 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
#undef __P
|
||||
#define __P(protos) protos
|
||||
#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. */
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
|
||||
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
#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
|
||||
|
||||
/* 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;
|
||||
}
|
||||
751
lib/getopt.c
751
lib/getopt.c
@@ -1,751 +0,0 @@
|
||||
#include "../rsync.h"
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#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 defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
The GNU C Library itself does not yet support such messages. */
|
||||
#if HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# define gettext(msgid) (msgid)
|
||||
#endif
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = NULL;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (optstring)
|
||||
const char *optstring;
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0)
|
||||
optstring = _getopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound;
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if (nameend - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, gettext ("%s: option `%s' is ambiguous\n"),
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `--%s' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `%c%s' doesn't allow an argument\n"),
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option `%s' requires an argument\n"),
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, gettext ("%s: unrecognized option `--%s'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, gettext ("%s: unrecognized option `%c%s'\n"),
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, gettext ("%s: illegal option -- %c\n"),
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, gettext ("%s: invalid option -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr,
|
||||
gettext ("%s: option requires an argument -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
#else /* HAVE_GETOPT_LONG */
|
||||
void getopt_dummy(void) {}
|
||||
#endif
|
||||
129
lib/getopt.h
129
lib/getopt.h
@@ -1,129 +0,0 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
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;
|
||||
}
|
||||
186
lib/inet_ntop.c
Normal file
186
lib/inet_ntop.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
|
||||
#ifdef AF_INET6
|
||||
static const char *inet_ntop6(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
/* char *
|
||||
* isc_net_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a unsigned char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char *fmt = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
size_t len;
|
||||
|
||||
len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]);
|
||||
if (len >= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
memcpy(dst, tmp, len + 1);
|
||||
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* isc_inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
static const char *
|
||||
inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i, inc;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
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) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
memcpy(dst, tmp, tp - tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
212
lib/inet_pton.c
Normal file
212
lib/inet_pton.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_INADDRSZ 4
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
#ifdef INET6
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
#endif
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(int af,
|
||||
const char *src,
|
||||
void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
unsigned int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef INET6
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
17
lib/md-defines.h
Normal file
17
lib/md-defines.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* Keep this simple so both C and ASM can use it */
|
||||
|
||||
#define MD4_DIGEST_LEN 16
|
||||
#define MD5_DIGEST_LEN 16
|
||||
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
|
||||
|
||||
#define CSUM_CHUNK 64
|
||||
|
||||
#define CSUM_NONE 0
|
||||
#define CSUM_MD4_ARCHAIC 1
|
||||
#define CSUM_MD4_BUSTED 2
|
||||
#define CSUM_MD4_OLD 3
|
||||
#define CSUM_MD4 4
|
||||
#define CSUM_MD5 5
|
||||
#define CSUM_XXH64 6
|
||||
#define CSUM_XXH3_64 7
|
||||
#define CSUM_XXH3_128 8
|
||||
701
lib/md5-asm-x86_64.S
Normal file
701
lib/md5-asm-x86_64.S
Normal file
@@ -0,0 +1,701 @@
|
||||
/*
|
||||
* x86-64 optimized assembler MD5 implementation
|
||||
*
|
||||
* Author: Marc Bevand, 2004
|
||||
*
|
||||
* This code was placed in the public domain by the author. The original
|
||||
* publication can be found at:
|
||||
*
|
||||
* https://www.zorinaq.com/papers/md5-amd64.html
|
||||
*/
|
||||
/*
|
||||
* No modifications were made aside from changing the function and file names.
|
||||
* The MD5_CTX structure as expected here (from OpenSSL) is binary compatible
|
||||
* with the md_context used by rsync, for the fields accessed.
|
||||
*
|
||||
* Benchmarks (in MB/s) C ASM
|
||||
* - Intel Atom D2700 302 334
|
||||
* - Intel i7-7700hq 351 376
|
||||
* - AMD ThreadRipper 2950x 728 784
|
||||
*
|
||||
* The original code was also incorporated into OpenSSL. It has since been
|
||||
* modified there. Those changes have not been made here due to licensing
|
||||
* incompatibilities. Benchmarks of those changes on the above CPUs did not
|
||||
* show any significant difference in performance, though.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "md-defines.h"
|
||||
|
||||
#ifdef USE_MD5_ASM /* { */
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define md5_process_asm _md5_process_asm
|
||||
#endif
|
||||
|
||||
.text
|
||||
.align 16
|
||||
|
||||
.globl md5_process_asm
|
||||
md5_process_asm:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13 # not really useful (r13 is unused)
|
||||
push %r14
|
||||
push %r15
|
||||
|
||||
# rdi = arg #1 (ctx, MD5_CTX pointer)
|
||||
# rsi = arg #2 (ptr, data pointer)
|
||||
# rdx = arg #3 (nbr, number of 16-word blocks to process)
|
||||
mov %rdi, %rbp # rbp = ctx
|
||||
shl $6, %rdx # rdx = nbr in bytes
|
||||
lea (%rsi,%rdx), %rdi # rdi = end
|
||||
mov 0*4(%rbp), %eax # eax = ctx->A
|
||||
mov 1*4(%rbp), %ebx # ebx = ctx->B
|
||||
mov 2*4(%rbp), %ecx # ecx = ctx->C
|
||||
mov 3*4(%rbp), %edx # edx = ctx->D
|
||||
# end is 'rdi'
|
||||
# ptr is 'rsi'
|
||||
# A is 'eax'
|
||||
# B is 'ebx'
|
||||
# C is 'ecx'
|
||||
# D is 'edx'
|
||||
|
||||
cmp %rdi, %rsi # cmp end with ptr
|
||||
je 1f # jmp if ptr == end
|
||||
|
||||
# BEGIN of loop over 16-word blocks
|
||||
2: # save old values of A, B, C, D
|
||||
mov %eax, %r8d
|
||||
mov %ebx, %r9d
|
||||
mov %ecx, %r14d
|
||||
mov %edx, %r15d
|
||||
mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
lea -680876936(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r11d /* x & ... */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $7, %eax /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
lea -389564586(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r11d /* x & ... */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $12, %edx /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
lea 606105819(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r11d /* x & ... */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $17, %ecx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
lea -1044525330(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r11d /* x & ... */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $22, %ebx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
lea -176418897(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r11d /* x & ... */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $7, %eax /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
lea 1200080426(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r11d /* x & ... */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $12, %edx /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
lea -1473231341(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r11d /* x & ... */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $17, %ecx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
lea -45705983(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r11d /* x & ... */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $22, %ebx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
lea 1770035416(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r11d /* x & ... */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $7, %eax /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
lea -1958414417(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r11d /* x & ... */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $12, %edx /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
lea -42063(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r11d /* x & ... */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $17, %ecx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
lea -1990404162(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r11d /* x & ... */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $22, %ebx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
lea 1804603682(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r11d /* x & ... */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $7, %eax /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
lea -40341101(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r11d /* x & ... */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $12, %edx /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
lea -1502002290(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r11d /* x & ... */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $17, %ecx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
lea 1236535329(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r11d /* x & ... */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $22, %ebx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
|
||||
not %r11d /* not z */
|
||||
lea -165796510(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r12d /* x & z */
|
||||
and %ecx, %r11d /* y & (not z) */
|
||||
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %r12d, %eax /* dst += ... */
|
||||
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
|
||||
rol $5, %eax /* dst <<< s */
|
||||
add %ebx, %eax /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -1069501632(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r12d /* x & z */
|
||||
and %ebx, %r11d /* y & (not z) */
|
||||
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %r12d, %edx /* dst += ... */
|
||||
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
|
||||
rol $9, %edx /* dst <<< s */
|
||||
add %eax, %edx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea 643717713(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r12d /* x & z */
|
||||
and %eax, %r11d /* y & (not z) */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %r12d, %ecx /* dst += ... */
|
||||
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
|
||||
rol $14, %ecx /* dst <<< s */
|
||||
add %edx, %ecx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -373897302(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r12d /* x & z */
|
||||
and %edx, %r11d /* y & (not z) */
|
||||
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %r12d, %ebx /* dst += ... */
|
||||
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
|
||||
rol $20, %ebx /* dst <<< s */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -701558691(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r12d /* x & z */
|
||||
and %ecx, %r11d /* y & (not z) */
|
||||
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %r12d, %eax /* dst += ... */
|
||||
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
|
||||
rol $5, %eax /* dst <<< s */
|
||||
add %ebx, %eax /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea 38016083(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r12d /* x & z */
|
||||
and %ebx, %r11d /* y & (not z) */
|
||||
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %r12d, %edx /* dst += ... */
|
||||
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
|
||||
rol $9, %edx /* dst <<< s */
|
||||
add %eax, %edx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -660478335(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r12d /* x & z */
|
||||
and %eax, %r11d /* y & (not z) */
|
||||
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %r12d, %ecx /* dst += ... */
|
||||
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
|
||||
rol $14, %ecx /* dst <<< s */
|
||||
add %edx, %ecx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -405537848(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r12d /* x & z */
|
||||
and %edx, %r11d /* y & (not z) */
|
||||
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %r12d, %ebx /* dst += ... */
|
||||
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
|
||||
rol $20, %ebx /* dst <<< s */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea 568446438(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r12d /* x & z */
|
||||
and %ecx, %r11d /* y & (not z) */
|
||||
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %r12d, %eax /* dst += ... */
|
||||
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
|
||||
rol $5, %eax /* dst <<< s */
|
||||
add %ebx, %eax /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -1019803690(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r12d /* x & z */
|
||||
and %ebx, %r11d /* y & (not z) */
|
||||
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %r12d, %edx /* dst += ... */
|
||||
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
|
||||
rol $9, %edx /* dst <<< s */
|
||||
add %eax, %edx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -187363961(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r12d /* x & z */
|
||||
and %eax, %r11d /* y & (not z) */
|
||||
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %r12d, %ecx /* dst += ... */
|
||||
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
|
||||
rol $14, %ecx /* dst <<< s */
|
||||
add %edx, %ecx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea 1163531501(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r12d /* x & z */
|
||||
and %edx, %r11d /* y & (not z) */
|
||||
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %r12d, %ebx /* dst += ... */
|
||||
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
|
||||
rol $20, %ebx /* dst <<< s */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -1444681467(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
and %ebx, %r12d /* x & z */
|
||||
and %ecx, %r11d /* y & (not z) */
|
||||
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ecx, %r11d /* (NEXT STEP) z' = %ecx */
|
||||
add %r12d, %eax /* dst += ... */
|
||||
mov %ecx, %r12d /* (NEXT STEP) z' = %ecx */
|
||||
rol $5, %eax /* dst <<< s */
|
||||
add %ebx, %eax /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -51403784(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
and %eax, %r12d /* x & z */
|
||||
and %ebx, %r11d /* y & (not z) */
|
||||
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %ebx, %r11d /* (NEXT STEP) z' = %ebx */
|
||||
add %r12d, %edx /* dst += ... */
|
||||
mov %ebx, %r12d /* (NEXT STEP) z' = %ebx */
|
||||
rol $9, %edx /* dst <<< s */
|
||||
add %eax, %edx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea 1735328473(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
and %edx, %r12d /* x & z */
|
||||
and %eax, %r11d /* y & (not z) */
|
||||
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %eax, %r11d /* (NEXT STEP) z' = %eax */
|
||||
add %r12d, %ecx /* dst += ... */
|
||||
mov %eax, %r12d /* (NEXT STEP) z' = %eax */
|
||||
rol $14, %ecx /* dst <<< s */
|
||||
add %edx, %ecx /* dst += x */
|
||||
not %r11d /* not z */
|
||||
lea -1926607734(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
and %ecx, %r12d /* x & z */
|
||||
and %edx, %r11d /* y & (not z) */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
or %r11d, %r12d /* (y & (not z)) | (x & z) */
|
||||
mov %edx, %r11d /* (NEXT STEP) z' = %edx */
|
||||
add %r12d, %ebx /* dst += ... */
|
||||
mov %edx, %r12d /* (NEXT STEP) z' = %edx */
|
||||
rol $20, %ebx /* dst <<< s */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */
|
||||
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
|
||||
lea -378558(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
xor %ebx, %r11d /* x ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $4, %eax /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -2022574463(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
xor %eax, %r11d /* x ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $11, %edx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea 1839030562(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
xor %edx, %r11d /* x ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $16, %ecx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -35309556(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
xor %ecx, %r11d /* x ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $23, %ebx /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea -1530992060(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
xor %ebx, %r11d /* x ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $4, %eax /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea 1272893353(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
xor %eax, %r11d /* x ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $11, %edx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea -155497632(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
xor %edx, %r11d /* x ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $16, %ecx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -1094730640(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
xor %ecx, %r11d /* x ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $23, %ebx /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea 681279174(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
xor %ebx, %r11d /* x ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $4, %eax /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -358537222(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
xor %eax, %r11d /* x ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $11, %edx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea -722521979(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
xor %edx, %r11d /* x ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $16, %ecx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea 76029189(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
xor %ecx, %r11d /* x ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $23, %ebx /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea -640364487(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
|
||||
xor %edx, %r11d /* z ^ ... */
|
||||
xor %ebx, %r11d /* x ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
rol $4, %eax /* dst <<< s */
|
||||
mov %ebx, %r11d /* (NEXT STEP) y' = %ebx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -421815835(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
|
||||
xor %ecx, %r11d /* z ^ ... */
|
||||
xor %eax, %r11d /* x ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
rol $11, %edx /* dst <<< s */
|
||||
mov %eax, %r11d /* (NEXT STEP) y' = %eax */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea 530742520(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
|
||||
xor %ebx, %r11d /* z ^ ... */
|
||||
xor %edx, %r11d /* x ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
rol $16, %ecx /* dst <<< s */
|
||||
mov %edx, %r11d /* (NEXT STEP) y' = %edx */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -995338651(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
xor %eax, %r11d /* z ^ ... */
|
||||
xor %ecx, %r11d /* x ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
rol $23, %ebx /* dst <<< s */
|
||||
mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */
|
||||
mov $0xffffffff, %r11d
|
||||
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/
|
||||
lea -198630844(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
or %ebx, %r11d /* x | ... */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
mov 7*4(%rsi),%r10d /* (NEXT STEP) X[7] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $6, %eax /* dst <<< s */
|
||||
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea 1126891415(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
or %eax, %r11d /* x | ... */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
mov 14*4(%rsi),%r10d /* (NEXT STEP) X[14] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $10, %edx /* dst <<< s */
|
||||
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea -1416354905(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
or %edx, %r11d /* x | ... */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
mov 5*4(%rsi),%r10d /* (NEXT STEP) X[5] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $15, %ecx /* dst <<< s */
|
||||
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -57434055(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
or %ecx, %r11d /* x | ... */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
mov 12*4(%rsi),%r10d /* (NEXT STEP) X[12] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $21, %ebx /* dst <<< s */
|
||||
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea 1700485571(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
or %ebx, %r11d /* x | ... */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
mov 3*4(%rsi),%r10d /* (NEXT STEP) X[3] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $6, %eax /* dst <<< s */
|
||||
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -1894986606(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
or %eax, %r11d /* x | ... */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
mov 10*4(%rsi),%r10d /* (NEXT STEP) X[10] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $10, %edx /* dst <<< s */
|
||||
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea -1051523(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
or %edx, %r11d /* x | ... */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
mov 1*4(%rsi),%r10d /* (NEXT STEP) X[1] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $15, %ecx /* dst <<< s */
|
||||
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -2054922799(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
or %ecx, %r11d /* x | ... */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
mov 8*4(%rsi),%r10d /* (NEXT STEP) X[8] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $21, %ebx /* dst <<< s */
|
||||
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea 1873313359(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
or %ebx, %r11d /* x | ... */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
mov 15*4(%rsi),%r10d /* (NEXT STEP) X[15] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $6, %eax /* dst <<< s */
|
||||
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -30611744(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
or %eax, %r11d /* x | ... */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
mov 6*4(%rsi),%r10d /* (NEXT STEP) X[6] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $10, %edx /* dst <<< s */
|
||||
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea -1560198380(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
or %edx, %r11d /* x | ... */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
mov 13*4(%rsi),%r10d /* (NEXT STEP) X[13] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $15, %ecx /* dst <<< s */
|
||||
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea 1309151649(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
or %ecx, %r11d /* x | ... */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
mov 4*4(%rsi),%r10d /* (NEXT STEP) X[4] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $21, %ebx /* dst <<< s */
|
||||
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
lea -145523070(%eax,%r10d),%eax /* Const + dst + ... */
|
||||
or %ebx, %r11d /* x | ... */
|
||||
xor %ecx, %r11d /* y ^ ... */
|
||||
add %r11d, %eax /* dst += ... */
|
||||
mov 11*4(%rsi),%r10d /* (NEXT STEP) X[11] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $6, %eax /* dst <<< s */
|
||||
xor %ecx, %r11d /* (NEXT STEP) not z' = not %ecx */
|
||||
add %ebx, %eax /* dst += x */
|
||||
lea -1120210379(%edx,%r10d),%edx /* Const + dst + ... */
|
||||
or %eax, %r11d /* x | ... */
|
||||
xor %ebx, %r11d /* y ^ ... */
|
||||
add %r11d, %edx /* dst += ... */
|
||||
mov 2*4(%rsi),%r10d /* (NEXT STEP) X[2] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $10, %edx /* dst <<< s */
|
||||
xor %ebx, %r11d /* (NEXT STEP) not z' = not %ebx */
|
||||
add %eax, %edx /* dst += x */
|
||||
lea 718787259(%ecx,%r10d),%ecx /* Const + dst + ... */
|
||||
or %edx, %r11d /* x | ... */
|
||||
xor %eax, %r11d /* y ^ ... */
|
||||
add %r11d, %ecx /* dst += ... */
|
||||
mov 9*4(%rsi),%r10d /* (NEXT STEP) X[9] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $15, %ecx /* dst <<< s */
|
||||
xor %eax, %r11d /* (NEXT STEP) not z' = not %eax */
|
||||
add %edx, %ecx /* dst += x */
|
||||
lea -343485551(%ebx,%r10d),%ebx /* Const + dst + ... */
|
||||
or %ecx, %r11d /* x | ... */
|
||||
xor %edx, %r11d /* y ^ ... */
|
||||
add %r11d, %ebx /* dst += ... */
|
||||
mov 0*4(%rsi),%r10d /* (NEXT STEP) X[0] */
|
||||
mov $0xffffffff, %r11d
|
||||
rol $21, %ebx /* dst <<< s */
|
||||
xor %edx, %r11d /* (NEXT STEP) not z' = not %edx */
|
||||
add %ecx, %ebx /* dst += x */
|
||||
# add old values of A, B, C, D
|
||||
add %r8d, %eax
|
||||
add %r9d, %ebx
|
||||
add %r14d, %ecx
|
||||
add %r15d, %edx
|
||||
|
||||
# loop control
|
||||
add $64, %rsi # ptr += 64
|
||||
cmp %rdi, %rsi # cmp end with ptr
|
||||
jb 2b # jmp if ptr < end
|
||||
# END of loop over 16-word blocks
|
||||
1:
|
||||
mov %eax, 0*4(%rbp) # ctx->A = A
|
||||
mov %ebx, 1*4(%rbp) # ctx->B = B
|
||||
mov %ecx, 2*4(%rbp) # ctx->C = C
|
||||
mov %edx, 3*4(%rbp) # ctx->D = D
|
||||
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13 # not really useful (r13 is unused)
|
||||
pop %r12
|
||||
pop %rbx
|
||||
pop %rbp
|
||||
ret
|
||||
|
||||
#endif /* } USE_MD5_ASM */
|
||||
323
lib/md5.c
Normal file
323
lib/md5.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* RFC 1321 compliant MD5 implementation
|
||||
*
|
||||
* Copyright (C) 2001-2003 Christophe Devine
|
||||
* Copyright (C) 2007-2022 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"
|
||||
|
||||
#if !defined USE_OPENSSL || USE_MD5_ASM /* { */
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef USE_MD5_ASM
|
||||
#if CSUM_CHUNK != 64
|
||||
#error The MD5 ASM code does not support CSUM_CHUNK != 64
|
||||
#endif
|
||||
extern void md5_process_asm(md_context *ctx, const void *data, size_t num);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef USE_MD5_ASM /* { */
|
||||
if (length >= CSUM_CHUNK) {
|
||||
uint32 chunks = length / CSUM_CHUNK;
|
||||
md5_process_asm(ctx, input, chunks);
|
||||
length -= chunks * CSUM_CHUNK;
|
||||
input += chunks * CSUM_CHUNK;
|
||||
}
|
||||
#else /* } { */
|
||||
while (length >= CSUM_CHUNK) {
|
||||
md5_process(ctx, input);
|
||||
length -= CSUM_CHUNK;
|
||||
input += CSUM_CHUNK;
|
||||
}
|
||||
#endif /* } */
|
||||
|
||||
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);
|
||||
}
|
||||
#endif /* } */
|
||||
|
||||
#ifdef TEST_MD5 /* { */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#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 /* } */
|
||||
247
lib/mdfour.c
Normal file
247
lib/mdfour.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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-2020 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. */
|
||||
|
||||
static md_context *m;
|
||||
|
||||
#define MASK32 (0xffffffff)
|
||||
|
||||
#define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
|
||||
#define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
|
||||
#define H(X,Y,Z) (((X)^(Y)^(Z)))
|
||||
#define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))
|
||||
|
||||
#define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s)
|
||||
#define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s)
|
||||
#define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)
|
||||
|
||||
/* this applies md4 to 64 byte chunks */
|
||||
static void mdfour64(uint32 *M)
|
||||
{
|
||||
uint32 AA, BB, CC, DD;
|
||||
uint32 A,B,C,D;
|
||||
|
||||
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(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(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(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(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(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(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(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(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(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(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(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
|
||||
|
||||
A += AA; B += BB;
|
||||
C += CC; D += DD;
|
||||
|
||||
A &= MASK32; B &= MASK32;
|
||||
C &= MASK32; D &= MASK32;
|
||||
|
||||
m->A = A; m->B = B; m->C = C; m->D = D;
|
||||
}
|
||||
|
||||
static void copy64(uint32 *M, const uchar *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
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(uchar *out,uint32 x)
|
||||
{
|
||||
out[0] = x&0xFF;
|
||||
out[1] = (x>>8)&0xFF;
|
||||
out[2] = (x>>16)&0xFF;
|
||||
out[3] = (x>>24)&0xFF;
|
||||
}
|
||||
|
||||
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(const uchar *in, uint32 length)
|
||||
{
|
||||
uchar buf[128];
|
||||
uint32 M[16];
|
||||
extern int protocol_version;
|
||||
|
||||
/*
|
||||
* 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 (length)
|
||||
memcpy(buf, in, length);
|
||||
buf[length] = 0x80;
|
||||
|
||||
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, 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);
|
||||
mdfour64(M);
|
||||
}
|
||||
}
|
||||
|
||||
void mdfour_update(md_context *md, const uchar *in, uint32 length)
|
||||
{
|
||||
uint32 M[16];
|
||||
|
||||
m = md;
|
||||
|
||||
if (length == 0)
|
||||
mdfour_tail(in, length);
|
||||
|
||||
while (length >= 64) {
|
||||
copy64(M, in);
|
||||
mdfour64(M);
|
||||
in += 64;
|
||||
length -= 64;
|
||||
m->totalN += 64 << 3;
|
||||
if (m->totalN < 64 << 3)
|
||||
m->totalN2++;
|
||||
}
|
||||
|
||||
if (length)
|
||||
mdfour_tail(in, length);
|
||||
}
|
||||
|
||||
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN])
|
||||
{
|
||||
m = md;
|
||||
|
||||
copy4(digest, m->A);
|
||||
copy4(digest+4, m->B);
|
||||
copy4(digest+8, m->C);
|
||||
copy4(digest+12, m->D);
|
||||
}
|
||||
|
||||
#ifdef TEST_MDFOUR
|
||||
|
||||
void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
|
||||
{
|
||||
md_context md;
|
||||
mdfour_begin(&md);
|
||||
mdfour_update(&md, in, length);
|
||||
mdfour_result(&md, digest);
|
||||
}
|
||||
|
||||
int protocol_version = 28;
|
||||
|
||||
static void file_checksum1(char *fname)
|
||||
{
|
||||
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) {
|
||||
perror("fname");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mdfour_begin(&md);
|
||||
|
||||
while (1) {
|
||||
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 < MD4_DIGEST_LEN; i++)
|
||||
printf("%02X", sum[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
while (--argc)
|
||||
file_checksum1(*++argv);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
30
lib/mdigest.h
Normal file
30
lib/mdigest.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* The include file for both the MD4 and MD5 routines. */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include "openssl/md4.h"
|
||||
#include "openssl/md5.h"
|
||||
#endif
|
||||
#include "md-defines.h"
|
||||
|
||||
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]);
|
||||
|
||||
#if defined USE_OPENSSL && !defined USE_MD5_ASM
|
||||
#define md5_context MD5_CTX
|
||||
#define md5_begin MD5_Init
|
||||
#define md5_update MD5_Update
|
||||
#define md5_result(cptr, digest) MD5_Final(digest, cptr)
|
||||
#else
|
||||
#define md5_context md_context
|
||||
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]);
|
||||
#endif
|
||||
65
lib/permstring.c
Normal file
65
lib/permstring.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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-2019 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).
|
||||
* The "buf" buffer must be at least 11 characters. */
|
||||
void permstring(char *perms, mode_t mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int 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
|
||||
* off by one, but remember there's a type char at the
|
||||
* start. */
|
||||
if (mode & S_ISUID)
|
||||
perms[3] = (mode & S_IXUSR) ? 's' : 'S';
|
||||
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
#ifdef S_ISVTX
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
#endif
|
||||
|
||||
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';
|
||||
}
|
||||
3
lib/permstring.h
Normal file
3
lib/permstring.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#define PERMSTRING_SIZE 11
|
||||
|
||||
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*,char*,int), 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
|
||||
375
lib/pool_alloc.c
Normal file
375
lib/pool_alloc.c
Normal file
@@ -0,0 +1,375 @@
|
||||
#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)(); /* called 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*, const char*, int), int flags)
|
||||
{
|
||||
struct alloc_pool *pool;
|
||||
|
||||
if ((MINALIGN & (MINALIGN - 1)) != (0)) {
|
||||
if (bomb)
|
||||
(*bomb)("Compiler error: MINALIGN is not a power of 2", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pool = new0(struct alloc_pool)))
|
||||
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, __FILE__, __LINE__);
|
||||
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*, const char*, int), 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))
|
||||
1512
lib/snprintf.c
Normal file
1512
lib/snprintf.c
Normal file
File diff suppressed because it is too large
Load Diff
2802
lib/sysacls.c
Normal file
2802
lib/sysacls.c
Normal file
File diff suppressed because it is too large
Load Diff
307
lib/sysacls.h
Normal file
307
lib/sysacls.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 2.2.x
|
||||
* Portable SMB ACL interface
|
||||
* Copyright (C) Jeremy Allison 2000
|
||||
* Copyright (C) 2007-2022 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. */
|
||||
|
||||
#ifndef __TANDEM
|
||||
#undef GROUP
|
||||
#endif
|
||||
#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 */
|
||||
301
lib/sysxattrs.c
Normal file
301
lib/sysxattrs.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Extended attribute support for rsync.
|
||||
*
|
||||
* Copyright (C) 2004 Red Hat, Inc.
|
||||
* Copyright (C) 2003-2022 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, (char*)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, (char*)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, (char*)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;
|
||||
|
||||
ret += len + 1;
|
||||
if ((size_t)ret > 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_SYS_XATTR_H
|
||||
#include <sys/xattr.h>
|
||||
#elif defined HAVE_ATTR_XATTR_H
|
||||
#include <attr/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);
|
||||
4601
lib/zlib.c
4601
lib/zlib.c
File diff suppressed because it is too large
Load Diff
632
lib/zlib.h
632
lib/zlib.h
@@ -1,632 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is derived from zlib.h and zconf.h from the zlib-0.95
|
||||
* distribution by Jean-loup Gailly and Mark Adler, with some additions
|
||||
* by Paul Mackerras to aid in implementing Deflate compression and
|
||||
* decompression for PPP packets.
|
||||
*/
|
||||
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 0.95, Aug 16th, 1995.
|
||||
|
||||
Copyright (C) 1995 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
gzip@prep.ai.mit.edu madler@alumni.caltech.edu
|
||||
*/
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#define _ZLIB_H
|
||||
|
||||
/* #include "zconf.h" */ /* included directly here */
|
||||
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
|
||||
|
||||
/*
|
||||
The library does not install any signal handler. It is recommended to
|
||||
add at least a handler for SIGSEGV when decompressing; the library checks
|
||||
the consistency of the input data whenever possible but may go nuts
|
||||
for some forms of corrupted input.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
* Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
|
||||
* at addresses which are not a multiple of their size.
|
||||
* Under DOS, -DFAR=far or -DFAR=__far may be needed.
|
||||
*/
|
||||
|
||||
#ifndef STDC
|
||||
# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
|
||||
# define STDC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
|
||||
# include <unix.h>
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
1 << (windowBits+2) + 1 << (memLevel+9)
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef int32 Long; /* 32 bits or more */
|
||||
typedef uint32 uLong; /* 32 bits or more */
|
||||
|
||||
typedef Byte FAR Bytef;
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
/* end of original zconf.h */
|
||||
|
||||
#define ZLIB_VERSION "0.95P"
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
decompression functions, including integrity checks of the uncompressed
|
||||
data. This version of the library supports only one compression method
|
||||
(deflation) but other algorithms may be added later and will have the same
|
||||
stream interface.
|
||||
|
||||
For compression the application must provide the output buffer and
|
||||
may optionally provide the input buffer for optimization. For decompression,
|
||||
the application must provide the input buffer and may optionally provide
|
||||
the output buffer for optimization.
|
||||
|
||||
Compression can be done in a single step if the buffers are large
|
||||
enough (for example if an input file is mmap'ed), or can be done by
|
||||
repeated calls of the compression function. In the latter case, the
|
||||
application must provide more input and/or consume the output
|
||||
(providing more output space) before each call.
|
||||
*/
|
||||
|
||||
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
|
||||
typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
|
||||
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
Bytef *next_in; /* next input byte */
|
||||
uInt avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
|
||||
Bytef *next_out; /* next output byte should be put there */
|
||||
uInt avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
|
||||
char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state FAR *state; /* not visible by applications */
|
||||
|
||||
alloc_func zalloc; /* used to allocate the internal state */
|
||||
free_func zfree; /* used to free the internal state */
|
||||
voidp opaque; /* private data object passed to zalloc and zfree */
|
||||
|
||||
Byte data_type; /* best guess about the data type: ascii or binary */
|
||||
|
||||
} z_stream;
|
||||
|
||||
/*
|
||||
The application must update next_in and avail_in when avail_in has
|
||||
dropped to zero. It must update next_out and avail_out when avail_out
|
||||
has dropped to zero. The application must initialize zalloc, zfree and
|
||||
opaque before calling the init function. All other fields are set by the
|
||||
compression library and must not be updated by the application.
|
||||
|
||||
The opaque value provided by the application will be passed as the first
|
||||
parameter for calls of zalloc and zfree. This can be useful for custom
|
||||
memory management. The compression library attaches no meaning to the
|
||||
opaque value.
|
||||
|
||||
zalloc must return Z_NULL if there is not enough memory for the object.
|
||||
On 16-bit systems, the functions zalloc and zfree must be able to allocate
|
||||
exactly 65536 bytes, but will not be required to allocate more than this
|
||||
if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
|
||||
pointers returned by zalloc for objects of exactly 65536 bytes *must*
|
||||
have their offset normalized to zero. The default allocation function
|
||||
provided by this library ensures this (see zutil.c). To reduce memory
|
||||
requirements and avoid any allocation of 64K objects, at the expense of
|
||||
compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
|
||||
|
||||
The fields total_in and total_out can be used for statistics or
|
||||
progress reports. After compression, total_in holds the total size of
|
||||
the uncompressed data and may be saved for use in the decompressor
|
||||
(particularly if the decompressor wants to decompress everything in
|
||||
a single step).
|
||||
*/
|
||||
|
||||
/* constants */
|
||||
|
||||
#define Z_NO_FLUSH 0
|
||||
#define Z_PARTIAL_FLUSH 1
|
||||
#define Z_FULL_FLUSH 2
|
||||
#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
|
||||
#define Z_FINISH 4
|
||||
#define Z_PACKET_FLUSH 5
|
||||
#define Z_INSERT_ONLY 6 /* update hash table etc., produce no output */
|
||||
/* See deflate() below for the usage of these constants */
|
||||
|
||||
#define Z_OK 0
|
||||
#define Z_STREAM_END 1
|
||||
#define Z_ERRNO (-1)
|
||||
#define Z_STREAM_ERROR (-2)
|
||||
#define Z_DATA_ERROR (-3)
|
||||
#define Z_MEM_ERROR (-4)
|
||||
#define Z_BUF_ERROR (-5)
|
||||
/* error codes for the compression/decompression functions */
|
||||
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
/* compression levels */
|
||||
|
||||
#define Z_FILTERED 1
|
||||
#define Z_HUFFMAN_ONLY 2
|
||||
#define Z_DEFAULT_STRATEGY 0
|
||||
|
||||
#define Z_BINARY 0
|
||||
#define Z_ASCII 1
|
||||
#define Z_UNKNOWN 2
|
||||
/* Used to set the data_type field */
|
||||
|
||||
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
|
||||
|
||||
extern char *zlib_version;
|
||||
/* The application can compare zlib_version and ZLIB_VERSION for consistency.
|
||||
If the first character differs, the library code actually used is
|
||||
not compatible with the zlib.h header file used by the application.
|
||||
*/
|
||||
|
||||
/* basic functions */
|
||||
|
||||
extern int deflateInit OF((z_stream *strm, int level));
|
||||
/*
|
||||
Initializes the internal stream state for compression. The fields
|
||||
zalloc, zfree and opaque must be initialized before by the caller.
|
||||
If zalloc and zfree are set to Z_NULL, deflateInit updates them to
|
||||
use default allocation functions.
|
||||
|
||||
The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9:
|
||||
1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests
|
||||
a default compromise between speed and compression (currently equivalent
|
||||
to level 6).
|
||||
|
||||
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if level is not a valid compression level.
|
||||
msg is set to null if there is no error message. deflateInit does not
|
||||
perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
|
||||
extern int deflate OF((z_stream *strm, int flush));
|
||||
/*
|
||||
Performs one or both of the following actions:
|
||||
|
||||
- Compress more input starting at next_in and update next_in and avail_in
|
||||
accordingly. If not all input can be processed (because there is not
|
||||
enough room in the output buffer), next_in and avail_in are updated and
|
||||
processing will resume at this point for the next call of deflate().
|
||||
|
||||
- Provide more output starting at next_out and update next_out and avail_out
|
||||
accordingly. This action is forced if the parameter flush is non zero.
|
||||
Forcing flush frequently degrades the compression ratio, so this parameter
|
||||
should be set only when necessary (in interactive applications).
|
||||
Some output may be provided even if flush is not set.
|
||||
|
||||
Before the call of deflate(), the application should ensure that at least
|
||||
one of the actions is possible, by providing more input and/or consuming
|
||||
more output, and updating avail_in or avail_out accordingly; avail_out
|
||||
should never be zero before the call. The application can consume the
|
||||
compressed output when it wants, for example when the output buffer is full
|
||||
(avail_out == 0), or after each call of deflate().
|
||||
|
||||
If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
|
||||
block is terminated and flushed to the output buffer so that the
|
||||
decompressor can get all input data available so far. For method 9, a future
|
||||
variant on method 8, the current block will be flushed but not terminated.
|
||||
If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
|
||||
special marker is output and the compression dictionary is discarded; this
|
||||
is useful to allow the decompressor to synchronize if one compressed block
|
||||
has been damaged (see inflateSync below). Flushing degrades compression and
|
||||
so should be used only when necessary. Using Z_FULL_FLUSH too often can
|
||||
seriously degrade the compression. If deflate returns with avail_out == 0,
|
||||
this function must be called again with the same value of the flush
|
||||
parameter and more output space (updated avail_out), until the flush is
|
||||
complete (deflate returns with non-zero avail_out).
|
||||
|
||||
If the parameter flush is set to Z_PACKET_FLUSH, the compression
|
||||
block is terminated, and a zero-length stored block is output,
|
||||
omitting the length bytes (the effect of this is that the 3-bit type
|
||||
code 000 for a stored block is output, and the output is then
|
||||
byte-aligned). This is designed for use at the end of a PPP packet.
|
||||
In addition, if the current compression block contains all the data
|
||||
since the last Z_PACKET_FLUSH, it is never output as a stored block.
|
||||
If the current compression block output as a static or dynamic block
|
||||
would not be at least `minCompression' bytes smaller than the
|
||||
original data, then nothing is output for that block. (The type
|
||||
code for the zero-length stored block is still output, resulting in
|
||||
a single zero byte being output for the whole packet.)
|
||||
`MinCompression' is a parameter to deflateInit2, or 0 if deflateInit
|
||||
is used.
|
||||
|
||||
If the parameter flush is set to Z_FINISH, all pending input is processed,
|
||||
all pending output is flushed and deflate returns with Z_STREAM_END if there
|
||||
was enough output space; if deflate returns with Z_OK, this function must be
|
||||
called again with Z_FINISH and more output space (updated avail_out) but no
|
||||
more input data, until it returns with Z_STREAM_END or an error. After
|
||||
deflate has returned Z_STREAM_END, the only possible operations on the
|
||||
stream are deflateReset or deflateEnd.
|
||||
|
||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||
is to be done in a single step. In this case, avail_out must be at least
|
||||
0.1% larger than avail_in plus 12 bytes. If deflate does not return
|
||||
Z_STREAM_END, then it must be called again as described above.
|
||||
|
||||
deflate() may update data_type if it can make a good guess about
|
||||
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
||||
binary. This field is only for information purposes and does not affect
|
||||
the compression algorithm in any manner.
|
||||
|
||||
deflate() returns Z_OK if some progress has been made (more input
|
||||
processed or more output produced), Z_STREAM_END if all input has been
|
||||
consumed and all output has been produced (only when flush is set to
|
||||
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
|
||||
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
|
||||
*/
|
||||
|
||||
|
||||
extern int deflateEnd OF((z_stream *strm));
|
||||
/*
|
||||
All dynamically allocated data structures for this stream are freed.
|
||||
This function discards any unprocessed input and does not flush any
|
||||
pending output.
|
||||
|
||||
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
|
||||
stream state was inconsistent. In the error case, msg may be set
|
||||
but then points to a static string (which must not be deallocated).
|
||||
*/
|
||||
|
||||
|
||||
extern int inflateInit OF((z_stream *strm));
|
||||
/*
|
||||
Initializes the internal stream state for decompression. The fields
|
||||
zalloc and zfree must be initialized before by the caller. If zalloc and
|
||||
zfree are set to Z_NULL, inflateInit updates them to use default allocation
|
||||
functions.
|
||||
|
||||
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory. msg is set to null if there is no error message.
|
||||
inflateInit does not perform any decompression: this will be done by
|
||||
inflate().
|
||||
*/
|
||||
|
||||
|
||||
extern int inflate OF((z_stream *strm, int flush));
|
||||
/*
|
||||
Performs one or both of the following actions:
|
||||
|
||||
- Decompress more input starting at next_in and update next_in and avail_in
|
||||
accordingly. If not all input can be processed (because there is not
|
||||
enough room in the output buffer), next_in is updated and processing
|
||||
will resume at this point for the next call of inflate().
|
||||
|
||||
- Provide more output starting at next_out and update next_out and avail_out
|
||||
accordingly. inflate() always provides as much output as possible
|
||||
(until there is no more input data or no more space in the output buffer).
|
||||
|
||||
Before the call of inflate(), the application should ensure that at least
|
||||
one of the actions is possible, by providing more input and/or consuming
|
||||
more output, and updating the next_* and avail_* values accordingly.
|
||||
The application can consume the uncompressed output when it wants, for
|
||||
example when the output buffer is full (avail_out == 0), or after each
|
||||
call of inflate().
|
||||
|
||||
If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
|
||||
inflate flushes as much output as possible to the output buffer. The
|
||||
flushing behavior of inflate is not specified for values of the flush
|
||||
parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
|
||||
current implementation actually flushes as much output as possible
|
||||
anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
|
||||
has been consumed, it is expecting to see the length field of a stored
|
||||
block; if not, it returns Z_DATA_ERROR.
|
||||
|
||||
inflate() should normally be called until it returns Z_STREAM_END or an
|
||||
error. However if all decompression is to be performed in a single step
|
||||
(a single call of inflate), the parameter flush should be set to
|
||||
Z_FINISH. In this case all pending input is processed and all pending
|
||||
output is flushed; avail_out must be large enough to hold all the
|
||||
uncompressed data. (The size of the uncompressed data may have been saved
|
||||
by the compressor for this purpose.) The next operation on this stream must
|
||||
be inflateEnd to deallocate the decompression state. The use of Z_FINISH
|
||||
is never required, but can be used to inform inflate that a faster routine
|
||||
may be used for the single inflate() call.
|
||||
|
||||
inflate() returns Z_OK if some progress has been made (more input
|
||||
processed or more output produced), Z_STREAM_END if the end of the
|
||||
compressed data has been reached and all uncompressed output has been
|
||||
produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
|
||||
the stream structure was inconsistent (for example if next_in or next_out
|
||||
was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
|
||||
progress is possible or if there was not enough room in the output buffer
|
||||
when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
|
||||
call inflateSync to look for a good compression block. */
|
||||
|
||||
|
||||
extern int inflateEnd OF((z_stream *strm));
|
||||
/*
|
||||
All dynamically allocated data structures for this stream are freed.
|
||||
This function discards any unprocessed input and does not flush any
|
||||
pending output.
|
||||
|
||||
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
|
||||
was inconsistent. In the error case, msg may be set but then points to a
|
||||
static string (which must not be deallocated).
|
||||
*/
|
||||
|
||||
/* advanced functions */
|
||||
|
||||
/*
|
||||
The following functions are needed only in some special applications.
|
||||
*/
|
||||
|
||||
extern int deflateInit2 OF((z_stream *strm,
|
||||
int level,
|
||||
int method,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy));
|
||||
/*
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc and zfree must be initialized before by the caller.
|
||||
|
||||
The method parameter is the compression method. It must be 8 in this
|
||||
version of the library. (Method 9 will allow a 64K history buffer and
|
||||
partial block flushes.)
|
||||
|
||||
The windowBits parameter is the base two logarithm of the window size
|
||||
(the size of the history buffer). It should be in the range 8..15 for this
|
||||
version of the library (the value 16 will be allowed for method 9). Larger
|
||||
values of this parameter result in better compression at the expense of
|
||||
memory usage. The default value is 15 if deflateInit is used instead.
|
||||
|
||||
The memLevel parameter specifies how much memory should be allocated
|
||||
for the internal compression state. memLevel=1 uses minimum memory but
|
||||
is slow and reduces compression ratio; memLevel=9 uses maximum memory
|
||||
for optimal speed. The default value is 8. See zconf.h for total memory
|
||||
usage as a function of windowBits and memLevel.
|
||||
|
||||
The strategy parameter is used to tune the compression algorithm. Use
|
||||
the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
|
||||
produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman
|
||||
encoding only (no string match). Filtered data consists mostly of small
|
||||
values with a somewhat random distribution. In this case, the
|
||||
compression algorithm is tuned to compress them better. The strategy
|
||||
parameter only affects the compression ratio but not the correctness of
|
||||
the compressed output even if it is not set appropriately.
|
||||
|
||||
The minCompression parameter specifies the minimum reduction in size
|
||||
required for a compressed block to be output when Z_PACKET_FLUSH is
|
||||
used (see the description of deflate above).
|
||||
|
||||
If next_in is not null, the library will use this buffer to hold also
|
||||
some history information; the buffer must either hold the entire input
|
||||
data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
|
||||
is null, the library will allocate its own history buffer (and leave next_in
|
||||
null). next_out need not be provided here but must be provided by the
|
||||
application for the next call of deflate().
|
||||
|
||||
If the history buffer is provided by the application, next_in must
|
||||
must never be changed by the application since the compressor maintains
|
||||
information inside this buffer from call to call; the application
|
||||
must provide more input only by increasing avail_in. next_in is always
|
||||
reset by the library in this case.
|
||||
|
||||
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
|
||||
not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
|
||||
an invalid method). msg is set to null if there is no error message.
|
||||
deflateInit2 does not perform any compression: this will be done by
|
||||
deflate().
|
||||
*/
|
||||
|
||||
extern int deflateCopy OF((z_stream *dest,
|
||||
z_stream *source));
|
||||
/*
|
||||
Sets the destination stream as a complete copy of the source stream. If
|
||||
the source stream is using an application-supplied history buffer, a new
|
||||
buffer is allocated for the destination stream. The compressed output
|
||||
buffer is always application-supplied. It's the responsibility of the
|
||||
application to provide the correct values of next_out and avail_out for the
|
||||
next call of deflate.
|
||||
|
||||
This function is useful when several compression strategies will be
|
||||
tried, for example when there are several ways of pre-processing the input
|
||||
data with a filter. The streams that will be discarded should then be freed
|
||||
by calling deflateEnd. Note that deflateCopy duplicates the internal
|
||||
compression state which can be quite large, so this strategy is slow and
|
||||
can consume lots of memory.
|
||||
|
||||
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
|
||||
(such as zalloc being NULL). msg is left unchanged in both source and
|
||||
destination.
|
||||
*/
|
||||
|
||||
extern int deflateReset OF((z_stream *strm));
|
||||
/*
|
||||
This function is equivalent to deflateEnd followed by deflateInit,
|
||||
but does not free and reallocate all the internal compression state.
|
||||
The stream will keep the same compression level and any other attributes
|
||||
that may have been set by deflateInit2.
|
||||
|
||||
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
extern int inflateInit2 OF((z_stream *strm,
|
||||
int windowBits));
|
||||
/*
|
||||
This is another version of inflateInit with more compression options. The
|
||||
fields next_out, zalloc and zfree must be initialized before by the caller.
|
||||
|
||||
The windowBits parameter is the base two logarithm of the maximum window
|
||||
size (the size of the history buffer). It should be in the range 8..15 for
|
||||
this version of the library (the value 16 will be allowed soon). The
|
||||
default value is 15 if inflateInit is used instead. If a compressed stream
|
||||
with a larger window size is given as input, inflate() will return with
|
||||
the error code Z_DATA_ERROR instead of trying to allocate a larger window.
|
||||
|
||||
If next_out is not null, the library will use this buffer for the history
|
||||
buffer; the buffer must either be large enough to hold the entire output
|
||||
data, or have at least 1<<windowBits bytes. If next_out is null, the
|
||||
library will allocate its own buffer (and leave next_out null). next_in
|
||||
need not be provided here but must be provided by the application for the
|
||||
next call of inflate().
|
||||
|
||||
If the history buffer is provided by the application, next_out must
|
||||
never be changed by the application since the decompressor maintains
|
||||
history information inside this buffer from call to call; the application
|
||||
can only reset next_out to the beginning of the history buffer when
|
||||
avail_out is zero and all output has been consumed.
|
||||
|
||||
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
|
||||
not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
|
||||
windowBits < 8). msg is set to null if there is no error message.
|
||||
inflateInit2 does not perform any decompression: this will be done by
|
||||
inflate().
|
||||
*/
|
||||
|
||||
extern int inflateSync OF((z_stream *strm));
|
||||
/*
|
||||
Skips invalid compressed data until the special marker (see deflate()
|
||||
above) can be found, or until all available input is skipped. No output
|
||||
is provided.
|
||||
|
||||
inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
|
||||
if no more input was provided, Z_DATA_ERROR if no marker has been found,
|
||||
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
|
||||
case, the application may save the current current value of total_in which
|
||||
indicates where valid compressed data was found. In the error case, the
|
||||
application may repeatedly call inflateSync, providing more input each time,
|
||||
until success or end of the input data.
|
||||
*/
|
||||
|
||||
extern int inflateReset OF((z_stream *strm));
|
||||
/*
|
||||
This function is equivalent to inflateEnd followed by inflateInit,
|
||||
but does not free and reallocate all the internal decompression state.
|
||||
The stream will keep attributes that may have been set by inflateInit2.
|
||||
|
||||
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
extern int inflateIncomp OF((z_stream *strm));
|
||||
/*
|
||||
This function adds the data at next_in (avail_in bytes) to the output
|
||||
history without performing any output. There must be no pending output,
|
||||
and the decompressor must be expecting to see the start of a block.
|
||||
Calling this function is equivalent to decompressing a stored block
|
||||
containing the data at next_in (except that the data is not output).
|
||||
*/
|
||||
|
||||
/* checksum functions */
|
||||
|
||||
/*
|
||||
This function is not related to compression but is exported
|
||||
anyway because it might be useful in applications using the
|
||||
compression library.
|
||||
*/
|
||||
|
||||
extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
|
||||
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
return the updated checksum. If buf is NULL, this function returns
|
||||
the required initial value for the checksum.
|
||||
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
|
||||
much faster. Usage example:
|
||||
|
||||
uLong adler = adler32(0L, Z_NULL, 0);
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
adler = adler32(adler, buffer, length);
|
||||
}
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
|
||||
#ifndef _Z_UTIL_H
|
||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||
#endif
|
||||
|
||||
#endif /* _ZLIB_H */
|
||||
989
loadparm.c
989
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
|
||||
])
|
||||
27
m4/header_major_fixed.m4
Normal file
27
m4/header_major_fixed.m4
Normal file
@@ -0,0 +1,27 @@
|
||||
AC_DEFUN([AC_HEADER_MAJOR_FIXED],
|
||||
[AC_CACHE_CHECK(whether sys/types.h defines makedev,
|
||||
ac_cv_header_sys_types_h_makedev,
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <sys/types.h>]],
|
||||
[[return makedev(0, 0);]])],
|
||||
[if grep sys/sysmacros.h conftest.err >/dev/null; then
|
||||
ac_cv_header_sys_types_h_makedev=no
|
||||
else
|
||||
ac_cv_header_sys_types_h_makedev=yes
|
||||
fi],
|
||||
[ac_cv_header_sys_types_h_makedev=no])
|
||||
])
|
||||
|
||||
if test $ac_cv_header_sys_types_h_makedev = no; then
|
||||
AC_CHECK_HEADER(sys/mkdev.h,
|
||||
[AC_DEFINE(MAJOR_IN_MKDEV, 1,
|
||||
[Define to 1 if `major', `minor', and `makedev' are
|
||||
declared in <mkdev.h>.])])
|
||||
|
||||
if test $ac_cv_header_sys_mkdev_h = no; then
|
||||
AC_CHECK_HEADER(sys/sysmacros.h,
|
||||
[AC_DEFINE(MAJOR_IN_SYSMACROS, 1,
|
||||
[Define to 1 if `major', `minor', and `makedev'
|
||||
are declared in <sysmacros.h>.])])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
45
m4/socklen_t.m4
Normal file
45
m4/socklen_t.m4
Normal file
@@ -0,0 +1,45 @@
|
||||
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
|
||||
dnl have to test to find something that will work.
|
||||
|
||||
dnl This is no good, because passing the wrong pointer on C compilers is
|
||||
dnl likely to only generate a warning, not an error. We don't call this at
|
||||
dnl the moment.
|
||||
|
||||
AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
[
|
||||
AC_CHECK_TYPE([socklen_t], ,[
|
||||
AC_MSG_CHECKING([for socklen_t equivalent])
|
||||
AC_CACHE_VAL([rsync_cv_socklen_t_equiv],
|
||||
[
|
||||
# Systems have either "struct sockaddr *" or
|
||||
# "void *" as the second argument to getpeername
|
||||
rsync_cv_socklen_t_equiv=
|
||||
for arg2 in "struct sockaddr" void; do
|
||||
for t in int size_t unsigned long "unsigned long"; do
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getpeername (int, $arg2 *, $t *);
|
||||
]],[[
|
||||
$t len;
|
||||
getpeername(0,0,&len);
|
||||
]])],[
|
||||
rsync_cv_socklen_t_equiv="$t"
|
||||
break
|
||||
])
|
||||
done
|
||||
done
|
||||
|
||||
if test "x$rsync_cv_socklen_t_equiv" = x; then
|
||||
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT($rsync_cv_socklen_t_equiv)
|
||||
AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv,
|
||||
[type to use in place of socklen_t if not defined])],
|
||||
[#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"
|
||||
])
|
||||
518
match.c
518
match.c
@@ -1,281 +1,445 @@
|
||||
/*
|
||||
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-2020 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 xfersum_type;
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
|
||||
extern int remote_version;
|
||||
|
||||
typedef unsigned short tag;
|
||||
|
||||
#define TABLESIZE (1<<16)
|
||||
#define NULL_TAG ((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 int data_transfer;
|
||||
static int64 data_transfer;
|
||||
|
||||
static int total_false_alarms;
|
||||
static int total_tag_hits;
|
||||
static int total_hash_hits;
|
||||
static int total_matches;
|
||||
static int64 total_data_transfer;
|
||||
|
||||
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 tag *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 = (tag *)malloc(sizeof(tag)*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);
|
||||
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<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;
|
||||
|
||||
|
||||
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
OFF_T offset,int i)
|
||||
/* 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,
|
||||
* or when we get bored of accumulating literal data and just need to
|
||||
* transmit it. As a result of this second case, it is called even if
|
||||
* we have not matched at all!
|
||||
*
|
||||
* 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;
|
||||
int j;
|
||||
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
|
||||
int32 j;
|
||||
|
||||
if (verbose > 2 && i >= 0)
|
||||
rprintf(FINFO,"match at %d last_match=%d j=%d len=%d n=%d\n",
|
||||
(int)offset,(int)last_match,i,(int)s->sums[i].len,(int)n);
|
||||
|
||||
send_token(f,i,buf,last_match,n,i==-1?0:s->sums[i].len);
|
||||
data_transfer += n;
|
||||
|
||||
if (n > 0)
|
||||
write_flush(f);
|
||||
|
||||
if (i >= 0)
|
||||
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);
|
||||
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);
|
||||
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) {
|
||||
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 && INFO_GTE(PROGRESS, 1))
|
||||
show_progress(last_match, 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;
|
||||
int j,k;
|
||||
int end;
|
||||
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;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"hash search b=%d len=%d\n",s->n,(int)len);
|
||||
/* want_i is used to encourage adjacent matches, allowing the RLL
|
||||
* coding of the output to work more efficiently. */
|
||||
want_i = 0;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "hash search b=%ld len=%s\n",
|
||||
(long)s->blength, big_num(len));
|
||||
}
|
||||
|
||||
k = (int32)MIN(len, (OFF_T)s->blength);
|
||||
|
||||
map = (schar *)map_ptr(buf, 0, k);
|
||||
|
||||
k = MIN(len, 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=%d len=%d count=%d\n",
|
||||
s->n,(int)len,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=%d sum=%08x\n",(int)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<s->count && targets[j].t == t; j++) {
|
||||
int i = targets[j].i;
|
||||
|
||||
if (sum != s->sums[i].sum1) continue;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"potential match at %d target=%d %d sum=%08x\n",
|
||||
(int)offset,j,i,sum);
|
||||
|
||||
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 (!done_csum2) {
|
||||
int l = MIN(s->n,len-offset);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
match comes a long way after last
|
||||
match. The 3 reads are caused by the
|
||||
running match, the checksum update and the
|
||||
literal send. */
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
|
||||
/**
|
||||
* Scan through a origin file, looking for sections that match
|
||||
* checksums from the generator, and transmit either literal or token
|
||||
* data.
|
||||
*
|
||||
* Also calculates the MD4 checksum of the whole file, using the md
|
||||
* accumulator. This is transmitted with the file as protection
|
||||
* against corruption on the wire.
|
||||
*
|
||||
* @param s Checksums received from the generator. If <tt>s->count ==
|
||||
* 0</tt>, then there are actually no checksums for this file.
|
||||
*
|
||||
* @param len Length of the file to send.
|
||||
**/
|
||||
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
{
|
||||
char file_sum[MD4_SUM_LENGTH];
|
||||
int sum_len;
|
||||
|
||||
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(xfersum_type, 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 {
|
||||
matched(f,s,buf,len,-1);
|
||||
OFF_T j;
|
||||
/* by doing this in pieces we avoid too many seeks */
|
||||
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);
|
||||
sum_len = sum_end(sender_file_sum);
|
||||
|
||||
if (remote_version >= 14) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending file_sum\n");
|
||||
write_buf(f,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 < sum_len && sender_file_sum[i] == 0; i++) {}
|
||||
memset(sender_file_sum, 0, sum_len);
|
||||
if (i == sum_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, sum_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;
|
||||
total_data_transfer += data_transfer;
|
||||
stats.literal_data += data_transfer;
|
||||
}
|
||||
|
||||
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=%ld\n",
|
||||
total_matches,total_tag_hits,
|
||||
total_false_alarms,(long)total_data_transfer);
|
||||
"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));
|
||||
}
|
||||
|
||||
35
maybe-make-man
Executable file
35
maybe-make-man
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# != 1 ]; then
|
||||
echo "Usage: $0 NAME.NUM.md" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
inname="$1"
|
||||
srcdir=`dirname "$0"`
|
||||
flagfile="$srcdir/.md2man-works"
|
||||
|
||||
if [ ! -f "$flagfile" ]; then
|
||||
# We test our smallest manpage just to see if the python setup works.
|
||||
if "$srcdir/md-convert" --test "$srcdir/rsync-ssl.1.md" >/dev/null 2>&1; then
|
||||
touch $flagfile
|
||||
else
|
||||
outname=`echo "$inname" | sed 's/\.md$//'`
|
||||
if [ -f "$outname" ]; then
|
||||
exit 0
|
||||
elif [ -f "$srcdir/$outname" ]; then
|
||||
echo "Copying $srcdir/$outname"
|
||||
cp -p "$srcdir/$outname" .
|
||||
exit 0
|
||||
else
|
||||
echo "ERROR: $outname cannot be created."
|
||||
if [ -f "$HOME/build_farm/build_test.fns" ]; then
|
||||
exit 0 # No exit errorno to avoid a build failure in the samba build farm
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
"$srcdir/md-convert" "$srcdir/$inname"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user