mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
666 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
594fe5e1cc | ||
|
|
9fb21d2882 | ||
|
|
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 |
@@ -1,9 +1,15 @@
|
||||
ID
|
||||
Makefile
|
||||
autom4te.cache
|
||||
confdefs.h
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
conftest.c
|
||||
conftest.log
|
||||
dox
|
||||
getgroups
|
||||
gmon.out
|
||||
rsync
|
||||
shconfig
|
||||
@@ -12,4 +18,7 @@ tests-dont-exist
|
||||
testtmp
|
||||
testtmp.*
|
||||
tls
|
||||
trimslash
|
||||
t_unsafe
|
||||
wildtest
|
||||
zlib/dummy
|
||||
|
||||
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 =
|
||||
22
INSTALL
22
INSTALL
@@ -11,11 +11,21 @@ to ./configure. To see them, use:
|
||||
|
||||
As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
|
||||
cut-down copy of release 1.5 is included in the rsync distribution,
|
||||
and will be used it there is no popt library on your build host, or if
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
-----------
|
||||
|
||||
@@ -38,5 +48,15 @@ completely implement the "New Sockets" API.
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
|
||||
IPv6 yet. If your build fails, try again with --disable-ipv6.
|
||||
|
||||
There is an unresolved problem with the OSX implimentation
|
||||
of setgroups causing rsyncd to fail. The workaround is to
|
||||
#undef HAVE_SETGROUPS in config.h
|
||||
|
||||
IBM AIX NOTES
|
||||
-------------
|
||||
|
||||
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
|
||||
The workaround is to append the below to config.h
|
||||
#ifdef _LARGE_FILES
|
||||
#undef HAVE_SECURE_MKSTEMP
|
||||
#endif
|
||||
|
||||
143
Makefile.in
143
Makefile.in
@@ -9,9 +9,12 @@ mandir=@mandir@
|
||||
LIBS=@LIBS@
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
|
||||
INSTALLCMD=@INSTALL@
|
||||
INSTALLMAN=@INSTALL@
|
||||
|
||||
srcdir=@srcdir@
|
||||
VPATH=$(srcdir)
|
||||
@@ -22,77 +25,109 @@ VERSION=@VERSION@
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o \
|
||||
@LIBOBJS@
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h
|
||||
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o @LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
|
||||
main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
|
||||
fileio.o batch.o clientname.o
|
||||
OBJS3=progress.o pipe.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
|
||||
tls_OBJ = tls.o syscall.o lib/permstring.o
|
||||
TLS_OBJ = tls.o syscall.o lib/permstring.o
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync tls
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) \
|
||||
trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
|
||||
|
||||
# Objects for CHECK_PROGS to clean
|
||||
CHECK_OBJS=getgroups.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:
|
||||
@OBJ_SAVE@
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
@OBJ_RESTORE@
|
||||
|
||||
all: rsync
|
||||
all: rsync$(EXEEXT)
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
|
||||
install: all
|
||||
-mkdir -p ${bindir}
|
||||
${INSTALLCMD} -m 755 rsync ${bindir}
|
||||
-mkdir -p ${mandir}/man1
|
||||
-mkdir -p ${mandir}/man5
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsync.1 ${mandir}/man1
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsyncd.conf.5 ${mandir}/man5
|
||||
-mkdir -p ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-mkdir -p ${DESTDIR}${mandir}/man1
|
||||
-mkdir -p ${DESTDIR}${mandir}/man5
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
|
||||
$(MAKE) STRIP='-s' install
|
||||
|
||||
rsync: $(OBJS)
|
||||
@echo "Please ignore warnings below about mktemp -- it is used in a safe way"
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
rsync$(EXEEXT): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
$(OBJS): config.h
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
tls: $(tls_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)
|
||||
tls$(EXEEXT): $(TLS_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
|
||||
|
||||
Makefile: Makefile.in configure config.status
|
||||
echo "WARNING: You need to run ./config.status --recheck"
|
||||
getgroups$(EXEEXT): getgroups.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
|
||||
|
||||
TRIMSLASH_OBJ = trimslash.o syscall.o
|
||||
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
|
||||
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o
|
||||
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
# I don't like these rules because CVS can skew the timestamps and
|
||||
# produce spurious warnings, and also make "make install" fail if the
|
||||
# source directory can no longer be found. Since we don't rebuild
|
||||
# automatically they're kind of lame anyhow.
|
||||
|
||||
#Makefile: Makefile.in configure config.status
|
||||
# echo "WARNING: You need to run ./config.status --recheck"
|
||||
|
||||
# don't actually run autoconf, just issue a warning
|
||||
configure: configure.in
|
||||
echo "WARNING: you need to rerun autoconf"
|
||||
#configure: configure.in
|
||||
# echo "WARNING: you need to rerun autoconf"
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
$(srcdir)/rsync.1: $(srcdir)/rsync.yo
|
||||
yodl2man -o $(srcdir)/rsync.1 $(srcdir)/rsync.yo
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
$(srcdir)/rsyncd.conf.5: $(srcdir)/rsyncd.conf.yo
|
||||
yodl2man -o $(srcdir)/rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
|
||||
|
||||
proto:
|
||||
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
|
||||
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk > $(srcdir)/proto.h
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
|
||||
rm -rf ./testtmp
|
||||
rm -f config.cache
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
|
||||
|
||||
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.
|
||||
distclean: clean
|
||||
rm -f Makefile config.h config.status
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
|
||||
|
||||
rm -f config.cache config.log
|
||||
rm -f $(srcdir)/config.cache $(srcdir)/config.log
|
||||
|
||||
rm -f shconfig $(srcdir)/shconfig
|
||||
|
||||
# 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
|
||||
@@ -100,7 +135,7 @@ distclean: clean
|
||||
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
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
|
||||
# 'check' is the GNU name, 'test' is the name for everybody else :-)
|
||||
.PHONY: check test
|
||||
@@ -122,13 +157,41 @@ test: check
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
wildtest.o: wildtest.c lib/wildmatch.c rsync.h
|
||||
wildtest$(EXEEXT): wildtest.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o @BUILD_POPT@ $(LIBS)
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
# if you want.
|
||||
|
||||
installcheck: $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
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
|
||||
|
||||
|
||||
rsync.dvi: doc/rsync.texinfo
|
||||
texi2dvi -o $@ $<
|
||||
|
||||
rsync.ps: rsync.dvi
|
||||
dvips -ta4 -o $@ $<
|
||||
|
||||
rsync.pdf: doc/rsync.texinfo
|
||||
texi2dvi -o $@ --pdf $<
|
||||
|
||||
|
||||
doxygen:
|
||||
cd $(srcdir) && rm dox/html/* && doxygen
|
||||
|
||||
# for maintainers only
|
||||
doxygen-upload:
|
||||
rsync -avzv $(srcdir)/dox/html/ --delete \
|
||||
samba.org:/home/httpd/html/rsync/doxygen/head/
|
||||
|
||||
113
NEWS
113
NEWS
@@ -1,34 +1,99 @@
|
||||
rsync 2.5.2 (???)
|
||||
NEWS for rsync version 2.5.7:
|
||||
|
||||
SECURITY FIXES:
|
||||
SECURITY:
|
||||
|
||||
* Signedness security patch from Sebastian Krahmer
|
||||
<krahmer@suse.de> -- in some cases we were not sufficiently
|
||||
careful about reading integers from the network.
|
||||
* Fix buffer handling bugs. (Andrew Tridgell, Martin Pool, Paul
|
||||
Russell, Andrea Barisani)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix possible string mangling in log files.
|
||||
|
||||
* Fix for setting local address of outgoing sockets.
|
||||
|
||||
* Better handling of hardlinks and devices on platforms with
|
||||
64-bit dev_t or ino_t.
|
||||
|
||||
* Name resolution on machines supporting IPv6 is improved.
|
||||
NEWS for rsync version 2.5.6, aka the dwd-between-jobs release
|
||||
Changes since version 2.5.5:
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* With -v, rsync now shows the command used to initiate an ssh/rsh
|
||||
connection.
|
||||
* The --delete-after option now implies --delete. (Wayne Davison)
|
||||
|
||||
* --statistics now shows memory heap usage on platforms that
|
||||
support mallinfo().
|
||||
* The --suffix option can now be used with --backup-dir. (Michael
|
||||
Zimmerman)
|
||||
|
||||
* "The Ted T'so school of program optimization": make progress
|
||||
visible and people will think it's faster. (With --progress,
|
||||
rsync will show you how many files it has seen as it builds the
|
||||
file_list, giving some indication that it has not hung.)
|
||||
* Combining "::" syntax with the -rsh/-e option now uses the
|
||||
specified remote-shell as a transport to talk to a (newly-spawned)
|
||||
server-daemon. This allows someone to use daemon features, such
|
||||
as modules, over a secure protocol, such as ssh. (JD Paul)
|
||||
|
||||
* Improvements to batch mode support. This is still experimental
|
||||
but testing would be welcome. (Jos Backus)
|
||||
* The rsync:// syntax for daemon connections is now accepted in the
|
||||
destination field.
|
||||
|
||||
* If the file name given to --include-from or --exclude-from is "-",
|
||||
rsync will read from standard input. (J.W. Schultz)
|
||||
|
||||
* New option --link-dest which is like --compare-dest except that
|
||||
unchanged files are hard-linked in to the destination directory.
|
||||
(J.W. Schultz)
|
||||
|
||||
* Don't report an error if an excluded file disappears during an
|
||||
rsync run. (Eugene Chupriyanov and Bo Kersey)
|
||||
|
||||
* Added .svn to --cvs-exclude list to support subversion. (Jon
|
||||
Middleton)
|
||||
|
||||
* Properly support IPv6 addresses in the rsyncd.conf "hosts allow"
|
||||
and "hosts deny" fields. (Hideaki Yoshifuji)
|
||||
|
||||
* Changed exclude file handling to permit DOS or MAC style line
|
||||
terminations. (J.W. Schultz)
|
||||
|
||||
* Ignore errors from chmod when -p/-a/--preserve-perms is not set.
|
||||
(Dave Dykstra)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix "forward name lookup failed" errors on AIX 4.3.3. (John
|
||||
L. Allen, Martin Pool)
|
||||
|
||||
* Generate each file's rolling-checksum data as we send it, not
|
||||
in a separate (memory-eating) pass before hand. This prevents
|
||||
timeout errors on really large files. (Stefan Nehlsen)
|
||||
|
||||
* Fix compilation on Tru64. (Albert Chin, Zoong Pham)
|
||||
|
||||
* Better handling of some client-server errors. (Martin Pool)
|
||||
|
||||
* Fixed a crash that would occur when sending a list of files that
|
||||
contains a duplicate name (if it sorts to the end of the file
|
||||
list) and using --delete. (Wayne Davison)
|
||||
|
||||
* Fixed the file-name duplicate-removal code when dealing with multiple
|
||||
dups in a row. (Wayne Davison)
|
||||
|
||||
* Fixed a bug that caused rsync to lose the exit status of its child
|
||||
processes and sometimes return an exit code of 0 instead of showing
|
||||
an error. (David R. Staples, Dave Dykstra)
|
||||
|
||||
* Fixed bug in --copy-unsafe-links that caused it to be completely
|
||||
broken. (Dave Dykstra)
|
||||
|
||||
* Prevent infinite recursion in cleanup code under certain circumstances.
|
||||
(Sviatoslav Sviridov and Marc Espie)
|
||||
|
||||
* Fixed a bug that prevented rsync from creating intervening directories
|
||||
when --relative-paths/-R is set. (Craig Barratt)
|
||||
|
||||
* Prevent "Connection reset by peer" messages from Cygwin. (Randy O'Meara)
|
||||
|
||||
INTERNAL:
|
||||
|
||||
* Many code cleanups and improved internal documentation. (Martin
|
||||
Pool, Nelson Beebe)
|
||||
|
||||
* Portability fixes. (Dave Dykstra and Wayne Davison)
|
||||
|
||||
* More test cases. (Martin Pool)
|
||||
|
||||
* Some test-case fixes. (Brian Poole, Wayne Davison)
|
||||
|
||||
* Updated included popt to the latest vendor drop, version 1.6.4.
|
||||
(Jos Backus)
|
||||
|
||||
* Updated config.guess and config.sub to latest versions; this
|
||||
means rsync should build on more platforms. (Paul Green)
|
||||
|
||||
194
OLDNEWS
194
OLDNEWS
@@ -1,4 +1,156 @@
|
||||
rsync 2.5.5 "Snowy River" (2 April 2002)
|
||||
protocol: 26 (unchanged)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* With --progress, when a transfer is complete show the time taken;
|
||||
otherwise show expected time to complete. (Cameron Simpson)
|
||||
|
||||
* Make "make install-strip" works properly, and "make install"
|
||||
accepts a DESTDIR variable for help in building binary packages.
|
||||
(Peter Breitenlohner, Greg Louis)
|
||||
|
||||
* If configured with --enable-maintainer-mode, then on receipt of
|
||||
a fatal signal rsync will try to open an xterm running gdb,
|
||||
similarly to Samba's "panic action" or GNOME's bug-buddy.
|
||||
(Martin Pool)
|
||||
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix situation where failure to fork (e.g. because out of process
|
||||
slots) would cause rsync to kill all processes owned by the
|
||||
current user. Yes, really! (Paul Haas, Martin Pool)
|
||||
|
||||
* Fix test suite on Solaris. (Jos Backus, Martin Pool)
|
||||
|
||||
* Fix minor memory leak in socket code. (Dave Dykstra, Martin
|
||||
Pool.)
|
||||
|
||||
* Fix --whole-file problem that caused it to be the default even
|
||||
for remote connections. (Martin Pool, Frank Schulz)
|
||||
|
||||
* Work around bug in Mac OS X mkdir(2), which cannot handle
|
||||
trailing slashes.
|
||||
<http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html>
|
||||
(Martin Pool)
|
||||
|
||||
* Improved network error handling. (Greg A. Woods)
|
||||
|
||||
|
||||
rsync 2.5.4 (13 March 2002)
|
||||
protocol: 26 (unchanged)
|
||||
|
||||
"Imitation lizard skin"
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Additional fix for zlib double-free bug. (Martin Pool, Andrew
|
||||
Tridgell) (CVE CAN-2002-0059)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* Merge in changes from zlib 1.1.3 to zlib 1.1.4. (Jos Backus)
|
||||
(Note that rsync still uses a custom version of zlib; you can
|
||||
not just link against a system library. See zlib/README.rsync)
|
||||
|
||||
* Additional test cases for --compress. (Martin Pool)
|
||||
|
||||
|
||||
rsync 2.5.3 (11 March 2002)
|
||||
protocol: 26 (unchanged)
|
||||
|
||||
"Happy 26"
|
||||
|
||||
SECURITY FIXES:
|
||||
|
||||
* Make sure that supplementary groups are removed from a server
|
||||
process after changing uid and gid. (Ethan Benson) (Debian bug
|
||||
#132272, CVE CAN-2002-0080)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix zlib double-free bug. (Owen Taylor, Mark J Cox) (CVE
|
||||
CAN-2002-0059)
|
||||
|
||||
* Fixed problem that in many cases caused the error message
|
||||
unexpected read size of 0 in map_ptr
|
||||
and resulted in the wrong data being copied.
|
||||
|
||||
* Fixed compilation errors on some systems caused by the use of
|
||||
"unsigned int64" in rsync.h.
|
||||
|
||||
* Fixed problem on systems such as Sunos4 that do not support realloc
|
||||
on a NULL pointer; error was "out of memory in flist_expand".
|
||||
|
||||
* Fix for rsync server processes hanging around after the client
|
||||
unexpectedly disconnects. (Colin Walters) (Debian bug #128632)
|
||||
|
||||
* Cope with BSD systems on which mkdir() will not accept a trailing
|
||||
slash.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* Merge in changes from zlib 1.1.2 to zlib 1.1.3. (Note that
|
||||
rsync still uses a custom version of zlib; you can not just link
|
||||
against a system library. See zlib/README.rsync)
|
||||
|
||||
* Command to initiate connections is only shown with -vv, rather
|
||||
than -v as in 2.5.2. Output from plain -v is more similar to
|
||||
what was historically used so as not to break scripts that try
|
||||
to parse the output.
|
||||
|
||||
* Added --no-whole-file and --no-blocking-io options (Dave Dykstra)
|
||||
|
||||
* Made the --write-batch and --read-batch options actually work
|
||||
and added documentation in the man page (Jos Backus)
|
||||
|
||||
* If the daemon is unable to fork a child to accept a connection,
|
||||
print an error message. (Colin Walters)
|
||||
|
||||
rsync 2.5.2 (26 Jan 2002)
|
||||
protocol: 26 (changed)
|
||||
|
||||
SECURITY FIXES:
|
||||
|
||||
* Signedness security patch from Sebastian Krahmer
|
||||
<krahmer@suse.de> -- in some cases we were not sufficiently
|
||||
careful about reading integers from the network.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix possible string mangling in log files.
|
||||
|
||||
* Fix for setting local address of outgoing sockets.
|
||||
|
||||
* Better handling of hardlinks and devices on platforms with
|
||||
64-bit dev_t or ino_t.
|
||||
|
||||
* Name resolution on machines supporting IPv6 is improved.
|
||||
|
||||
* Fix for device nodes. (dann frazier) (Debian #129135)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* With -v, rsync now shows the command used to initiate an ssh/rsh
|
||||
connection.
|
||||
|
||||
* --statistics now shows memory heap usage on platforms that
|
||||
support mallinfo().
|
||||
|
||||
* "The Ted T'so school of program optimization": make progress
|
||||
visible and people will think it's faster. (With --progress,
|
||||
rsync will show you how many files it has seen as it builds the
|
||||
file_list, giving some indication that it has not hung.)
|
||||
|
||||
* Improvements to batch mode support. This is still experimental
|
||||
but testing would be welcome. (Jos Backus)
|
||||
|
||||
* New --ignore-existing option, patch previously distributed with
|
||||
Vipul's Razor. (Debian #124286)
|
||||
|
||||
rsync 2.5.1 (2002-01-03)
|
||||
protocol: 25 (unchanged)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
@@ -32,7 +184,9 @@ rsync 2.5.1 (2002-01-03)
|
||||
|
||||
* Clearer error messages for some conditions.
|
||||
|
||||
|
||||
rsync 2.5.0 (2001-11-30)
|
||||
protocol: 25 (changed)
|
||||
|
||||
ANNOUNCEMENTS
|
||||
|
||||
@@ -146,3 +300,43 @@ rsync 2.5.0 (2001-11-30)
|
||||
* The existing test.sh script by Phil Hands has been merged into a
|
||||
test framework that works from both "make check" and the Samba
|
||||
build farm.
|
||||
|
||||
Partial Protocol History
|
||||
DATE RELEASE PROTOCOL
|
||||
2003/01/26 20:11:16 release-2-5-6 26
|
||||
2002/02/23 00:17:50 release-2-5-3 26
|
||||
2002/01/25 23:00:21 release-2-5-2 26
|
||||
2001/12/18 06:47:40 release-2-5-1 25
|
||||
release-2-4-6 24
|
||||
2000/08/16 08:34:18 release-2-4-5 24
|
||||
2000/07/29 04:52:05 release-2-4-4 24
|
||||
2000/03/30 14:15:00 release-2-4-2 24
|
||||
2000/01/29 23:49:36 release-2-4-1 24
|
||||
2000/01/29 02:56:37 release-2-4-0 23
|
||||
release-2-3-3 21
|
||||
1999/06/26 01:06:38 release-2-3-2 21
|
||||
release-2-3-1 20
|
||||
1999/03/15 21:17:59 release-2-3-0 20
|
||||
1998/11/15 01:21:42 release-2-2-1 19
|
||||
1998/11/03 07:08:28 release-2-2-0 19
|
||||
1998/09/09 06:31:14 release-2-1-1 19
|
||||
1998/07/17 14:43:05 release-2-0-19 19
|
||||
1998/06/18 12:17:24 release-2-0-18 19
|
||||
1998/06/18 09:51:56 release-2-0-17 19
|
||||
1998/06/01 03:42:22 release-2-0-16 19
|
||||
1998/05/27 13:47:34 release-2-0-13 19
|
||||
1998/05/26 14:19:00 release-2-0-12 18
|
||||
1998/05/21 05:55:33 release-2-0-11 18
|
||||
1998/05/18 08:20:34 release-2-0-9 18
|
||||
1998/05/17 05:56:33 release-2-0-8 17
|
||||
1998/05/15 07:34:21 release-2-0-2 17
|
||||
1998/05/13 15:44:11 release-2-0-0 17
|
||||
1998/04/17 06:07:26 release-1-7-4 17
|
||||
1998/04/05 06:43:55 release-1-7-2 17
|
||||
1998/03/26 04:18:57 release-1-7-0 17 MAX=30
|
||||
1998/01/13 15:57:32 release-1-6-9 15 MAX=20
|
||||
1997/12/17 11:07:30 release-1-6-7 14
|
||||
1997/12/15 18:36:21 release-1-6-4 14
|
||||
|
||||
* DATE OF COMMIT is the date the protocl change was committed
|
||||
to cvs, not the release date.
|
||||
|
||||
85
README
85
README
@@ -18,73 +18,12 @@ this package.
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Basically you use rsync just like rcp, but rsync has many additional options.
|
||||
Basically you use rsync just like rcp, but rsync has many additional
|
||||
options. To get a complete list of supported options type
|
||||
|
||||
Here is a brief description of rsync usage:
|
||||
|
||||
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
|
||||
or rsync [OPTION]... [USER@]HOST:SRC DEST
|
||||
or rsync [OPTION]... SRC [SRC]... DEST
|
||||
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
|
||||
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
|
||||
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
SRC on single-colon remote HOST will be expanded by remote shell
|
||||
SRC on server remote HOST may contain shell wildcards or multiple
|
||||
sources separated by space as long as they have same top-level
|
||||
|
||||
Options
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ suffix)
|
||||
--suffix=SUFFIX override backup suffix
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
--copy-unsafe-links copy links outside the source tree
|
||||
--safe-links ignore links outside the destination tree
|
||||
-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 (default 700)
|
||||
-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
|
||||
--delete-excluded also delete excluded files on the receiving side
|
||||
--partial keep partially transferred files
|
||||
--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
|
||||
--size-only only use file size when determining if a file should be transferred
|
||||
-T --temp-dir=DIR create temporary files in directory DIR
|
||||
--compare-dest=DIR also compare destination files relative to DIR
|
||||
-z, --compress compress file data
|
||||
--exclude=PATTERN exclude files matching PATTERN
|
||||
--exclude-from=FILE exclude patterns listed in FILE
|
||||
--include=PATTERN don't exclude files matching PATTERN
|
||||
--include-from=FILE don't exclude patterns listed in FILE
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--stats give some file transfer stats
|
||||
--progress show progress during transfer
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
--password-file=FILE get password from FILE
|
||||
-h, --help show this help screen
|
||||
rsync --help
|
||||
|
||||
and see the manual for more information.
|
||||
|
||||
|
||||
SETUP
|
||||
@@ -137,13 +76,19 @@ BUG REPORTS
|
||||
-----------
|
||||
|
||||
If you have web access then please look at
|
||||
http://rsync.samba.org/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.
|
||||
http://rsync.samba.org
|
||||
|
||||
If you don't have web access then mail bug reports to rsync@samba.org.
|
||||
That page contains links to the current bug list, and information on
|
||||
how to report a bug well. You might also like to try searching the
|
||||
internet for the error message you've received, or looking in the
|
||||
mailing list archives at
|
||||
|
||||
http://mail-archive.com/rsync@lists.samba.org/
|
||||
|
||||
Please send bug reports to
|
||||
|
||||
rsync@lists.samba.org
|
||||
|
||||
|
||||
CVS TREE
|
||||
|
||||
565
TODO
565
TODO
@@ -1,12 +1,111 @@
|
||||
-*- indented-text -*-
|
||||
|
||||
URGENT ---------------------------------------------------------------
|
||||
BUGS ---------------------------------------------------------------
|
||||
|
||||
rsync-url barfs on upload
|
||||
|
||||
rsync foo rsync://localhost/transfer/
|
||||
|
||||
Fix the parser.
|
||||
|
||||
|
||||
IMPORTANT ------------------------------------------------------------
|
||||
There seems to be a bug with hardlinks
|
||||
|
||||
mbp/2 build$ ls -l /tmp/a /tmp/b -i
|
||||
/tmp/a:
|
||||
total 32
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
|
||||
/tmp/b:
|
||||
total 32
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
mbp/2 build$ rm -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
building file list ... done
|
||||
created directory /tmp/b
|
||||
./
|
||||
a1
|
||||
a4
|
||||
a2 => a1
|
||||
a3 => a2
|
||||
wrote 350 bytes read 52 bytes 804.00 bytes/sec
|
||||
total size is 232 speedup is 0.58
|
||||
mbp/2 build$ rm -r /tmp/b
|
||||
mbp/2 build$ ls -l /tmp/b
|
||||
ls: /tmp/b: No such file or directory
|
||||
mbp/2 build$ rm -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
rm: cannot remove `/tmp/b': No such file or directory
|
||||
mbp/2 build$ rm -f -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
building file list ... done
|
||||
created directory /tmp/b
|
||||
./
|
||||
a1
|
||||
a4
|
||||
a2 => a1
|
||||
a3 => a2
|
||||
wrote 350 bytes read 52 bytes 804.00 bytes/sec
|
||||
total size is 232 speedup is 0.58
|
||||
mbp/2 build$ ls -l /tmp/b
|
||||
total 32
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
mbp/2 build$ ls -l /tmp/a
|
||||
total 32
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
|
||||
|
||||
Progress indicator can produce corrupt output when transferring directories:
|
||||
|
||||
main/binary-arm/
|
||||
main/binary-arm/admin/
|
||||
main/binary-arm/base/
|
||||
main/binary-arm/comm/8.56kB/s 0:00:52
|
||||
main/binary-arm/devel/
|
||||
main/binary-arm/doc/
|
||||
main/binary-arm/editors/
|
||||
main/binary-arm/electronics/s 0:00:53
|
||||
main/binary-arm/games/
|
||||
main/binary-arm/graphics/
|
||||
main/binary-arm/hamradio/
|
||||
main/binary-arm/interpreters/
|
||||
main/binary-arm/libs/6.61kB/s 0:00:54
|
||||
main/binary-arm/mail/
|
||||
main/binary-arm/math/
|
||||
main/binary-arm/misc/
|
||||
|
||||
|
||||
lchmod
|
||||
I don't think we handle this properly on systems that don't have the
|
||||
call. Are there any such?
|
||||
|
||||
|
||||
Cross-test versions
|
||||
|
||||
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 the cross product of versions.
|
||||
@@ -16,6 +115,39 @@ Cross-test versions
|
||||
some testing and also be the most common case for having different
|
||||
versions and not being able to upgrade.
|
||||
|
||||
--no-blocking-io might be broken
|
||||
|
||||
in the same way as --no-whole-file; somebody needs to check.
|
||||
|
||||
Do not rely on having a group called "nobody"
|
||||
|
||||
http://www.linuxbase.org/spec/refspecs/LSB_1.1.0/gLSB/usernames.html
|
||||
|
||||
On Debian it's "nogroup"
|
||||
|
||||
DAEMON --------------------------------------------------------------
|
||||
|
||||
server-imposed bandwidth limits
|
||||
|
||||
rsyncd over ssh
|
||||
|
||||
There are already some patches to do this.
|
||||
|
||||
BitKeeper uses a server whose login shell is set to bkd. That's
|
||||
probably a reasonable approach.
|
||||
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
|
||||
|
||||
--dry-run is too dry
|
||||
|
||||
Mark Santcroos points out that -n fails to list files which have
|
||||
only metadata changes, though it probably should.
|
||||
|
||||
There may be a Debian bug about this as well.
|
||||
|
||||
|
||||
use chroot
|
||||
|
||||
If the platform doesn't support it, then don't even try.
|
||||
@@ -26,12 +158,24 @@ use chroot
|
||||
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
|
||||
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
|
||||
|
||||
--files-from
|
||||
|
||||
Avoids traversal. Better option than a pile of --include statements
|
||||
for people who want to generate the file list using a find(1)
|
||||
command or a script.
|
||||
supplementary groups
|
||||
|
||||
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.
|
||||
|
||||
|
||||
File list structure in memory
|
||||
|
||||
Rather than one big array, perhaps have a tree in memory mirroring
|
||||
the directory tree.
|
||||
|
||||
This might make sorting much faster! (I'm not sure it's a big CPU
|
||||
problem, mind you.)
|
||||
|
||||
It might also reduce memory use in storing repeated directory names
|
||||
-- again I'm not sure this is a problem.
|
||||
|
||||
Performance
|
||||
|
||||
@@ -52,7 +196,7 @@ Handling duplicate names
|
||||
through the pipeline at the same time. For example we might have
|
||||
updated the first occurrence after reading the checksums for the
|
||||
second. So possibly we just need to make sure that we don't have
|
||||
both in the pipeline at the same time.
|
||||
both in the pipeline at the same time.
|
||||
|
||||
Possibly if we did one directory at a time that would be sufficient.
|
||||
|
||||
@@ -94,14 +238,11 @@ Memory accounting
|
||||
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.
|
||||
|
||||
We can try using the GNU/SVID/XPG mallinfo() function to get some
|
||||
heap statistics.
|
||||
|
||||
|
||||
Hard-link handling
|
||||
|
||||
At the moment hardlink handling is very expensive, so it's off by
|
||||
default. It does not need to be so.
|
||||
default. It does not need to be so.
|
||||
|
||||
Since most of the solutions are rather intertwined with the file
|
||||
list it is probably better to fix that first, although fixing
|
||||
@@ -115,7 +256,7 @@ Hard-link handling
|
||||
but I have not seen them.
|
||||
|
||||
When trying to reproduce hard links, we only need to worry about
|
||||
files that have more than one name (nlinks>1 && !S_ISDIR).
|
||||
files that have more than one name (nlinks>1 && !S_ISDIR).
|
||||
|
||||
The basic point of this is to discover alternate names that refer to
|
||||
the same file. All operations, including creating the file and
|
||||
@@ -165,8 +306,39 @@ Hard-link handling
|
||||
might need a little program to check whether several names refer to
|
||||
the same file.
|
||||
|
||||
IPv6
|
||||
|
||||
|
||||
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 improtant.
|
||||
|
||||
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
|
||||
|
||||
@@ -182,11 +354,11 @@ IPv6
|
||||
colons, they tend to break most naming systems, including ours.
|
||||
Based on the HTTP IPv6 syntax, I think we should use
|
||||
|
||||
rsync://[::1]/foo/bar
|
||||
[::1]::bar
|
||||
rsync://[::1]/foo/bar [::1]::bar
|
||||
|
||||
which should just take a small change to the parser code.
|
||||
|
||||
|
||||
Errors
|
||||
|
||||
If we hang or get SIGINT, then explain where we were up to. Perhaps
|
||||
@@ -196,7 +368,17 @@ Errors
|
||||
|
||||
"The dungeon collapses! You are killed." Rather than "unexpected
|
||||
eof" give a message that is more detailed if possible and also more
|
||||
helpful.
|
||||
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.
|
||||
|
||||
|
||||
File attributes
|
||||
|
||||
@@ -213,10 +395,30 @@ Empty directories
|
||||
can end up with many empty directories. We might avoid this by
|
||||
lazily creating such directories.
|
||||
|
||||
|
||||
zlib
|
||||
|
||||
Perhaps don't use our own zlib. Will we actually be incompatible,
|
||||
or just be slightly less efficient?
|
||||
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.
|
||||
|
||||
|
||||
logging
|
||||
|
||||
@@ -227,14 +429,26 @@ logging
|
||||
At the connections that just get a list of modules are not logged,
|
||||
but they should be.
|
||||
|
||||
rsyncd over ssh
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
that when we reap it and log a message.
|
||||
|
||||
Keep stderr and stdout properly separated (Debian #23626)
|
||||
|
||||
After we get the @RSYNCD greeting from the server, we know it's
|
||||
version but we have not yet sent the command line, so we could just
|
||||
remove the -z option if the server is too old.
|
||||
|
||||
For ssh invocation it's not so simple, because we actually use the
|
||||
command line to start the remote process. However, we only actually
|
||||
do compression in token.c, and we could therefore once we discover
|
||||
the remote version emit an error if it's too old. I'm not sure if
|
||||
that's a good tradeoff or not.
|
||||
|
||||
There are already some patches to do this.
|
||||
|
||||
proxy authentication
|
||||
|
||||
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
|
||||
HTTP Basic Proxy-Authentication.
|
||||
HTTP Basic Proxy-Authentication.
|
||||
|
||||
Multiple schemes are possible, up to and including the insanity that
|
||||
is NTLM, but Basic probably covers most cases.
|
||||
@@ -244,6 +458,120 @@ SOCKS
|
||||
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.
|
||||
|
||||
|
||||
Better statistics:
|
||||
|
||||
<Rasmus> mbp: 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> Rasmus: nice idea <mbp> there is --stats
|
||||
<mbp> but at the moment it's very tridge-oriented <mbp> rather than
|
||||
user-friendly <mbp> it would be nice to improve it <mbp> that would
|
||||
also work well with --dryrun
|
||||
|
||||
TDB:
|
||||
|
||||
Rather than storing the file list in memory, store it in a TDB.
|
||||
|
||||
This *might* make memory usage lower while building the file list.
|
||||
|
||||
Hashtable lookup will mean files are not transmitted in order,
|
||||
though... hm.
|
||||
|
||||
This would neatly eliminate one of the major post-fork shared data
|
||||
structures.
|
||||
|
||||
|
||||
chmod:
|
||||
|
||||
On 12 Mar 2002, Dave Dykstra <dwd@bell-labs.com> wrote: > If we
|
||||
would add an option to do that functionality, I would vote for one >
|
||||
that was more general which could mask off any set of permission bits
|
||||
and > possibly add any set of bits. Perhaps a chmod-like syntax if it
|
||||
could be > implemented simply.
|
||||
|
||||
I think that would be good too. For example, people uploading files
|
||||
to a web server might like to say
|
||||
|
||||
rsync -avzP --chmod a+rX ./ sourcefrog.net:/home/www/sourcefrog/
|
||||
|
||||
Ideally the patch would implement as many of the gnu chmod semantics
|
||||
as possible. I think the mode parser should be a separate function
|
||||
that passes back something like (mask,set) description to the rest
|
||||
of the program. For bonus points there would be a test case for the
|
||||
parser.
|
||||
|
||||
Possibly also --chown
|
||||
|
||||
(Debian #23628)
|
||||
|
||||
|
||||
--diff
|
||||
|
||||
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?
|
||||
|
||||
(Suggestion from david.e.sewell)
|
||||
|
||||
|
||||
Incorrect timestamps (Debian #100295)
|
||||
|
||||
A bit hard to believe, but apparently it happens.
|
||||
|
||||
|
||||
Check "refuse options works"
|
||||
|
||||
We need a test case for this...
|
||||
|
||||
Was this broken when we changed to popt?
|
||||
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
|
||||
MD4 file_sum
|
||||
|
||||
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.
|
||||
|
||||
Indeed for transfers over zlib or ssh we can also rely on the
|
||||
transport to have quite strong protection against corruption.
|
||||
|
||||
Perhaps we should have an option to disable this, analogous to
|
||||
--whole-file, although it would default to disabled. The file
|
||||
checksum takes up a definite space in the protocol -- we can either
|
||||
set it to 0, or perhaps just leave it out.
|
||||
|
||||
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?
|
||||
|
||||
String area code
|
||||
|
||||
Test whether this is actually faster than just using malloc(). If
|
||||
it's not (anymore), throw it out.
|
||||
|
||||
|
||||
PLATFORMS ------------------------------------------------------------
|
||||
|
||||
Win32
|
||||
@@ -252,29 +580,174 @@ Win32
|
||||
|
||||
http://sources.redhat.com/ml/cygwin/2001-08/msg00234.html
|
||||
|
||||
According to "Effective TCP/IP Programming" (??) close() on a socket
|
||||
has incorrect behaviour on Windows -- it sends a RST packet to the
|
||||
other side, which gives a "connection reset by peer" error. On that
|
||||
platform we should probably do shutdown() instead. However, on Unix
|
||||
we are correct to call close(), because shutdown() discards
|
||||
untransmitted data.
|
||||
|
||||
DEVELOPMENT ----------------------------------------------------------
|
||||
|
||||
Splint
|
||||
|
||||
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.
|
||||
|
||||
Torture test
|
||||
|
||||
Something that just keeps running rsync continuously over a data set
|
||||
likely to generate problems.
|
||||
|
||||
Cross-testing
|
||||
|
||||
Run current rsync versions against significant past releases.
|
||||
|
||||
Memory debugger
|
||||
|
||||
jra recommends Valgrind:
|
||||
|
||||
http://devel-home.kde.org/~sewardj/
|
||||
|
||||
Release script
|
||||
|
||||
Update spec files
|
||||
|
||||
Build tar file; upload
|
||||
|
||||
Send announcement to mailing list and c.o.l.a.
|
||||
|
||||
Make freshmeat announcement
|
||||
|
||||
Update web site
|
||||
|
||||
|
||||
|
||||
TESTING --------------------------------------------------------------
|
||||
|
||||
Cross-test versions
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
|
||||
Mutator program
|
||||
|
||||
Insert bytes, delete bytes, swap blocks, ...
|
||||
|
||||
configure option to enable dangerous tests
|
||||
|
||||
If tests are skipped, say why.
|
||||
|
||||
Test daemon feature to disallow particular options.
|
||||
|
||||
Pipe program that makes slow/jerky connections.
|
||||
|
||||
Versions of read() and write() that corrupt the stream, or abruptly
|
||||
fail
|
||||
|
||||
Separate makefile target to run rough tests -- or perhaps just run
|
||||
them every time?
|
||||
|
||||
Test "refuse options" works
|
||||
|
||||
What about for --recursive?
|
||||
|
||||
If you specify an unrecognized option here, you should get an error.
|
||||
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
|
||||
Update README
|
||||
|
||||
Keep list of open issues and todos on the web site
|
||||
|
||||
Update web site from CVS
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
BUILD FARM -----------------------------------------------------------
|
||||
|
||||
Add machines
|
||||
|
||||
AMDAHL UTS (Dave Dykstra)
|
||||
|
||||
Cygwin (on different versions of Win32?)
|
||||
|
||||
HP-UX variants (via HP?)
|
||||
|
||||
SCO
|
||||
|
||||
|
||||
LOGGING --------------------------------------------------------------
|
||||
|
||||
Perhaps flush stdout after each filename, so that people trying to
|
||||
monitor progress in a log file can do so more easily. See
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
|
||||
|
||||
At the connections that just get a list of modules are not logged,
|
||||
but they should be.
|
||||
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
that when we reap it and log a message.
|
||||
|
||||
Keep stderr and stdout properly separated (Debian #23626)
|
||||
|
||||
Use a separate function for reporting errors; prefix it with
|
||||
"rsync:" or "rsync(remote)", or perhaps even "rsync(local
|
||||
generator): ".
|
||||
|
||||
verbose output
|
||||
|
||||
Indicate whether files are new, updated, or deleted
|
||||
|
||||
At end of transfer, show how many files were or were not transferred
|
||||
correctly.
|
||||
|
||||
-vv
|
||||
|
||||
Explain *why* every file is transferred or not (e.g. "local mtime
|
||||
123123 newer than 1283198")
|
||||
|
||||
|
||||
debugging of daemon
|
||||
|
||||
Add an rsyncd.conf parameter to turn on debugging on the server.
|
||||
|
||||
|
||||
|
||||
NICE -----------------------------------------------------------------
|
||||
|
||||
--no-detach and --no-fork options
|
||||
@@ -285,20 +758,18 @@ NICE -----------------------------------------------------------------
|
||||
|
||||
hang/timeout friendliness
|
||||
|
||||
verbose output
|
||||
|
||||
Indicate whether files are new, updated, or deleted
|
||||
|
||||
internationalization
|
||||
|
||||
Change to using gettext(). Probably need to ship this for platforms
|
||||
that don't have it.
|
||||
that don't have it.
|
||||
|
||||
Solicit translations.
|
||||
|
||||
Does anyone care?
|
||||
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.
|
||||
|
||||
rsyncsh
|
||||
rsyncsh
|
||||
|
||||
Write a small emulation of interactive ftp as a Pythonn program
|
||||
that calls rsync. Commands such as "cd", "ls", "ls *.c" etc map
|
||||
@@ -306,4 +777,22 @@ rsyncsh
|
||||
current host, directory and so on. We can probably even do
|
||||
completion of remote filenames.
|
||||
|
||||
%K%
|
||||
|
||||
RELATED PROJECTS -----------------------------------------------------
|
||||
|
||||
http://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.
|
||||
|
||||
|
||||
|
||||
194
access.c
194
access.c
@@ -27,57 +27,185 @@
|
||||
static int match_hostname(char *host, char *tok)
|
||||
{
|
||||
if (!host || !*host) return 0;
|
||||
return (fnmatch(tok, host, 0) == 0);
|
||||
return wildmatch(tok, host);
|
||||
}
|
||||
|
||||
static int match_binary(char *b1, char *b2, 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(char *addr, char *tok)
|
||||
{
|
||||
char *p;
|
||||
unsigned long a, t, mask = (unsigned long)~0;
|
||||
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;
|
||||
unsigned int len;
|
||||
|
||||
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 = '/';
|
||||
*p = '\0';
|
||||
len = p - tok;
|
||||
}
|
||||
else
|
||||
len = strlen(tok);
|
||||
|
||||
if (t == INADDR_NONE) {
|
||||
rprintf(FERROR,"malformed address %s\n", tok);
|
||||
/* Fail quietly if tok is a hostname (not an address) */
|
||||
if (strspn(tok, ".0123456789") != len
|
||||
#ifdef INET6
|
||||
&& !strchr(tok, ':')
|
||||
#endif
|
||||
) 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
|
||||
|
||||
gai = getaddrinfo(addr, NULL, &hints, &resa);
|
||||
if (gai) return 0;
|
||||
|
||||
gai = getaddrinfo(tok, NULL, &hints, &rest);
|
||||
if (p)
|
||||
*p++ = '/';
|
||||
if (gai) {
|
||||
rprintf(FERROR,
|
||||
"error matching address %s: %s\n",
|
||||
tok,
|
||||
gai_strerror(gai));
|
||||
freeaddrinfo(resa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = ntohl(a);
|
||||
t = ntohl(t);
|
||||
|
||||
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) return 1;
|
||||
if (bits <= 0 || bits > 32) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
return 0;
|
||||
}
|
||||
mask &= (mask << (32-bits));
|
||||
}
|
||||
if (rest->ai_family != resa->ai_family) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return ((a&mask) == (t&mask));
|
||||
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(FERROR,"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(FERROR,"malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
for (pp = (unsigned char *)p; *pp; pp++) {
|
||||
if (!isascii(*pp) || !isdigit(*pp)) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
bits = atoi(p);
|
||||
#endif
|
||||
if (bits == 0) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
if (bits < 0 || bits > (addrlen << 3)) {
|
||||
rprintf(FERROR,"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(char *list, char *addr, char *host)
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef ENABLE_IPV6
|
||||
#undef HAVE_SOCKADDR_LEN
|
||||
#undef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
@@ -203,7 +203,7 @@ static void generate_hash(char *in, char *challenge, char *out)
|
||||
|
||||
otherwise return username
|
||||
*/
|
||||
char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
|
||||
{
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[16];
|
||||
@@ -222,9 +222,9 @@ char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
|
||||
base64_encode(challenge, 16, b64_challenge);
|
||||
|
||||
io_printf(fd,"%s%s\n", leader, b64_challenge);
|
||||
io_printf(f_out, "%s%s\n", leader, b64_challenge);
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
if (!users) return NULL;
|
||||
|
||||
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
|
||||
if (fnmatch(tok, user, 0) == 0) break;
|
||||
if (wildmatch(tok, user)) break;
|
||||
}
|
||||
free(users);
|
||||
|
||||
@@ -273,8 +273,14 @@ void auth_client(int fd, char *user, char *challenge)
|
||||
|
||||
if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
|
||||
/* XXX: cyeoh says that getpass is deprecated, because
|
||||
it may return a truncated password on some systems,
|
||||
and it is not in the LSB. */
|
||||
* it may return a truncated password on some systems,
|
||||
* and it is not in the LSB.
|
||||
*
|
||||
* Andrew Klein says that getpassphrase() is present
|
||||
* on Solaris and reads up to 256 characters.
|
||||
*
|
||||
* OpenBSD has a readpassphrase() that might be more suitable.
|
||||
*/
|
||||
pass = getpass("Password: ");
|
||||
}
|
||||
|
||||
|
||||
222
backup.c
222
backup.c
@@ -21,10 +21,11 @@
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int backup_suffix_len;
|
||||
extern int backup_dir_len;
|
||||
extern char *backup_suffix;
|
||||
extern char *backup_dir;
|
||||
|
||||
|
||||
extern int am_root;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_links;
|
||||
@@ -34,20 +35,20 @@ extern int preserve_hard_links;
|
||||
static int make_simple_backup(char *fname)
|
||||
{
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
if (strlen(fname) + backup_suffix_len > MAXPATHLEN-1) {
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0) {
|
||||
snprintf(fnamebak, sizeof(fnamebak), "%s%s", fname, backup_suffix);
|
||||
if (do_rename(fname, fnamebak) != 0) {
|
||||
/* cygwin (at least version b19) reports EINVAL */
|
||||
if (errno != ENOENT && errno != EINVAL) {
|
||||
rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
|
||||
return 0;
|
||||
}
|
||||
} else if (verbose > 1) {
|
||||
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
|
||||
rprintf(FINFO, "backed up %s to %s\n", fname, fnamebak);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -80,50 +81,53 @@ static int make_dir(char *name, int mask)
|
||||
Create a directory given an absolute path, perms based upon another directory
|
||||
path
|
||||
****************************************************************************/
|
||||
static int make_bak_dir(char *fname,char *bak_path)
|
||||
static int make_bak_dir(char *fname, char *bak_path)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
STRUCT_STAT *st2;
|
||||
char fullpath[MAXPATHLEN];
|
||||
extern int orig_umask;
|
||||
char *p;
|
||||
char *q;
|
||||
STRUCT_STAT st;
|
||||
STRUCT_STAT *st2;
|
||||
char fullpath[MAXPATHLEN];
|
||||
extern int orig_umask;
|
||||
char *p;
|
||||
char *q;
|
||||
|
||||
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
|
||||
while(strncmp(bak_path, "./", 2) == 0) bak_path += 2;
|
||||
|
||||
if(bak_path[strlen(bak_path)-1]!='/') {
|
||||
snprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
|
||||
} else {
|
||||
snprintf(fullpath,sizeof(fullpath),"%s",bak_path);
|
||||
}
|
||||
p=fullpath;
|
||||
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
|
||||
strcat(fullpath,fname);
|
||||
if(bak_path[strlen(bak_path)-1] != '/') {
|
||||
snprintf(fullpath, sizeof(fullpath), "%s/", bak_path);
|
||||
} else {
|
||||
snprintf(fullpath, sizeof(fullpath), "%s", bak_path);
|
||||
}
|
||||
p = fullpath;
|
||||
q = &fullpath[strlen(fullpath)]; /* End of bak_path string */
|
||||
strcat(fullpath, fname);
|
||||
|
||||
/* Make the directories */
|
||||
while ((p=strchr(p,'/'))) {
|
||||
*p = 0;
|
||||
if(do_lstat(fullpath,&st)!=0) {
|
||||
do_mkdir(fullpath,0777 & ~orig_umask);
|
||||
if(p>q) {
|
||||
if(do_lstat(q,&st)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
|
||||
} else {
|
||||
st2=&st;
|
||||
set_modtime(fullpath,st2->st_mtime);
|
||||
if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
|
||||
};
|
||||
if(do_chmod(fullpath,st2->st_mode)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
*p = '/';
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
/* Make the directories */
|
||||
while ((p = strchr(p, '/'))) {
|
||||
*p = 0;
|
||||
if(do_lstat(fullpath, &st) != 0) {
|
||||
do_mkdir(fullpath, 0777 & ~orig_umask);
|
||||
if(p>q) {
|
||||
if(do_lstat(q, &st) != 0) {
|
||||
rprintf(FERROR, "make_bak_dir stat %s failed: %s\n",
|
||||
full_fname(fullpath), strerror(errno));
|
||||
} else {
|
||||
st2 = &st;
|
||||
set_modtime(fullpath, st2->st_mtime);
|
||||
if(do_lchown(fullpath, st2->st_uid, st2->st_gid) != 0) {
|
||||
rprintf(FERROR, "make_bak_dir chown %s failed: %s\n",
|
||||
full_fname(fullpath), strerror(errno));
|
||||
}
|
||||
if(do_chmod(fullpath, st2->st_mode) != 0) {
|
||||
rprintf(FERROR, "make_bak_dir failed to set permissions on %s: %s\n",
|
||||
full_fname(fullpath), strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*p = '/';
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* robustly move a file, creating new directory structures if necessary */
|
||||
@@ -146,7 +150,7 @@ static int robust_move(char *src, char *dst)
|
||||
if (failed) {
|
||||
if (verbose > 2)
|
||||
rprintf (FERROR, "robust_move failed: %s(%d)\n",
|
||||
strerror (errno), errno);
|
||||
strerror (errno), errno);
|
||||
switch (errno) {
|
||||
/* external filesystem */
|
||||
case EXDEV:
|
||||
@@ -155,7 +159,7 @@ static int robust_move(char *src, char *dst)
|
||||
break;
|
||||
/* no directory to write to */
|
||||
case ENOENT:
|
||||
make_dir (dst, 0755);
|
||||
make_dir(dst, 0700);
|
||||
keep_trying--;
|
||||
break;
|
||||
default:
|
||||
@@ -179,12 +183,12 @@ static int keep_backup(char *fname)
|
||||
STRUCT_STAT st;
|
||||
struct file_struct *file;
|
||||
|
||||
int kept=0;
|
||||
int kept = 0;
|
||||
int ret_code;
|
||||
|
||||
if (!initialised) {
|
||||
if (backup_dir[strlen(backup_dir) - 1] == '/')
|
||||
backup_dir[strlen(backup_dir) - 1] = 0;
|
||||
if (backup_dir_len && backup_dir[backup_dir_len - 1] == '/')
|
||||
backup_dir[--backup_dir_len] = '\0';
|
||||
if (verbose > 0)
|
||||
rprintf (FINFO, "backup_dir is %s\n", backup_dir);
|
||||
initialised = 1;
|
||||
@@ -197,79 +201,86 @@ static int keep_backup(char *fname)
|
||||
if (do_stat (fname, &st)) return 1;
|
||||
#endif
|
||||
|
||||
file = make_file(-1, fname, NULL, 1);
|
||||
file = make_file(fname, NULL, NO_EXCLUDES);
|
||||
|
||||
/* the file could have disappeared */
|
||||
if (!file) return 1;
|
||||
|
||||
/* make a complete pathname for backup file */
|
||||
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
|
||||
rprintf (FERROR, "keep_backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
|
||||
/* make a complete pathname for backup file */
|
||||
if (backup_dir_len+strlen(fname)+backup_suffix_len > MAXPATHLEN-1) {
|
||||
rprintf (FERROR, "keep_backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s%s",
|
||||
backup_dir, fname, backup_suffix);
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
/* Check to see if this is a device file, or link */
|
||||
if(IS_DEVICE(file->mode)) {
|
||||
if(am_root && preserve_devices) {
|
||||
make_bak_dir(fname,backup_dir);
|
||||
if(do_mknod(keep_name,file->mode,file->rdev)!=0) {
|
||||
rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno));
|
||||
} else {
|
||||
if(verbose>2)
|
||||
rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname);
|
||||
};
|
||||
};
|
||||
kept=1;
|
||||
do_unlink(fname);
|
||||
};
|
||||
if(IS_DEVICE(file->mode)) {
|
||||
if(am_root && preserve_devices) {
|
||||
make_bak_dir(fname, backup_dir);
|
||||
if(do_mknod(keep_name, file->mode, file->rdev) != 0) {
|
||||
rprintf(FERROR, "mknod %s failed: %s\n",
|
||||
full_fname(keep_name), strerror(errno));
|
||||
} else if(verbose>2) {
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname);
|
||||
}
|
||||
}
|
||||
kept = 1;
|
||||
do_unlink(fname);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!kept && S_ISDIR(file->mode)) {
|
||||
/* make an empty directory */
|
||||
make_bak_dir(fname,backup_dir);
|
||||
do_mkdir(keep_name,file->mode);
|
||||
ret_code=do_rmdir(fname);
|
||||
if(verbose>2)
|
||||
rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code);
|
||||
kept=1;
|
||||
};
|
||||
make_bak_dir(fname, backup_dir);
|
||||
do_mkdir(keep_name, file->mode);
|
||||
ret_code = do_rmdir(fname);
|
||||
|
||||
if(verbose>2) {
|
||||
rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
|
||||
full_fname(fname), ret_code);
|
||||
}
|
||||
kept = 1;
|
||||
}
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if(!kept && preserve_links && S_ISLNK(file->mode)) {
|
||||
extern int safe_symlinks;
|
||||
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
|
||||
keep_name,file->link);
|
||||
}
|
||||
kept=1;
|
||||
}
|
||||
make_bak_dir(fname,backup_dir);
|
||||
if(do_symlink(file->link,keep_name) != 0) {
|
||||
rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno));
|
||||
};
|
||||
do_unlink(fname);
|
||||
kept=1;
|
||||
};
|
||||
if(!kept && preserve_links && S_ISLNK(file->mode)) {
|
||||
extern int safe_symlinks;
|
||||
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n",
|
||||
full_fname(keep_name), file->link);
|
||||
}
|
||||
kept = 1;
|
||||
}
|
||||
make_bak_dir(fname, backup_dir);
|
||||
if(do_symlink(file->link, keep_name) != 0) {
|
||||
rprintf(FERROR, "link %s -> %s : %s\n",
|
||||
full_fname(keep_name), file->link, strerror(errno));
|
||||
}
|
||||
do_unlink(fname);
|
||||
kept = 1;
|
||||
}
|
||||
#endif
|
||||
if(!kept && preserve_hard_links && check_hard_link(file)) {
|
||||
if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file));
|
||||
};
|
||||
if(!kept && preserve_hard_links && check_hard_link(file)) {
|
||||
if(verbose > 1)
|
||||
rprintf(FINFO, "%s is a hard link\n", f_name(file));
|
||||
}
|
||||
|
||||
if(!kept && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname);
|
||||
}
|
||||
if(!kept && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
|
||||
fname);
|
||||
}
|
||||
|
||||
/* move to keep tree if a file */
|
||||
if(!kept) {
|
||||
if (!robust_move (fname, keep_name))
|
||||
rprintf(FERROR, "keep_backup failed %s -> %s : %s\n",
|
||||
fname, keep_name, strerror(errno));
|
||||
};
|
||||
if (!robust_move (fname, keep_name)) {
|
||||
rprintf(FERROR, "keep_backup failed: %s -> \"%s\": %s\n",
|
||||
full_fname(fname), keep_name, strerror(errno));
|
||||
}
|
||||
}
|
||||
set_perms (keep_name, file, NULL, 0);
|
||||
free_file (file);
|
||||
free (file);
|
||||
@@ -288,4 +299,3 @@ int make_backup(char *fname)
|
||||
else
|
||||
return (make_simple_backup(fname));
|
||||
}
|
||||
|
||||
|
||||
266
batch.c
266
batch.c
@@ -8,55 +8,38 @@
|
||||
#include "rsync.h"
|
||||
#include <time.h>
|
||||
|
||||
char rsync_flist_file[27] = "rsync_flist.";
|
||||
char rsync_csums_file[27] = "rsync_csums.";
|
||||
char rsync_delta_file[27] = "rsync_delta.";
|
||||
char rsync_argvs_file[27] = "rsync_argvs.";
|
||||
|
||||
char batch_file_ext[15];
|
||||
|
||||
int fdb;
|
||||
int fdb_delta;
|
||||
int fdb_open;
|
||||
int fdb_close;
|
||||
extern char *batch_prefix;
|
||||
|
||||
struct file_list *batch_flist;
|
||||
|
||||
void create_batch_file_ext()
|
||||
{
|
||||
struct tm *timeptr;
|
||||
time_t elapsed_seconds;
|
||||
static char rsync_flist_file[] = ".rsync_flist";
|
||||
static char rsync_csums_file[] = ".rsync_csums";
|
||||
static char rsync_delta_file[] = ".rsync_delta";
|
||||
static char rsync_argvs_file[] = ".rsync_argvs";
|
||||
|
||||
/* Save run date and time to use for batch file extensions */
|
||||
time(&elapsed_seconds);
|
||||
timeptr = localtime(&elapsed_seconds);
|
||||
|
||||
sprintf(batch_file_ext, "%4d%02d%02d%02d%02d%02d",
|
||||
timeptr->tm_year + 1900, timeptr->tm_mon + 1,
|
||||
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min,
|
||||
timeptr->tm_sec);
|
||||
rprintf(FINFO,"batch file extension: %s\n", batch_file_ext);
|
||||
}
|
||||
|
||||
void set_batch_file_ext(char *ext)
|
||||
{
|
||||
strcpy(batch_file_ext, ext);
|
||||
}
|
||||
static int fdb;
|
||||
static int fdb_delta;
|
||||
static int fdb_open;
|
||||
static int fdb_close;
|
||||
|
||||
void write_batch_flist_file(char *buff, int bytes_to_write)
|
||||
{
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strcat(rsync_flist_file, batch_file_ext);
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_flist_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for writing; create it if it doesn't exist */
|
||||
fdb =
|
||||
do_open(rsync_flist_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
/*
|
||||
* Open batch flist file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_flist_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -67,12 +50,11 @@ void write_batch_flist_file(char *buff, int bytes_to_write)
|
||||
|
||||
if (write(fdb, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
rsync_flist_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
|
||||
if (fdb_close) {
|
||||
close(fdb);
|
||||
}
|
||||
@@ -110,7 +92,6 @@ void write_batch_flist_info(int flist_count, struct file_struct **fptr)
|
||||
}
|
||||
write_char_bufs(fptr[i]->sum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void write_char_bufs(char *buf)
|
||||
@@ -118,11 +99,8 @@ void write_char_bufs(char *buf)
|
||||
/* Write the size of the string which will follow */
|
||||
|
||||
char b[4];
|
||||
if (buf != NULL)
|
||||
SIVAL(b, 0, strlen(buf));
|
||||
else {
|
||||
SIVAL(b, 0, 0);
|
||||
}
|
||||
|
||||
SIVAL(b, 0, buf != NULL ? strlen(buf) : 0);
|
||||
|
||||
write_batch_flist_file(b, sizeof(int));
|
||||
|
||||
@@ -137,36 +115,52 @@ void write_batch_argvs_file(int argc, char *argv[])
|
||||
{
|
||||
int fdb;
|
||||
int i;
|
||||
char buff[256];
|
||||
char buff[256]; /* XXX */
|
||||
char buff2[MAXPATHLEN + 6];
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
strcat(rsync_argvs_file, batch_file_ext);
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_argvs_file, sizeof(filename));
|
||||
|
||||
|
||||
/* Open batch argvs file for writing; create it if it doesn't exist */
|
||||
fdb = do_open(rsync_argvs_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
/*
|
||||
* Open batch argvs file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE | S_IEXEC);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_argvs_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
buff[0] = '\0';
|
||||
|
||||
/* Write argvs info to batch file */
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (i == argc - 2)
|
||||
if (i == argc - 2) /* Skip source directory on cmdline */
|
||||
continue;
|
||||
/*
|
||||
* FIXME:
|
||||
* I think directly manipulating argv[] is probably bogus
|
||||
*/
|
||||
if (!strcmp(argv[i], "--write-batch")) {
|
||||
if (!strncmp(argv[i], "--write-batch",
|
||||
strlen("--write-batch"))) {
|
||||
/* Safer to change it here than script */
|
||||
/* Change to --read-batch + ext * to get ready for remote */
|
||||
strlcat(buff, "--read-batch ", sizeof(buff));
|
||||
strlcat(buff, batch_file_ext, sizeof(buff));
|
||||
} else {
|
||||
/*
|
||||
* Change to --read-batch=prefix
|
||||
* to get ready for remote
|
||||
*/
|
||||
strlcat(buff, "--read-batch=", sizeof(buff));
|
||||
strlcat(buff, batch_prefix, sizeof(buff));
|
||||
} else
|
||||
if (i == argc - 1) {
|
||||
snprintf(buff2, sizeof(buff2), "${1:-%s}", argv[i]);
|
||||
strlcat(buff, buff2, sizeof(buff));
|
||||
}
|
||||
else {
|
||||
strlcat(buff, argv[i], sizeof(buff));
|
||||
}
|
||||
|
||||
@@ -177,31 +171,30 @@ void write_batch_argvs_file(int argc, char *argv[])
|
||||
strlcat(buff, "\n", sizeof(buff));
|
||||
if (!write(fdb, buff, strlen(buff))) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
rsync_argvs_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
struct file_list *create_flist_from_batch()
|
||||
struct file_list *create_flist_from_batch(void)
|
||||
{
|
||||
unsigned char flags;
|
||||
|
||||
fdb_open = 1;
|
||||
fdb_close = 0;
|
||||
|
||||
batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
|
||||
batch_flist = new(struct file_list);
|
||||
if (!batch_flist) {
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
batch_flist->count = 0;
|
||||
batch_flist->malloced = 1000;
|
||||
batch_flist->files =
|
||||
(struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
|
||||
batch_flist->malloced);
|
||||
batch_flist->files = new_array(struct file_struct *,
|
||||
batch_flist->malloced);
|
||||
if (!batch_flist->files) {
|
||||
out_of_memory("create_flist_from_batch"); /* dw -- will exit */
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
|
||||
for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
|
||||
@@ -213,14 +206,10 @@ struct file_list *create_flist_from_batch()
|
||||
batch_flist->malloced += 1000;
|
||||
else
|
||||
batch_flist->malloced *= 2;
|
||||
batch_flist->files =
|
||||
(struct file_struct **) realloc(batch_flist->
|
||||
files,
|
||||
sizeof
|
||||
(batch_flist->
|
||||
files[0]) *
|
||||
batch_flist->
|
||||
malloced);
|
||||
batch_flist->files
|
||||
= realloc_array(batch_flist->files,
|
||||
struct file_struct *,
|
||||
batch_flist->malloced);
|
||||
if (!batch_flist->files)
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
@@ -231,23 +220,23 @@ struct file_list *create_flist_from_batch()
|
||||
}
|
||||
|
||||
return batch_flist;
|
||||
|
||||
}
|
||||
|
||||
int read_batch_flist_file(char *buff, int len)
|
||||
{
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
|
||||
/* Set up file extension */
|
||||
strcat(rsync_flist_file, batch_file_ext);
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_flist_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb = do_open(rsync_flist_file, O_RDONLY, 0);
|
||||
fdb = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_flist_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -256,21 +245,21 @@ int read_batch_flist_file(char *buff, int len)
|
||||
|
||||
/* Read flist batch file */
|
||||
|
||||
bytes_read = read(fdb, buff, len);
|
||||
|
||||
if (bytes_read == -1) {
|
||||
switch (bytes_read = read(fdb, buff, len)) {
|
||||
case -1:
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
rsync_flist_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
if (bytes_read == 0) { /* EOF */
|
||||
break;
|
||||
case 0: /* EOF */
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
unsigned char read_batch_flags()
|
||||
unsigned char read_batch_flags(void)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -288,13 +277,17 @@ void read_batch_flist_info(struct file_struct **fptr)
|
||||
char buff[256];
|
||||
struct file_struct *file;
|
||||
|
||||
file = (struct file_struct *) malloc(sizeof(*file));
|
||||
file = new(struct file_struct);
|
||||
if (!file)
|
||||
out_of_memory("read_batch_flist_info");
|
||||
memset((char *) file, 0, sizeof(*file));
|
||||
|
||||
(*fptr) = file;
|
||||
*fptr = file;
|
||||
|
||||
/*
|
||||
* Keep these in sync with bytes_to_write assignment
|
||||
* in write_batch_flist_info()
|
||||
*/
|
||||
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
|
||||
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
|
||||
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
|
||||
@@ -356,20 +349,23 @@ void read_batch_flist_info(struct file_struct **fptr)
|
||||
|
||||
void write_batch_csums_file(void *buff, int bytes_to_write)
|
||||
{
|
||||
|
||||
static int fdb_open = 1;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strcat(rsync_csums_file, batch_file_ext);
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_csums_file, sizeof(filename));
|
||||
|
||||
/* Open batch csums file for writing; create it if it doesn't exist */
|
||||
fdb =
|
||||
do_open(rsync_csums_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
/*
|
||||
* Open batch csums file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_csums_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -380,35 +376,38 @@ void write_batch_csums_file(void *buff, int bytes_to_write)
|
||||
|
||||
if (write(fdb, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
rsync_csums_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
|
||||
void close_batch_csums_file()
|
||||
void close_batch_csums_file(void)
|
||||
{
|
||||
close(fdb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write csum info to batch file
|
||||
*
|
||||
* @todo This will break if s->count is ever larger than maxint. The
|
||||
* batch code should probably be changed to consistently use the
|
||||
* variable-length integer routines, which is probably a compatible
|
||||
* change.
|
||||
**/
|
||||
void write_batch_csum_info(int *flist_entry, int flist_count,
|
||||
struct sum_struct *s)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int int_zero = 0;
|
||||
int int_count;
|
||||
extern int csum_length;
|
||||
|
||||
fdb_open = 1;
|
||||
|
||||
/* Write csum info to batch file */
|
||||
|
||||
/* FIXME: This will break if s->count is ever not exactly an int. */
|
||||
write_batch_csums_file(flist_entry, sizeof(int));
|
||||
if (s)
|
||||
write_batch_csums_file(&s->count, sizeof(int));
|
||||
else
|
||||
write_batch_csums_file(&int_zero, sizeof (int));
|
||||
int_count = s ? (int) s->count : 0;
|
||||
write_batch_csums_file(&int_count, sizeof int_count);
|
||||
|
||||
if (s) {
|
||||
for (i = 0; i < s->count; i++) {
|
||||
@@ -417,8 +416,7 @@ void write_batch_csum_info(int *flist_entry, int flist_count,
|
||||
&& (i == s->count - 1)) {
|
||||
fdb_close = 1;
|
||||
}
|
||||
write_batch_csums_file(s->sums[i].sum2,
|
||||
csum_length);
|
||||
write_batch_csums_file(s->sums[i].sum2, csum_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,17 +425,18 @@ int read_batch_csums_file(char *buff, int len)
|
||||
{
|
||||
static int fdb_open = 1;
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
|
||||
/* Set up file extension */
|
||||
strcat(rsync_csums_file, batch_file_ext);
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_csums_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb = do_open(rsync_csums_file, O_RDONLY, 0);
|
||||
fdb = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_csums_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -450,14 +449,14 @@ int read_batch_csums_file(char *buff, int len)
|
||||
|
||||
if (bytes_read == -1) {
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
rsync_csums_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
|
||||
void read_batch_csum_info(int flist_entry, struct sum_struct *s,
|
||||
int *checksums_match)
|
||||
{
|
||||
@@ -468,11 +467,9 @@ void read_batch_csum_info(int flist_entry, struct sum_struct *s,
|
||||
char file_sum2[SUM_LENGTH];
|
||||
extern int csum_length;
|
||||
|
||||
|
||||
read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
|
||||
if (file_flist_entry != flist_entry) {
|
||||
rprintf(FINFO, "file_list_entry NE flist_entry\n");
|
||||
rprintf(FINFO, "file_flist_entry = %d flist_entry = %d\n",
|
||||
rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n",
|
||||
file_flist_entry, flist_entry);
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
@@ -488,31 +485,33 @@ void read_batch_csum_info(int flist_entry, struct sum_struct *s,
|
||||
read_batch_csums_file(file_sum2, csum_length);
|
||||
|
||||
if ((s->sums[i].sum1 != file_sum1) ||
|
||||
(memcmp
|
||||
(s->sums[i].sum2, file_sum2,
|
||||
csum_length) != 0)) {
|
||||
(memcmp(s->sums[i].sum2, file_sum2, csum_length)
|
||||
!= 0)) {
|
||||
*checksums_match = 0;
|
||||
}
|
||||
} /* end for */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void write_batch_delta_file(char *buff, int bytes_to_write)
|
||||
{
|
||||
static int fdb_delta_open = 1;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_delta_open) {
|
||||
/* Set up file extension */
|
||||
strcat(rsync_delta_file, batch_file_ext);
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_delta_file, sizeof(filename));
|
||||
|
||||
/* Open batch delta file for writing; create it if it doesn't exist */
|
||||
fdb_delta =
|
||||
do_open(rsync_delta_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
/*
|
||||
* Open batch delta file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb_delta == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_delta_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -523,32 +522,33 @@ void write_batch_delta_file(char *buff, int bytes_to_write)
|
||||
|
||||
if (write(fdb_delta, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
rsync_delta_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
void close_batch_delta_file()
|
||||
|
||||
void close_batch_delta_file(void)
|
||||
{
|
||||
close(fdb_delta);
|
||||
|
||||
}
|
||||
|
||||
int read_batch_delta_file(char *buff, int len)
|
||||
{
|
||||
static int fdb_delta_open = 1;
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_delta_open) {
|
||||
|
||||
/* Set up file extension */
|
||||
strcat(rsync_delta_file, batch_file_ext);
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_delta_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb_delta = do_open(rsync_delta_file, O_RDONLY, 0);
|
||||
fdb_delta = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb_delta == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
rsync_delta_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
@@ -561,14 +561,14 @@ int read_batch_delta_file(char *buff, int len)
|
||||
|
||||
if (bytes_read == -1) {
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
rsync_delta_file, strerror(errno));
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
|
||||
void show_flist(int index, struct file_struct **fptr)
|
||||
{
|
||||
/* for debugging show_flist(flist->count, flist->files * */
|
||||
|
||||
12
checksum.c
12
checksum.c
@@ -58,7 +58,7 @@ void get_checksum2(char *buf,int len,char *sum)
|
||||
|
||||
if (len > len1) {
|
||||
if (buf1) free(buf1);
|
||||
buf1 = (char *)malloc(len+4);
|
||||
buf1 = new_array(char, len+4);
|
||||
len1 = len;
|
||||
if (!buf1) out_of_memory("get_checksum2");
|
||||
}
|
||||
@@ -140,7 +140,15 @@ void sum_init(void)
|
||||
sum_update(s,4);
|
||||
}
|
||||
|
||||
void sum_update(char *p,int len)
|
||||
/**
|
||||
* 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(char *p, int len)
|
||||
{
|
||||
int i;
|
||||
if (len + sumresidue < CSUM_CHUNK) {
|
||||
|
||||
73
cleanup.c
73
cleanup.c
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,9 +21,50 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* 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 */
|
||||
/**
|
||||
* 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--) {
|
||||
ret = fstat(fd,&st);
|
||||
if (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 char *cleanup_fname;
|
||||
@@ -35,17 +77,31 @@ extern int io_error;
|
||||
|
||||
pid_t cleanup_child_pid = -1;
|
||||
|
||||
/*
|
||||
* Code is one of the RERR_* codes from errcode.h.
|
||||
*/
|
||||
/**
|
||||
* Eventually calls exit(), passing @p code, therefore does not return.
|
||||
*
|
||||
* @param code one of the RERR_* codes from errcode.h.
|
||||
**/
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
int ocode = code;
|
||||
extern int keep_partial;
|
||||
extern int log_got_error;
|
||||
static int inside_cleanup = 0;
|
||||
|
||||
if (inside_cleanup > 10) {
|
||||
/* prevent the occasional infinite recursion */
|
||||
return;
|
||||
}
|
||||
inside_cleanup++;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, file, line);
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
|
||||
@@ -81,6 +137,11 @@ void _exit_cleanup(int code, const char *file, int line)
|
||||
|
||||
if (code) log_exit(code, file, line);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
|
||||
ocode, file, line, code);
|
||||
|
||||
close_all();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
|
||||
364
clientname.c
Normal file
364
clientname.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file clientname.c
|
||||
*
|
||||
* Functions for looking up the remote name or addr of a socket.
|
||||
*
|
||||
* This file is now converted to use the new-style getaddrinfo()
|
||||
* interface, which supports IPv6 but is also supported on recent
|
||||
* IPv4-only machines. On systems that don't have that interface, we
|
||||
* emulate it using the KAME implementation.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/**
|
||||
* Return the IP addr of the client as a string
|
||||
**/
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
char *ssh_client, *p;
|
||||
int len;
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
|
||||
if (initialised) return addr_buf;
|
||||
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
strcpy(addr_buf, "0.0.0.0");
|
||||
if ((ssh_client = getenv("SSH_CLIENT")) != NULL) {
|
||||
/* truncate SSH_CLIENT to just IP address */
|
||||
p = strchr(ssh_client, ' ');
|
||||
if (p) {
|
||||
len = MIN((unsigned int) (p - ssh_client),
|
||||
sizeof(addr_buf) - 1);
|
||||
strncpy(addr_buf, ssh_client, len);
|
||||
*(addr_buf + len) = '\0';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
getnameinfo((struct sockaddr *)&ss, length,
|
||||
addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
|
||||
}
|
||||
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
|
||||
static int get_sockaddr_family(const struct sockaddr_storage *ss)
|
||||
{
|
||||
return ((struct sockaddr *) ss)->sa_family;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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(int fd)
|
||||
{
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
static int initialised;
|
||||
struct sockaddr_storage ss, *ssp;
|
||||
struct sockaddr_in sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
socklen_t ss_len;
|
||||
|
||||
if (initialised) return name_buf;
|
||||
|
||||
strcpy(name_buf, default_name);
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
|
||||
char *addr = client_addr(fd);
|
||||
#ifdef INET6
|
||||
int dots = 0;
|
||||
char *p;
|
||||
|
||||
for (p = addr; *p && (dots <= 3); p++) {
|
||||
if (*p == '.')
|
||||
dots++;
|
||||
}
|
||||
if (dots > 3) {
|
||||
/* more than 4 parts to IP address, must be ipv6 */
|
||||
ssp = (struct sockaddr_storage *) &sin6;
|
||||
ss_len = sizeof sin6;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET6, addr, &sin6.sin6_addr);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ssp = (struct sockaddr_storage *) &sin;
|
||||
ss_len = sizeof sin;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET, addr, &sin.sin_addr);
|
||||
sin.sin_family = AF_INET;
|
||||
}
|
||||
|
||||
} else {
|
||||
ss_len = sizeof ss;
|
||||
ssp = &ss;
|
||||
|
||||
client_sockaddr(fd, &ss, &ss_len);
|
||||
|
||||
}
|
||||
|
||||
if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf))
|
||||
check_name(fd, ssp, name_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
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? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
fd, strerror(errno));
|
||||
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_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
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up a name from @p ss into @p name_buf.
|
||||
*
|
||||
* @param fd file descriptor for client socket.
|
||||
**/
|
||||
int lookup_name(int fd, const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
char *name_buf, size_t name_buf_len,
|
||||
char *port_buf, size_t port_buf_len)
|
||||
{
|
||||
int name_err;
|
||||
|
||||
/* reverse lookup */
|
||||
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
|
||||
name_buf, name_buf_len,
|
||||
port_buf, port_buf_len,
|
||||
NI_NAMEREQD | NI_NUMERICSERV);
|
||||
if (name_err != 0) {
|
||||
strcpy(name_buf, default_name);
|
||||
rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
|
||||
client_addr(fd),
|
||||
gai_strerror(name_err));
|
||||
return name_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Compare an addrinfo from the resolver to a sockinfo.
|
||||
*
|
||||
* Like strcmp, returns 0 for identical.
|
||||
**/
|
||||
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(FERROR,
|
||||
"%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
|
||||
else if (ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sin1, *sin2;
|
||||
|
||||
sin1 = (const struct sockaddr_in6 *) ss;
|
||||
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
|
||||
|
||||
if (ai->ai_addrlen < sizeof(struct sockaddr_in6)) {
|
||||
rprintf(FERROR,
|
||||
"%s: too short sockaddr_in6; length=%d\n",
|
||||
fn, ai->ai_addrlen);
|
||||
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 */
|
||||
else {
|
||||
/* 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.
|
||||
**/
|
||||
int check_name(int fd,
|
||||
const struct sockaddr_storage *ss,
|
||||
char *name_buf)
|
||||
{
|
||||
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(FERROR,
|
||||
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
|
||||
name_buf, gai_strerror(error));
|
||||
strcpy(name_buf, default_name);
|
||||
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(FERROR, RSYNC_NAME
|
||||
": no known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
} else if (res == NULL) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": %s is not a known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
client_addr(fd),
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
411
clientserver.c
411
clientserver.c
@@ -1,24 +1,29 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001-2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* the socket based protocol for setting up a connection with rsyncd */
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The socket based protocol for setting up a connection with
|
||||
* rsyncd.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -27,43 +32,37 @@ extern int read_only;
|
||||
extern int verbose;
|
||||
extern int rsync_port;
|
||||
char *auth_user;
|
||||
int sanitize_paths = 0;
|
||||
extern int sanitize_paths;
|
||||
extern int filesfrom_fd;
|
||||
extern int remote_protocol;
|
||||
extern int protocol_version;
|
||||
extern struct exclude_struct **server_exclude_list;
|
||||
extern char *exclude_path_prefix;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Run a client connected to an rsyncd. The alternative to this
|
||||
* function for remote-shell connections is do_cmd.
|
||||
*/
|
||||
* function for remote-shell connections is do_cmd().
|
||||
*
|
||||
* After negotiating which module to use and reading the server's
|
||||
* motd, this hands over to client_run(). Telling the server the
|
||||
* module will cause it to chroot/setuid/etc.
|
||||
*
|
||||
* Instead of doing a transfer, the client may at this stage instead
|
||||
* get a listing of remote modules and exit.
|
||||
*
|
||||
* @return -1 for error in startup, or the result of client_run().
|
||||
* Either way, it eventually gets passed to exit_cleanup().
|
||||
**/
|
||||
int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
{
|
||||
int fd, i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc=0;
|
||||
char line[MAXPATHLEN];
|
||||
int fd, ret;
|
||||
char *p, *user=NULL;
|
||||
extern int remote_version;
|
||||
extern int am_sender;
|
||||
extern char *shell_cmd;
|
||||
extern int kludge_around_eof;
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
|
||||
if (argc == 0 && !am_sender) {
|
||||
extern int list_only;
|
||||
list_only = 1;
|
||||
}
|
||||
|
||||
/* This is just a friendliness enhancement: if the connection
|
||||
* is to an rsyncd then there is no point specifying the -e option.
|
||||
* Note that this is only set if the -e was explicitly specified,
|
||||
* not if the environment variable just happens to be set.
|
||||
* See http://lists.samba.org/pipermail/rsync/2000-September/002744.html
|
||||
*/
|
||||
if (shell_cmd) {
|
||||
rprintf(FERROR, "WARNING: --rsh or -e option ignored when "
|
||||
"connecting to rsync daemon\n");
|
||||
/* continue */
|
||||
}
|
||||
|
||||
/* this is redundant with code in start_inband_exchange(), but
|
||||
* this short-circuits a problem before we open a socket, and
|
||||
* the extra check won't hurt */
|
||||
if (*path == '/') {
|
||||
rprintf(FERROR,"ERROR: The remote path must start with a module name not a /\n");
|
||||
return -1;
|
||||
@@ -76,77 +75,133 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
|
||||
default_af_hint);
|
||||
if (verbose >= 2) {
|
||||
/* FIXME: If we're going to use a socket program for
|
||||
* testing, then this message is wrong. We need to
|
||||
* say something like "(except really using %s)" */
|
||||
rprintf(FINFO, "opening tcp connection to %s port %d\n",
|
||||
host, rsync_port);
|
||||
}
|
||||
fd = open_socket_out_wrapped(host, rsync_port, bind_address,
|
||||
default_af_hint);
|
||||
if (fd == -1) {
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
server_options(sargs,&sargc);
|
||||
|
||||
ret = start_inband_exchange(user, path, fd, fd, argc);
|
||||
|
||||
return ret < 0? ret : client_run(fd, fd, -1, argc, argv);
|
||||
}
|
||||
|
||||
int start_inband_exchange(char *user, char *path, int f_in, int f_out, int argc)
|
||||
{
|
||||
int i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc = 0;
|
||||
char line[MAXPATHLEN];
|
||||
char *p;
|
||||
extern int kludge_around_eof;
|
||||
extern int am_sender;
|
||||
extern int daemon_over_rsh;
|
||||
extern int list_only;
|
||||
|
||||
if (argc == 0 && !am_sender)
|
||||
list_only = 1;
|
||||
|
||||
if (*path == '/') {
|
||||
rprintf(FERROR, "ERROR: The remote path must start with a module name\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
/* set daemon_over_rsh to false since we need to build the
|
||||
* true set of args passed through the rsh/ssh connection;
|
||||
* this is a no-op for direct-socket-connection mode */
|
||||
daemon_over_rsh = 0;
|
||||
server_options(sargs, &sargc);
|
||||
|
||||
sargs[sargc++] = ".";
|
||||
|
||||
if (path && *path)
|
||||
if (path && *path)
|
||||
sargs[sargc++] = path;
|
||||
|
||||
sargs[sargc] = NULL;
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
io_printf(f_out, "@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
rprintf(FERROR, "rsync: did not see server greeting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) {
|
||||
/* note that read_line strips of \n or \r */
|
||||
rprintf(FERROR, "rsync: server sent \"%s\" rather than greeting\n",
|
||||
line);
|
||||
return -1;
|
||||
}
|
||||
if (protocol_version > remote_protocol)
|
||||
protocol_version = remote_protocol;
|
||||
|
||||
p = strchr(path,'/');
|
||||
if (p) *p = 0;
|
||||
io_printf(fd,"%s\n",path);
|
||||
io_printf(f_out, "%s\n", path);
|
||||
if (p) *p = '/';
|
||||
|
||||
/* Old servers may just drop the connection here,
|
||||
rather than sending a proper EXIT command. Yuck. */
|
||||
kludge_around_eof = remote_version < 25;
|
||||
kludge_around_eof = list_only && (protocol_version < 25);
|
||||
|
||||
while (1) {
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
rprintf(FERROR, "rsync: didn't get server startup line\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(line,"@RSYNCD: AUTHREQD ",18) == 0) {
|
||||
auth_client(fd, user, line+18);
|
||||
auth_client(f_out, user, line+18);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(line,"@RSYNCD: OK") == 0) break;
|
||||
|
||||
if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
|
||||
if (strcmp(line,"@RSYNCD: EXIT") == 0) {
|
||||
/* This is sent by recent versions of the
|
||||
* server to terminate the listing of modules.
|
||||
* We don't want to go on and transfer
|
||||
* anything; just exit. */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
rprintf(FINFO,"%s\n", line);
|
||||
if (strncmp(line, "@ERROR", 6) == 0) {
|
||||
rprintf(FERROR,"%s\n", line);
|
||||
/* This is always fatal; the server will now
|
||||
* close the socket. */
|
||||
return RERR_STARTCLIENT;
|
||||
} else {
|
||||
rprintf(FINFO,"%s\n", line);
|
||||
}
|
||||
}
|
||||
kludge_around_eof = False;
|
||||
|
||||
for (i=0;i<sargc;i++) {
|
||||
io_printf(fd,"%s\n", sargs[i]);
|
||||
for (i = 0; i < sargc; i++) {
|
||||
io_printf(f_out, "%s\n", sargs[i]);
|
||||
}
|
||||
io_printf(fd,"\n");
|
||||
io_printf(f_out, "\n");
|
||||
|
||||
if (remote_version < 23) {
|
||||
if (remote_version == 22 || (remote_version > 17 && !am_sender))
|
||||
io_start_multiplex_in(fd);
|
||||
if (protocol_version < 23) {
|
||||
if (protocol_version == 22 || (protocol_version > 17 && !am_sender))
|
||||
io_start_multiplex_in(f_in);
|
||||
}
|
||||
|
||||
return client_run(fd, fd, -1, argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int rsync_module(int fd, int i)
|
||||
static int rsync_module(int f_in, int f_out, int i)
|
||||
{
|
||||
int argc=0;
|
||||
char *argv[MAX_ARGS];
|
||||
@@ -155,47 +210,54 @@ static int rsync_module(int fd, int i)
|
||||
uid_t uid = (uid_t)-2; /* canonically "nobody" */
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p;
|
||||
char *addr = client_addr(fd);
|
||||
char *host = client_name(fd);
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
char *name = lp_name(i);
|
||||
int use_chroot = lp_use_chroot(i);
|
||||
int start_glob=0;
|
||||
int ret;
|
||||
char *request=NULL;
|
||||
extern int am_sender;
|
||||
extern int remote_version;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_root;
|
||||
|
||||
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
|
||||
rprintf(FERROR,"rsync denied on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
io_printf(fd,"@ERROR: access denied to %s from %s (%s)\n",
|
||||
io_printf(f_out, "@ERROR: access denied to %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (am_daemon && am_server) {
|
||||
rprintf(FINFO, "rsync allowed access on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
}
|
||||
|
||||
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
|
||||
if (errno) {
|
||||
rprintf(FERROR,"failed to open lock file %s : %s\n",
|
||||
lp_lock_file(i), strerror(errno));
|
||||
io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
|
||||
io_printf(f_out, "@ERROR: failed to open lock file %s : %s\n",
|
||||
lp_lock_file(i), strerror(errno));
|
||||
} else {
|
||||
rprintf(FERROR,"max connections (%d) reached\n",
|
||||
lp_max_connections(i));
|
||||
io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
|
||||
io_printf(f_out, "@ERROR: max connections (%d) reached - try again later\n",
|
||||
lp_max_connections(i));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
auth_user = auth_server(fd, i, addr, "@RSYNCD: AUTHREQD ");
|
||||
|
||||
auth_user = auth_server(f_in, f_out, i, addr, "@RSYNCD: AUTHREQD ");
|
||||
|
||||
if (!auth_user) {
|
||||
rprintf(FERROR,"auth failed on module %s from %s (%s)\n",
|
||||
name, client_name(fd), client_addr(fd));
|
||||
io_printf(fd,"@ERROR: auth failed on module %s\n",name);
|
||||
return -1;
|
||||
name, host, addr);
|
||||
io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
module_id = i;
|
||||
@@ -205,43 +267,49 @@ static int rsync_module(int fd, int i)
|
||||
if (am_root) {
|
||||
p = lp_uid(i);
|
||||
if (!name_to_uid(p, &uid)) {
|
||||
if (!isdigit(*p)) {
|
||||
if (!isdigit(* (unsigned char *) p)) {
|
||||
rprintf(FERROR,"Invalid uid %s\n", p);
|
||||
io_printf(fd,"@ERROR: invalid uid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
uid = atoi(p);
|
||||
}
|
||||
|
||||
p = lp_gid(i);
|
||||
if (!name_to_gid(p, &gid)) {
|
||||
if (!isdigit(*p)) {
|
||||
if (!isdigit(* (unsigned char *) p)) {
|
||||
rprintf(FERROR,"Invalid gid %s\n", p);
|
||||
io_printf(fd,"@ERROR: invalid gid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid gid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
gid = atoi(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: If we're not root, but the configuration requests
|
||||
* that we change to some uid other than the current one, then
|
||||
* log a warning. */
|
||||
|
||||
/* TODO: Perhaps take a list of gids, and make them into the
|
||||
* supplementary groups. */
|
||||
/* TODO: If we're not root, but the configuration requests
|
||||
* that we change to some uid other than the current one, then
|
||||
* log a warning. */
|
||||
|
||||
/* TODO: Perhaps take a list of gids, and make them into the
|
||||
* supplementary groups. */
|
||||
|
||||
exclude_path_prefix = use_chroot? "" : lp_path(i);
|
||||
if (*exclude_path_prefix == '/' && !exclude_path_prefix[1])
|
||||
exclude_path_prefix = "";
|
||||
|
||||
p = lp_include_from(i);
|
||||
add_exclude_file(p, 1, 1);
|
||||
add_exclude_file(&server_exclude_list, p, MISSING_FATAL, ADD_INCLUDE);
|
||||
|
||||
p = lp_include(i);
|
||||
add_include_line(p);
|
||||
add_exclude_line(&server_exclude_list, p, ADD_INCLUDE);
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
add_exclude_file(p, 1, 0);
|
||||
add_exclude_file(&server_exclude_list, p, MISSING_FATAL, ADD_EXCLUDE);
|
||||
|
||||
p = lp_exclude(i);
|
||||
add_exclude_line(p);
|
||||
add_exclude_line(&server_exclude_list, p, ADD_EXCLUDE);
|
||||
|
||||
exclude_path_prefix = NULL;
|
||||
|
||||
log_init();
|
||||
|
||||
@@ -260,47 +328,66 @@ static int rsync_module(int fd, int i)
|
||||
*/
|
||||
if (chroot(lp_path(i))) {
|
||||
rsyserr(FERROR, errno, "chroot %s failed", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chroot failed\n");
|
||||
io_printf(f_out, "@ERROR: chroot failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!push_dir("/", 0)) {
|
||||
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chdir failed\n");
|
||||
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!push_dir(lp_path(i), 0)) {
|
||||
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chdir failed\n");
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
sanitize_paths = 1;
|
||||
}
|
||||
|
||||
if (am_root) {
|
||||
/* XXXX: You could argue that if the daemon is started
|
||||
* by a non-root user and they explicitly specify a
|
||||
* gid, then we should try to change to that gid --
|
||||
* this could be possible if it's already in their
|
||||
* supplementary groups. */
|
||||
|
||||
/* TODO: Perhaps we need to document that if rsyncd is
|
||||
* started by somebody other than root it will inherit
|
||||
* all their supplementary groups. */
|
||||
|
||||
if (setgid(gid)) {
|
||||
rsyserr(FERROR, errno, "setgid %d failed", (int) gid);
|
||||
io_printf(fd,"@ERROR: setgid failed\n");
|
||||
io_printf(f_out, "@ERROR: setgid failed\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_SETGROUPS
|
||||
/* Get rid of any supplementary groups this process
|
||||
* might have inheristed. */
|
||||
if (setgroups(1, &gid)) {
|
||||
rsyserr(FERROR, errno, "setgroups failed");
|
||||
io_printf(f_out, "@ERROR: setgroups failed\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setuid(uid)) {
|
||||
rsyserr(FERROR, errno, "setuid %d failed", (int) uid);
|
||||
io_printf(fd,"@ERROR: setuid failed\n");
|
||||
io_printf(f_out, "@ERROR: setuid failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
am_root = (getuid() == 0);
|
||||
}
|
||||
|
||||
io_printf(fd,"@RSYNCD: OK\n");
|
||||
io_printf(f_out, "@RSYNCD: OK\n");
|
||||
|
||||
argv[argc++] = "rsyncd";
|
||||
|
||||
while (1) {
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -345,9 +432,12 @@ static int rsync_module(int fd, int i)
|
||||
}
|
||||
}
|
||||
|
||||
argp = argv;
|
||||
argp = argv;
|
||||
ret = parse_arguments(&argc, (const char ***) &argp, 0);
|
||||
|
||||
if (filesfrom_fd == 0)
|
||||
filesfrom_fd = f_in;
|
||||
|
||||
if (request) {
|
||||
if (*auth_user) {
|
||||
rprintf(FINFO,"rsync %s %s from %s@%s (%s)\n",
|
||||
@@ -366,22 +456,22 @@ static int rsync_module(int fd, int i)
|
||||
if (verbose > 1) verbose = 1;
|
||||
#endif
|
||||
|
||||
if (remote_version < 23) {
|
||||
if (remote_version == 22 || (remote_version > 17 && am_sender))
|
||||
io_start_multiplex_out(fd);
|
||||
if (protocol_version < 23) {
|
||||
if (protocol_version == 22 || (protocol_version > 17 && am_sender))
|
||||
io_start_multiplex_out(f_out);
|
||||
}
|
||||
|
||||
/* For later protocol versions, we don't start multiplexing
|
||||
* until we've configured nonblocking in start_server. That
|
||||
* means we're in a sticky situation now: there's no way to
|
||||
* convey errors to the client. */
|
||||
|
||||
/* FIXME: Hold off on reporting option processing errors until
|
||||
* we've set up nonblocking and multiplexed IO and can get the
|
||||
* message back to them. */
|
||||
/* For later protocol versions, we don't start multiplexing
|
||||
* until we've configured nonblocking in start_server. That
|
||||
* means we're in a sticky situation now: there's no way to
|
||||
* convey errors to the client. */
|
||||
|
||||
/* FIXME: Hold off on reporting option processing errors until
|
||||
* we've set up nonblocking and multiplexed IO and can get the
|
||||
* message back to them. */
|
||||
if (!ret) {
|
||||
option_error();
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
option_error();
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
if (lp_timeout(i)) {
|
||||
@@ -389,7 +479,7 @@ static int rsync_module(int fd, int i)
|
||||
io_timeout = lp_timeout(i);
|
||||
}
|
||||
|
||||
start_server(fd, fd, argc, argp);
|
||||
start_server(f_in, f_out, argc, argp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -400,36 +490,39 @@ static void send_listing(int fd)
|
||||
{
|
||||
int n = lp_numservices();
|
||||
int i;
|
||||
extern int remote_version;
|
||||
|
||||
for (i=0;i<n;i++)
|
||||
if (lp_list(i))
|
||||
io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
|
||||
io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
|
||||
|
||||
if (remote_version >= 25)
|
||||
if (protocol_version >= 25)
|
||||
io_printf(fd,"@RSYNCD: EXIT\n");
|
||||
}
|
||||
|
||||
/* this is called when a socket connection is established to a client
|
||||
/* this is called when a connection is established to a client
|
||||
and we want to start talking. The setup of the system is done from
|
||||
here */
|
||||
static int start_daemon(int fd)
|
||||
int start_daemon(int f_in, int f_out)
|
||||
{
|
||||
char line[200];
|
||||
char *motd;
|
||||
int i = -1;
|
||||
extern char *config_file;
|
||||
extern int remote_version;
|
||||
extern int am_server;
|
||||
|
||||
if (!lp_load(config_file, 0)) {
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
set_socket_options(fd,"SO_KEEPALIVE");
|
||||
set_socket_options(fd,lp_socket_options());
|
||||
set_nonblocking(fd);
|
||||
log_init();
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
if (!am_server) {
|
||||
set_socket_options(f_in, "SO_KEEPALIVE");
|
||||
set_socket_options(f_in, lp_socket_options());
|
||||
set_nonblocking(f_in);
|
||||
}
|
||||
|
||||
io_printf(f_out, "@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
motd = lp_motd_file();
|
||||
if (motd && *motd) {
|
||||
@@ -438,47 +531,49 @@ static int start_daemon(int fd)
|
||||
int len = fread(line, 1, sizeof(line)-1, f);
|
||||
if (len > 0) {
|
||||
line[len] = 0;
|
||||
io_printf(fd,"%s", line);
|
||||
io_printf(f_out, "%s", line);
|
||||
}
|
||||
}
|
||||
if (f) fclose(f);
|
||||
io_printf(fd,"\n");
|
||||
io_printf(f_out, "\n");
|
||||
}
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
|
||||
io_printf(fd,"@ERROR: protocol startup error\n");
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) {
|
||||
io_printf(f_out, "@ERROR: protocol startup error\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (protocol_version > remote_protocol)
|
||||
protocol_version = remote_protocol;
|
||||
|
||||
while (i == -1) {
|
||||
line[0] = 0;
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!*line || strcmp(line,"#list")==0) {
|
||||
send_listing(fd);
|
||||
send_listing(f_out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*line == '#') {
|
||||
/* it's some sort of command that I don't understand */
|
||||
io_printf(fd,"@ERROR: Unknown command '%s'\n", line);
|
||||
io_printf(f_out, "@ERROR: Unknown command '%s'\n", line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = lp_number(line);
|
||||
if (i == -1) {
|
||||
io_printf(fd,"@ERROR: Unknown module '%s'\n", line);
|
||||
io_printf(f_out, "@ERROR: Unknown module '%s'\n", line);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return rsync_module(fd, i);
|
||||
return rsync_module(f_in, f_out, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -493,18 +588,18 @@ int daemon_main(void)
|
||||
int i;
|
||||
|
||||
/* we are running via inetd - close off stdout and
|
||||
stderr so that library functions (and getopt) don't
|
||||
try to use them. Redirect them to /dev/null */
|
||||
* stderr so that library functions (and getopt) don't
|
||||
* try to use them. Redirect them to /dev/null */
|
||||
for (i=1;i<3;i++) {
|
||||
close(i);
|
||||
close(i);
|
||||
open("/dev/null", O_RDWR);
|
||||
}
|
||||
|
||||
return start_daemon(STDIN_FILENO);
|
||||
return start_daemon(STDIN_FILENO, STDIN_FILENO);
|
||||
}
|
||||
|
||||
if (!no_detach)
|
||||
become_daemon();
|
||||
become_daemon();
|
||||
|
||||
if (!lp_load(config_file, 1)) {
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -513,11 +608,10 @@ int daemon_main(void)
|
||||
log_init();
|
||||
|
||||
rprintf(FINFO, "rsyncd version %s starting, listening on port %d\n",
|
||||
RSYNC_VERSION,
|
||||
rsync_port);
|
||||
/* TODO: If listening on a particular address, then show that
|
||||
* address too. In fact, why not just do inet_ntop on the
|
||||
* local address??? */
|
||||
RSYNC_VERSION, rsync_port);
|
||||
/* TODO: If listening on a particular address, then show that
|
||||
* address too. In fact, why not just do inet_ntop on the
|
||||
* local address??? */
|
||||
|
||||
if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
|
||||
char pidbuf[16];
|
||||
@@ -526,9 +620,9 @@ int daemon_main(void)
|
||||
cleanup_set_pid(pid);
|
||||
if ((fd = do_open(lp_pid_file(), O_WRONLY|O_CREAT|O_TRUNC,
|
||||
0666 & ~orig_umask)) == -1) {
|
||||
cleanup_set_pid(0);
|
||||
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
cleanup_set_pid(0);
|
||||
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
snprintf(pidbuf, sizeof(pidbuf), "%d\n", pid);
|
||||
write(fd, pidbuf, strlen(pidbuf));
|
||||
@@ -538,4 +632,3 @@ int daemon_main(void)
|
||||
start_accept_loop(rsync_port, start_daemon);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
73
compat.c
73
compat.c
@@ -17,10 +17,16 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* compatability routines for older rsync protocol versions */
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
* Compatibility routines for older rsync protocol versions.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int remote_protocol = 0;
|
||||
|
||||
extern int am_server;
|
||||
|
||||
extern int preserve_links;
|
||||
@@ -33,43 +39,58 @@ extern int always_checksum;
|
||||
extern int checksum_seed;
|
||||
|
||||
|
||||
extern int remote_version;
|
||||
extern int protocol_version;
|
||||
extern int verbose;
|
||||
|
||||
extern int read_batch; /* dw */
|
||||
extern int write_batch; /* dw */
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
|
||||
void setup_protocol(int f_out,int f_in)
|
||||
{
|
||||
if (remote_version == 0) {
|
||||
if (remote_protocol == 0) {
|
||||
if (am_server) {
|
||||
remote_version = read_int(f_in);
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
remote_protocol = read_int(f_in);
|
||||
write_int(f_out, protocol_version);
|
||||
} else {
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
remote_version = read_int(f_in);
|
||||
write_int(f_out, protocol_version);
|
||||
remote_protocol = read_int(f_in);
|
||||
}
|
||||
if (protocol_version > remote_protocol)
|
||||
protocol_version = remote_protocol;
|
||||
}
|
||||
|
||||
if (remote_version < MIN_PROTOCOL_VERSION ||
|
||||
remote_version > MAX_PROTOCOL_VERSION) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
|
||||
am_server? "Server" : "Client", remote_protocol, protocol_version);
|
||||
}
|
||||
if (remote_protocol < MIN_PROTOCOL_VERSION
|
||||
|| remote_protocol > MAX_PROTOCOL_VERSION) {
|
||||
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
|
||||
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (remote_version >= 12) {
|
||||
if (am_server) {
|
||||
if (read_batch || write_batch) /* dw */
|
||||
checksum_seed = 32761;
|
||||
else
|
||||
checksum_seed = time(NULL);
|
||||
write_int(f_out,checksum_seed);
|
||||
} else {
|
||||
checksum_seed = read_int(f_in);
|
||||
}
|
||||
}
|
||||
|
||||
checksum_init();
|
||||
}
|
||||
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 (am_server) {
|
||||
if (read_batch || write_batch)
|
||||
checksum_seed = 32761;
|
||||
else
|
||||
checksum_seed = time(NULL);
|
||||
write_int(f_out,checksum_seed);
|
||||
} else {
|
||||
checksum_seed = read_int(f_in);
|
||||
}
|
||||
}
|
||||
|
||||
458
config.guess
vendored
458
config.guess
vendored
@@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2001-07-19'
|
||||
timestamp='2003-01-10'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -24,8 +24,9 @@ timestamp='2001-07-19'
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <bothner@cygnus.com>.
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
@@ -87,30 +88,41 @@ if test $# != 0; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap 'exit 1' 1 2 15
|
||||
|
||||
dummy=dummy-$$
|
||||
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
|
||||
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
|
||||
# compiler to aid in system detection is discouraged as it requires
|
||||
# temporary files to be created and, as you can see below, it is a
|
||||
# headache to deal with in a portable fashion.
|
||||
|
||||
# CC_FOR_BUILD -- compiler used by this script.
|
||||
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
|
||||
# use `HOST_CC' if defined, but it is deprecated.
|
||||
|
||||
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
|
||||
,,) echo "int dummy(){}" > $dummy.c ;
|
||||
for c in cc gcc c89 ; do
|
||||
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
|
||||
if test $? = 0 ; then
|
||||
# Portable tmp directory creation inspired by the Autoconf team.
|
||||
|
||||
set_cc_for_build='
|
||||
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
|
||||
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
|
||||
: ${TMPDIR=/tmp} ;
|
||||
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
|
||||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
|
||||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
|
||||
dummy=$tmp/dummy ;
|
||||
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
|
||||
case $CC_FOR_BUILD,$HOST_CC,$CC in
|
||||
,,) echo "int x;" > $dummy.c ;
|
||||
for c in cc gcc c89 c99 ; do
|
||||
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
|
||||
CC_FOR_BUILD="$c"; break ;
|
||||
fi ;
|
||||
done ;
|
||||
rm -f $dummy.c $dummy.o $dummy.rel ;
|
||||
if test x"$CC_FOR_BUILD" = x ; then
|
||||
CC_FOR_BUILD=no_compiler_found ;
|
||||
fi
|
||||
;;
|
||||
,,*) CC_FOR_BUILD=$CC ;;
|
||||
,*,*) CC_FOR_BUILD=$HOST_CC ;;
|
||||
esac'
|
||||
esac ;'
|
||||
|
||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||
# (ghazi@noc.rutgers.edu 1994-08-24)
|
||||
@@ -127,29 +139,30 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# Netbsd (nbsd) targets should (where applicable) match one or
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
# compatibility and a consistent mechanism for selecting the
|
||||
# object file format.
|
||||
# Determine the machine/vendor (is the vendor relevant).
|
||||
case "${UNAME_MACHINE}" in
|
||||
amiga) machine=m68k-unknown ;;
|
||||
arm32) machine=arm-unknown ;;
|
||||
atari*) machine=m68k-atari ;;
|
||||
sun3*) machine=m68k-sun ;;
|
||||
mac68k) machine=m68k-apple ;;
|
||||
macppc) machine=powerpc-apple ;;
|
||||
hp3[0-9][05]) machine=m68k-hp ;;
|
||||
ibmrt|romp-ibm) machine=romp-ibm ;;
|
||||
*) machine=${UNAME_MACHINE}-unknown ;;
|
||||
#
|
||||
# Note: NetBSD doesn't particularly care about the vendor
|
||||
# portion of the name. We always set it to "unknown".
|
||||
sysctl="sysctl -n hw.machine_arch"
|
||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
armeb) machine=armeb-unknown ;;
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
# to ELF recently, or will in the future.
|
||||
case "${UNAME_MACHINE}" in
|
||||
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep __ELF__ >/dev/null
|
||||
@@ -166,12 +179,65 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
# Debian GNU/NetBSD machines have a different userland, and
|
||||
# thus, need a distinct triplet. However, they do not need
|
||||
# kernel version information, so it can be replaced with a
|
||||
# suitable tag, in the style of linux-gnu.
|
||||
case "${UNAME_VERSION}" in
|
||||
Debian*)
|
||||
release='-gnu'
|
||||
;;
|
||||
*)
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
;;
|
||||
esac
|
||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
macppc:OpenBSD:*:*)
|
||||
echo powerpc-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvmeppc:OpenBSD:*:*)
|
||||
echo powerpc-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mipseb-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:MicroBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
@@ -180,6 +246,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
eval $set_cc_for_build
|
||||
cat <<EOF >$dummy.s
|
||||
.data
|
||||
\$Lformat:
|
||||
@@ -205,10 +272,9 @@ main:
|
||||
jsr \$26,exit
|
||||
.end main
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
|
||||
$CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
case `./$dummy` in
|
||||
case `$dummy` in
|
||||
0-0)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
@@ -227,9 +293,14 @@ EOF
|
||||
2-307)
|
||||
UNAME_MACHINE="alphaev67"
|
||||
;;
|
||||
2-1307)
|
||||
UNAME_MACHINE="alphaev68"
|
||||
;;
|
||||
3-1307)
|
||||
UNAME_MACHINE="alphaev7"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -f $dummy.s $dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit 0 ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
@@ -244,29 +315,11 @@ EOF
|
||||
Amiga*:UNIX_System_V:4.0:*)
|
||||
echo m68k-unknown-sysv4
|
||||
exit 0;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:[Aa]miga[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-amigaos
|
||||
exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hkmips:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
*:[Mm]orph[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-morphos
|
||||
exit 0 ;;
|
||||
*:OS/390:*:*)
|
||||
echo i370-ibm-openedition
|
||||
@@ -288,6 +341,10 @@ EOF
|
||||
NILE*:*:*:dcosx)
|
||||
echo pyramid-pyramid-svr4
|
||||
exit 0 ;;
|
||||
DRS?6000:UNIX_SV:4.2*:7*)
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7 && exit 0 ;;
|
||||
esac ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
@@ -316,7 +373,7 @@ EOF
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun*:*:4.2BSD:*)
|
||||
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
||||
case "`/bin/arch`" in
|
||||
sun3)
|
||||
@@ -330,9 +387,6 @@ EOF
|
||||
aushp:SunOS:*:*)
|
||||
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
# The situation for MiNT is a little confusing. The machine name
|
||||
# can be virtually everything (everything which is not
|
||||
# "atarist" or "atariste" at least should have a processor
|
||||
@@ -359,18 +413,6 @@ EOF
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -387,6 +429,7 @@ EOF
|
||||
echo clipper-intergraph-clix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
@@ -408,16 +451,20 @@ EOF
|
||||
exit (-1);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy \
|
||||
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c \
|
||||
&& $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& exit 0
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Motorola:PowerMAX_OS:*:*)
|
||||
echo powerpc-motorola-powermax
|
||||
exit 0 ;;
|
||||
Motorola:*:4.3:PL8-*)
|
||||
echo powerpc-harris-powermax
|
||||
exit 0 ;;
|
||||
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
|
||||
echo powerpc-harris-powermax
|
||||
exit 0 ;;
|
||||
Night_Hawk:Power_UNIX:*:*)
|
||||
echo powerpc-harris-powerunix
|
||||
exit 0 ;;
|
||||
@@ -478,6 +525,7 @@ EOF
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
@@ -489,9 +537,7 @@ EOF
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
|
||||
echo rs6000-ibm-aix3.2.5
|
||||
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
echo rs6000-ibm-aix3.2.4
|
||||
@@ -500,7 +546,7 @@ EOF
|
||||
fi
|
||||
exit 0 ;;
|
||||
*:AIX:*:[45])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
else
|
||||
@@ -540,10 +586,8 @@ EOF
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/[678][0-9][0-9])
|
||||
case "${HPUX_REV}" in
|
||||
11.[0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
@@ -552,12 +596,13 @@ EOF
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
fi ;;
|
||||
esac
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
@@ -590,12 +635,21 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
|
||||
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
|
||||
rm -f $dummy.c $dummy
|
||||
fi ;;
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
fi ;;
|
||||
esac
|
||||
if [ ${HP_ARCH} = "hppa2.0w" ]
|
||||
then
|
||||
# avoid double evaluation of $set_cc_for_build
|
||||
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
HP_ARCH="hppa64"
|
||||
fi
|
||||
fi
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
ia64:HP-UX:*:*)
|
||||
@@ -603,6 +657,7 @@ EOF
|
||||
echo ia64-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
@@ -628,9 +683,7 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
|
||||
echo unknown-hitachi-hiuxwe2
|
||||
exit 0 ;;
|
||||
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||
@@ -658,9 +711,6 @@ EOF
|
||||
parisc*:Lites*:*:*)
|
||||
echo hppa1.1-hp-lites
|
||||
exit 0 ;;
|
||||
hppa*:OpenBSD:*:*)
|
||||
echo hppa-unknown-openbsd
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
@@ -679,9 +729,6 @@ EOF
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
CRAY*X-MP:*:*:*)
|
||||
echo xmp-cray-unicos
|
||||
exit 0 ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
@@ -694,27 +741,21 @@ EOF
|
||||
CRAY*TS:*:*:*)
|
||||
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*T3D:*:*:*)
|
||||
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*T3E:*:*:*)
|
||||
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*SV1:*:*:*)
|
||||
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
*:UNICOS/mp:*:*)
|
||||
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -725,10 +766,18 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:FreeBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
# Determine whether the default compiler uses glibc.
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
|
||||
exit 0 ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
@@ -739,11 +788,17 @@ EOF
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit 0 ;;
|
||||
x86:Interix*:3*)
|
||||
echo i586-pc-interix3
|
||||
exit 0 ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit 0 ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
# UNAME_MACHINE based on the output of uname instead of i386?
|
||||
echo i386-pc-interix
|
||||
echo i586-pc-interix
|
||||
exit 0 ;;
|
||||
i*:UWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-uwin
|
||||
@@ -764,16 +819,48 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
mips:Linux:*:*)
|
||||
case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
|
||||
big) echo mips-unknown-linux-gnu && exit 0 ;;
|
||||
little) echo mipsel-unknown-linux-gnu && exit 0 ;;
|
||||
esac
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
|
||||
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
|
||||
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
|
||||
;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
@@ -789,7 +876,7 @@ EOF
|
||||
PCA57) UNAME_MACHINE=alphapca56 ;;
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
@@ -822,7 +909,8 @@ EOF
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
ld_supported_targets=`cd /; ld --help 2>&1 \
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
@@ -834,7 +922,7 @@ EOF
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit 0 ;;
|
||||
@@ -845,33 +933,29 @@ EOF
|
||||
exit 0 ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >$dummy.c <<EOF
|
||||
#include <features.h>
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
int main (int argc, char *argv[]) {
|
||||
#else
|
||||
int main (argc, argv) int argc; char *argv[]; {
|
||||
#endif
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
printf ("%s-pc-linux-gnu\n", argv[1]);
|
||||
# else
|
||||
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
# else
|
||||
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
#else
|
||||
printf ("%s-pc-linux-gnuaout\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#ifdef __INTEL_COMPILER
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
|
||||
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
|
||||
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
@@ -888,6 +972,23 @@ EOF
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit 0 ;;
|
||||
i*86:OS/2:*:*)
|
||||
# If we were able to find `uname', then EMX Unix compatibility
|
||||
# is probably installed.
|
||||
echo ${UNAME_MACHINE}-pc-os2-emx
|
||||
exit 0 ;;
|
||||
i*86:XTS-300:*:STOP)
|
||||
echo ${UNAME_MACHINE}-unknown-stop
|
||||
exit 0 ;;
|
||||
i*86:atheos:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-atheos
|
||||
exit 0 ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i*86:*DOS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
|
||||
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
|
||||
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||
@@ -909,22 +1010,19 @@ EOF
|
||||
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
|
||||
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
|
||||
elif /bin/uname -X 2>/dev/null >/dev/null ; then
|
||||
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
|
||||
&& UNAME_MACHINE=i586
|
||||
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
|
||||
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
|
||||
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
i*86:*DOS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
@@ -948,9 +1046,15 @@ EOF
|
||||
# "miniframe"
|
||||
echo m68010-convergent-sysv
|
||||
exit 0 ;;
|
||||
mc68k:UNIX:SYSTEM5:3.51m)
|
||||
echo m68k-convergent-sysv
|
||||
exit 0 ;;
|
||||
M680?0:D-NIX:5.3:*)
|
||||
echo m68k-diab-dnix
|
||||
exit 0 ;;
|
||||
M68*:*:R3V[567]*:*)
|
||||
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
|
||||
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
|
||||
OS_REL=''
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
@@ -967,9 +1071,6 @@ EOF
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.*:*)
|
||||
echo sparc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -996,8 +1097,8 @@ EOF
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit 0 ;;
|
||||
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
@@ -1009,6 +1110,10 @@ EOF
|
||||
# From seanf@swdc.stratus.com.
|
||||
echo i860-stratus-sysv4
|
||||
exit 0 ;;
|
||||
*:VOS:*:*)
|
||||
# From Paul.Green@stratus.com.
|
||||
echo hppa1.1-stratus-vos
|
||||
exit 0 ;;
|
||||
mc68*:A/UX:*:*)
|
||||
echo m68k-apple-aux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -1037,6 +1142,9 @@ EOF
|
||||
SX-5:SUPER-UX:*:*)
|
||||
echo sx5-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -1044,18 +1152,24 @@ EOF
|
||||
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:Darwin:*:*)
|
||||
echo `uname -p`-apple-darwin${UNAME_RELEASE}
|
||||
case `uname -p` in
|
||||
*86) UNAME_PROCESSOR=i686 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
if test "${UNAME_MACHINE}" = "x86pc"; then
|
||||
UNAME_PROCESSOR=`uname -p`
|
||||
if test "$UNAME_PROCESSOR" = "x86"; then
|
||||
UNAME_PROCESSOR=i386
|
||||
UNAME_MACHINE=pc
|
||||
fi
|
||||
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
|
||||
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit 0 ;;
|
||||
NSR-[KW]:NONSTOP_KERNEL:*:*)
|
||||
NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
|
||||
echo nsr-tandem-nsk${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:NonStop-UX:*:*)
|
||||
@@ -1078,11 +1192,6 @@ EOF
|
||||
fi
|
||||
echo ${UNAME_MACHINE}-unknown-plan9
|
||||
exit 0 ;;
|
||||
i*86:OS/2:*:*)
|
||||
# If we were able to find `uname', then EMX Unix compatibility
|
||||
# is probably installed.
|
||||
echo ${UNAME_MACHINE}-pc-os2-emx
|
||||
exit 0 ;;
|
||||
*:TOPS-10:*:*)
|
||||
echo pdp10-unknown-tops10
|
||||
exit 0 ;;
|
||||
@@ -1106,6 +1215,7 @@ esac
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
@@ -1220,9 +1330,7 @@ main ()
|
||||
}
|
||||
EOF
|
||||
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
|
||||
325
config.sub
vendored
325
config.sub
vendored
@@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2001-06-08'
|
||||
timestamp='2003-01-22'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -29,7 +29,8 @@ timestamp='2001-06-08'
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
@@ -117,7 +118,7 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@@ -223,26 +224,48 @@ esac
|
||||
case $basic_machine in
|
||||
# Recognize the basic CPU types without company name.
|
||||
# Some are omitted here because they have special meanings below.
|
||||
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
|
||||
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
|
||||
| pyramid | mn10200 | mn10300 | tron | a29k \
|
||||
| 580 | i960 | h8300 \
|
||||
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
|
||||
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
|
||||
| hppa64 \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
|
||||
| alphaev6[78] \
|
||||
| we32k | ns16k | clipper | i370 | sh | sh[34] \
|
||||
| powerpc | powerpcle \
|
||||
| 1750a | dsp16xx | pdp10 | pdp11 \
|
||||
| mips16 | mips64 | mipsel | mips64el \
|
||||
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
|
||||
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
|
||||
| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
|
||||
| v850 | c4x \
|
||||
| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
|
||||
| pj | pjl | h8500 | z8k)
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| msp430 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
@@ -265,31 +288,58 @@ case $basic_machine in
|
||||
exit 1
|
||||
;;
|
||||
# Recognize the basic CPU types with company name.
|
||||
# FIXME: clean up the formatting here.
|
||||
vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
|
||||
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
|
||||
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
|
||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
|
||||
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
|
||||
| xmp-* | ymp-* \
|
||||
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
|
||||
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
|
||||
| hppa2.0n-* | hppa64-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
|
||||
| alphaev6[78]-* \
|
||||
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
|
||||
| clipper-* | orion-* \
|
||||
| sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
|
||||
| powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
|
||||
| mips16-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
|
||||
| mipstx39-* | mipstx39el-* | mcore-* \
|
||||
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
|
||||
| [cjt]90-* \
|
||||
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
|
||||
| thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
|
||||
| bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| msp430-* \
|
||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -352,6 +402,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -372,16 +426,8 @@ case $basic_machine in
|
||||
basic_machine=c38-convex
|
||||
os=-bsd
|
||||
;;
|
||||
cray | ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cray2)
|
||||
basic_machine=cray2-cray
|
||||
os=-unicos
|
||||
;;
|
||||
[cjt]90)
|
||||
basic_machine=${basic_machine}-cray
|
||||
cray | j90)
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -396,6 +442,14 @@ case $basic_machine in
|
||||
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
|
||||
basic_machine=mips-dec
|
||||
;;
|
||||
decsystem10* | dec10*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops10
|
||||
;;
|
||||
decsystem20* | dec20*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops20
|
||||
;;
|
||||
delta | 3300 | motorola-3300 | motorola-delta \
|
||||
| 3300-motorola | delta-motorola)
|
||||
basic_machine=m68k-motorola
|
||||
@@ -576,14 +630,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-atari
|
||||
os=-mint
|
||||
;;
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips*-linux*)
|
||||
basic_machine=mips-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips3*-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||
;;
|
||||
@@ -598,6 +644,10 @@ case $basic_machine in
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
;;
|
||||
morphos)
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@@ -670,6 +720,10 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
nv1)
|
||||
basic_machine=nv1-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -677,6 +731,10 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
os=-ose
|
||||
@@ -699,19 +757,19 @@ case $basic_machine in
|
||||
pbb)
|
||||
basic_machine=m68k-tti
|
||||
;;
|
||||
pc532 | pc532-*)
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen)
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | 6x86 | athlon)
|
||||
pentiumpro | p6 | 6x86 | athlon | athlon_*)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
||||
@@ -726,15 +784,25 @@ case $basic_machine in
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ps2)
|
||||
basic_machine=i386-ibm
|
||||
;;
|
||||
@@ -752,10 +820,22 @@ case $basic_machine in
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
s390 | s390-*)
|
||||
basic_machine=s390-ibm
|
||||
;;
|
||||
s390x | s390x-*)
|
||||
basic_machine=s390x-ibm
|
||||
;;
|
||||
sa29200)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
sb1)
|
||||
basic_machine=mipsisa64sb1-unknown
|
||||
;;
|
||||
sb1el)
|
||||
basic_machine=mipsisa64sb1el-unknown
|
||||
;;
|
||||
sequent)
|
||||
basic_machine=i386-sequent
|
||||
;;
|
||||
@@ -763,7 +843,7 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sparclite-wrs)
|
||||
sparclite-wrs | simso-wrs)
|
||||
basic_machine=sparclite-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
@@ -830,9 +910,17 @@ case $basic_machine in
|
||||
os=-dynix
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=t3e-cray
|
||||
basic_machine=alphaev5-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t90)
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic4x | c4x*)
|
||||
basic_machine=tic4x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
@@ -843,6 +931,10 @@ case $basic_machine in
|
||||
tx39el)
|
||||
basic_machine=mipstx39el-unknown
|
||||
;;
|
||||
toad1)
|
||||
basic_machine=pdp10-xkl
|
||||
os=-tops20
|
||||
;;
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
@@ -867,8 +959,8 @@ case $basic_machine in
|
||||
os=-vms
|
||||
;;
|
||||
vpp*|vx|vx-*)
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
vxworks960)
|
||||
basic_machine=i960-wrs
|
||||
os=-vxworks
|
||||
@@ -889,17 +981,13 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
windows32)
|
||||
basic_machine=i386-pc
|
||||
os=-windows32-msvcrt
|
||||
;;
|
||||
xmp)
|
||||
basic_machine=xmp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
xps | xps100)
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
z8k-*-coff)
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
@@ -920,13 +1008,6 @@ case $basic_machine in
|
||||
op60c)
|
||||
basic_machine=hppa1.1-oki
|
||||
;;
|
||||
mips)
|
||||
if [ x$os = x-linux-gnu ]; then
|
||||
basic_machine=mips-unknown
|
||||
else
|
||||
basic_machine=mips-mips
|
||||
fi
|
||||
;;
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
@@ -946,13 +1027,16 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4)
|
||||
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
cydra)
|
||||
basic_machine=cydra-cydrome
|
||||
;;
|
||||
orion)
|
||||
@@ -967,10 +1051,6 @@ case $basic_machine in
|
||||
pmac | pmac-mpw)
|
||||
basic_machine=powerpc-apple
|
||||
;;
|
||||
c4x*)
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*-unknown)
|
||||
# Make sure to match an already-canonicalized machine name.
|
||||
;;
|
||||
@@ -1033,9 +1113,12 @@ case $os in
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -microbsd*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1047,8 +1130,10 @@ case $os in
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-nto-qnx*)
|
||||
;;
|
||||
-nto*)
|
||||
os=-nto-qnx
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
@@ -1087,14 +1172,20 @@ case $os in
|
||||
-acis*)
|
||||
os=-aos
|
||||
;;
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
-ctix* | -uts*)
|
||||
os=-sysv
|
||||
;;
|
||||
-nova*)
|
||||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk*)
|
||||
os=-nsk
|
||||
@@ -1133,8 +1224,11 @@ case $os in
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
;;
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
@@ -1167,10 +1261,11 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
;;
|
||||
pdp11-*)
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
*-dec | vax-*)
|
||||
@@ -1197,6 +1292,9 @@ case $basic_machine in
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
or32-*)
|
||||
os=-coff
|
||||
;;
|
||||
*-tti) # must be before sparc entry or we get the wrong os.
|
||||
os=-sysv3
|
||||
;;
|
||||
@@ -1260,19 +1358,19 @@ case $basic_machine in
|
||||
*-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
*-gould)
|
||||
*-gould)
|
||||
os=-sysv
|
||||
;;
|
||||
*-highlevel)
|
||||
*-highlevel)
|
||||
os=-bsd
|
||||
;;
|
||||
*-encore)
|
||||
os=-bsd
|
||||
;;
|
||||
*-sgi)
|
||||
*-sgi)
|
||||
os=-irix
|
||||
;;
|
||||
*-siemens)
|
||||
*-siemens)
|
||||
os=-sysv4
|
||||
;;
|
||||
*-masscomp)
|
||||
@@ -1344,7 +1442,7 @@ case $basic_machine in
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-vxsim* | -vxworks*)
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
-aux*)
|
||||
@@ -1359,6 +1457,9 @@ case $basic_machine in
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
vendor=atari
|
||||
;;
|
||||
-vos*)
|
||||
vendor=stratus
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
|
||||
103
configure.in
103
configure.in
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
RSYNC_VERSION=2.5.2pre3
|
||||
RSYNC_VERSION=2.5.7
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
@@ -25,7 +25,7 @@ AC_SUBST(SHELL)
|
||||
AC_DEFINE([_GNU_SOURCE], 1,
|
||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||
|
||||
if test "$xac_cv_prog_cc_stdc" = xno
|
||||
if test "x$ac_cv_prog_cc_stdc" = xno
|
||||
then
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
|
||||
fi
|
||||
@@ -65,6 +65,17 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# Specifically, this turns on panic_action handling.
|
||||
AC_ARG_ENABLE(maintainer-mode,
|
||||
AC_HELP_STRING([--enable-maintainer-mode],
|
||||
[turn on extra debug features],
|
||||
[], []))
|
||||
if test x"$enable_maintainer_mode" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
|
||||
fi
|
||||
|
||||
|
||||
# This is needed for our included version of popt. Kind of silly, but
|
||||
# I don't want our version too far out of sync.
|
||||
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
|
||||
@@ -82,11 +93,26 @@ AC_ARG_WITH(rsync-path,
|
||||
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: \"rsync\")],
|
||||
[ RSYNC_PATH="$with_rsync_path" ],
|
||||
[ RSYNC_PATH="rsync" ])
|
||||
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [ ])
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
|
||||
|
||||
AC_ARG_WITH(rsh,
|
||||
AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"rsh\")]))
|
||||
|
||||
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
|
||||
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [ ])
|
||||
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
|
||||
|
||||
if test x"$with_rsh" != x
|
||||
then
|
||||
RSYNC_RSH="$with_rsh"
|
||||
elif test x"$HAVE_REMSH" = x1
|
||||
then
|
||||
RSYNC_RSH="remsh"
|
||||
else
|
||||
RSYNC_RSH="rsh"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
|
||||
|
||||
# arrgh. libc in the current debian stable screws up the largefile
|
||||
# stuff, getting byte range locking wrong
|
||||
@@ -221,16 +247,26 @@ yes
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to call shutdown on all sockets])
|
||||
case $host_os in
|
||||
*cygwin* ) AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(SHUTDOWN_ALL_SOCKETS, 1,
|
||||
[Define if sockets need to be shutdown])
|
||||
;;
|
||||
* ) AC_MSG_RESULT(no);;
|
||||
esac
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h sys/un.h)
|
||||
AC_CHECK_HEADERS(glob.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(netdb.h)
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
AC_CHECK_HEADERS(float.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -300,8 +336,39 @@ dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
|
||||
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
# Irix 6.5 has getaddrinfo but not the corresponding defines, so use
|
||||
# builtin getaddrinfo if one of the defines don't exist
|
||||
AC_CACHE_CHECK([whether defines needed by getaddrinfo exist],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES,[
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#ifdef AI_PASSIVE
|
||||
yes
|
||||
#endif],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=yes,
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=no)])
|
||||
if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes"; then
|
||||
# Tru64 UNIX has getaddrinfo() but has it renamed in libc as
|
||||
# something else so we must include <netdb.h> to get the
|
||||
# redefinition.
|
||||
AC_CHECK_FUNCS(getaddrinfo, ,
|
||||
[AC_MSG_CHECKING([for getaddrinfo by including <netdb.h>])
|
||||
AC_TRY_LINK([#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>],[getaddrinfo(NULL, NULL, NULL, NULL);],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_GETADDRINFO, 1,
|
||||
[Define if you have the `getaddrinfo' function.])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_LIBOBJ(lib/getaddrinfo)])])
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
else
|
||||
AC_LIBOBJ(lib/getaddrinfo)
|
||||
AC_LIBOBJ(lib/getnameinfo)
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
@@ -320,6 +387,15 @@ AC_TRY_COMPILE([#include <sys/types.h>
|
||||
[Define if you have strct sockaddr_storage.] ),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
])
|
||||
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
@@ -333,10 +409,11 @@ dnl every platform has a memcmp that can do at least that.
|
||||
dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy strtol mtrace mallinfo setgroups)
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([
|
||||
@@ -372,6 +449,12 @@ then
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
BUILD_POPT='$(popt_OBJS)'
|
||||
CFLAGS="$CFLAGS -I$srcdir/popt"
|
||||
if test x"$ALLOCA" != x
|
||||
then
|
||||
# this can be removed when/if we add an included alloca.c;
|
||||
# see autoconf documentation on AC_FUNC_ALLOCA
|
||||
AC_MSG_WARN([included libpopt will use malloc, not alloca (which wastes a small amount of memory)])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
2
doc/.cvsignore
Normal file
2
doc/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
rsync.pdf
|
||||
rsync.ps
|
||||
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 ommitted 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>
|
||||
@@ -19,13 +19,15 @@
|
||||
|
||||
/*
|
||||
* error codes returned by rsync. If you change these, please also update the
|
||||
* string mappings in log.c
|
||||
* 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 */
|
||||
|
||||
79
exclude.c
79
exclude.c
@@ -1,22 +1,23 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 1996 by Paul Mackerras
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 1996 by Paul Mackerras
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* a lot of this stuff was originally derived from GNU tar, although
|
||||
it has now changed so much that it is hard to tell :) */
|
||||
@@ -30,12 +31,12 @@ extern int delete_mode;
|
||||
|
||||
static struct exclude_struct **exclude_list;
|
||||
|
||||
/* build an exclude structure given a exclude pattern */
|
||||
/** Build an exclude structure given a exclude pattern */
|
||||
static struct exclude_struct *make_exclude(const char *pattern, int include)
|
||||
{
|
||||
struct exclude_struct *ret;
|
||||
|
||||
ret = (struct exclude_struct *)malloc(sizeof(*ret));
|
||||
ret = new(struct exclude_struct);
|
||||
if (!ret) out_of_memory("make_exclude");
|
||||
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
@@ -196,14 +197,16 @@ void add_exclude_list(const char *pattern, struct exclude_struct ***list, int in
|
||||
return;
|
||||
}
|
||||
|
||||
*list = (struct exclude_struct **)Realloc(*list,sizeof(struct exclude_struct *)*(len+2));
|
||||
*list = realloc_array(*list, struct exclude_struct *, len+2);
|
||||
|
||||
if (!*list || !((*list)[len] = make_exclude(pattern, include)))
|
||||
out_of_memory("add_exclude");
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"add_exclude(%s)\n",pattern);
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"add_exclude(%s,%s)\n",pattern,
|
||||
include ? "include" : "exclude");
|
||||
}
|
||||
|
||||
(*list)[len+1] = NULL;
|
||||
}
|
||||
|
||||
@@ -217,8 +220,14 @@ struct exclude_struct **make_exclude_list(const char *fname,
|
||||
int fatal, int include)
|
||||
{
|
||||
struct exclude_struct **list=list1;
|
||||
FILE *f = fopen(fname,"r");
|
||||
FILE *f;
|
||||
char line[MAXPATHLEN];
|
||||
|
||||
if (strcmp(fname, "-")) {
|
||||
f = fopen(fname,"r");
|
||||
} else {
|
||||
f = fdopen(0, "r");
|
||||
}
|
||||
if (!f) {
|
||||
if (fatal) {
|
||||
rsyserr(FERROR, errno,
|
||||
@@ -232,7 +241,7 @@ struct exclude_struct **make_exclude_list(const char *fname,
|
||||
|
||||
while (fgets(line,MAXPATHLEN,f)) {
|
||||
int l = strlen(line);
|
||||
if (l && line[l-1] == '\n') l--;
|
||||
while (l && (line[l-1] == '\n' || line[l-1] == '\r')) l--;
|
||||
line[l] = 0;
|
||||
if (line[0] && (line[0] != ';') && (line[0] != '#')) {
|
||||
/* Skip lines starting with semicolon or pound.
|
||||
@@ -260,7 +269,10 @@ void send_exclude_list(int f)
|
||||
extern int remote_version;
|
||||
extern int list_only, recurse;
|
||||
|
||||
/* this is a complete hack - blame Rusty */
|
||||
/* This is a complete hack - blame Rusty.
|
||||
*
|
||||
* FIXME: This pattern shows up in the output of
|
||||
* report_exclude_result(), which is not ideal. */
|
||||
if (list_only && !recurse) {
|
||||
add_exclude("/*/*", 0);
|
||||
}
|
||||
@@ -329,7 +341,7 @@ char *get_exclude_tok(char *p)
|
||||
return(NULL);
|
||||
|
||||
/* Skip over any initial spaces */
|
||||
while(isspace(*s))
|
||||
while (isspace(* (unsigned char *) s))
|
||||
s++;
|
||||
|
||||
/* Are we at the end of the string? */
|
||||
@@ -342,7 +354,7 @@ char *get_exclude_tok(char *p)
|
||||
s+=2;
|
||||
|
||||
/* Skip to the next space or the end of the string */
|
||||
while(!isspace(*s) && *s!='\0')
|
||||
while (!isspace(* (unsigned char *) s) && *s != '\0')
|
||||
s++;
|
||||
} else {
|
||||
t=NULL;
|
||||
@@ -381,12 +393,11 @@ void add_include_line(char *p)
|
||||
|
||||
|
||||
static char *cvs_ignore_list[] = {
|
||||
"RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
|
||||
"tags","TAGS",".make.state",".nse_depinfo",
|
||||
"*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig",
|
||||
"RCS/", "SCCS/", "CVS/", ".svn/", "CVS.adm", "RCSLOG", "cvslog.*",
|
||||
"tags", "TAGS", ".make.state", ".nse_depinfo",
|
||||
"*~", "#*", ".#*", ", *", "*.old", "*.bak", "*.BAK", "*.orig",
|
||||
"*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln",
|
||||
"core",NULL};
|
||||
|
||||
"core", NULL};
|
||||
|
||||
|
||||
void add_cvs_excludes(void)
|
||||
|
||||
14
fileio.c
14
fileio.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -38,7 +39,7 @@ int sparse_end(int f)
|
||||
|
||||
static int write_sparse(int f,char *buf,size_t len)
|
||||
{
|
||||
int l1=0,l2=0;
|
||||
size_t l1=0, l2=0;
|
||||
int ret;
|
||||
|
||||
for (l1=0;l1<len && buf[l1]==0;l1++) ;
|
||||
@@ -56,10 +57,11 @@ static int write_sparse(int f,char *buf,size_t len)
|
||||
if (l1 == len)
|
||||
return len;
|
||||
|
||||
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
|
||||
if (ret == -1 || ret == 0) return ret;
|
||||
ret = write(f, buf + l1, len - (l1+l2));
|
||||
if (ret == -1 || ret == 0)
|
||||
return ret;
|
||||
else if (ret != (int) (len - (l1+l2)))
|
||||
return (l1+ret);
|
||||
}
|
||||
|
||||
if (l2 > 0)
|
||||
do_lseek(f,l2,SEEK_CUR);
|
||||
@@ -100,7 +102,7 @@ int write_file(int f,char *buf,size_t len)
|
||||
struct map_struct *map_file(int fd,OFF_T len)
|
||||
{
|
||||
struct map_struct *map;
|
||||
map = (struct map_struct *)malloc(sizeof(*map));
|
||||
map = new(struct map_struct);
|
||||
if (!map) out_of_memory("map_file");
|
||||
|
||||
map->fd = fd;
|
||||
@@ -154,7 +156,7 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
|
||||
/* make sure we have allocated enough memory for the window */
|
||||
if (window_size > map->p_size) {
|
||||
map->p = (char *)Realloc(map->p, window_size);
|
||||
map->p = realloc_array(map->p, char, window_size);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p_size = window_size;
|
||||
}
|
||||
|
||||
423
generator.c
423
generator.c
@@ -1,21 +1,21 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
@@ -31,16 +31,16 @@ extern int am_root;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_hard_links;
|
||||
extern int update_only;
|
||||
extern int whole_file;
|
||||
extern int block_size;
|
||||
extern int opt_ignore_existing;
|
||||
extern int csum_length;
|
||||
extern int ignore_times;
|
||||
extern int size_only;
|
||||
extern int io_timeout;
|
||||
extern int remote_version;
|
||||
extern int protocol_version;
|
||||
extern int always_checksum;
|
||||
extern int modify_window;
|
||||
extern char *compare_dest;
|
||||
extern int link_dest;
|
||||
|
||||
|
||||
/* choose whether to skip a particular file */
|
||||
@@ -50,8 +50,23 @@ static int skip_file(char *fname,
|
||||
if (st->st_size != file->length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if always checksum is set then we use the checksum instead
|
||||
if (link_dest) {
|
||||
extern int preserve_perms;
|
||||
extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
|
||||
if(preserve_perms
|
||||
&& (st->st_mode & ~_S_IFMT) != (file->mode & ~_S_IFMT))
|
||||
return 0;
|
||||
|
||||
if (preserve_uid && st->st_uid != file->uid)
|
||||
return 0;
|
||||
|
||||
if (preserve_gid && st->st_gid != file->gid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if always checksum is set then we use the checksum instead
|
||||
of the file time to determine whether to sync */
|
||||
if (always_checksum && S_ISREG(st->st_mode)) {
|
||||
char sum[MD4_SUM_LENGTH];
|
||||
@@ -60,12 +75,12 @@ static int skip_file(char *fname,
|
||||
if (compare_dest != NULL) {
|
||||
if (access(fname, 0) != 0) {
|
||||
snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
|
||||
compare_dest,fname);
|
||||
compare_dest,fname);
|
||||
fname = fnamecmpdest;
|
||||
}
|
||||
}
|
||||
file_checksum(fname,sum,st->st_size);
|
||||
if (remote_version < 21) {
|
||||
if (protocol_version < 21) {
|
||||
return (memcmp(sum,file->sum,2) == 0);
|
||||
} else {
|
||||
return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
|
||||
@@ -84,122 +99,179 @@ static int skip_file(char *fname,
|
||||
}
|
||||
|
||||
|
||||
/* use a larger block size for really big files */
|
||||
static int adapt_block_size(struct file_struct *file, int bsize)
|
||||
/*
|
||||
* NULL sum_struct means we have no checksums
|
||||
*/
|
||||
|
||||
void write_sum_head(int f, struct sum_struct *sum)
|
||||
{
|
||||
int ret;
|
||||
static struct sum_struct null_sum;
|
||||
|
||||
if (bsize != BLOCK_SIZE) return bsize;
|
||||
if (sum == (struct sum_struct *)NULL)
|
||||
sum = &null_sum;
|
||||
|
||||
ret = file->length / (10000); /* rough heuristic */
|
||||
ret = ret & ~15; /* multiple of 16 */
|
||||
if (ret < bsize) ret = bsize;
|
||||
if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
|
||||
return ret;
|
||||
write_int(f, sum->count);
|
||||
write_int(f, sum->blength);
|
||||
if (protocol_version >= 27)
|
||||
write_int(f, sum->s2length);
|
||||
write_int(f, sum->remainder);
|
||||
}
|
||||
|
||||
/*
|
||||
* set (initialize) the size entries in the per-file sum_struct
|
||||
* calulating dynamic block ans checksum sizes.
|
||||
*
|
||||
* This is only called from generate_and_send_sums() but is a seperate
|
||||
* function to encapsulate the logic.
|
||||
*
|
||||
* The block size is a rounded square root of file length.
|
||||
*
|
||||
* The checksum size is determined according to:
|
||||
* blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
|
||||
* provided by Donovan Baarda which gives a probability of rsync
|
||||
* algorithm corrupting data and falling back using the whole md4
|
||||
* checksums.
|
||||
*
|
||||
* This might be made one of several selectable heuristics.
|
||||
*/
|
||||
|
||||
/*
|
||||
send a sums struct down a fd
|
||||
*/
|
||||
static void send_sums(struct sum_struct *s, int f_out)
|
||||
static void sum_sizes_sqroot_baarda(struct sum_struct *sum, uint64 len)
|
||||
{
|
||||
if (s) {
|
||||
size_t i;
|
||||
extern int block_size;
|
||||
int blength, s2length, b;
|
||||
uint32 c;
|
||||
uint64 l;
|
||||
|
||||
/* tell the other guy how many we are going to be
|
||||
doing and how many bytes there are in the last
|
||||
chunk */
|
||||
write_int(f_out, s->count);
|
||||
write_int(f_out, s->n);
|
||||
write_int(f_out, s->remainder);
|
||||
|
||||
for (i = 0; i < s->count; i++) {
|
||||
write_int(f_out, s->sums[i].sum1);
|
||||
write_buf(f_out, s->sums[i].sum2, csum_length);
|
||||
}
|
||||
if (block_size) {
|
||||
blength = block_size;
|
||||
} else if (len <= BLOCK_SIZE * BLOCK_SIZE) {
|
||||
blength = BLOCK_SIZE;
|
||||
} else {
|
||||
/* we don't have checksums */
|
||||
write_int(f_out, 0);
|
||||
write_int(f_out, block_size);
|
||||
write_int(f_out, 0);
|
||||
l = len;
|
||||
c = 1;
|
||||
while (l >>= 2) {
|
||||
c <<= 1;
|
||||
}
|
||||
blength = 0;
|
||||
do {
|
||||
blength |= c;
|
||||
if (len < (uint64)blength * blength)
|
||||
blength &= ~c;
|
||||
c >>= 1;
|
||||
} while (c >= 8); /* round to multiple of 8 */
|
||||
blength = MAX(blength, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (protocol_version < 27) {
|
||||
s2length = csum_length;
|
||||
} else if (csum_length == SUM_LENGTH) {
|
||||
s2length = SUM_LENGTH;
|
||||
} else {
|
||||
b = BLOCKSUM_BIAS;
|
||||
l = len;
|
||||
while (l >>= 1) {
|
||||
b += 2;
|
||||
}
|
||||
c = blength;
|
||||
while (c >>= 1 && b) {
|
||||
b--;
|
||||
}
|
||||
s2length = (b + 1 - 32 + 7) / 8; /* add a bit,
|
||||
* subtract rollsum,
|
||||
* round up
|
||||
* --optimize in compiler--
|
||||
*/
|
||||
s2length = MAX(s2length, csum_length);
|
||||
s2length = MIN(s2length, SUM_LENGTH);
|
||||
}
|
||||
|
||||
sum->flength = len;
|
||||
sum->blength = blength;
|
||||
sum->s2length = s2length;
|
||||
sum->count = (len + (blength - 1)) / blength;
|
||||
sum->remainder = (len % blength);
|
||||
|
||||
if (sum->count && verbose > 2) {
|
||||
rprintf(FINFO, "count=%ld rem=%ld blength=%ld s2length=%ld flength=%.0f\n",
|
||||
(long) sum->count, (long) sum->remainder,
|
||||
(long) sum->blength, (long) sum->s2length,
|
||||
(double) sum->flength);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
generate a stream of signatures/checksums that describe a buffer
|
||||
|
||||
generate approximately one checksum every n bytes
|
||||
*/
|
||||
static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
|
||||
/**
|
||||
* Perhaps we want to just send an empty checksum set for this file,
|
||||
* which will force the whole thing to be literally transferred.
|
||||
*
|
||||
* When do we do this? If the user's explicitly said they
|
||||
* want the whole thing, or if { they haven't explicitly
|
||||
* requested a delta, and it's local but not batch mode.}
|
||||
*
|
||||
* Whew. */
|
||||
static BOOL disable_deltas_p(void)
|
||||
{
|
||||
int i;
|
||||
struct sum_struct *s;
|
||||
int count;
|
||||
int block_len = n;
|
||||
int remainder = (len%block_len);
|
||||
extern int whole_file;
|
||||
extern int local_server;
|
||||
extern int write_batch;
|
||||
|
||||
if (whole_file > 0)
|
||||
return True;
|
||||
if (whole_file == 0 || write_batch)
|
||||
return False;
|
||||
return local_server;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate and send a stream of signatures/checksums that describe a buffer
|
||||
*
|
||||
* Generate approximately one checksum every block_len bytes.
|
||||
*/
|
||||
static void generate_and_send_sums(struct map_struct *buf, OFF_T len, int f_out)
|
||||
{
|
||||
size_t i;
|
||||
struct sum_struct sum;
|
||||
OFF_T offset = 0;
|
||||
|
||||
count = (len+(block_len-1))/block_len;
|
||||
sum_sizes_sqroot_baarda(&sum, len);
|
||||
|
||||
s = (struct sum_struct *)malloc(sizeof(*s));
|
||||
if (!s) out_of_memory("generate_sums");
|
||||
write_sum_head(f_out, &sum);
|
||||
|
||||
s->count = count;
|
||||
s->remainder = remainder;
|
||||
s->n = n;
|
||||
s->flength = len;
|
||||
for (i = 0; i < sum.count; i++) {
|
||||
int n1 = MIN(len, sum.blength);
|
||||
char *map = map_ptr(buf, offset, n1);
|
||||
uint32 sum1 = get_checksum1(map, n1);
|
||||
char sum2[SUM_LENGTH];
|
||||
|
||||
if (count==0) {
|
||||
s->sums = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
|
||||
s->count,s->remainder,s->n,(double)s->flength);
|
||||
|
||||
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
|
||||
if (!s->sums) out_of_memory("generate_sums");
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int n1 = MIN(len,n);
|
||||
char *map = map_ptr(buf,offset,n1);
|
||||
|
||||
s->sums[i].sum1 = get_checksum1(map,n1);
|
||||
get_checksum2(map,n1,s->sums[i].sum2);
|
||||
|
||||
s->sums[i].offset = offset;
|
||||
s->sums[i].len = n1;
|
||||
s->sums[i].i = i;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"chunk[%d] offset=%.0f len=%d sum1=%08x\n",
|
||||
i,(double)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
|
||||
get_checksum2(map, n1, sum2);
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"chunk[%ld] offset=%.0f len=%d sum1=%08lx\n",
|
||||
(long)i,(double)offset,n1,(unsigned long)sum1);
|
||||
}
|
||||
write_int(f_out, sum1);
|
||||
write_buf(f_out, sum2, sum.s2length);
|
||||
len -= n1;
|
||||
offset += n1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Acts on file number I from FLIST, whose name is fname.
|
||||
/**
|
||||
* Acts on file number @p i from @p flist, whose name is @p fname.
|
||||
*
|
||||
* First fixes up permissions, then generates checksums for the file.
|
||||
*
|
||||
* (This comment was added later by mbp who was trying to work it out;
|
||||
* it might be wrong.)
|
||||
*/
|
||||
void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
{
|
||||
* @note This comment was added later by mbp who was trying to work it
|
||||
* out. It might be wrong.
|
||||
**/
|
||||
void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
|
||||
{
|
||||
int fd;
|
||||
STRUCT_STAT st;
|
||||
struct map_struct *buf;
|
||||
struct sum_struct *s;
|
||||
int statret;
|
||||
struct file_struct *file = flist->files[i];
|
||||
char *fnamecmp;
|
||||
@@ -208,6 +280,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
extern int list_only;
|
||||
extern int preserve_perms;
|
||||
extern int only_existing;
|
||||
extern int orig_umask;
|
||||
|
||||
if (list_only) return;
|
||||
|
||||
@@ -218,48 +291,47 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (only_existing && statret == -1 && errno == ENOENT) {
|
||||
/* we only want to update existing files */
|
||||
if (verbose > 1) rprintf(FINFO, RSYNC_NAME
|
||||
": not creating new file \"%s\"\n",fname);
|
||||
if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (statret == 0 &&
|
||||
!preserve_perms &&
|
||||
if (statret == 0 &&
|
||||
!preserve_perms &&
|
||||
(S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
|
||||
/* if the file exists already and we aren't perserving
|
||||
presmissions then act as though the remote end sent
|
||||
us the file permissions we already have */
|
||||
* permissions then act as though the remote end sent
|
||||
* us the file permissions we already have */
|
||||
file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
|
||||
}
|
||||
|
||||
if (S_ISDIR(file->mode)) {
|
||||
/* The file to be received is a directory, so we need
|
||||
* to prepare appropriately. If there is already a
|
||||
* file of that name and it is *not* a directory, then
|
||||
* we need to delete it. If it doesn't exist, then
|
||||
* recursively create it. */
|
||||
|
||||
/* The file to be received is a directory, so we need
|
||||
* to prepare appropriately. If there is already a
|
||||
* file of that name and it is *not* a directory, then
|
||||
* we need to delete it. If it doesn't exist, then
|
||||
* recursively create it. */
|
||||
|
||||
if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
|
||||
if (statret == 0 && !S_ISDIR(st.st_mode)) {
|
||||
if (robust_unlink(fname) != 0) {
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": recv_generator: unlink \"%s\" to make room for directory: %s\n",
|
||||
fname,strerror(errno));
|
||||
rprintf(FERROR,
|
||||
"recv_generator: unlink %s to make room for directory: %s\n",
|
||||
full_fname(fname), strerror(errno));
|
||||
return;
|
||||
}
|
||||
statret = -1;
|
||||
}
|
||||
if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
|
||||
if (!(relative_paths && errno==ENOENT &&
|
||||
create_directory_path(fname)==0 &&
|
||||
if (!(relative_paths && errno==ENOENT &&
|
||||
create_directory_path(fname, orig_umask)==0 &&
|
||||
do_mkdir(fname,file->mode)==0)) {
|
||||
rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
|
||||
fname,strerror(errno));
|
||||
rprintf(FERROR, "recv_generator: mkdir %s failed: %s\n",
|
||||
full_fname(fname), strerror(errno));
|
||||
}
|
||||
}
|
||||
/* f_out is set to -1 when doing final directory
|
||||
/* f_out is set to -1 when doing final directory
|
||||
permission and modification time repair */
|
||||
if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
|
||||
if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
|
||||
rprintf(FINFO,"%s/\n",fname);
|
||||
return;
|
||||
}
|
||||
@@ -272,8 +344,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,RSYNC_NAME ": ignoring unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
fname,file->link);
|
||||
rprintf(FINFO, "ignoring unsafe symlink %s -> \"%s\"\n",
|
||||
full_fname(fname), file->link);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -288,20 +360,19 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not a symlink, so delete whatever's
|
||||
* already there and put a new symlink
|
||||
* in place. */
|
||||
* in place. */
|
||||
delete_file(fname);
|
||||
}
|
||||
if (do_symlink(file->link,fname) != 0) {
|
||||
rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
|
||||
fname,file->link,strerror(errno));
|
||||
rprintf(FERROR, "symlink %s -> \"%s\" failed: %s\n",
|
||||
full_fname(fname), file->link, strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose) {
|
||||
rprintf(FINFO,RSYNC_NAME": %s -> %s\n",
|
||||
fname,file->link);
|
||||
rprintf(FINFO,"%s -> %s\n", fname,file->link);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -310,15 +381,16 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
|
||||
if (statret != 0 ||
|
||||
if (statret != 0 ||
|
||||
st.st_mode != file->mode ||
|
||||
st.st_rdev != file->rdev) {
|
||||
(DEV64_T)st.st_rdev != file->rdev) {
|
||||
delete_file(fname);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
|
||||
fname,(int)file->mode,(int)file->rdev);
|
||||
if (do_mknod(fname,file->mode,file->rdev) != 0) {
|
||||
rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
|
||||
rprintf(FERROR, "mknod %s failed: %s\n",
|
||||
full_fname(fname), strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose)
|
||||
@@ -333,14 +405,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (preserve_hard_links && check_hard_link(file)) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO, RSYNC_NAME
|
||||
": \"%s\" is a hard link\n",f_name(file));
|
||||
rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, RSYNC_NAME
|
||||
": skipping non-regular file \"%s\"\n",fname);
|
||||
rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -355,6 +425,18 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
statret = -1;
|
||||
if (statret == -1)
|
||||
errno = saveerrno;
|
||||
#if HAVE_LINK
|
||||
else if (link_dest && !dry_run) {
|
||||
if (do_link(fnamecmpbuf, fname) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"link %s => %s : %s\n",
|
||||
fnamecmpbuf,
|
||||
fname,
|
||||
strerror(errno));
|
||||
}
|
||||
fnamecmp = fnamecmpbuf;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
fnamecmp = fnamecmpbuf;
|
||||
}
|
||||
@@ -362,12 +444,11 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (statret == -1) {
|
||||
if (errno == ENOENT) {
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": recv_generator failed to open \"%s\": %s\n",
|
||||
fname, strerror(errno));
|
||||
if (!dry_run) write_sum_head(f_out, NULL);
|
||||
} else if (verbose > 1) {
|
||||
rprintf(FERROR,
|
||||
"recv_generator: failed to open %s: %s\n",
|
||||
full_fname(fname), strerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -379,7 +460,13 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
/* now pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
if (!dry_run) write_sum_head(f_out, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt_ignore_existing && fnamecmp == fname) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"%s exists\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -400,20 +487,21 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
return;
|
||||
}
|
||||
|
||||
if (whole_file) {
|
||||
if (disable_deltas_p()) {
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
write_sum_head(f_out, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* open the file */
|
||||
/* open the file */
|
||||
fd = do_open(fnamecmp, O_RDONLY, 0);
|
||||
|
||||
if (fd == -1) {
|
||||
rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
|
||||
rprintf(FERROR, "failed to open %s, continuing: %s\n",
|
||||
full_fname(fnamecmp), strerror(errno));
|
||||
/* pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
write_sum_head(f_out, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -426,18 +514,14 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
|
||||
|
||||
s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending sums for %d\n",i);
|
||||
rprintf(FINFO, "generating and sending sums for %d\n", i);
|
||||
|
||||
write_int(f_out,i);
|
||||
send_sums(s,f_out);
|
||||
generate_and_send_sums(buf, st.st_size, f_out);
|
||||
|
||||
close(fd);
|
||||
if (buf) unmap_file(buf);
|
||||
|
||||
free_sums(s);
|
||||
}
|
||||
|
||||
|
||||
@@ -451,6 +535,13 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
rprintf(FINFO,"generator starting pid=%d count=%d\n",
|
||||
(int)getpid(),flist->count);
|
||||
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO,
|
||||
disable_deltas_p()
|
||||
? "delta-transmission disabled for local transfer or --whole-file\n"
|
||||
: "delta transmission enabled\n");
|
||||
}
|
||||
|
||||
/* we expect to just sit around now, so don't exit on a
|
||||
timeout. If we really get a timeout then the other process should
|
||||
exit */
|
||||
@@ -466,12 +557,11 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
them. This is then fixed after the files are transferred */
|
||||
if (!am_root && S_ISDIR(file->mode)) {
|
||||
file->mode |= S_IWUSR; /* user write */
|
||||
/* XXX: Could this be causing a problem on SCO? Perhaps their
|
||||
* handling of permissions is strange? */
|
||||
/* XXX: Could this be causing a problem on SCO? Perhaps their
|
||||
* handling of permissions is strange? */
|
||||
}
|
||||
|
||||
recv_generator(local_name?local_name:f_name(file),
|
||||
flist,i,f);
|
||||
recv_generator(local_name?local_name:f_name(file), flist,i,f);
|
||||
|
||||
file->mode = saved_mode;
|
||||
}
|
||||
@@ -485,19 +575,16 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
|
||||
write_int(f,-1);
|
||||
|
||||
if (remote_version >= 13) {
|
||||
/* in newer versions of the protocol the files can cycle through
|
||||
the system more than once to catch initial checksum errors */
|
||||
for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
|
||||
struct file_struct *file = flist->files[i];
|
||||
recv_generator(local_name?local_name:f_name(file),
|
||||
flist,i,f);
|
||||
}
|
||||
|
||||
phase++;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
/* files can cycle through the system more than once
|
||||
* to catch initial checksum errors */
|
||||
for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
|
||||
struct file_struct *file = flist->files[i];
|
||||
recv_generator(local_name?local_name:f_name(file), flist,i,f);
|
||||
}
|
||||
|
||||
phase++;
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"generate_files phase=%d\n",phase);
|
||||
|
||||
write_int(f,-1);
|
||||
}
|
||||
|
||||
50
getgroups.c
Normal file
50
getgroups.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file getgroups.c
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is
|
||||
* like `id -G` on Linux, but it's too hard to find a portable
|
||||
* equivalent.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef NGROUPS
|
||||
/* It ought to be defined, but just in case. */
|
||||
# define NGROUPS 32
|
||||
#endif
|
||||
|
||||
int
|
||||
main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
{
|
||||
int n, i;
|
||||
gid_t list[NGROUPS];
|
||||
|
||||
if ((n = getgroups(NGROUPS, list)) == -1) {
|
||||
perror("getgroups");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%u ", list[i]);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
13
hlink.c
13
hlink.c
@@ -57,9 +57,7 @@ void init_hard_links(struct file_list *flist)
|
||||
if (hlink_list)
|
||||
free(hlink_list);
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
|
||||
flist->count)))
|
||||
if (!(hlink_list = new_array(struct file_struct, flist->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
for (i = 0; i < flist->count; i++)
|
||||
@@ -97,14 +95,21 @@ int check_hard_link(struct file_struct *file)
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
/* XXX: To me this looks kind of dodgy -- why do we use [low]
|
||||
* here and [low-1] below? -- mbp */
|
||||
if (hlink_compare(&hlink_list[low], file) != 0)
|
||||
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)
|
||||
file->inode == hlink_list[low - 1].inode) {
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "check_hard_link: \"%s\" is a hard link to file %d, \"%s\"\n",
|
||||
f_name(file), low-1, f_name(&hlink_list[low-1]));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
215
io.c
215
io.c
@@ -1,32 +1,42 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
socket and pipe IO utilities used in rsync
|
||||
/**
|
||||
* @file io.c
|
||||
*
|
||||
* Socket and pipe IO utilities used in rsync.
|
||||
*
|
||||
* rsync provides its own multiplexing system, which is used to send
|
||||
* stderr and stdout over a single socket. We need this because
|
||||
* stdout normally carries the binary data stream, and stderr all our
|
||||
* error messages.
|
||||
*
|
||||
* For historical reasons this is off during the start of the
|
||||
* connection, but it's switched on quite early using
|
||||
* io_start_multiplex_out() and io_start_multiplex_in().
|
||||
**/
|
||||
|
||||
tridge, June 1996
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
/* if no timeout is specified then use a 60 second select timeout */
|
||||
/** If no timeout is specified then use a 60 second select timeout */
|
||||
#define SELECT_TIMEOUT 60
|
||||
|
||||
static int io_multiplexing_out;
|
||||
@@ -42,6 +52,24 @@ extern int io_timeout;
|
||||
extern struct stats stats;
|
||||
|
||||
|
||||
const char phase_unknown[] = "unknown";
|
||||
|
||||
/**
|
||||
* The connection might be dropped at some point; perhaps because the
|
||||
* remote instance crashed. Just giving the offset on the stream is
|
||||
* not very helpful. So instead we try to make io_phase_name point to
|
||||
* something useful.
|
||||
*
|
||||
* For buffered/multiplexed IO these names will be somewhat
|
||||
* approximate; perhaps for ease of support we would rather make the
|
||||
* buffer always flush when a single application-level IO finishes.
|
||||
*
|
||||
* @todo Perhaps we want some simple stack functionality, but there's
|
||||
* no need to overdo it.
|
||||
**/
|
||||
const char *io_write_phase = phase_unknown;
|
||||
const char *io_read_phase = phase_unknown;
|
||||
|
||||
/** Ignore EOF errors while reading a module listing if the remote
|
||||
version is 24 or less. */
|
||||
int kludge_around_eof = False;
|
||||
@@ -76,13 +104,13 @@ static void check_timeout(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the fd used to propogate errors */
|
||||
/** Setup the fd used to propagate errors */
|
||||
void io_set_error_fd(int fd)
|
||||
{
|
||||
io_error_fd = fd;
|
||||
}
|
||||
|
||||
/* read some data from the error fd and write it to the write log code */
|
||||
/** Read some data from the error fd and write it to the write log code */
|
||||
static void read_error_fd(void)
|
||||
{
|
||||
char buf[200];
|
||||
@@ -114,21 +142,18 @@ static void read_error_fd(void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It's almost always an error to get an EOF when we're trying to read
|
||||
* from the network, because the protocol is self-terminating.
|
||||
*
|
||||
* However, there is one unfortunate cases where it is not, which is
|
||||
* rsync <2.4.6 sending a list of modules on a server, since the list
|
||||
* is terminated by closing the socket. So, for the section of the
|
||||
* program where that is a problem (start_socket_client),
|
||||
* kludge_around_eof is True and we just exit.
|
||||
*/
|
||||
static void whine_about_eof (void)
|
||||
{
|
||||
/**
|
||||
It's almost always an error to get an EOF when we're trying
|
||||
to read from the network, because the protocol is
|
||||
self-terminating.
|
||||
|
||||
However, there is one unfortunate cases where it is not,
|
||||
which is rsync <2.4.6 sending a list of modules on a
|
||||
server, since the list is terminated by closing the socket.
|
||||
So, for the section of the program where that is a problem
|
||||
(start_socket_client), kludge_around_eof is True and we
|
||||
just exit.
|
||||
*/
|
||||
|
||||
if (kludge_around_eof)
|
||||
exit_cleanup (0);
|
||||
else {
|
||||
@@ -153,7 +178,7 @@ static void die_from_readerr (int err)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Read from a socket with IO timeout. return the number of bytes
|
||||
* read. If no bytes can be read then exit, never return a number <= 0.
|
||||
*
|
||||
@@ -235,8 +260,10 @@ static int read_timeout (int fd, char *buf, size_t len)
|
||||
|
||||
|
||||
|
||||
/*! Continue trying to read len bytes - don't return until len has
|
||||
been read. */
|
||||
/**
|
||||
* Continue trying to read len bytes - don't return until len has been
|
||||
* read.
|
||||
**/
|
||||
static void read_loop (int fd, char *buf, size_t len)
|
||||
{
|
||||
while (len) {
|
||||
@@ -306,8 +333,11 @@ static int read_unbuffered(int fd, char *buf, size_t len)
|
||||
|
||||
|
||||
|
||||
/* do a buffered read from fd. don't return until all N bytes
|
||||
have been read. If all N can't be read then exit with an error */
|
||||
/**
|
||||
* Do a buffered read from @p fd. Don't return until all @p n bytes
|
||||
* have been read. If all @p n can't be read then exit with an
|
||||
* error.
|
||||
**/
|
||||
static void readfd (int fd, char *buffer, size_t N)
|
||||
{
|
||||
int ret;
|
||||
@@ -377,7 +407,40 @@ unsigned char read_byte(int f)
|
||||
return c;
|
||||
}
|
||||
|
||||
/* write len bytes to fd */
|
||||
|
||||
/**
|
||||
* Sleep after writing to limit I/O bandwidth usage.
|
||||
*
|
||||
* @todo Rather than sleeping after each write, it might be better to
|
||||
* use some kind of averaging. The current algorithm seems to always
|
||||
* use a bit less bandwidth than specified, because it doesn't make up
|
||||
* for slow periods. But arguably this is a feature. In addition, we
|
||||
* ought to take the time used to write the data into account.
|
||||
**/
|
||||
static void sleep_for_bwlimit(int bytes_written)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (!bwlimit)
|
||||
return;
|
||||
|
||||
assert(bytes_written > 0);
|
||||
assert(bwlimit > 0);
|
||||
|
||||
tv.tv_usec = bytes_written * 1000 / bwlimit;
|
||||
tv.tv_sec = tv.tv_usec / 1000000;
|
||||
tv.tv_usec = tv.tv_usec % 1000000;
|
||||
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write len bytes to the file descriptor @p fd.
|
||||
*
|
||||
* This function underlies the multiplexing system. The body of the
|
||||
* application never calls this function directly.
|
||||
**/
|
||||
static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
{
|
||||
size_t total = 0;
|
||||
@@ -442,25 +505,17 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
rprintf(FERROR,
|
||||
"error writing %d unbuffered bytes"
|
||||
" - exiting: %s\n", len,
|
||||
/* Don't try to write errors back
|
||||
* across the stream */
|
||||
io_multiplexing_close();
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": writefd_unbuffered failed to write %ld bytes: phase \"%s\": %s\n",
|
||||
(long) len, io_write_phase,
|
||||
strerror(errno));
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
/* Sleep after writing to limit I/O bandwidth */
|
||||
if (bwlimit)
|
||||
{
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = ret * 1000 / bwlimit;
|
||||
while (tv.tv_usec > 1000000)
|
||||
{
|
||||
tv.tv_sec++;
|
||||
tv.tv_usec -= 1000000;
|
||||
}
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
sleep_for_bwlimit(ret);
|
||||
|
||||
total += ret;
|
||||
|
||||
@@ -480,13 +535,15 @@ void io_start_buffering(int fd)
|
||||
{
|
||||
if (io_buffer) return;
|
||||
multiplex_out_fd = fd;
|
||||
io_buffer = (char *)malloc(IO_BUFFER_SIZE);
|
||||
io_buffer = new_array(char, IO_BUFFER_SIZE);
|
||||
if (!io_buffer) out_of_memory("writefd");
|
||||
io_buffer_count = 0;
|
||||
}
|
||||
|
||||
/* write an message to a multiplexed stream. If this fails then rsync
|
||||
exits */
|
||||
/**
|
||||
* Write an message to a multiplexed stream. If this fails then rsync
|
||||
* exits.
|
||||
**/
|
||||
static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
char buffer[4096];
|
||||
@@ -527,8 +584,7 @@ void io_flush(void)
|
||||
}
|
||||
|
||||
|
||||
/* XXX: fd is ignored, which seems a little strange. */
|
||||
void io_end_buffering(int fd)
|
||||
void io_end_buffering(void)
|
||||
{
|
||||
io_flush();
|
||||
if (!io_multiplexing_out) {
|
||||
@@ -549,7 +605,7 @@ static void writefd(int fd,char *buf,size_t len)
|
||||
}
|
||||
|
||||
while (len) {
|
||||
int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
|
||||
int n = MIN((int) len, IO_BUFFER_SIZE-io_buffer_count);
|
||||
if (n > 0) {
|
||||
memcpy(io_buffer+io_buffer_count, buf, n);
|
||||
buf += n;
|
||||
@@ -570,6 +626,14 @@ void write_int(int f,int32 x)
|
||||
}
|
||||
|
||||
|
||||
void write_int_named(int f, int32 x, const char *phase)
|
||||
{
|
||||
io_write_phase = phase;
|
||||
write_int(f, x);
|
||||
io_write_phase = phase_unknown;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Note: int64 may actually be a 32-bit type if ./configure couldn't find any
|
||||
* 64-bit types on this platform.
|
||||
@@ -596,7 +660,7 @@ void write_buf(int f,char *buf,size_t len)
|
||||
writefd(f,buf,len);
|
||||
}
|
||||
|
||||
/* write a string to the connection */
|
||||
/** Write a string to the connection */
|
||||
static void write_sbuf(int f,char *buf)
|
||||
{
|
||||
write_buf(f, buf, strlen(buf));
|
||||
@@ -610,12 +674,19 @@ void write_byte(int f,unsigned char c)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read a line of up to @p maxlen characters into @p buf. Does not
|
||||
* contain a trailing newline or carriage return.
|
||||
*
|
||||
* @return 1 for success; 0 for io error or truncation.
|
||||
**/
|
||||
int read_line(int f, char *buf, size_t maxlen)
|
||||
{
|
||||
while (maxlen) {
|
||||
buf[0] = 0;
|
||||
read_buf(f, buf, 1);
|
||||
if (buf[0] == 0) return 0;
|
||||
if (buf[0] == 0)
|
||||
return 0;
|
||||
if (buf[0] == '\n') {
|
||||
buf[0] = 0;
|
||||
break;
|
||||
@@ -650,7 +721,7 @@ void io_printf(int fd, const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
/* setup for multiplexing an error stream with the data stream */
|
||||
/** Setup for multiplexing an error stream with the data stream */
|
||||
void io_start_multiplex_out(int fd)
|
||||
{
|
||||
multiplex_out_fd = fd;
|
||||
@@ -659,7 +730,7 @@ void io_start_multiplex_out(int fd)
|
||||
io_multiplexing_out = 1;
|
||||
}
|
||||
|
||||
/* setup for multiplexing an error stream with the data stream */
|
||||
/** Setup for multiplexing an error stream with the data stream */
|
||||
void io_start_multiplex_in(int fd)
|
||||
{
|
||||
multiplex_in_fd = fd;
|
||||
@@ -667,7 +738,7 @@ void io_start_multiplex_in(int fd)
|
||||
io_multiplexing_in = 1;
|
||||
}
|
||||
|
||||
/* write an message to the multiplexed error stream */
|
||||
/** Write an message to the multiplexed error stream */
|
||||
int io_multiplex_write(enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
if (!io_multiplexing_out) return 0;
|
||||
@@ -678,7 +749,7 @@ int io_multiplex_write(enum logcode code, char *buf, size_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* stop output multiplexing */
|
||||
/** Stop output multiplexing */
|
||||
void io_multiplexing_close(void)
|
||||
{
|
||||
io_multiplexing_out = 0;
|
||||
|
||||
41
lib/compat.c
41
lib/compat.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -16,11 +17,15 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
compatibility functions - replacing functions for platforms that don't
|
||||
have them.
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
* Reimplementations of standard functions for platforms that don't
|
||||
* have them.
|
||||
**/
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
@@ -78,9 +83,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRPBRK
|
||||
/* Find the first ocurrence in S of any character in ACCEPT.
|
||||
derived from glibc
|
||||
*/
|
||||
/**
|
||||
* Find the first ocurrence in @p s of any character in @p accept.
|
||||
*
|
||||
* Derived from glibc
|
||||
**/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
@@ -97,10 +104,14 @@
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates. bufsize is the size of the destination buffer.
|
||||
/**
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* Returns the index of the terminating byte. */
|
||||
* @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);
|
||||
@@ -114,9 +125,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/* like strncat but does not 0 fill the buffer and always null
|
||||
terminates. bufsize is the length of the buffer, which should
|
||||
be one more than the maximum resulting string length */
|
||||
/**
|
||||
* 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);
|
||||
|
||||
482
lib/fnmatch.c
482
lib/fnmatch.c
@@ -1,482 +0,0 @@
|
||||
#include "../rsync.h"
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
|
||||
except for the parts with '#if 0' */
|
||||
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if 0 /* header files included better by ../rsync.h */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Enable GNU extensions in fnmatch.h. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#endif /* 0 */
|
||||
/* For platform which support the ISO C amendement 1 functionality we
|
||||
support user defined character classes. */
|
||||
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if 1
|
||||
|
||||
# if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
# else
|
||||
# define ISASCII(c) isascii(c)
|
||||
# endif
|
||||
|
||||
#ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII (c) && isblank (c))
|
||||
#else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
#ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
|
||||
#else
|
||||
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
|
||||
#endif
|
||||
|
||||
#define ISPRINT(c) (ISASCII (c) && isprint (c))
|
||||
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
|
||||
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
|
||||
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
|
||||
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
|
||||
#define ISLOWER(c) (ISASCII (c) && islower (c))
|
||||
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
|
||||
#define ISSPACE(c) (ISASCII (c) && isspace (c))
|
||||
#define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
|
||||
|
||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* The GNU C library provides support for user-defined character classes
|
||||
and the functions from ISO C amendement 1. */
|
||||
# ifdef CHARCLASS_NAME_MAX
|
||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
||||
# else
|
||||
/* This shouldn't happen but some implementation might still have this
|
||||
problem. Use a reasonable default value. */
|
||||
# define CHAR_CLASS_MAX_LENGTH 256
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
||||
# else
|
||||
# define IS_CHAR_CLASS(string) wctype (string)
|
||||
# endif
|
||||
# else
|
||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
||||
|
||||
# define IS_CHAR_CLASS(string) \
|
||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
# if !defined _LIBC && !defined getenv
|
||||
extern char *getenv ();
|
||||
# endif
|
||||
|
||||
# ifndef errno
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int
|
||||
#ifdef _LIBC
|
||||
internal_function
|
||||
#endif
|
||||
internal_fnmatch (const char *pattern, const char *string,
|
||||
int no_leading_period, int flags)
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
/* Trailing \ loses. */
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD ((unsigned char) *n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++)
|
||||
{
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* A slash does not match a wildcard under FNM_FILE_NAME. */
|
||||
return FNM_NOMATCH;
|
||||
else if (c == '?')
|
||||
{
|
||||
/* A ? needs to match one character. */
|
||||
if (*n == '\0')
|
||||
/* There isn't another character; no match. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
less than three characters. */
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
/* The wildcard(s) is/are the last element of the pattern.
|
||||
If the name is a file name and contains another slash
|
||||
this does mean it cannot match. */
|
||||
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
|
||||
? FNM_NOMATCH : 0);
|
||||
else
|
||||
{
|
||||
const char *endp;
|
||||
|
||||
#if 0
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
#else
|
||||
/* replace call to internal glibc function with equivalent */
|
||||
if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
|
||||
endp = n + strlen(n);
|
||||
#endif
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
for (--p; n < endp; ++n)
|
||||
if (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
else if (c == '/' && (flags & FNM_FILE_NAME))
|
||||
{
|
||||
while (*n != '\0' && *n != '/')
|
||||
++n;
|
||||
if (*n == '/'
|
||||
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
|
||||
flags) == 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *p;
|
||||
c = FOLD (c);
|
||||
for (--p; n < endp; ++n)
|
||||
if (FOLD ((unsigned char) *n) == c
|
||||
&& (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we come here no match is possible with the wildcard. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '.' && no_leading_period && (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* `/' cannot be matched. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char fn = FOLD ((unsigned char) *n);
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD ((unsigned char) *p);
|
||||
++p;
|
||||
|
||||
if (c == fn)
|
||||
goto matched;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
/* Leave room for the null. */
|
||||
char str[CHAR_CLASS_MAX_LENGTH + 1];
|
||||
size_t c1 = 0;
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wctype_t wt;
|
||||
# endif
|
||||
const char *startp = p;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (c1 == CHAR_CLASS_MAX_LENGTH)
|
||||
/* The name is too long and therefore the pattern
|
||||
is ill-formed. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *++p;
|
||||
if (c == ':' && p[1] == ']')
|
||||
{
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (c < 'a' || c >= 'z')
|
||||
{
|
||||
/* This cannot possibly be a character class name.
|
||||
Match it as a normal range. */
|
||||
p = startp;
|
||||
c = '[';
|
||||
goto normal_bracket;
|
||||
}
|
||||
str[c1++] = c;
|
||||
}
|
||||
str[c1] = '\0';
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wt = IS_CHAR_CLASS (str);
|
||||
if (wt == 0)
|
||||
/* Invalid character class name. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (__iswctype (__btowc ((unsigned char) *n), wt))
|
||||
goto matched;
|
||||
# else
|
||||
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|
||||
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|
||||
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|
||||
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|
||||
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|
||||
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|
||||
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|
||||
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|
||||
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|
||||
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|
||||
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|
||||
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
|
||||
goto matched;
|
||||
# endif
|
||||
}
|
||||
else if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
{
|
||||
normal_bracket:
|
||||
if (FOLD (c) == fn)
|
||||
goto matched;
|
||||
|
||||
cold = c;
|
||||
c = *p++;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
/* It is a range. */
|
||||
unsigned char cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (cold <= fn && fn <= FOLD (cend))
|
||||
goto matched;
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
do
|
||||
if (*++p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
while (*p != ':' || p[1] == ']');
|
||||
p += 2;
|
||||
c = *p;
|
||||
}
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD ((unsigned char) *n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
|
||||
# undef FOLD
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
/* ----- END glibc-2.1.2 posix/fnmatch.c */
|
||||
|
||||
#else /* HAVE_FNMATCH */
|
||||
void fnmatch_dummy(void) {}
|
||||
#endif
|
||||
@@ -1,88 +0,0 @@
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#ifndef FNM_FILE_NAME
|
||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
#endif
|
||||
#ifndef FNM_LEADING_DIR
|
||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
#endif
|
||||
#ifndef FNM_CASEFOLD
|
||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* This value is returned if the implementation does not support
|
||||
`fnmatch'. Since this is not the case here it will never be
|
||||
returned but the conformance test suites still require the symbol
|
||||
to be defined. */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# define FNM_NOSYS (-1)
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
||||
@@ -27,10 +27,12 @@
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
#ifdef INET6
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
#endif
|
||||
|
||||
/* int
|
||||
* isc_net_pton(af, src, dst)
|
||||
* 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:
|
||||
|
||||
49
lib/mdfour.c
49
lib/mdfour.c
@@ -109,29 +109,53 @@ void mdfour_begin(struct mdfour *md)
|
||||
md->C = 0x98badcfe;
|
||||
md->D = 0x10325476;
|
||||
md->totalN = 0;
|
||||
md->totalN2 = 0;
|
||||
}
|
||||
|
||||
|
||||
static void mdfour_tail(unsigned char *in, int n)
|
||||
static void mdfour_tail(unsigned char *in, uint32 n)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
uint32 M[16];
|
||||
uint32 b;
|
||||
extern int protocol_version;
|
||||
|
||||
m->totalN += n;
|
||||
|
||||
b = m->totalN * 8;
|
||||
/*
|
||||
* Count total number of bits, modulo 2^64
|
||||
*/
|
||||
m->totalN += n << 3;
|
||||
if (m->totalN < (n << 3)) {
|
||||
m->totalN2++;
|
||||
}
|
||||
m->totalN2 += n >> 29;
|
||||
|
||||
memset(buf, 0, 128);
|
||||
if (n) memcpy(buf, in, n);
|
||||
buf[n] = 0x80;
|
||||
|
||||
if (n <= 55) {
|
||||
copy4(buf+56, b);
|
||||
copy4(buf+56, m->totalN);
|
||||
/*
|
||||
* Prior to protocol version 27 only the number of bits
|
||||
* modulo 2^32 was included. MD4 requires the number
|
||||
* of bits modulo 2^64, which was fixed starting with
|
||||
* protocol version 27.
|
||||
*/
|
||||
if (protocol_version >= 27) {
|
||||
copy4(buf+60, m->totalN2);
|
||||
}
|
||||
copy64(M, buf);
|
||||
mdfour64(M);
|
||||
} else {
|
||||
copy4(buf+120, b);
|
||||
copy4(buf+120, m->totalN);
|
||||
/*
|
||||
* Prior to protocol version 27 only the number of bits
|
||||
* modulo 2^32 was included. MD4 requires the number
|
||||
* of bits modulo 2^64, which was fixed starting with
|
||||
* protocol version 27.
|
||||
*/
|
||||
if (protocol_version >= 27) {
|
||||
copy4(buf+124, m->totalN2);
|
||||
}
|
||||
copy64(M, buf);
|
||||
mdfour64(M);
|
||||
copy64(M, buf+64);
|
||||
@@ -139,20 +163,23 @@ static void mdfour_tail(unsigned char *in, int n)
|
||||
}
|
||||
}
|
||||
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, int n)
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n)
|
||||
{
|
||||
uint32 M[16];
|
||||
|
||||
if (n == 0) mdfour_tail(in, n);
|
||||
|
||||
m = md;
|
||||
|
||||
if (n == 0) mdfour_tail(in, n);
|
||||
|
||||
while (n >= 64) {
|
||||
copy64(M, in);
|
||||
mdfour64(M);
|
||||
in += 64;
|
||||
n -= 64;
|
||||
m->totalN += 64;
|
||||
m->totalN += 64 << 3;
|
||||
if (m->totalN < 64 << 3) {
|
||||
m->totalN2++;
|
||||
}
|
||||
}
|
||||
|
||||
if (n) mdfour_tail(in, n);
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
|
||||
struct mdfour {
|
||||
uint32 A, B, C, D;
|
||||
uint32 totalN;
|
||||
uint32 totalN; /* bit count, lower 32 bits */
|
||||
uint32 totalN2; /* bit count, upper 32 bits */
|
||||
};
|
||||
|
||||
void mdfour_begin(struct mdfour *md);
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, int n);
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n);
|
||||
void mdfour_result(struct mdfour *md, unsigned char *out);
|
||||
void mdfour(unsigned char *out, unsigned char *in, int n);
|
||||
|
||||
|
||||
@@ -47,8 +47,10 @@ void permstring(char *perms,
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
#ifdef S_ISVTX
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
* got rid of fcvt code (twas buggy and made testing harder)
|
||||
* added C99 semantics
|
||||
*
|
||||
* Paul Green (paulg@samba.org) April 9, 2003
|
||||
* fixed handling of %f when converting fractions with leading zeros.
|
||||
* (e.g., 0.025).
|
||||
**************************************************************/
|
||||
|
||||
#ifndef NO_CONFIG_H /* for some tests */
|
||||
@@ -725,15 +728,15 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||
if (max > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '.');
|
||||
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
while (fplace > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
|
||||
}
|
||||
|
||||
while (zpadlen > 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
while (padlen < 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
@@ -749,13 +752,15 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
|
||||
}
|
||||
|
||||
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
|
||||
#define vsnprintf rsync_vsnprintf
|
||||
int vsnprintf(char *str, size_t count, const char *fmt, va_list args)
|
||||
{
|
||||
return dopr(str, count, fmt, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
|
||||
#define snprintf rsync_snprintf
|
||||
int snprintf(char *str,size_t count,const char *fmt,...)
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
229
lib/wildmatch.c
Normal file
229
lib/wildmatch.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
** 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 domatch(const unsigned char *p, const unsigned char *text)
|
||||
{
|
||||
int matched, special;
|
||||
unsigned char ch, prev;
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count++;
|
||||
#endif
|
||||
|
||||
for ( ; (ch = *p) != '\0'; text++, p++) {
|
||||
if (*text == '\0' && ch != '*')
|
||||
return FALSE;
|
||||
switch (ch) {
|
||||
case '\\':
|
||||
/* Literal match with following character. Note that the test
|
||||
* in "default" handles the p[1] == '\0' failure case. */
|
||||
ch = *++p;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (*text != ch)
|
||||
return FALSE;
|
||||
continue;
|
||||
case '?':
|
||||
/* Match anything but '/'. */
|
||||
if (*text == '/')
|
||||
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. */
|
||||
return special? TRUE : strchr((char*)text, '/') == NULL;
|
||||
}
|
||||
for ( ; *text; text++) {
|
||||
if ((matched = domatch(p, text)) != FALSE) {
|
||||
if (!special || matched != ABORT_TO_STARSTAR)
|
||||
return matched;
|
||||
}
|
||||
else if (!special && *text == '/')
|
||||
return ABORT_TO_STARSTAR;
|
||||
}
|
||||
return ABORT_ALL;
|
||||
case '[':
|
||||
ch = *++p;
|
||||
#ifdef NEGATE_CLASS2
|
||||
if (ch == NEGATE_CLASS2)
|
||||
ch = NEGATE_CLASS;
|
||||
#endif
|
||||
/* Assign literal TRUE/FALSE because of "matched" comparison. */
|
||||
special = ch == NEGATE_CLASS? TRUE : FALSE;
|
||||
if (special) {
|
||||
/* Inverted character class. */
|
||||
ch = *++p;
|
||||
}
|
||||
prev = 0;
|
||||
matched = FALSE;
|
||||
do {
|
||||
if (!ch)
|
||||
return ABORT_ALL;
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
return ABORT_ALL;
|
||||
if (*text == ch)
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (ch == '-' && prev && p[1] && p[1] != ']') {
|
||||
ch = *++p;
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
return ABORT_ALL;
|
||||
}
|
||||
if (*text <= ch && *text >= prev)
|
||||
matched = TRUE;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (ch == '[' && p[1] == ':') {
|
||||
const unsigned char *s = p += 2;
|
||||
int i;
|
||||
while ((ch = *p) && ch != ']') p++;
|
||||
if (!ch)
|
||||
return ABORT_ALL;
|
||||
i = p - s - 1;
|
||||
if (i < 0 || p[-1] != ':') {
|
||||
/* Didn't find ":]", so treat like a normal set. */
|
||||
p = s - 2;
|
||||
ch = '[';
|
||||
if (*text == ch)
|
||||
matched = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (CC_EQ(s,i, "alnum")) {
|
||||
if (ISALNUM(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "alpha")) {
|
||||
if (ISALPHA(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "blank")) {
|
||||
if (ISBLANK(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "cntrl")) {
|
||||
if (ISCNTRL(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "digit")) {
|
||||
if (ISDIGIT(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "graph")) {
|
||||
if (ISGRAPH(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "lower")) {
|
||||
if (ISLOWER(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "print")) {
|
||||
if (ISPRINT(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "punct")) {
|
||||
if (ISPUNCT(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "space")) {
|
||||
if (ISSPACE(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "upper")) {
|
||||
if (ISUPPER(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "xdigit")) {
|
||||
if (ISXDIGIT(*text))
|
||||
matched = TRUE;
|
||||
}
|
||||
else /* malformed [:class:] string */
|
||||
return ABORT_ALL;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (*text == ch)
|
||||
matched = TRUE;
|
||||
} while (prev = ch, (ch = *++p) != ']');
|
||||
if (matched == special || *text == '/')
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return *text == '\0';
|
||||
}
|
||||
|
||||
/* Find the pattern (p) in the text string (t). */
|
||||
int wildmatch(const char *p, const char *t)
|
||||
{
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count = 0;
|
||||
#endif
|
||||
return domatch((const unsigned char*)p, (const unsigned char*)t) == TRUE;
|
||||
}
|
||||
3
lib/wildmatch.h
Normal file
3
lib/wildmatch.h
Normal file
@@ -0,0 +1,3 @@
|
||||
/* wildmatch.h */
|
||||
|
||||
int wildmatch(const char *p, const char *text);
|
||||
34
loadparm.c
34
loadparm.c
@@ -3,7 +3,7 @@
|
||||
|
||||
/* some fixes
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -48,6 +48,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: Parameter to set debug level on server. */
|
||||
|
||||
#include "rsync.h"
|
||||
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
|
||||
#define strequal(a,b) (strcasecmp(a,b)==0)
|
||||
@@ -154,7 +156,16 @@ static service sDefault =
|
||||
False, /* transfer logging */
|
||||
False, /* ignore errors */
|
||||
"nobody",/* uid */
|
||||
|
||||
/* TODO: This causes problems on Debian, where it is called
|
||||
* "nogroup". Debian patch this in their version of the
|
||||
* package, but it would be nice to be consistent. Possibly
|
||||
* other systems are different again.
|
||||
*
|
||||
* What is the best behaviour? Perhaps always using (gid_t)
|
||||
* -2? */
|
||||
"nobody",/* gid */
|
||||
|
||||
NULL, /* hosts allow */
|
||||
NULL, /* hosts deny */
|
||||
NULL, /* auth users */
|
||||
@@ -431,10 +442,10 @@ static int add_a_service(service *pservice, char *name)
|
||||
|
||||
i = iNumServices;
|
||||
|
||||
ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
|
||||
ServicePtrs = realloc_array(ServicePtrs, service *, num_to_alloc);
|
||||
|
||||
if (ServicePtrs)
|
||||
pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
|
||||
pSERVICE(iNumServices) = new(service);
|
||||
|
||||
if (!ServicePtrs || !pSERVICE(iNumServices))
|
||||
return(-1);
|
||||
@@ -468,11 +479,12 @@ static int strwicmp(char *psz1, char *psz2)
|
||||
/* sync the strings on first non-whitespace */
|
||||
while (1)
|
||||
{
|
||||
while (isspace(*psz1))
|
||||
while (isspace(* (unsigned char *) psz1))
|
||||
psz1++;
|
||||
while (isspace(*psz2))
|
||||
while (isspace(* (unsigned char *) psz2))
|
||||
psz2++;
|
||||
if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
|
||||
if (toupper(* (unsigned char *) psz1) != toupper(* (unsigned char *) psz2)
|
||||
|| *psz1 == '\0' || *psz2 == '\0')
|
||||
break;
|
||||
psz1++;
|
||||
psz2++;
|
||||
@@ -736,6 +748,9 @@ False on failure.
|
||||
***************************************************************************/
|
||||
BOOL lp_load(char *pszFname, int globals_only)
|
||||
{
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_root;
|
||||
pstring n2;
|
||||
BOOL bRetval;
|
||||
|
||||
@@ -745,7 +760,12 @@ BOOL lp_load(char *pszFname, int globals_only)
|
||||
|
||||
init_globals();
|
||||
|
||||
pstrcpy(n2,pszFname);
|
||||
if (pszFname)
|
||||
pstrcpy(n2,pszFname);
|
||||
else if (am_server && am_daemon && !am_root)
|
||||
pstrcpy(n2,RSYNCD_USERCONF);
|
||||
else
|
||||
pstrcpy(n2,RSYNCD_SYSCONF);
|
||||
|
||||
/* We get sections first, so have to start 'behind' to make up */
|
||||
iServiceIndex = -1;
|
||||
|
||||
50
log.c
50
log.c
@@ -27,9 +27,11 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
static int log_initialised;
|
||||
static char *logfname;
|
||||
static FILE *logfile;
|
||||
static int log_error_fd = -1;
|
||||
struct stats stats;
|
||||
|
||||
int log_got_error=0;
|
||||
|
||||
@@ -41,6 +43,7 @@ struct {
|
||||
{ RERR_PROTOCOL , "protocol incompatibility" },
|
||||
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
|
||||
{ RERR_UNSUPPORTED, "requested action not supported" },
|
||||
{ RERR_STARTCLIENT, "error starting client-server protocol" },
|
||||
{ RERR_SOCKETIO , "error in socket IO" },
|
||||
{ RERR_FILEIO , "error in file IO" },
|
||||
{ RERR_STREAMIO , "error in rsync protocol data stream" },
|
||||
@@ -49,7 +52,7 @@ struct {
|
||||
{ RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
|
||||
{ RERR_WAITCHILD , "some error returned by waitpid()" },
|
||||
{ RERR_MALLOC , "error allocating core memory buffers" },
|
||||
{ RERR_PARTIAL , "partial transfer" },
|
||||
{ RERR_PARTIAL , "some files could not be transferred" },
|
||||
{ RERR_TIMEOUT , "timeout in data send/receive" },
|
||||
{ RERR_CMD_FAILED , "remote shell failed" },
|
||||
{ RERR_CMD_KILLED , "remote shell killed" },
|
||||
@@ -87,10 +90,10 @@ static struct err_list *err_list_tail;
|
||||
static void err_list_add(int code, char *buf, int len)
|
||||
{
|
||||
struct err_list *el;
|
||||
el = (struct err_list *)malloc(sizeof(*el));
|
||||
el = new(struct err_list);
|
||||
if (!el) exit_cleanup(RERR_MALLOC);
|
||||
el->next = NULL;
|
||||
el->buf = malloc(len+4);
|
||||
el->buf = new_array(char, len+4);
|
||||
if (!el->buf) exit_cleanup(RERR_MALLOC);
|
||||
memcpy(el->buf+4, buf, len);
|
||||
SIVAL(el->buf, 0, ((code+MPLEX_BASE)<<24) | len);
|
||||
@@ -144,12 +147,11 @@ static void logit(int priority, char *buf)
|
||||
|
||||
void log_init(void)
|
||||
{
|
||||
static int initialised;
|
||||
int options = LOG_PID;
|
||||
time_t t;
|
||||
|
||||
if (initialised) return;
|
||||
initialised = 1;
|
||||
if (log_initialised) return;
|
||||
log_initialised = 1;
|
||||
|
||||
/* this looks pointless, but it is needed in order for the
|
||||
C library on some systems to fetch the timezone info
|
||||
@@ -182,7 +184,7 @@ void log_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_open()
|
||||
void log_open(void)
|
||||
{
|
||||
if (logfname && !logfile) {
|
||||
extern int orig_umask;
|
||||
@@ -192,7 +194,7 @@ void log_open()
|
||||
}
|
||||
}
|
||||
|
||||
void log_close()
|
||||
void log_close(void)
|
||||
{
|
||||
if (logfile) {
|
||||
fclose(logfile);
|
||||
@@ -236,12 +238,20 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
/* if that fails, try to pass it to the other end */
|
||||
if (am_server && io_multiplex_write(code, buf, len)) {
|
||||
/* next, if we are a server but not in daemon mode, and multiplexing
|
||||
* is enabled, pass it to the other side. */
|
||||
if (am_server && !am_daemon && io_multiplex_write(code, buf, len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (am_daemon) {
|
||||
/* otherwise, if in daemon mode and either we are not a server
|
||||
* (that is, we are not running --daemon over a remote shell) or
|
||||
* the log has already been initialised, log the message on this
|
||||
* side because we don't want the client to see most errors for
|
||||
* security reasons. We do want early messages when running daemon
|
||||
* mode over a remote shell to go to the remote side; those will
|
||||
* fall through to the next case. */
|
||||
if (am_daemon && (!am_server || log_initialised)) {
|
||||
static int depth;
|
||||
int priority = LOG_INFO;
|
||||
if (code == FERROR) priority = LOG_WARNING;
|
||||
@@ -341,6 +351,8 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
len = vsnprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* TODO: Put in RSYNC_NAME at the start. */
|
||||
|
||||
if ((size_t) len > sizeof(buf)-1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
@@ -559,20 +571,16 @@ void log_exit(int code, const char *file, int line)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* log the incoming transfer of a file for interactive use, this
|
||||
will be called at the end where the client was run
|
||||
|
||||
it i called when a file starts to be transferred
|
||||
*/
|
||||
/*
|
||||
* Log the incoming transfer of a file for interactive use,
|
||||
* this will be called at the end where the client was run.
|
||||
* Called when a file starts to be transferred.
|
||||
*/
|
||||
void log_transfer(struct file_struct *file, const char *fname)
|
||||
{
|
||||
extern int verbose;
|
||||
|
||||
if (!verbose) return;
|
||||
|
||||
rprintf(FINFO,"%s\n", fname);
|
||||
rprintf(FINFO, "%s\n", fname);
|
||||
}
|
||||
|
||||
|
||||
52
match.c
52
match.c
@@ -65,13 +65,13 @@ static void build_hash_table(struct sum_struct *s)
|
||||
int i;
|
||||
|
||||
if (!tag_table)
|
||||
tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
|
||||
tag_table = new_array(int, TABLESIZE);
|
||||
|
||||
targets = (struct target *)malloc(sizeof(targets[0])*s->count);
|
||||
targets = new_array(struct target, s->count);
|
||||
if (!tag_table || !targets)
|
||||
out_of_memory("build_hash_table");
|
||||
|
||||
for (i=0;i<s->count;i++) {
|
||||
for (i=0;i<(int) s->count;i++) {
|
||||
targets[i].i = i;
|
||||
targets[i].t = gettag(s->sums[i].sum1);
|
||||
}
|
||||
@@ -90,6 +90,18 @@ static void build_hash_table(struct sum_struct *s)
|
||||
static OFF_T last_match;
|
||||
|
||||
|
||||
/**
|
||||
* 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!
|
||||
*
|
||||
* @param i If >0, the number of a matched token. If 0, indicates we
|
||||
* have only literal data.
|
||||
**/
|
||||
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
OFF_T offset,int i)
|
||||
{
|
||||
@@ -141,9 +153,12 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
last_i = -1;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
|
||||
rprintf(FINFO,"hash search b=%ld len=%.0f\n",
|
||||
(long) s->n, (double)len);
|
||||
|
||||
k = MIN(len, s->n);
|
||||
/* cast is to make s->n signed; it should always be reasonably
|
||||
* small */
|
||||
k = MIN(len, (OFF_T) s->n);
|
||||
|
||||
map = (schar *)map_ptr(buf,0,k);
|
||||
|
||||
@@ -158,8 +173,8 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
end = len + 1 - s->sums[s->count-1].len;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
|
||||
s->n,(double)len,s->count);
|
||||
rprintf(FINFO, "hash search s->n=%ld len=%.0f count=%ld\n",
|
||||
(long) s->n, (double) len, (long) s->count);
|
||||
|
||||
do {
|
||||
tag t = gettag2(s1,s2);
|
||||
@@ -175,7 +190,7 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
tag_hits++;
|
||||
for (; j<s->count && targets[j].t == t; j++) {
|
||||
for (; j < (int) s->count && targets[j].t == t; j++) {
|
||||
int l, i = targets[j].i;
|
||||
|
||||
if (sum != s->sums[i].sum1) continue;
|
||||
@@ -201,7 +216,7 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
|
||||
/* we've found a match, but now check to see
|
||||
if last_i can hint at a better match */
|
||||
for (j++; j<s->count && targets[j].t == t; j++) {
|
||||
for (j++; j < (int) s->count && targets[j].t == t; j++) {
|
||||
int i2 = targets[j].i;
|
||||
if (i2 == last_i + 1) {
|
||||
if (sum != s->sums[i2].sum1) break;
|
||||
@@ -246,7 +261,8 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
match. The 3 reads are caused by the
|
||||
running match, the checksum update and the
|
||||
literal send. */
|
||||
if (offset-last_match >= CHUNK_SIZE+s->n &&
|
||||
if (offset > last_match &&
|
||||
offset-last_match >= CHUNK_SIZE+s->n &&
|
||||
(end-offset > CHUNK_SIZE)) {
|
||||
matched(f,s,buf,offset - s->n, -2);
|
||||
}
|
||||
@@ -257,7 +273,21 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
}
|
||||
|
||||
|
||||
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
|
||||
/**
|
||||
* 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];
|
||||
extern int write_batch; /* dw */
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.7
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -21,11 +21,18 @@ A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
|
||||
* Thu Jan 30 2003 Horst von Brand <vonbrand@inf.utfsm.cl>
|
||||
Fixed "Sept" date in %changelog here
|
||||
Use %{_mandir} to point to manpages
|
||||
Support for compressed manpages (* at end catches them in %files)
|
||||
Add doc/README-SGML and doc/rsync.sgml to %doc
|
||||
|
||||
* Mon Sep 11 2000 John H Terpstra <jht@turbolinux.com>
|
||||
Changed target paths to be Linux Standards Base compliant
|
||||
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
@@ -62,23 +69,25 @@ previous package(s).)
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr --mandir=/usr/share/man
|
||||
./configure --prefix=/usr --mandir=%{_mandir}
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man{1,5}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/%{_mandir}/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/%{_mandir}/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/share/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %{_mandir}/man1/rsync.1*
|
||||
%attr(-,root,root) %{_mandir}/man5/rsyncd.conf.5*
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
%attr(-,root,root) %doc doc/README-SGML doc/rsync.sgml
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.7
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.7
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.7.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1*
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
94
packaging/solaris/build_pkg.sh
Normal file
94
packaging/solaris/build_pkg.sh
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/bin/sh
|
||||
# Shell script for building Solaris package of rsync
|
||||
# Author: Jens Apel <jens.apel@web.de>
|
||||
# License: GPL
|
||||
#
|
||||
# BASEDIR is /usr/local and should be the same as the
|
||||
# --prefix parameter of configure
|
||||
#
|
||||
# this script should be copied under
|
||||
# packaging/solaris/5.8/build_pkg.sh
|
||||
|
||||
# Definitions start here
|
||||
# you can edit this, if you like
|
||||
|
||||
# The Package name under which rsync will b installed
|
||||
PKGNAME=SMBrsync
|
||||
|
||||
# Extract common info requires for the 'info' part of the package.
|
||||
# This should be made generic and generated by the configure script
|
||||
# but for now it is hard coded
|
||||
BASEDIR=/usr/local
|
||||
VERSION="2.5.5"
|
||||
ARCH=`uname -p`
|
||||
NAME=rsync
|
||||
|
||||
# Definitions end here
|
||||
# Please do not edit below this line or you know what you do.
|
||||
|
||||
## Start by faking root install
|
||||
echo "Creating install directory (fake $BASEDIR)..."
|
||||
START=`pwd`
|
||||
FAKE_ROOT=$START/${PKGNAME}
|
||||
mkdir $FAKE_ROOT
|
||||
|
||||
# copy the binary and the man page to their places
|
||||
mkdir $FAKE_ROOT/bin
|
||||
mkdir -p $FAKE_ROOT/doc/rsync
|
||||
mkdir -p $FAKE_ROOT/man/man1
|
||||
mkdir -p $FAKE_ROOT/man/man5
|
||||
|
||||
cp ../../../rsync $FAKE_ROOT/bin/rsync
|
||||
cp ../../../rsync.1 $FAKE_ROOT/man/man1/rsync.1
|
||||
cp ../../../rsyncd.conf.5 $FAKE_ROOT/man/man5/rsyncd.conf.5
|
||||
cp ../../../README $FAKE_ROOT/doc/rsync/README
|
||||
cp ../../../COPYING $FAKE_ROOT/doc/rsync/COPYING
|
||||
cp ../../../tech_report.pdf $FAKE_ROOT/doc/rsync/tech_report.pdf
|
||||
cp ../../../COPYING $FAKE_ROOT/COPYING
|
||||
|
||||
## Build info file
|
||||
echo "Building pkginfo file..."
|
||||
cat > $FAKE_ROOT/pkginfo << EOF_INFO
|
||||
PKG=$PKGNAME
|
||||
NAME=$NAME
|
||||
DESC="Program for efficient remote updates of files."
|
||||
VENDOR="Samba Team URL: http://samba.anu.edu.au/rsync/"
|
||||
BASEDIR=$BASEDIR
|
||||
ARCH=$ARCH
|
||||
VERSION=$VERSION
|
||||
CATEGORY=application
|
||||
CLASSES=none
|
||||
EOF_INFO
|
||||
|
||||
## Build prototype file
|
||||
cat > $FAKE_ROOT/prototype << EOFPROTO
|
||||
i copyright=COPYING
|
||||
i pkginfo=pkginfo
|
||||
d none bin 0755 bin bin
|
||||
f none bin/rsync 0755 bin bin
|
||||
d none doc 0755 bin bin
|
||||
d none doc/$NAME 0755 bin bin
|
||||
f none doc/$NAME/README 0644 bin bin
|
||||
f none doc/$NAME/COPYING 0644 bin bin
|
||||
f none doc/$NAME/tech_report.pdf 0644 bin bin
|
||||
d none man 0755 bin bin
|
||||
d none man/man1 0755 bin bin
|
||||
f none man/man1/rsync.1 0644 bin bin
|
||||
d none man/man5 0755 bin bin
|
||||
f none man/man5/rsyncd.conf.5 0644 bin bin
|
||||
EOFPROTO
|
||||
|
||||
## And now build the package.
|
||||
OUTPUTFILE=$PKGNAME-$VERSION-sol8-$ARCH-local.pkg
|
||||
echo "Building package.."
|
||||
echo FAKE_ROOT = $FAKE_ROOT
|
||||
cd $FAKE_ROOT
|
||||
pkgmk -d . -r . -f ./prototype -o
|
||||
pkgtrans -os . $OUTPUTFILE $PKGNAME
|
||||
|
||||
mv $OUTPUTFILE ..
|
||||
cd ..
|
||||
|
||||
# Comment this out if you want to see, which file structure has been created
|
||||
rm -rf $FAKE_ROOT
|
||||
|
||||
16
params.c
16
params.c
@@ -164,7 +164,7 @@ static int Continuation( char *line, int pos )
|
||||
*/
|
||||
{
|
||||
pos--;
|
||||
while( (pos >= 0) && isspace(line[pos]) )
|
||||
while( (pos >= 0) && isspace(((unsigned char *)line)[pos]) )
|
||||
pos--;
|
||||
|
||||
return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
|
||||
@@ -207,7 +207,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
if( i > (bSize - 2) )
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func);
|
||||
@@ -301,7 +301,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
|
||||
@@ -366,7 +366,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
if( i > (bSize - 2) ) /* Make sure there's enough room. */
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
|
||||
@@ -386,7 +386,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
c = 0;
|
||||
else
|
||||
{
|
||||
for( end = i; (end >= 0) && isspace(bufr[end]); end-- )
|
||||
for( end = i; (end >= 0) && isspace(((unsigned char *) bufr)[end]); end-- )
|
||||
;
|
||||
c = getc( InFile );
|
||||
}
|
||||
@@ -491,8 +491,8 @@ static FILE *OpenConfFile( char *FileName )
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rprintf(FERROR,"%s Unable to open configuration file \"%s\":\n\t%s\n",
|
||||
func, FileName, strerror(errno));
|
||||
rprintf(FERROR,"rsync: unable to open configuration file \"%s\": %s\n",
|
||||
FileName, strerror(errno));
|
||||
}
|
||||
|
||||
return( OpenedFile );
|
||||
@@ -530,7 +530,7 @@ BOOL pm_process( char *FileName,
|
||||
else /* If we don't have a buffer */
|
||||
{ /* allocate one, then parse, */
|
||||
bSize = BUFR_INC; /* then free. */
|
||||
bufr = (char *)malloc( bSize );
|
||||
bufr = new_array( char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR,"%s memory allocation failure.\n", func);
|
||||
|
||||
152
pipe.c
Normal file
152
pipe.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* Create a child connected to use on stdin/stdout.
|
||||
*
|
||||
* This is derived from CVS code
|
||||
*
|
||||
* Note that in the child STDIN is set to blocking and STDOUT
|
||||
* is set to non-blocking. This is necessary as rsh relies on stdin being blocking
|
||||
* and ssh relies on stdout being non-blocking
|
||||
*
|
||||
* If blocking_io is set then use blocking io on both fds. That can be
|
||||
* used to cope with badly broken rsh implementations like the one on
|
||||
* Solaris.
|
||||
**/
|
||||
pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int blocking_io;
|
||||
|
||||
if (verbose >= 2) {
|
||||
print_child_argv(command);
|
||||
}
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR, "pipe: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR, "fork: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int orig_umask;
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR, "Failed to dup/close : %s\n",
|
||||
strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io) {
|
||||
set_blocking(STDOUT_FILENO);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
rprintf(FERROR, "Failed to exec %s : %s\n",
|
||||
command[0], strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
|
||||
int (*child_main)(int, char*[]))
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int read_batch;
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
extern int filesfrom_fd;
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 ||
|
||||
fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR,"pipe: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR,"fork: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
am_sender = read_batch ? 0 : !am_sender;
|
||||
am_server = 1;
|
||||
|
||||
if (!am_sender)
|
||||
filesfrom_fd = -1;
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
|
||||
child_main(argc, argv);
|
||||
}
|
||||
|
||||
if (!am_sender)
|
||||
filesfrom_fd = -1;
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
1.3 ->
|
||||
1.5 -> 1.6
|
||||
- add ability to perform callbacks for every, not just first, match.
|
||||
|
||||
1.3 -> 1.5
|
||||
- heavy dose of const's
|
||||
- poptParseArgvString() now NULL terminates the list
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ to getopt(3), it contains a number of enhancements, including:
|
||||
2) popt can parse arbitrary argv[] style arrays while
|
||||
getopt(2) makes this quite difficult
|
||||
3) popt allows users to alias command line arguments
|
||||
4) popt provides convience functions for parsting strings
|
||||
4) popt provides convience functions for parsing strings
|
||||
into argv[] style arrays
|
||||
|
||||
popt is used by rpm, the Red Hat install program, and many other Red Hat
|
||||
|
||||
4
popt/README.rsync
Normal file
4
popt/README.rsync
Normal file
@@ -0,0 +1,4 @@
|
||||
This is a perfectly ordinary copy of libpopt. It is only used on platforms
|
||||
that do not have a sufficiently up-to-date copy of their own. If you build
|
||||
rsync on a platform which has popt, this directory should not be used. (You
|
||||
can control that using the --with-included-popt configure flag.)
|
||||
104
popt/config.log
104
popt/config.log
@@ -1,104 +0,0 @@
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
configure:592: checking host system type
|
||||
configure:613: checking target system type
|
||||
configure:631: checking build system type
|
||||
configure:665: checking for a BSD compatible install
|
||||
configure:718: checking whether build environment is sane
|
||||
configure:775: checking whether make sets ${MAKE}
|
||||
configure:821: checking for working aclocal
|
||||
configure:834: checking for working autoconf
|
||||
configure:847: checking for working automake
|
||||
configure:860: checking for working autoheader
|
||||
configure:873: checking for working makeinfo
|
||||
configure:891: checking for gcc
|
||||
configure:1004: checking whether the C compiler (gcc ) works
|
||||
configure:1020: gcc -o conftest conftest.c 1>&5
|
||||
configure:1046: checking whether the C compiler (gcc ) is a cross-compiler
|
||||
configure:1051: checking whether we are using GNU C
|
||||
configure:1079: checking whether gcc accepts -g
|
||||
configure:1111: checking for POSIXized ISC
|
||||
configure:1135: checking for gcc
|
||||
configure:1248: checking whether the C compiler (gcc -g -O2 ) works
|
||||
configure:1264: gcc -o conftest -g -O2 conftest.c 1>&5
|
||||
configure:1290: checking whether the C compiler (gcc -g -O2 ) is a cross-compiler
|
||||
configure:1295: checking whether we are using GNU C
|
||||
configure:1323: checking whether gcc accepts -g
|
||||
configure:1355: checking how to run the C preprocessor
|
||||
configure:1436: checking whether gcc needs -traditional
|
||||
configure:1485: checking for gcc option to accept ANSI C
|
||||
configure:1564: checking for function prototypes
|
||||
configure:1795: checking for ranlib
|
||||
configure:1834: checking for ld used by GCC
|
||||
configure:1896: checking if the linker (/usr/bin/ld) is GNU ld
|
||||
configure:1912: checking for BSD-compatible nm
|
||||
configure:1948: checking whether ln -s works
|
||||
ltconfig:603: checking for object suffix
|
||||
ltconfig:604: gcc -c -g -O2 conftest.c 1>&5
|
||||
ltconfig:629: checking for executable suffix
|
||||
ltconfig:630: gcc -o conftest -g -O2 conftest.c 1>&5
|
||||
ltconfig:776: checking if gcc PIC flag -fPIC works
|
||||
ltconfig:777: gcc -c -g -O2 -fPIC -DPIC conftest.c 1>&5
|
||||
ltconfig:829: checking if gcc supports -c -o file.o
|
||||
ltconfig:830: gcc -c -g -O2 -o out/conftest2.o conftest.c 1>&5
|
||||
ltconfig:862: checking if gcc supports -c -o file.lo
|
||||
ltconfig:863: gcc -c -g -O2 -c -o conftest.lo conftest.c 1>&5
|
||||
ltconfig:914: checking if gcc supports -fno-rtti -fno-exceptions
|
||||
ltconfig:915: gcc -c -g -O2 -fno-rtti -fno-exceptions -c conftest.c conftest.c 1>&5
|
||||
ltconfig:958: checking if gcc static flag -static works
|
||||
ltconfig:959: gcc -o conftest -g -O2 -static conftest.c 1>&5
|
||||
GNU ld version 2.10.91 (with BFD 2.10.91.0.2)
|
||||
ltconfig:1635: checking if global_symbol_pipe works
|
||||
ltconfig:1636: gcc -c -g -O2 conftest.c 1>&5
|
||||
ltconfig:1639: eval "/usr/bin/nm -B conftest.o | sed -n -e 's/^.*[ ]\([ABCDGISTW]\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' > conftest.nm"
|
||||
ltconfig:1691: gcc -o conftest -g -O2 -fno-builtin -fno-rtti -fno-exceptions conftest.c conftstm.o 1>&5
|
||||
configure:2150: checking for a BSD compatible install
|
||||
configure:2231: checking for alloca.h
|
||||
configure:2231: checking for libintl.h
|
||||
configure:2231: checking for mcheck.h
|
||||
configure:2231: checking for unistd.h
|
||||
configure:2268: checking for /usr/ucblib in LIBS
|
||||
configure:2284: checking for GNU xgettext
|
||||
configure:2294: checking for strerror
|
||||
configure:2294: checking for mtrace
|
||||
configure:2347: checking for setreuid
|
||||
configure:2438: checking for working const
|
||||
configure:2513: checking for inline
|
||||
configure:2553: checking for off_t
|
||||
configure:2586: checking for size_t
|
||||
configure:2621: checking for working alloca.h
|
||||
configure:2654: checking for alloca
|
||||
configure:2856: checking for unistd.h
|
||||
configure:2895: checking for getpagesize
|
||||
configure:2948: checking for working mmap
|
||||
configure:3124: checking for argz.h
|
||||
configure:3124: checking for limits.h
|
||||
configure:3124: checking for locale.h
|
||||
configure:3124: checking for nl_types.h
|
||||
configure:3124: checking for malloc.h
|
||||
configure:3124: checking for string.h
|
||||
configure:3124: checking for unistd.h
|
||||
configure:3124: checking for sys/param.h
|
||||
configure:3164: checking for getcwd
|
||||
configure:3164: checking for munmap
|
||||
configure:3164: checking for putenv
|
||||
configure:3164: checking for setenv
|
||||
configure:3164: checking for setlocale
|
||||
configure:3164: checking for strchr
|
||||
configure:3164: checking for strcasecmp
|
||||
configure:3164: checking for strdup
|
||||
configure:3164: checking for __argz_count
|
||||
configure:3164: checking for __argz_stringify
|
||||
configure:3164: checking for __argz_next
|
||||
configure:3283: checking for LC_MESSAGES
|
||||
configure:3316: checking whether NLS is requested
|
||||
configure:3336: checking whether included gettext is requested
|
||||
configure:3355: checking for libintl.h
|
||||
configure:3382: checking for gettext in libc
|
||||
configure:3508: checking for msgfmt
|
||||
configure:3542: checking for dcgettext
|
||||
configure:3597: checking for gmsgfmt
|
||||
configure:3633: checking for xgettext
|
||||
configure:3673: gcc -o conftest -Wall -g -O2 conftest.c 1>&5
|
||||
configure:4131: checking for catalogs to be installed
|
||||
@@ -1,6 +1,10 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/findme.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "findme.h"
|
||||
@@ -9,38 +13,38 @@ const char * findProgramPath(const char * argv0) {
|
||||
char * path = getenv("PATH");
|
||||
char * pathbuf;
|
||||
char * start, * chptr;
|
||||
char * buf, *local = NULL;
|
||||
char * buf;
|
||||
|
||||
/* If there is a / in the argv[0], it has to be an absolute
|
||||
path */
|
||||
if (argv0 == NULL) return NULL; /* XXX can't happen */
|
||||
/* If there is a / in the argv[0], it has to be an absolute path */
|
||||
if (strchr(argv0, '/'))
|
||||
return xstrdup(argv0);
|
||||
|
||||
if (!path) return NULL;
|
||||
if (path == NULL) return NULL;
|
||||
|
||||
local = start = pathbuf = malloc(strlen(path) + 1);
|
||||
buf = malloc(strlen(path) + strlen(argv0) + 2);
|
||||
start = pathbuf = alloca(strlen(path) + 1);
|
||||
buf = malloc(strlen(path) + strlen(argv0) + sizeof("/"));
|
||||
if (buf == NULL) return NULL; /* XXX can't happen */
|
||||
strcpy(pathbuf, path);
|
||||
|
||||
chptr = NULL;
|
||||
/*@-branchstate@*/
|
||||
do {
|
||||
if ((chptr = strchr(start, ':')))
|
||||
*chptr = '\0';
|
||||
sprintf(buf, "%s/%s", start, argv0);
|
||||
|
||||
if (!access(buf, X_OK)) {
|
||||
if (local) free(local);
|
||||
return buf;
|
||||
}
|
||||
if (!access(buf, X_OK))
|
||||
return buf;
|
||||
|
||||
if (chptr)
|
||||
start = chptr + 1;
|
||||
else
|
||||
start = NULL;
|
||||
} while (start && *start);
|
||||
/*@=branchstate@*/
|
||||
|
||||
free(buf);
|
||||
if (local) free(local);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/findme.h
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_FINDME
|
||||
#define H_FINDME
|
||||
|
||||
const char * findProgramPath(const char * argv0);
|
||||
/**
|
||||
* Return absolute path to executable by searching PATH.
|
||||
* @param argv0 name of executable
|
||||
* @return (malloc'd) absolute path to executable (or NULL)
|
||||
*/
|
||||
/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0)
|
||||
/*@*/;
|
||||
|
||||
#endif
|
||||
|
||||
1055
popt/popt.c
1055
popt/popt.c
File diff suppressed because it is too large
Load Diff
480
popt/popt.h
480
popt/popt.h
@@ -1,128 +1,444 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \file popt/popt.h
|
||||
* \ingroup popt
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_POPT
|
||||
#define H_POPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for FILE * */
|
||||
|
||||
#define POPT_OPTION_DEPTH 10
|
||||
|
||||
#define POPT_ARG_NONE 0
|
||||
#define POPT_ARG_STRING 1
|
||||
#define POPT_ARG_INT 2
|
||||
#define POPT_ARG_LONG 3
|
||||
#define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */
|
||||
#define POPT_ARG_CALLBACK 5 /* table-wide callback... must be
|
||||
/** \ingroup popt
|
||||
* \name Arg type identifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ARG_NONE 0 /*!< no arg */
|
||||
#define POPT_ARG_STRING 1 /*!< arg will be saved as string */
|
||||
#define POPT_ARG_INT 2 /*!< arg will be converted to int */
|
||||
#define POPT_ARG_LONG 3 /*!< arg will be converted to long */
|
||||
#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */
|
||||
#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be
|
||||
set first in table; arg points
|
||||
to callback, descrip points to
|
||||
callback data to pass */
|
||||
#define POPT_ARG_INTL_DOMAIN 6 /* set the translation domain
|
||||
#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain
|
||||
for this table and any
|
||||
included tables; arg points
|
||||
to the domain string */
|
||||
#define POPT_ARG_VAL 7 /* arg should take value val */
|
||||
#define POPT_ARG_VAL 7 /*!< arg should take value val */
|
||||
#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */
|
||||
#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */
|
||||
|
||||
#define POPT_ARG_MASK 0x0000FFFF
|
||||
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
|
||||
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
|
||||
#define POPT_ARGFLAG_STRIP 0x20000000 /* strip this arg from argv (only applies to long args) */
|
||||
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
|
||||
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
|
||||
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Arg modifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */
|
||||
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */
|
||||
#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */
|
||||
#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */
|
||||
|
||||
#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */
|
||||
#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */
|
||||
#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */
|
||||
#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */
|
||||
#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */
|
||||
#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */
|
||||
#define POPT_ARGFLAG_LOGICALOPS \
|
||||
(POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
|
||||
|
||||
#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR)
|
||||
/*!< set arg bit(s) */
|
||||
#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND)
|
||||
/*!< clear arg bit(s) */
|
||||
|
||||
#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Callback modifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */
|
||||
#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */
|
||||
#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line,
|
||||
not the subtable */
|
||||
#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */
|
||||
#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */
|
||||
/*@}*/
|
||||
|
||||
#define POPT_ERROR_NOARG -10
|
||||
#define POPT_ERROR_BADOPT -11
|
||||
#define POPT_ERROR_OPTSTOODEEP -13
|
||||
#define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */
|
||||
#define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */
|
||||
#define POPT_ERROR_BADNUMBER -17
|
||||
#define POPT_ERROR_OVERFLOW -18
|
||||
/** \ingroup popt
|
||||
* \name Error return values
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ERROR_NOARG -10 /*!< missing argument */
|
||||
#define POPT_ERROR_BADOPT -11 /*!< unknown option */
|
||||
#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */
|
||||
#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */
|
||||
#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */
|
||||
#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */
|
||||
#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */
|
||||
#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */
|
||||
#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */
|
||||
#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */
|
||||
/*@}*/
|
||||
|
||||
/* poptBadOption() flags */
|
||||
#define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */
|
||||
/** \ingroup popt
|
||||
* \name poptBadOption() flags
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */
|
||||
/*@}*/
|
||||
|
||||
/* poptGetContext() flags */
|
||||
#define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */
|
||||
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
|
||||
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */
|
||||
/** \ingroup popt
|
||||
* \name poptGetContext() flags
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */
|
||||
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */
|
||||
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */
|
||||
#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
struct poptOption {
|
||||
/*@observer@*/ /*@null@*/ const char * longName; /* may be NULL */
|
||||
char shortName; /* may be '\0' */
|
||||
/*@observer@*/ /*@null@*/ const char * longName; /*!< may be NULL */
|
||||
char shortName; /*!< may be '\0' */
|
||||
int argInfo;
|
||||
/*@shared@*/ /*@null@*/ void * arg; /* depends on argInfo */
|
||||
int val; /* 0 means don't return, just update flag */
|
||||
/*@shared@*/ /*@null@*/ const char * descrip; /* description for autohelp -- may be NULL */
|
||||
/*@shared@*/ /*@null@*/ const char * argDescrip; /* argument description for autohelp */
|
||||
/*@shared@*/ /*@null@*/ void * arg; /*!< depends on argInfo */
|
||||
int val; /*!< 0 means don't return, just update flag */
|
||||
/*@observer@*/ /*@null@*/ const char * descrip; /*!< description for autohelp -- may be NULL */
|
||||
/*@observer@*/ /*@null@*/ const char * argDescrip; /*!< argument description for autohelp */
|
||||
};
|
||||
|
||||
/** \ingroup popt
|
||||
* A popt alias argument for poptAddAlias().
|
||||
*/
|
||||
struct poptAlias {
|
||||
/*@owned@*/ /*@null@*/ const char * longName; /* may be NULL */
|
||||
char shortName; /* may be '\0' */
|
||||
/*@owned@*/ /*@null@*/ const char * longName; /*!< may be NULL */
|
||||
char shortName; /*!< may be '\0' */
|
||||
int argc;
|
||||
/*@owned@*/ const char ** argv; /* must be free()able */
|
||||
/*@owned@*/ const char ** argv; /*!< must be free()able */
|
||||
};
|
||||
|
||||
/** \ingroup popt
|
||||
* A popt alias or exec argument for poptAddItem().
|
||||
*/
|
||||
typedef struct poptItem_s {
|
||||
struct poptOption option; /*!< alias/exec name(s) and description. */
|
||||
int argc; /*!< (alias) no. of args. */
|
||||
/*@owned@*/ const char ** argv; /*!< (alias) args, must be free()able. */
|
||||
} * poptItem;
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Auto-generated help/usage
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* Empty table marker to enable displaying popt alias/exec options.
|
||||
*/
|
||||
/*@observer@*/ /*@checked@*/
|
||||
extern struct poptOption poptAliasOptions[];
|
||||
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
|
||||
0, "Options implemented via popt alias/exec:", NULL },
|
||||
|
||||
/**
|
||||
* Auto help table options.
|
||||
*/
|
||||
/*@observer@*/ /*@checked@*/
|
||||
extern struct poptOption poptHelpOptions[];
|
||||
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
|
||||
0, "Help options", NULL },
|
||||
0, "Help options:", NULL },
|
||||
|
||||
typedef struct poptContext_s * poptContext;
|
||||
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
typedef /*@abstract@*/ struct poptContext_s * poptContext;
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
/*@-typeuse@*/
|
||||
typedef struct poptOption * poptOption;
|
||||
/*@=typeuse@*/
|
||||
#endif
|
||||
|
||||
enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
|
||||
POPT_CALLBACK_REASON_POST,
|
||||
POPT_CALLBACK_REASON_OPTION };
|
||||
typedef void (*poptCallbackType)(poptContext con,
|
||||
enum poptCallbackReason reason,
|
||||
const struct poptOption * opt,
|
||||
const char * arg, const void * data);
|
||||
|
||||
/*@only@*/ poptContext poptGetContext(/*@keep@*/ const char * name,
|
||||
int argc, /*@keep@*/ const char ** argv,
|
||||
/*@keep@*/ const struct poptOption * options, int flags);
|
||||
void poptResetContext(poptContext con);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*@-type@*/
|
||||
|
||||
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
|
||||
int poptGetNextOpt(poptContext con);
|
||||
/* returns NULL if no argument is available */
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(poptContext con);
|
||||
/* returns NULL if no more options are available */
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetArg(poptContext con);
|
||||
/*@observer@*/ /*@null@*/ const char * poptPeekArg(poptContext con);
|
||||
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(poptContext con);
|
||||
/* returns the option which caused the most recent error */
|
||||
/*@observer@*/ const char * poptBadOption(poptContext con, int flags);
|
||||
void poptFreeContext( /*@only@*/ poptContext con);
|
||||
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv);
|
||||
int poptAddAlias(poptContext con, struct poptAlias alias, int flags);
|
||||
int poptReadConfigFile(poptContext con, const char * fn);
|
||||
/* like above, but reads /etc/popt and $HOME/.popt along with environment
|
||||
vars */
|
||||
int poptReadDefaultConfig(poptContext con, int useEnv);
|
||||
/* argv should be freed -- this allows ', ", and \ quoting, but ' is treated
|
||||
the same as " and both may include \ quotes */
|
||||
int poptDupArgv(int argc, const char **argv,
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
|
||||
/** \ingroup popt
|
||||
* Table callback prototype.
|
||||
* @param con context
|
||||
* @param reason reason for callback
|
||||
* @param opt option that triggered callback
|
||||
* @param arg @todo Document.
|
||||
* @param data @todo Document.
|
||||
*/
|
||||
typedef void (*poptCallbackType) (poptContext con,
|
||||
enum poptCallbackReason reason,
|
||||
/*@null@*/ const struct poptOption * opt,
|
||||
/*@null@*/ const char * arg,
|
||||
/*@null@*/ const void * data)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Initialize popt context.
|
||||
* @param name
|
||||
* @param argc no. of arguments
|
||||
* @param argv argument array
|
||||
* @param options address of popt option table
|
||||
* @param flags or'd POPT_CONTEXT_* bits
|
||||
* @return initialized popt context
|
||||
*/
|
||||
/*@only@*/ /*@null@*/ poptContext poptGetContext(
|
||||
/*@dependent@*/ /*@keep@*/ const char * name,
|
||||
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
|
||||
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
|
||||
int flags)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Reinitialize popt context.
|
||||
* @param con context
|
||||
*/
|
||||
void poptResetContext(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return value of next option found.
|
||||
* @param con context
|
||||
* @return next option val, -1 on last item, POPT_ERROR_* on error
|
||||
*/
|
||||
int poptGetNextOpt(/*@null@*/poptContext con)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies con, fileSystem @*/;
|
||||
|
||||
/*@-redecl@*/
|
||||
/** \ingroup popt
|
||||
* Return next option argument (if any).
|
||||
* @param con context
|
||||
* @return option argument, NULL if no more options are available
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return current option's argument.
|
||||
* @param con context
|
||||
* @return option argument, NULL if no more options are available
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Peek at current option's argument.
|
||||
* @param con context
|
||||
* @return option argument
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return remaining arguments.
|
||||
* @param con context
|
||||
* @return argument array, terminated with NULL
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return the option which caused the most recent error.
|
||||
* @param con context
|
||||
* @return offending option
|
||||
*/
|
||||
/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags)
|
||||
/*@*/;
|
||||
/*@=redecl@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Destroy context.
|
||||
* @param con context
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add arguments to context.
|
||||
* @param con context
|
||||
* @param argv argument array, NULL terminated
|
||||
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
|
||||
*/
|
||||
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add alias to context.
|
||||
* @todo Pass alias by reference, not value.
|
||||
* @deprecated Use poptAddItem instead.
|
||||
* @param con context
|
||||
* @param alias alias to add
|
||||
* @param flags (unused)
|
||||
* @return 0 on success
|
||||
*/
|
||||
/*@unused@*/
|
||||
int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add alias/exec item to context.
|
||||
* @param con context
|
||||
* @param item alias/exec item to add
|
||||
* @param flags 0 for alias, 1 for exec
|
||||
* @return 0 on success
|
||||
*/
|
||||
int poptAddItem(poptContext con, poptItem newItem, int flags)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Read configuration file.
|
||||
* @param con context
|
||||
* @param fn file name to read
|
||||
* @return 0 on success, POPT_ERROR_ERRNO on failure
|
||||
*/
|
||||
int poptReadConfigFile(poptContext con, const char * fn)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem,
|
||||
con->execs, con->numExecs @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Read default configuration from /etc/popt and $HOME/.popt.
|
||||
* @param con context
|
||||
* @param useEnv (unused)
|
||||
* @return 0 on success, POPT_ERROR_ERRNO on failure
|
||||
*/
|
||||
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem,
|
||||
con->execs, con->numExecs @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Duplicate an argument array.
|
||||
* @note: The argument array is malloc'd as a single area, so only argv must
|
||||
* be free'd.
|
||||
*
|
||||
* @param argc no. of arguments
|
||||
* @param argv argument array
|
||||
* @retval argcPtr address of returned no. of arguments
|
||||
* @retval argvPtr address of returned argument array
|
||||
* @return 0 on success, POPT_ERROR_NOARG on failure
|
||||
*/
|
||||
int poptDupArgv(int argc, /*@null@*/ const char **argv,
|
||||
/*@null@*/ /*@out@*/ int * argcPtr,
|
||||
/*@null@*/ /*@out@*/ const char *** argvPtr)
|
||||
/*@modifies *argcPtr, *argvPtr @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Parse a string into an argument array.
|
||||
* The parse allows ', ", and \ quoting, but ' is treated the same as " and
|
||||
* both may include \ quotes.
|
||||
* @note: The argument array is malloc'd as a single area, so only argv must
|
||||
* be free'd.
|
||||
*
|
||||
* @param s string to parse
|
||||
* @retval argcPtr address of returned no. of arguments
|
||||
* @retval argvPtr address of returned argument array
|
||||
*/
|
||||
int poptParseArgvString(const char * s,
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
|
||||
/*@observer@*/ const char *const poptStrerror(const int error);
|
||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
|
||||
void poptPrintHelp(poptContext con, FILE * f, int flags);
|
||||
void poptPrintUsage(poptContext con, FILE * f, int flags);
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text);
|
||||
/*@observer@*/ const char * poptGetInvocationName(poptContext con);
|
||||
/* shuffles argv pointers to remove stripped args, returns new argc */
|
||||
int poptStrippedArgv(poptContext con, int argc, char **argv);
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr)
|
||||
/*@modifies *argcPtr, *argvPtr @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return formatted error string for popt failure.
|
||||
* @param error popt error
|
||||
* @return error string
|
||||
*/
|
||||
/*@-redecl@*/
|
||||
/*@observer@*/ const char *const poptStrerror(const int error)
|
||||
/*@*/;
|
||||
/*@=redecl@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Limit search for executables.
|
||||
* @param con context
|
||||
* @param path single path to search for executables
|
||||
* @param allowAbsolute absolute paths only?
|
||||
*/
|
||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Print detailed description of options.
|
||||
* @param con context
|
||||
* @param fp ouput file handle
|
||||
* @param flags (unused)
|
||||
*/
|
||||
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Print terse description of options.
|
||||
* @param con context
|
||||
* @param fp ouput file handle
|
||||
* @param flags (unused)
|
||||
*/
|
||||
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Provide text to replace default "[OPTION...]" in help/usage output.
|
||||
* @param con context
|
||||
* @param text replacement text
|
||||
*/
|
||||
/*@-fcnuse@*/
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text)
|
||||
/*@modifies con @*/;
|
||||
/*@=fcnuse@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Return argv[0] from context.
|
||||
* @param con context
|
||||
* @return argv[0]
|
||||
*/
|
||||
/*@-redecl -fcnuse@*/
|
||||
/*@observer@*/ const char * poptGetInvocationName(poptContext con)
|
||||
/*@*/;
|
||||
/*@=redecl =fcnuse@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Shuffle argv pointers to remove stripped args, returns new argc.
|
||||
* @param con context
|
||||
* @param argc no. of args
|
||||
* @param argv arg vector
|
||||
* @return new argc
|
||||
*/
|
||||
/*@-fcnuse@*/
|
||||
int poptStrippedArgv(poptContext con, int argc, char ** argv)
|
||||
/*@modifies *argv @*/;
|
||||
/*@=fcnuse@*/
|
||||
|
||||
/*@=type@*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,101 +1,144 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptconfig.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "poptint.h"
|
||||
|
||||
static void configLine(poptContext con, char * line) {
|
||||
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
|
||||
static void configLine(poptContext con, char * line)
|
||||
/*@modifies con @*/
|
||||
{
|
||||
/*@-type@*/
|
||||
int nameLength = strlen(con->appName);
|
||||
char * opt;
|
||||
struct poptAlias alias;
|
||||
char * entryType;
|
||||
char * longName = NULL;
|
||||
char shortName = '\0';
|
||||
/*@=type@*/
|
||||
const char * entryType;
|
||||
const char * opt;
|
||||
poptItem item = (poptItem) alloca(sizeof(*item));
|
||||
int i, j;
|
||||
|
||||
memset(item, 0, sizeof(*item));
|
||||
|
||||
/*@-type@*/
|
||||
if (strncmp(line, con->appName, nameLength)) return;
|
||||
/*@=type@*/
|
||||
|
||||
line += nameLength;
|
||||
if (!*line || !isspace(*line)) return;
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (*line == '\0' || !isspace(*line)) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
entryType = line;
|
||||
|
||||
while (!*line || !isspace(*line)) line++;
|
||||
while (*line == '\0' || !isspace(*line)) line++;
|
||||
*line++ = '\0';
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (!*line) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
if (*line == '\0') return;
|
||||
opt = line;
|
||||
|
||||
while (!*line || !isspace(*line)) line++;
|
||||
while (*line == '\0' || !isspace(*line)) line++;
|
||||
*line++ = '\0';
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (!*line) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
if (*line == '\0') return;
|
||||
|
||||
/*@-temptrans@*/ /* FIX: line alias is saved */
|
||||
if (opt[0] == '-' && opt[1] == '-')
|
||||
longName = opt + 2;
|
||||
else if (opt[0] == '-' && !opt[2])
|
||||
shortName = opt[1];
|
||||
item->option.longName = opt + 2;
|
||||
else if (opt[0] == '-' && opt[2] == '\0')
|
||||
item->option.shortName = opt[1];
|
||||
/*@=temptrans@*/
|
||||
|
||||
if (!strcmp(entryType, "alias")) {
|
||||
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
|
||||
alias.longName = longName, alias.shortName = shortName;
|
||||
poptAddAlias(con, alias, 0);
|
||||
} else if (!strcmp(entryType, "exec")) {
|
||||
con->execs = realloc(con->execs,
|
||||
sizeof(*con->execs) * (con->numExecs + 1));
|
||||
if (longName)
|
||||
con->execs[con->numExecs].longName = xstrdup(longName);
|
||||
else
|
||||
con->execs[con->numExecs].longName = NULL;
|
||||
if (poptParseArgvString(line, &item->argc, &item->argv)) return;
|
||||
|
||||
con->execs[con->numExecs].shortName = shortName;
|
||||
con->execs[con->numExecs].script = xstrdup(line);
|
||||
|
||||
con->numExecs++;
|
||||
/*@-modobserver@*/
|
||||
item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
|
||||
for (i = 0, j = 0; i < item->argc; i++, j++) {
|
||||
const char * f;
|
||||
if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
|
||||
f = item->argv[i] + sizeof("--POPTdesc=");
|
||||
if (f[0] == '$' && f[1] == '"') f++;
|
||||
item->option.descrip = f;
|
||||
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
|
||||
j--;
|
||||
} else
|
||||
if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
|
||||
f = item->argv[i] + sizeof("--POPTargs=");
|
||||
if (f[0] == '$' && f[1] == '"') f++;
|
||||
item->option.argDescrip = f;
|
||||
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
|
||||
item->option.argInfo |= POPT_ARG_STRING;
|
||||
j--;
|
||||
} else
|
||||
if (j != i)
|
||||
item->argv[j] = item->argv[i];
|
||||
}
|
||||
if (j != i) {
|
||||
item->argv[j] = NULL;
|
||||
item->argc = j;
|
||||
}
|
||||
/*@=modobserver@*/
|
||||
|
||||
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
|
||||
if (!strcmp(entryType, "alias"))
|
||||
(void) poptAddItem(con, item, 0);
|
||||
else if (!strcmp(entryType, "exec"))
|
||||
(void) poptAddItem(con, item, 1);
|
||||
/*@=nullstate@*/
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
int poptReadConfigFile(poptContext con, const char * fn) {
|
||||
char * file=NULL, * chptr, * end;
|
||||
char * buf=NULL, * dst;
|
||||
int poptReadConfigFile(poptContext con, const char * fn)
|
||||
{
|
||||
const char * file, * chptr, * end;
|
||||
char * buf;
|
||||
/*@dependent@*/ char * dst;
|
||||
int fd, rc;
|
||||
int fileLength;
|
||||
off_t fileLength;
|
||||
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
if (fd < 0)
|
||||
return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
|
||||
|
||||
fileLength = lseek(fd, 0, SEEK_END);
|
||||
(void) lseek(fd, 0, 0);
|
||||
|
||||
file = malloc(fileLength + 1);
|
||||
if (read(fd, file, fileLength) != fileLength) {
|
||||
if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
|
||||
rc = errno;
|
||||
close(fd);
|
||||
(void) close(fd);
|
||||
/*@-mods@*/
|
||||
errno = rc;
|
||||
if (file) free(file);
|
||||
/*@=mods@*/
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
dst = buf = malloc(fileLength + 1);
|
||||
file = alloca(fileLength + 1);
|
||||
if (read(fd, (char *)file, fileLength) != fileLength) {
|
||||
rc = errno;
|
||||
(void) close(fd);
|
||||
/*@-mods@*/
|
||||
errno = rc;
|
||||
/*@=mods@*/
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
if (close(fd) == -1)
|
||||
return POPT_ERROR_ERRNO;
|
||||
|
||||
dst = buf = alloca(fileLength + 1);
|
||||
|
||||
chptr = file;
|
||||
end = (file + fileLength);
|
||||
/*@-infloops@*/ /* LCL: can't detect chptr++ */
|
||||
while (chptr < end) {
|
||||
switch (*chptr) {
|
||||
case '\n':
|
||||
*dst = '\0';
|
||||
dst = buf;
|
||||
while (*dst && isspace(*dst)) dst++;
|
||||
if (*dst && *dst != '#') {
|
||||
if (*dst && *dst != '#')
|
||||
configLine(con, dst);
|
||||
}
|
||||
chptr++;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
case '\\':
|
||||
*dst++ = *chptr++;
|
||||
if (chptr < end) {
|
||||
@@ -105,15 +148,13 @@ int poptReadConfigFile(poptContext con, const char * fn) {
|
||||
else
|
||||
*dst++ = *chptr++;
|
||||
}
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
default:
|
||||
*dst++ = *chptr++;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
free(file);
|
||||
free(buf);
|
||||
/*@=infloops@*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -122,21 +163,21 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
|
||||
char * fn, * home;
|
||||
int rc;
|
||||
|
||||
/*@-type@*/
|
||||
if (!con->appName) return 0;
|
||||
/*@=type@*/
|
||||
|
||||
rc = poptReadConfigFile(con, "/etc/popt");
|
||||
if (rc) return rc;
|
||||
if (getuid() != geteuid()) return 0;
|
||||
|
||||
if ((home = getenv("HOME"))) {
|
||||
fn = malloc(strlen(home) + 20);
|
||||
fn = alloca(strlen(home) + 20);
|
||||
strcpy(fn, home);
|
||||
strcat(fn, "/.popt");
|
||||
rc = poptReadConfigFile(con, fn);
|
||||
free(fn);
|
||||
if (rc) return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
612
popt/popthelp.c
612
popt/popthelp.c
@@ -1,48 +1,92 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/*@-type@*/
|
||||
/** \ingroup popt
|
||||
* \file popt/popthelp.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "poptint.h"
|
||||
|
||||
/**
|
||||
* @param con context
|
||||
* @param key option(s)
|
||||
*/
|
||||
static void displayArgs(poptContext con,
|
||||
/*@unused@*/ enum poptCallbackReason foo,
|
||||
struct poptOption * key,
|
||||
/*@unused@*/ const char * arg, /*@unused@*/ void * data) {
|
||||
if (key->shortName== '?')
|
||||
/*@unused@*/ const char * arg, /*@unused@*/ void * data)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem@*/
|
||||
{
|
||||
if (key->shortName == '?')
|
||||
poptPrintHelp(con, stdout, 0);
|
||||
else
|
||||
poptPrintUsage(con, stdout, 0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
/*@unchecked@*/
|
||||
static int show_option_defaults = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Empty table marker to enable displaying popt alias/exec options.
|
||||
*/
|
||||
/*@observer@*/ /*@unchecked@*/
|
||||
struct poptOption poptAliasOptions[] = {
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
/**
|
||||
* Auto help table options.
|
||||
*/
|
||||
/*@-castfcnptr@*/
|
||||
/*@observer@*/ /*@unchecked@*/
|
||||
struct poptOption poptHelpOptions[] = {
|
||||
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
|
||||
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
|
||||
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
|
||||
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
|
||||
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
|
||||
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
|
||||
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
|
||||
#ifdef NOTYET
|
||||
{ "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
|
||||
N_("Display option defaults in message"), NULL },
|
||||
#endif
|
||||
POPT_TABLEEND
|
||||
} ;
|
||||
/*@=castfcnptr@*/
|
||||
|
||||
|
||||
/**
|
||||
* @param table option(s)
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ static const char *const
|
||||
getTableTranslationDomain(const struct poptOption *table)
|
||||
getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
|
||||
/*@*/
|
||||
{
|
||||
const struct poptOption *opt;
|
||||
const struct poptOption *opt;
|
||||
|
||||
for(opt = table;
|
||||
opt->longName || opt->shortName || opt->arg;
|
||||
opt++) {
|
||||
if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
|
||||
return opt->arg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (table != NULL)
|
||||
for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
|
||||
if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
|
||||
return opt->arg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ static const char *const
|
||||
getArgDescrip(const struct poptOption * opt, const char *translation_domain)
|
||||
getArgDescrip(const struct poptOption * opt,
|
||||
/*@-paramuse@*/ /* FIX: wazzup? */
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@=paramuse@*/
|
||||
/*@*/
|
||||
{
|
||||
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
|
||||
|
||||
@@ -50,45 +94,229 @@ getArgDescrip(const struct poptOption * opt, const char *translation_domain)
|
||||
if (opt->argDescrip) return POPT_(opt->argDescrip);
|
||||
|
||||
if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
|
||||
return POPT_("ARG");
|
||||
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_NONE: return POPT_("NONE");
|
||||
case POPT_ARG_VAL: return POPT_("VAL");
|
||||
case POPT_ARG_INT: return POPT_("INT");
|
||||
case POPT_ARG_LONG: return POPT_("LONG");
|
||||
case POPT_ARG_STRING: return POPT_("STRING");
|
||||
case POPT_ARG_FLOAT: return POPT_("FLOAT");
|
||||
case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
|
||||
default: return POPT_("ARG");
|
||||
}
|
||||
}
|
||||
|
||||
static void singleOptionHelp(FILE * f, int maxLeftCol,
|
||||
const struct poptOption * opt,
|
||||
const char *translation_domain) {
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static /*@only@*/ /*@null@*/ char *
|
||||
singleOptionDefaultValue(int lineLength,
|
||||
const struct poptOption * opt,
|
||||
/*@-paramuse@*/ /* FIX: i18n macros disable with lclint */
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@=paramuse@*/
|
||||
/*@*/
|
||||
{
|
||||
const char * defstr = D_(translation_domain, "default");
|
||||
char * le = malloc(4*lineLength + 1);
|
||||
char * l = le;
|
||||
|
||||
if (le == NULL) return NULL; /* XXX can't happen */
|
||||
*le = '\0';
|
||||
*le++ = '(';
|
||||
strcpy(le, defstr); le += strlen(le);
|
||||
*le++ = ':';
|
||||
*le++ = ' ';
|
||||
if (opt->arg) /* XXX programmer error */
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_VAL:
|
||||
case POPT_ARG_INT:
|
||||
{ long aLong = *((int *)opt->arg);
|
||||
sprintf(le, "%ld", aLong);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_LONG:
|
||||
{ long aLong = *((long *)opt->arg);
|
||||
sprintf(le, "%ld", aLong);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_FLOAT:
|
||||
{ double aDouble = *((float *)opt->arg);
|
||||
sprintf(le, "%g", aDouble);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_DOUBLE:
|
||||
{ double aDouble = *((double *)opt->arg);
|
||||
sprintf(le, "%g", aDouble);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_STRING:
|
||||
{ const char * s = *(const char **)opt->arg;
|
||||
if (s == NULL) {
|
||||
strcpy(le, "null"); le += strlen(le);
|
||||
} else {
|
||||
size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
|
||||
*le++ = '"';
|
||||
strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
|
||||
if (slen < strlen(s)) {
|
||||
strcpy(le, "..."); le += strlen(le);
|
||||
}
|
||||
*le++ = '"';
|
||||
}
|
||||
} break;
|
||||
case POPT_ARG_NONE:
|
||||
default:
|
||||
l = _free(l);
|
||||
return NULL;
|
||||
/*@notreached@*/ break;
|
||||
}
|
||||
*le++ = ')';
|
||||
*le = '\0';
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void singleOptionHelp(FILE * fp, int maxLeftCol,
|
||||
const struct poptOption * opt,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int indentLength = maxLeftCol + 5;
|
||||
int lineLength = 79 - indentLength;
|
||||
const char * help = D_(translation_domain, opt->descrip);
|
||||
int helpLength;
|
||||
const char * ch;
|
||||
char format[10];
|
||||
char * left;
|
||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
||||
int helpLength;
|
||||
char * defs = NULL;
|
||||
char * left;
|
||||
int nb = maxLeftCol + 1;
|
||||
|
||||
left = malloc(maxLeftCol + 1);
|
||||
*left = '\0';
|
||||
/* Make sure there's more than enough room in target buffer. */
|
||||
if (opt->longName) nb += strlen(opt->longName);
|
||||
if (argDescrip) nb += strlen(argDescrip);
|
||||
|
||||
left = malloc(nb);
|
||||
if (left == NULL) return; /* XXX can't happen */
|
||||
left[0] = '\0';
|
||||
left[maxLeftCol] = '\0';
|
||||
|
||||
if (opt->longName && opt->shortName)
|
||||
sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
|
||||
else if (opt->shortName)
|
||||
sprintf(left, "-%c, %s%s", opt->shortName,
|
||||
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
|
||||
opt->longName);
|
||||
else if (opt->shortName != '\0')
|
||||
sprintf(left, "-%c", opt->shortName);
|
||||
else if (opt->longName)
|
||||
sprintf(left, "--%s", opt->longName);
|
||||
if (!*left) return ;
|
||||
sprintf(left, "%s%s",
|
||||
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
|
||||
opt->longName);
|
||||
if (!*left) goto out;
|
||||
if (argDescrip) {
|
||||
strcat(left, "=");
|
||||
strcat(left, argDescrip);
|
||||
char * le = left + strlen(left);
|
||||
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
|
||||
*le++ = '[';
|
||||
|
||||
/* Choose type of output */
|
||||
/*@-branchstate@*/
|
||||
if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
|
||||
defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
|
||||
if (defs) {
|
||||
char * t = malloc((help ? strlen(help) : 0) +
|
||||
strlen(defs) + sizeof(" "));
|
||||
if (t) {
|
||||
char * te = t;
|
||||
*te = '\0';
|
||||
if (help) {
|
||||
strcpy(te, help); te += strlen(te);
|
||||
}
|
||||
*te++ = ' ';
|
||||
strcpy(te, defs);
|
||||
defs = _free(defs);
|
||||
}
|
||||
defs = t;
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
if (opt->argDescrip == NULL) {
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_NONE:
|
||||
break;
|
||||
case POPT_ARG_VAL:
|
||||
{ long aLong = opt->val;
|
||||
int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
|
||||
int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
|
||||
|
||||
/* Don't bother displaying typical values */
|
||||
if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
|
||||
break;
|
||||
*le++ = '[';
|
||||
switch (ops) {
|
||||
case POPT_ARGFLAG_OR:
|
||||
*le++ = '|';
|
||||
/*@innerbreak@*/ break;
|
||||
case POPT_ARGFLAG_AND:
|
||||
*le++ = '&';
|
||||
/*@innerbreak@*/ break;
|
||||
case POPT_ARGFLAG_XOR:
|
||||
*le++ = '^';
|
||||
/*@innerbreak@*/ break;
|
||||
default:
|
||||
/*@innerbreak@*/ break;
|
||||
}
|
||||
*le++ = '=';
|
||||
if (negate) *le++ = '~';
|
||||
/*@-formatconst@*/
|
||||
sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
|
||||
le += strlen(le);
|
||||
/*@=formatconst@*/
|
||||
*le++ = ']';
|
||||
} break;
|
||||
case POPT_ARG_INT:
|
||||
case POPT_ARG_LONG:
|
||||
case POPT_ARG_FLOAT:
|
||||
case POPT_ARG_DOUBLE:
|
||||
case POPT_ARG_STRING:
|
||||
*le++ = '=';
|
||||
strcpy(le, argDescrip); le += strlen(le);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*le++ = '=';
|
||||
strcpy(le, argDescrip); le += strlen(le);
|
||||
}
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
|
||||
*le++ = ']';
|
||||
*le = '\0';
|
||||
}
|
||||
|
||||
if (help)
|
||||
fprintf(f," %-*s ", maxLeftCol, left);
|
||||
fprintf(fp," %-*s ", maxLeftCol, left);
|
||||
else {
|
||||
fprintf(f," %s\n", left);
|
||||
fprintf(fp," %s\n", left);
|
||||
goto out;
|
||||
}
|
||||
|
||||
left = _free(left);
|
||||
if (defs) {
|
||||
help = defs; defs = NULL;
|
||||
}
|
||||
|
||||
helpLength = strlen(help);
|
||||
while (helpLength > lineLength) {
|
||||
const char * ch;
|
||||
char format[10];
|
||||
|
||||
ch = help + lineLength - 1;
|
||||
while (ch > help && !isspace(*ch)) ch--;
|
||||
if (ch == help) break; /* give up */
|
||||
@@ -96,39 +324,56 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
|
||||
ch++;
|
||||
|
||||
sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
|
||||
fprintf(f, format, help, " ");
|
||||
/*@-formatconst@*/
|
||||
fprintf(fp, format, help, " ");
|
||||
/*@=formatconst@*/
|
||||
help = ch;
|
||||
while (isspace(*help) && *help) help++;
|
||||
helpLength = strlen(help);
|
||||
}
|
||||
|
||||
if (helpLength) fprintf(f, "%s\n", help);
|
||||
if (helpLength) fprintf(fp, "%s\n", help);
|
||||
|
||||
out:
|
||||
free(left);
|
||||
/*@-dependenttrans@*/
|
||||
defs = _free(defs);
|
||||
/*@=dependenttrans@*/
|
||||
left = _free(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int maxArgWidth(const struct poptOption * opt,
|
||||
const char * translation_domain) {
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@*/
|
||||
{
|
||||
int max = 0;
|
||||
int this;
|
||||
int len = 0;
|
||||
const char * s;
|
||||
|
||||
if (opt != NULL)
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
this = maxArgWidth(opt->arg, translation_domain);
|
||||
if (this > max) max = this;
|
||||
if (opt->arg) /* XXX program error */
|
||||
len = maxArgWidth(opt->arg, translation_domain);
|
||||
if (len > max) max = len;
|
||||
} else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
this = opt->shortName ? 2 : 0;
|
||||
len = sizeof(" ")-1;
|
||||
if (opt->shortName != '\0') len += sizeof("-X")-1;
|
||||
if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
|
||||
if (opt->longName) {
|
||||
if (this) this += 2;
|
||||
this += strlen(opt->longName) + 2;
|
||||
len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
|
||||
? sizeof("-")-1 : sizeof("--")-1);
|
||||
len += strlen(opt->longName);
|
||||
}
|
||||
|
||||
s = getArgDescrip(opt, translation_domain);
|
||||
if (s)
|
||||
this += strlen(s) + 1;
|
||||
if (this > max) max = this;
|
||||
len += sizeof("=")-1 + strlen(s);
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
|
||||
if (len > max) max = len;
|
||||
}
|
||||
|
||||
opt++;
|
||||
@@ -137,77 +382,134 @@ static int maxArgWidth(const struct poptOption * opt,
|
||||
return max;
|
||||
}
|
||||
|
||||
static void singleTableHelp(FILE * f, const struct poptOption * table,
|
||||
int left,
|
||||
const char *translation_domain) {
|
||||
const struct poptOption * opt;
|
||||
const char *sub_transdom;
|
||||
/**
|
||||
* Display popt alias and exec help.
|
||||
* @param fp output file handle
|
||||
* @param items alias/exec array
|
||||
* @param nitems no. of alias/exec entries
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void itemHelp(FILE * fp,
|
||||
/*@null@*/ poptItem items, int nitems, int left,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
poptItem item;
|
||||
int i;
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if (items != NULL)
|
||||
for (i = 0, item = items; i < nitems; i++, item++) {
|
||||
const struct poptOption * opt;
|
||||
opt = &item->option;
|
||||
if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
singleOptionHelp(f, left, opt, translation_domain);
|
||||
opt++;
|
||||
}
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
sub_transdom = getTableTranslationDomain(opt->arg);
|
||||
if(!sub_transdom)
|
||||
sub_transdom = translation_domain;
|
||||
|
||||
if (opt->descrip)
|
||||
fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
|
||||
|
||||
singleTableHelp(f, opt->arg, left, sub_transdom);
|
||||
}
|
||||
opt++;
|
||||
singleOptionHelp(fp, left, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
|
||||
static int showHelpIntro(poptContext con, FILE * f) {
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param table option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void singleTableHelp(poptContext con, FILE * fp,
|
||||
/*@null@*/ const struct poptOption * table, int left,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
const struct poptOption * opt;
|
||||
const char *sub_transdom;
|
||||
|
||||
if (table == poptAliasOptions) {
|
||||
itemHelp(fp, con->aliases, con->numAliases, left, NULL);
|
||||
itemHelp(fp, con->execs, con->numExecs, left, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (table != NULL)
|
||||
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
singleOptionHelp(fp, left, opt, translation_domain);
|
||||
}
|
||||
|
||||
if (table != NULL)
|
||||
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
|
||||
continue;
|
||||
sub_transdom = getTableTranslationDomain(opt->arg);
|
||||
if (sub_transdom == NULL)
|
||||
sub_transdom = translation_domain;
|
||||
|
||||
if (opt->descrip)
|
||||
fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
|
||||
|
||||
singleTableHelp(con, fp, opt->arg, left, sub_transdom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param con context
|
||||
* @param fp output file handle
|
||||
*/
|
||||
static int showHelpIntro(poptContext con, FILE * fp)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int len = 6;
|
||||
const char * fn;
|
||||
|
||||
fprintf(f, POPT_("Usage:"));
|
||||
fprintf(fp, POPT_("Usage:"));
|
||||
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
|
||||
/*@-nullderef@*/ /* LCL: wazzup? */
|
||||
fn = con->optionStack->argv[0];
|
||||
if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
|
||||
fprintf(f, " %s", fn);
|
||||
/*@=nullderef@*/
|
||||
if (fn == NULL) return len;
|
||||
if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
|
||||
fprintf(fp, " %s", fn);
|
||||
len += strlen(fn) + 1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int flags) {
|
||||
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
{
|
||||
int leftColWidth;
|
||||
|
||||
showHelpIntro(con, f);
|
||||
(void) showHelpIntro(con, fp);
|
||||
if (con->otherHelp)
|
||||
fprintf(f, " %s\n", con->otherHelp);
|
||||
fprintf(fp, " %s\n", con->otherHelp);
|
||||
else
|
||||
fprintf(f, " %s\n", POPT_("[OPTION...]"));
|
||||
fprintf(fp, " %s\n", POPT_("[OPTION...]"));
|
||||
|
||||
leftColWidth = maxArgWidth(con->options, NULL);
|
||||
singleTableHelp(f, con->options, leftColWidth, NULL);
|
||||
singleTableHelp(con, fp, con->options, leftColWidth, NULL);
|
||||
}
|
||||
|
||||
static int singleOptionUsage(FILE * f, int cursor,
|
||||
const struct poptOption * opt,
|
||||
const char *translation_domain) {
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int singleOptionUsage(FILE * fp, int cursor,
|
||||
const struct poptOption * opt,
|
||||
/*@null@*/ const char *translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int len = 3;
|
||||
char shortStr[2] = { '\0', '\0' };
|
||||
const char * item = shortStr;
|
||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
||||
|
||||
if (opt->shortName) {
|
||||
if (opt->shortName!= '\0' ) {
|
||||
if (!(opt->argInfo & POPT_ARG_MASK))
|
||||
return cursor; /* we did these already */
|
||||
len++;
|
||||
*shortStr = opt->shortName;
|
||||
shortStr[0] = opt->shortName;
|
||||
shortStr[1] = '\0';
|
||||
} else if (opt->longName) {
|
||||
len += 1 + strlen(opt->longName);
|
||||
@@ -220,82 +522,140 @@ static int singleOptionUsage(FILE * f, int cursor,
|
||||
len += strlen(argDescrip) + 1;
|
||||
|
||||
if ((cursor + len) > 79) {
|
||||
fprintf(f, "\n ");
|
||||
fprintf(fp, "\n ");
|
||||
cursor = 7;
|
||||
}
|
||||
|
||||
fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
|
||||
argDescrip ? (opt->shortName ? " " : "=") : "",
|
||||
argDescrip ? argDescrip : "");
|
||||
fprintf(fp, " [-%s%s%s%s]",
|
||||
((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
|
||||
item,
|
||||
(argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
|
||||
(argDescrip ? argDescrip : ""));
|
||||
|
||||
return cursor + len + 1;
|
||||
}
|
||||
|
||||
static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
|
||||
const char *translation_domain) {
|
||||
const struct poptOption * opt;
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
|
||||
translation_domain = (const char *)opt->arg;
|
||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
||||
cursor = singleTableUsage(f, cursor, opt->arg,
|
||||
translation_domain);
|
||||
else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
cursor = singleOptionUsage(f, cursor, opt, translation_domain);
|
||||
/**
|
||||
* Display popt alias and exec usage.
|
||||
* @param fp output file handle
|
||||
* @param item alias/exec array
|
||||
* @param nitems no. of ara/exec entries
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int i;
|
||||
|
||||
opt++;
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (item != NULL)
|
||||
for (i = 0; i < nitems; i++, item++) {
|
||||
const struct poptOption * opt;
|
||||
opt = &item->option;
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
|
||||
translation_domain = (const char *)opt->arg;
|
||||
} else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static int showShortOptions(const struct poptOption * opt, FILE * f,
|
||||
char * str) {
|
||||
char s[300]; /* this is larger then the ascii set, so
|
||||
it should do just fine */
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int singleTableUsage(poptContext con, FILE * fp,
|
||||
int cursor, const struct poptOption * opt,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (opt != NULL)
|
||||
for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
|
||||
translation_domain = (const char *)opt->arg;
|
||||
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
if (opt->arg) /* XXX program error */
|
||||
cursor = singleTableUsage(con, fp, cursor, opt->arg,
|
||||
translation_domain);
|
||||
} else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return concatenated short options for display.
|
||||
* @param opt option(s)
|
||||
* @param fp output file handle
|
||||
* @retval str concatenation of short options
|
||||
* @return length of display string
|
||||
*/
|
||||
static int showShortOptions(const struct poptOption * opt, FILE * fp,
|
||||
/*@null@*/ char * str)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *str, *fp, fileSystem @*/
|
||||
{
|
||||
char * s = alloca(300); /* larger then the ascii set */
|
||||
|
||||
s[0] = '\0';
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (str == NULL) {
|
||||
memset(s, 0, sizeof(s));
|
||||
str = s;
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if (opt != NULL)
|
||||
for (; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
|
||||
str[strlen(str)] = opt->shortName;
|
||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
||||
showShortOptions(opt->arg, f, str);
|
||||
|
||||
opt++;
|
||||
if (opt->arg) /* XXX program error */
|
||||
(void) showShortOptions(opt->arg, fp, str);
|
||||
}
|
||||
|
||||
if (s != str || !*s)
|
||||
if (s != str || *s != '\0')
|
||||
return 0;
|
||||
|
||||
fprintf(f, " [-%s]", s);
|
||||
fprintf(fp, " [-%s]", s);
|
||||
return strlen(s) + 4;
|
||||
}
|
||||
|
||||
void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int flags) {
|
||||
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
{
|
||||
int cursor;
|
||||
|
||||
cursor = showHelpIntro(con, f);
|
||||
cursor += showShortOptions(con->options, f, NULL);
|
||||
singleTableUsage(f, cursor, con->options, NULL);
|
||||
cursor = showHelpIntro(con, fp);
|
||||
cursor += showShortOptions(con->options, fp, NULL);
|
||||
(void) singleTableUsage(con, fp, cursor, con->options, NULL);
|
||||
(void) itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
|
||||
(void) itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
|
||||
|
||||
if (con->otherHelp) {
|
||||
cursor += strlen(con->otherHelp) + 1;
|
||||
if (cursor > 79) fprintf(f, "\n ");
|
||||
fprintf(f, " %s", con->otherHelp);
|
||||
if (cursor > 79) fprintf(fp, "\n ");
|
||||
fprintf(fp, " %s", con->otherHelp);
|
||||
}
|
||||
|
||||
fprintf(f, "\n");
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text) {
|
||||
if (con->otherHelp) xfree(con->otherHelp);
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text)
|
||||
{
|
||||
con->otherHelp = _free(con->otherHelp);
|
||||
con->otherHelp = xstrdup(text);
|
||||
}
|
||||
/*@=type@*/
|
||||
|
||||
@@ -1,69 +1,78 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptint.h
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_POPTINT
|
||||
#define H_POPTINT
|
||||
|
||||
/**
|
||||
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
|
||||
* @param p memory to free
|
||||
* @retval NULL always
|
||||
*/
|
||||
/*@unused@*/ static inline /*@null@*/ void *
|
||||
_free(/*@only@*/ /*@null@*/ const void * p)
|
||||
/*@modifies p @*/
|
||||
{
|
||||
if (p != NULL) free((void *)p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Bit mask macros. */
|
||||
typedef unsigned int __pbm_bits;
|
||||
#define __PBM_NBITS (8 * sizeof (__pbm_bits))
|
||||
#define __PBM_IX(d) ((d) / __PBM_NBITS)
|
||||
#define __PBM_MASK(d) ((__pbm_bits) 1 << ((d) % __PBM_NBITS))
|
||||
#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
|
||||
typedef struct {
|
||||
__pbm_bits bits[1];
|
||||
} pbm_set;
|
||||
#define __PBM_BITS(set) ((set)->bits)
|
||||
|
||||
#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
|
||||
#define PBM_FREE(s) free(s);
|
||||
#define PBM_FREE(s) _free(s);
|
||||
#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
|
||||
#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
|
||||
#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
|
||||
|
||||
struct optionStackEntry {
|
||||
int argc;
|
||||
/*@only@*/ const char ** argv;
|
||||
/*@only@*/ pbm_set * argb;
|
||||
/*@only@*/ /*@null@*/ const char ** argv;
|
||||
/*@only@*/ /*@null@*/ pbm_set * argb;
|
||||
int next;
|
||||
/*@only@*/ const char * nextArg;
|
||||
/*@keep@*/ const char * nextCharArg;
|
||||
/*@dependent@*/ struct poptAlias * currAlias;
|
||||
/*@only@*/ /*@null@*/ const char * nextArg;
|
||||
/*@keep@*/ /*@null@*/ const char * nextCharArg;
|
||||
/*@dependent@*/ /*@null@*/ poptItem currAlias;
|
||||
int stuffed;
|
||||
};
|
||||
|
||||
struct execEntry {
|
||||
const char * longName;
|
||||
char shortName;
|
||||
const char * script;
|
||||
};
|
||||
|
||||
struct poptContext_s {
|
||||
struct optionStackEntry optionStack[POPT_OPTION_DEPTH];
|
||||
/*@dependent@*/ struct optionStackEntry * os;
|
||||
/*@owned@*/ const char ** leftovers;
|
||||
/*@dependent@*/ struct optionStackEntry * os;
|
||||
/*@owned@*/ /*@null@*/ const char ** leftovers;
|
||||
int numLeftovers;
|
||||
int nextLeftover;
|
||||
/*@keep@*/ const struct poptOption * options;
|
||||
/*@keep@*/ const struct poptOption * options;
|
||||
int restLeftover;
|
||||
/*@only@*/ const char * appName;
|
||||
/*@only@*/ struct poptAlias * aliases;
|
||||
/*@only@*/ /*@null@*/ const char * appName;
|
||||
/*@only@*/ /*@null@*/ poptItem aliases;
|
||||
int numAliases;
|
||||
int flags;
|
||||
struct execEntry * execs;
|
||||
/*@owned@*/ /*@null@*/ poptItem execs;
|
||||
int numExecs;
|
||||
/*@only@*/ const char ** finalArgv;
|
||||
/*@only@*/ /*@null@*/ const char ** finalArgv;
|
||||
int finalArgvCount;
|
||||
int finalArgvAlloced;
|
||||
/*@dependent@*/ struct execEntry * doExec;
|
||||
/*@only@*/ const char * execPath;
|
||||
/*@dependent@*/ /*@null@*/ poptItem doExec;
|
||||
/*@only@*/ const char * execPath;
|
||||
int execAbsolute;
|
||||
/*@only@*/ const char * otherHelp;
|
||||
pbm_set * arg_strip;
|
||||
/*@only@*/ const char * otherHelp;
|
||||
/*@null@*/ pbm_set * arg_strip;
|
||||
};
|
||||
|
||||
#define xfree(_a) free((void *)_a)
|
||||
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
@@ -71,17 +80,17 @@ struct poptContext_s {
|
||||
#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
|
||||
#define _(foo) gettext(foo)
|
||||
#else
|
||||
#define _(foo) (foo)
|
||||
#define _(foo) foo
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DGETTEXT) && !defined(__LCLINT__)
|
||||
#define D_(dom, str) dgettext(dom, str)
|
||||
#define POPT_(foo) D_("popt", foo)
|
||||
#else
|
||||
#define POPT_(foo) (foo)
|
||||
#define D_(dom, str) (str)
|
||||
#define D_(dom, str) str
|
||||
#define POPT_(foo) foo
|
||||
#endif
|
||||
|
||||
#define N_(foo) (foo)
|
||||
#define N_(foo) foo
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptparse.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
|
||||
@@ -14,6 +18,8 @@ int poptDupArgv(int argc, const char **argv,
|
||||
char * dst;
|
||||
int i;
|
||||
|
||||
if (argc <= 0 || argv == NULL) /* XXX can't happen */
|
||||
return POPT_ERROR_NOARG;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL)
|
||||
return POPT_ERROR_NOARG;
|
||||
@@ -21,17 +27,27 @@ int poptDupArgv(int argc, const char **argv,
|
||||
}
|
||||
|
||||
dst = malloc(nb);
|
||||
if (dst == NULL) /* XXX can't happen */
|
||||
return POPT_ERROR_MALLOC;
|
||||
argv2 = (void *) dst;
|
||||
dst += (argc + 1) * sizeof(*argv);
|
||||
|
||||
/*@-branchstate@*/
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv2[i] = dst;
|
||||
dst += strlen(strcpy(dst, argv[i])) + 1;
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
argv2[argc] = NULL;
|
||||
|
||||
*argvPtr = argv2;
|
||||
*argcPtr = argc;
|
||||
if (argvPtr) {
|
||||
*argvPtr = argv2;
|
||||
} else {
|
||||
free(argv2);
|
||||
argv2 = NULL;
|
||||
}
|
||||
if (argcPtr)
|
||||
*argcPtr = argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,31 +59,32 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
const char ** argv = malloc(sizeof(*argv) * argvAlloced);
|
||||
int argc = 0;
|
||||
int buflen = strlen(s) + 1;
|
||||
char *buf0 = calloc(buflen, 1);
|
||||
char *buf = buf0;
|
||||
char * buf = memset(alloca(buflen), 0, buflen);
|
||||
int rc = POPT_ERROR_MALLOC;
|
||||
|
||||
if (argv == NULL) return rc;
|
||||
argv[argc] = buf;
|
||||
|
||||
for (src = s; *src; src++) {
|
||||
for (src = s; *src != '\0'; src++) {
|
||||
if (quote == *src) {
|
||||
quote = '\0';
|
||||
} else if (quote) {
|
||||
} else if (quote != '\0') {
|
||||
if (*src == '\\') {
|
||||
src++;
|
||||
if (!*src) {
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return POPT_ERROR_BADQUOTE;
|
||||
rc = POPT_ERROR_BADQUOTE;
|
||||
goto exit;
|
||||
}
|
||||
if (*src != quote) *buf++ = '\\';
|
||||
}
|
||||
*buf++ = *src;
|
||||
} else if (isspace(*src)) {
|
||||
if (*argv[argc]) {
|
||||
if (*argv[argc] != '\0') {
|
||||
buf++, argc++;
|
||||
if (argc == argvAlloced) {
|
||||
argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
|
||||
argv = realloc(argv, sizeof(*argv) * argvAlloced);
|
||||
if (argv == NULL) goto exit;
|
||||
}
|
||||
argv[argc] = buf;
|
||||
}
|
||||
@@ -75,18 +92,17 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
case '"':
|
||||
case '\'':
|
||||
quote = *src;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
case '\\':
|
||||
src++;
|
||||
if (!*src) {
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return POPT_ERROR_BADQUOTE;
|
||||
rc = POPT_ERROR_BADQUOTE;
|
||||
goto exit;
|
||||
}
|
||||
/*@fallthrough@*/
|
||||
default:
|
||||
*buf++ = *src;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +110,9 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
argc++, buf++;
|
||||
}
|
||||
|
||||
(void) poptDupArgv(argc, argv, argcPtr, argvPtr);
|
||||
rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
|
||||
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return 0;
|
||||
exit:
|
||||
if (argv) free(argv);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
#include <libc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LCLINT__)
|
||||
/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */
|
||||
/*@only@*/ void * alloca (size_t __size)
|
||||
/*@ensures MaxSet(result) == (__size - 1) @*/
|
||||
/*@*/;
|
||||
/*@=declundef =incondefs =redecl@*/
|
||||
#endif
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifndef __GNUC__
|
||||
# if HAVE_ALLOCA_H
|
||||
@@ -33,8 +41,15 @@
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# if HAVE_ALLOCA
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# else
|
||||
# ifdef alloca
|
||||
# undef alloca
|
||||
# endif
|
||||
# define alloca(sz) malloc(sz) /* Kludge this for now */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
@@ -42,7 +57,10 @@ char *alloca ();
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
/*@only@*/ char * xstrdup (const char *str);
|
||||
/*@-redecl -redef@*/
|
||||
/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str)
|
||||
/*@*/;
|
||||
/*@=redecl =redef@*/
|
||||
|
||||
#if HAVE_MCHECK_H && defined(__GNUC__)
|
||||
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
|
||||
|
||||
121
progress.c
Normal file
121
progress.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static OFF_T last_ofs;
|
||||
static struct timeval print_time;
|
||||
static struct timeval start_time;
|
||||
static OFF_T start_ofs;
|
||||
|
||||
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return (t2->tv_sec - t1->tv_sec) * 1000
|
||||
+ (t2->tv_usec - t1->tv_usec) / 1000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ofs Current position in file
|
||||
* @param size Total size of file
|
||||
* @param is_last True if this is the last time progress will be
|
||||
* printed for this file, so we should output a newline. (Not
|
||||
* necessarily the same as all bytes being received.)
|
||||
**/
|
||||
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
int is_last)
|
||||
{
|
||||
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
|
||||
unsigned long diff = msdiff(&start_time, now);
|
||||
double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0;
|
||||
const char *units;
|
||||
/* If we've finished transferring this file, show the time taken;
|
||||
* otherwise show expected time to complete. That's kind of
|
||||
* inconsistent, but people can probably cope. Hopefully we'll
|
||||
* get more consistent and complete progress reporting soon. --
|
||||
* mbp */
|
||||
double remain = is_last
|
||||
? (double) diff / 1000.0
|
||||
: rate ? (double) (size-ofs) / rate / 1000.0 : 0.0;
|
||||
int remain_h, remain_m, remain_s;
|
||||
|
||||
if (rate > 1024*1024) {
|
||||
rate /= 1024.0 * 1024.0;
|
||||
units = "GB/s";
|
||||
} else if (rate > 1024) {
|
||||
rate /= 1024.0;
|
||||
units = "MB/s";
|
||||
} else {
|
||||
units = "kB/s";
|
||||
}
|
||||
|
||||
remain_s = (int) remain % 60;
|
||||
remain_m = (int) (remain / 60.0) % 60;
|
||||
remain_h = (int) (remain / 3600.0);
|
||||
|
||||
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
(double) ofs, pct, rate, units,
|
||||
remain_h, remain_m, remain_s,
|
||||
is_last ? "\n" : "\r");
|
||||
}
|
||||
|
||||
void end_progress(OFF_T size)
|
||||
{
|
||||
extern int am_server;
|
||||
|
||||
if (!am_server) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
rprint_progress(size, size, &now, True);
|
||||
}
|
||||
last_ofs = 0;
|
||||
start_ofs = 0;
|
||||
print_time.tv_sec = print_time.tv_usec = 0;
|
||||
start_time.tv_sec = start_time.tv_usec = 0;
|
||||
}
|
||||
|
||||
void show_progress(OFF_T ofs, OFF_T size)
|
||||
{
|
||||
extern int am_server;
|
||||
struct timeval now;
|
||||
|
||||
if (!start_time.tv_sec) {
|
||||
gettimeofday(&now, NULL);
|
||||
start_time.tv_sec = now.tv_sec;
|
||||
start_time.tv_usec = now.tv_usec;
|
||||
start_ofs = ofs;
|
||||
if (am_server)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (am_server)
|
||||
return;
|
||||
gettimeofday(&now, NULL);
|
||||
}
|
||||
|
||||
if (ofs > last_ofs + 1000
|
||||
&& msdiff(&print_time, &now) > 250) {
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
last_ofs = ofs;
|
||||
print_time.tv_sec = now.tv_sec;
|
||||
print_time.tv_usec = now.tv_usec;
|
||||
}
|
||||
}
|
||||
25
receiver.c
25
receiver.c
@@ -67,7 +67,8 @@ static void add_delete_entry(struct file_struct *file)
|
||||
{
|
||||
if (dlist_len == dlist_alloc_len) {
|
||||
dlist_alloc_len += 1024;
|
||||
delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
|
||||
delete_list = realloc_array(delete_list, struct delete_list,
|
||||
dlist_alloc_len);
|
||||
if (!delete_list) out_of_memory("add_delete_entry");
|
||||
}
|
||||
|
||||
@@ -249,7 +250,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
i = -(i+1);
|
||||
offset2 = i*(OFF_T)n;
|
||||
len = n;
|
||||
if (i == count-1 && remainder != 0)
|
||||
if (i == (int) count-1 && remainder != 0)
|
||||
len = remainder;
|
||||
|
||||
stats.matched_data += len;
|
||||
@@ -265,7 +266,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
sum_update(map,len);
|
||||
}
|
||||
|
||||
if (fd != -1 && write_file(fd,map,len) != len) {
|
||||
if (fd != -1 && write_file(fd,map,len) != (int) len) {
|
||||
rprintf(FERROR,"write failed on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
@@ -297,9 +298,10 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
}
|
||||
|
||||
|
||||
/* main routine for receiver process. Receiver process runs on the
|
||||
same host as the generator process. */
|
||||
|
||||
/**
|
||||
* main routine for receiver process.
|
||||
*
|
||||
* Receiver process runs on the same host as the generator process. */
|
||||
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
{
|
||||
int fd1,fd2;
|
||||
@@ -317,6 +319,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
extern struct stats stats;
|
||||
extern int preserve_perms;
|
||||
extern int delete_after;
|
||||
extern int orig_umask;
|
||||
struct stats initial_stats;
|
||||
|
||||
if (verbose > 2) {
|
||||
@@ -423,23 +426,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
this out. We also set it initially without group
|
||||
access because of a similar race condition. */
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"mkstemp %s failed\n",fnametmp);
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* in most cases parent directories will already exist
|
||||
because their information should have been previously
|
||||
transferred, but that may not be the case with -R */
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
create_directory_path(fnametmp, orig_umask) == 0) {
|
||||
strlcpy(fnametmp, template, sizeof(fnametmp));
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
|
||||
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
|
||||
2
rsync.c
2
rsync.c
@@ -124,7 +124,7 @@ static int is_in_group(gid_t gid)
|
||||
/* treat failure (-1) as if not member of any group */
|
||||
ngroups = getgroups(0, 0);
|
||||
if (ngroups > 0) {
|
||||
gidset = (GETGROUPS_T *) malloc(ngroups * sizeof(GETGROUPS_T));
|
||||
gidset = new_array(GETGROUPS_T, ngroups);
|
||||
ngroups = getgroups(ngroups, gidset);
|
||||
}
|
||||
}
|
||||
|
||||
71
rsync.h
71
rsync.h
@@ -26,7 +26,8 @@
|
||||
#define RSYNC_RSH_ENV "RSYNC_RSH"
|
||||
|
||||
#define RSYNC_NAME "rsync"
|
||||
#define RSYNCD_CONF "/etc/rsyncd.conf"
|
||||
#define RSYNCD_SYSCONF "/etc/rsyncd.conf"
|
||||
#define RSYNCD_USERCONF "rsyncd.conf"
|
||||
|
||||
#define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
|
||||
#define URL_PREFIX "rsync://"
|
||||
@@ -85,11 +86,9 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_REMSH
|
||||
#define RSYNC_RSH "remsh"
|
||||
#else
|
||||
#define RSYNC_RSH "rsh"
|
||||
#endif
|
||||
/* The default RSYNC_RSH is always set in config.h, either to "remsh",
|
||||
* "rsh", or otherwise something specified by the user. HAVE_REMSH
|
||||
* controls parameter munging for HP/UX, etc. */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -219,6 +218,8 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#include <compat.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define BOOL int
|
||||
|
||||
@@ -330,6 +331,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
#ifndef IN_LOOPBACKNET
|
||||
#define IN_LOOPBACKNET 127
|
||||
#endif
|
||||
|
||||
struct file_struct {
|
||||
unsigned flags;
|
||||
time_t modtime;
|
||||
@@ -369,19 +374,19 @@ struct file_list {
|
||||
};
|
||||
|
||||
struct sum_buf {
|
||||
OFF_T offset; /* offset in file of this chunk */
|
||||
int len; /* length of chunk of file */
|
||||
int i; /* index of this chunk */
|
||||
uint32 sum1; /* simple checksum */
|
||||
char sum2[SUM_LENGTH]; /* checksum */
|
||||
OFF_T offset; /**< offset in file of this chunk */
|
||||
int len; /**< length of chunk of file */
|
||||
int i; /**< index of this chunk */
|
||||
uint32 sum1; /**< simple checksum */
|
||||
char sum2[SUM_LENGTH]; /**< checksum */
|
||||
};
|
||||
|
||||
struct sum_struct {
|
||||
OFF_T flength; /* total file length */
|
||||
size_t count; /* how many chunks */
|
||||
size_t remainder; /* flength % block_length */
|
||||
size_t n; /* block_length */
|
||||
struct sum_buf *sums; /* points to info for each chunk */
|
||||
OFF_T flength; /**< total file length */
|
||||
size_t count; /**< how many chunks */
|
||||
size_t remainder; /**< flength % block_length */
|
||||
size_t n; /**< block_length */
|
||||
struct sum_buf *sums; /**< points to info for each chunk */
|
||||
};
|
||||
|
||||
struct map_struct {
|
||||
@@ -463,6 +468,9 @@ extern int errno;
|
||||
#define SUPPORT_LINKS HAVE_READLINK
|
||||
#define SUPPORT_HARD_LINKS HAVE_LINK
|
||||
|
||||
/* This could be bad on systems which have no lchown and where chown
|
||||
* follows symbollic links. On such systems it might be better not to
|
||||
* try to chown symlinks at all. */
|
||||
#ifndef HAVE_LCHOWN
|
||||
#define lchown chown
|
||||
#endif
|
||||
@@ -563,19 +571,28 @@ extern int errno;
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
#if !defined(__GNUC__) || defined(APPLE)
|
||||
/* Apparently the OS X port of gcc gags on __attribute__.
|
||||
*
|
||||
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
|
||||
#define __attribute__(x)
|
||||
|
||||
#endif
|
||||
|
||||
/* Convenient wrappers for malloc and realloc. Use them. */
|
||||
#define new(type) ((type *)malloc(sizeof(type)))
|
||||
#define new_array(type, num) ((type *)_new_array(sizeof(type), (num)))
|
||||
#define realloc_array(ptr, type, num) ((type *)_realloc_array((ptr), sizeof(type), (num)))
|
||||
|
||||
/* use magic gcc attributes to catch format errors */
|
||||
void rprintf(enum logcode , const char *, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
;
|
||||
|
||||
/* This is just like rprintf, but it also tries to print some
|
||||
* representation of the error code. Normally errcode = errno. */
|
||||
void rsyserr(enum logcode, int, const char *, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 3, 4)))
|
||||
#endif
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
;
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
@@ -606,5 +623,13 @@ inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
int isc_net_pton(int af, const char *src, void *dst);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void);
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) x __attribute__((__unused__))
|
||||
|
||||
extern const char *io_write_phase, *io_read_phase;
|
||||
|
||||
571
rsync.yo
571
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(14 Dec 2001)()()
|
||||
manpage(rsync)(1)(26 Jan 2003)()()
|
||||
manpagename(rsync)(faster, flexible replacement for rcp)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -15,6 +15,8 @@ rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
|
||||
|
||||
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
|
||||
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
|
||||
|
||||
manpagedescription()
|
||||
|
||||
rsync is a program that behaves in much the same way that rcp does,
|
||||
@@ -23,7 +25,7 @@ greatly speed up file transfers when the destination file already
|
||||
exists.
|
||||
|
||||
The rsync remote-update protocol allows rsync to transfer just the
|
||||
differences between two sets of files across the network link, using
|
||||
differences between two sets of files across the network connection, using
|
||||
an efficient checksum-search algorithm described in the technical
|
||||
report that accompanies this package.
|
||||
|
||||
@@ -42,7 +44,7 @@ itemize(
|
||||
|
||||
manpagesection(GENERAL)
|
||||
|
||||
There are six different ways of using rsync. They are:
|
||||
There are eight different ways of using rsync. They are:
|
||||
|
||||
itemize(
|
||||
it() for copying local files. This is invoked when neither
|
||||
@@ -63,7 +65,19 @@ itemize(
|
||||
|
||||
it() for copying from the local machine to a remote rsync
|
||||
server. This is invoked when the destination path contains a ::
|
||||
separator.
|
||||
separator or a rsync:// URL.
|
||||
|
||||
it() for copying from a remote machine using a remote shell
|
||||
program as the transport, using rsync server on the remote
|
||||
machine. This is invoked when the source path contains a ::
|
||||
separator and the --rsh=COMMAND (aka "-e COMMAND") option is
|
||||
also provided.
|
||||
|
||||
it() for copying from the local machine to a remote machine
|
||||
using a remote shell program as the transport, using rsync
|
||||
server on the remote machine. This is invoked when the
|
||||
destination path contains a :: separator and the
|
||||
--rsh=COMMMAND option is also provided.
|
||||
|
||||
it() for listing files on a remote machine. This is done the
|
||||
same way as rsync transfers except that you leave off the
|
||||
@@ -77,11 +91,13 @@ manpagesection(SETUP)
|
||||
|
||||
See the file README for installation instructions.
|
||||
|
||||
Once installed you can use rsync to any machine that you can use rsh
|
||||
to. rsync uses rsh for its communications, unless both the source and
|
||||
destination are local.
|
||||
Once installed, you can use rsync to any machine that you can access via
|
||||
a remote shell (as well as some that you can access using the rsync
|
||||
daemon-mode protocol). For remote transfers, rsync typically uses rsh
|
||||
for its communications, but it may have been configured to use a
|
||||
different remote shell by default, such as ssh.
|
||||
|
||||
You can also specify an alternative to rsh, either by using the -e
|
||||
You can also specify any remote shell you like, either by using the -e
|
||||
command line option, or by setting the RSYNC_RSH environment variable.
|
||||
|
||||
One common substitute is to use ssh, which offers a high degree of
|
||||
@@ -99,7 +115,7 @@ Perhaps the best way to explain the syntax is some examples:
|
||||
|
||||
quote(rsync *.c foo:src/)
|
||||
|
||||
this would transfer all files matching the pattern *.c from the
|
||||
This would transfer all files matching the pattern *.c from the
|
||||
current directory to the directory src on the machine foo. If any of
|
||||
the files already exist on the remote system then the rsync
|
||||
remote-update protocol is used to update the file by sending only the
|
||||
@@ -107,7 +123,7 @@ differences. See the tech report for details.
|
||||
|
||||
quote(rsync -avz foo:src/bar /data/tmp)
|
||||
|
||||
this would recursively transfer all files from the directory src/bar on the
|
||||
This would recursively transfer all files from the directory src/bar on the
|
||||
machine foo into the /data/tmp/bar directory on the local machine. The
|
||||
files are transferred in "archive" mode, which ensures that symbolic
|
||||
links, devices, attributes, permissions, ownerships etc are preserved
|
||||
@@ -116,12 +132,17 @@ size of data portions of the transfer.
|
||||
|
||||
quote(rsync -avz foo:src/bar/ /data/tmp)
|
||||
|
||||
a trailing slash on the source changes this behavior to transfer
|
||||
all files from the directory src/bar on the machine foo into the
|
||||
/data/tmp/. A trailing / on a source name means "copy the
|
||||
contents of this directory". Without a trailing slash it means "copy
|
||||
the directory". This difference becomes particularly important when
|
||||
using the --delete option.
|
||||
A trailing slash on the source changes this behavior to avoid creating an
|
||||
additional directory level at the destination. You can think of a trailing
|
||||
/ on a source as meaning "copy the contents of this directory" as opposed
|
||||
to "copy the directory by name", but in both cases the attributes of the
|
||||
containing directory are transferred to the containing directory on the
|
||||
destination. In other words, each of the following commands copies the
|
||||
files in the same way, including their setting of the attributes of
|
||||
/dest/foo:
|
||||
|
||||
quote(rsync -avz /src/foo /dest)
|
||||
quote(rsync -avz /src/foo/ /dest/foo)
|
||||
|
||||
You can also use rsync in local-only mode, where both the source and
|
||||
destination don't have a ':' in the name. In this case it behaves like
|
||||
@@ -129,13 +150,13 @@ an improved copy command.
|
||||
|
||||
quote(rsync somehost.mydomain.com::)
|
||||
|
||||
this would list all the anonymous rsync modules available on the host
|
||||
This would list all the anonymous rsync modules available on the host
|
||||
somehost.mydomain.com. (See the following section for more details.)
|
||||
|
||||
|
||||
manpagesection(CONNECTING TO AN RSYNC SERVER)
|
||||
|
||||
It is also possible to use rsync without using rsh or ssh as the
|
||||
It is also possible to use rsync without a remote shell as the
|
||||
transport. In this case you will connect to a remote rsync server
|
||||
running on TCP port 873.
|
||||
|
||||
@@ -144,12 +165,12 @@ environment variable RSYNC_PROXY to a hostname:port pair pointing to
|
||||
your web proxy. Note that your web proxy's configuration must allow
|
||||
proxying to port 873.
|
||||
|
||||
Using rsync in this way is the same as using it with rsh or ssh except
|
||||
Using rsync in this way is the same as using it with a remote shell except
|
||||
that:
|
||||
|
||||
itemize(
|
||||
it() you use a double colon :: instead of a single colon to
|
||||
separate the hostname from the path.
|
||||
separate the hostname from the path or a rsync:// URL.
|
||||
|
||||
it() the remote server may print a message of the day when you
|
||||
connect.
|
||||
@@ -170,11 +191,61 @@ may be useful when scripting rsync.
|
||||
WARNING: On some systems environment variables are visible to all
|
||||
users. On those systems using --password-file is recommended.
|
||||
|
||||
manpagesection(CONNECTING TO AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM)
|
||||
|
||||
It is sometimes useful to be able to set up file transfers using rsync
|
||||
server capabilities on the remote machine, while still using rsh or
|
||||
ssh for transport. This is especially useful when you want to connect
|
||||
to a remote machine via ssh (for encryption or to get through a
|
||||
firewall), but you still want to have access to the rsync server
|
||||
features (see RUNNING AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM,
|
||||
below).
|
||||
|
||||
From the user's perspective, using rsync in this way is the same as
|
||||
using it to connect to an rsync server, except that you must
|
||||
explicitly set the remote shell program on the command line with
|
||||
--rsh=COMMAND. (Setting RSYNC_RSH in the environment will not turn on
|
||||
this functionality.)
|
||||
|
||||
In order to distinguish between the remote-shell user and the rsync
|
||||
server user, you can use '-l user' on your remote-shell command:
|
||||
|
||||
quote(rsync -av --rsh="ssh -l ssh-user" rsync-user@host::module[/path] local-path)
|
||||
|
||||
The "ssh-user" will be used at the ssh level; the "rsync-user" will be
|
||||
used to check against the rsyncd.conf on the remote host.
|
||||
|
||||
manpagesection(RUNNING AN RSYNC SERVER)
|
||||
|
||||
An rsync server is configured using a config file which by default is
|
||||
called /etc/rsyncd.conf. Please see the rsyncd.conf(5) man page for more
|
||||
information.
|
||||
An rsync server is configured using a config file. Please see the
|
||||
rsyncd.conf(5) man page for more information. By default the configuration
|
||||
file is called /etc/rsyncd.conf, unless rsync is running over a remote
|
||||
shell program and is not running as root; in that case, the default name
|
||||
is rsyncd.conf in the current directory on the remote computer
|
||||
(typically $HOME).
|
||||
|
||||
manpagesection(RUNNING AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM)
|
||||
|
||||
See the rsyncd.conf(5) man page for full information on the rsync
|
||||
server configuration file.
|
||||
|
||||
Several configuration options will not be available unless the remote
|
||||
user is root (e.g. chroot, setuid/setgid, etc.). There is no need to
|
||||
configure inetd or the services map to include the rsync server port
|
||||
if you run an rsync server only via a remote shell program.
|
||||
|
||||
To run an rsync server out of a single-use ssh key, use the
|
||||
"command=em(COMMAND)" syntax in the remote user's
|
||||
authorized_keys entry, where command would be
|
||||
|
||||
quote(rsync --server --daemon .)
|
||||
|
||||
NOTE: rsync's argument parsing expects the trailing ".", so make sure
|
||||
that it's there. If you want to use a rsyncd.conf(5)-style
|
||||
configuration file other than the default, you can added a
|
||||
--config option to the em(command):
|
||||
|
||||
quote(rsync --server --daemon --config=em(file) .)
|
||||
|
||||
manpagesection(EXAMPLES)
|
||||
|
||||
@@ -185,7 +256,7 @@ files and mail folders, I use a cron job that runs
|
||||
|
||||
quote(rsync -Cavz . arvidsjaur:backup)
|
||||
|
||||
each night over a PPP link to a duplicate directory on my machine
|
||||
each night over a PPP connection to a duplicate directory on my machine
|
||||
"arvidsjaur".
|
||||
|
||||
To synchronize my samba source trees I use the following Makefile
|
||||
@@ -200,7 +271,7 @@ quote( get:nl()
|
||||
sync: get put)
|
||||
|
||||
this allows me to sync with a CVS directory at the other end of the
|
||||
link. I then do cvs operations on the remote machine, which saves a
|
||||
connection. I then do cvs operations on the remote machine, which saves a
|
||||
lot of time as the remote cvs protocol isn't very efficient.
|
||||
|
||||
I mirror a directory between my "old" and "new" ftp sites with the
|
||||
@@ -219,12 +290,14 @@ verb(
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode
|
||||
-a, --archive archive mode, equivalent to -rlptgoD
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ suffix)
|
||||
--no-relative turn off --relative
|
||||
--no-implied-dirs don't send implied dirs with -R
|
||||
-b, --backup make backups (see --suffix)
|
||||
--backup-dir make backups into this directory
|
||||
--suffix=SUFFIX override backup suffix
|
||||
--suffix=SUFFIX define backup suffix (default ~ w/o --backup-dir)
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links copy symlinks as symlinks
|
||||
-L, --copy-links copy the referent of symlinks
|
||||
@@ -239,12 +312,13 @@ verb(
|
||||
-S, --sparse handle sparse files efficiently
|
||||
-n, --dry-run show what would have been transferred
|
||||
-W, --whole-file copy whole files, no incremental checks
|
||||
--no-whole-file turn off --whole-file
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size=SIZE checksum blocking size (default 700)
|
||||
-e, --rsh=COMMAND specify rsh replacement
|
||||
-e, --rsh=COMMAND specify the remote shell to use
|
||||
--rsync-path=PATH specify path to rsync on the remote machine
|
||||
-C, --cvs-exclude auto ignore files in the same way CVS does
|
||||
--existing only update files that already exist
|
||||
--ignore-existing ignore files that already exist on the receiving side
|
||||
--delete delete files that don't exist on the sending side
|
||||
--delete-excluded also delete excluded files on the receiving side
|
||||
--delete-after delete after transferring, not before
|
||||
@@ -259,12 +333,16 @@ verb(
|
||||
--modify-window=NUM Timestamp window (seconds) for file match (default=0)
|
||||
-T --temp-dir=DIR create temporary files in directory DIR
|
||||
--compare-dest=DIR also compare destination files relative to DIR
|
||||
--link-dest=DIR create hardlinks to DIR for unchanged files
|
||||
-P equivalent to --partial --progress
|
||||
-z, --compress compress file data
|
||||
-C, --cvs-exclude auto ignore files in the same way CVS does
|
||||
--exclude=PATTERN exclude files matching PATTERN
|
||||
--exclude-from=FILE exclude patterns listed in FILE
|
||||
--include=PATTERN don't exclude files matching PATTERN
|
||||
--include-from=FILE don't exclude patterns listed in FILE
|
||||
--files-from=FILE read FILE for list of source-file names
|
||||
-0 --from0 file names we read are separated by nulls, not newlines
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--no-detach do not detach from the parent
|
||||
@@ -272,13 +350,14 @@ verb(
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--blocking-io use blocking IO for the remote shell
|
||||
--no-blocking-io turn off --blocking-io
|
||||
--stats give some file transfer stats
|
||||
--progress show progress during transfer
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
--password-file=FILE get password from FILE
|
||||
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
|
||||
--read-batch=FILE read batch file
|
||||
--write-batch write batch file
|
||||
--read-batch=PREFIX read batch fileset starting with PREFIX
|
||||
--write-batch=PREFIX write batch fileset starting with PREFIX
|
||||
-h, --help show this help screen
|
||||
|
||||
|
||||
@@ -326,8 +405,8 @@ dit(bf(--modify-window)) When comparing two timestamps rsync treats
|
||||
the timestamps as being equal if they are within the value of
|
||||
modify_window. This is normally zero, but you may find it useful to
|
||||
set this to a larger value in some situations. In particular, when
|
||||
transferring to/from FAT filesystems which cannot represent times with
|
||||
a 1 second resolution this option is useful.
|
||||
transferring to Windows FAT filesystems which cannot represent times
|
||||
with a 1 second resolution --modify-window=1 is useful.
|
||||
|
||||
dit(bf(-c, --checksum)) This forces the sender to checksum all files using
|
||||
a 128-bit MD4 checksum before transfer. The checksum is then
|
||||
@@ -361,18 +440,38 @@ machine. If instead you used
|
||||
verb(rsync -R foo/bar/foo.c remote:/tmp/)
|
||||
|
||||
then a file called /tmp/foo/bar/foo.c would be created on the remote
|
||||
machine. The full path name is preserved.
|
||||
machine -- the full path name is preserved.
|
||||
|
||||
dit(bf(-b, --backup)) With this option preexisting destination files are
|
||||
renamed with a ~ extension as each file is transferred. You can
|
||||
control the backup suffix using the --suffix option.
|
||||
dit(bf(--no-relative)) Turn off the --relative option. This is only
|
||||
needed if you want to use --files-from without its implied --relative
|
||||
file processing.
|
||||
|
||||
dit(bf(--no-implied-dirs)) When combined with the --relative option, the
|
||||
implied directories in each path are not explicitly duplicated as part
|
||||
of the transfer. This makes the transfer more optimal and also allows
|
||||
the two sides to have non-matching symlinks in the implied part of the
|
||||
path. For instance, if you transfer the file "/path/foo/file" with -R,
|
||||
the default is for rsync to ensure that "/path" and "/path/foo" on the
|
||||
destination exactly match the directories/symlinks of the source. Using
|
||||
the --no-implied-dirs option would omit both of these implied dirs,
|
||||
which means that if "/path" was a real directory on one machine and a
|
||||
symlink of the other machine, rsync would not try to change this.
|
||||
|
||||
dit(bf(-b, --backup)) With this option, preexisting destination files are
|
||||
renamed as each file is transferred or deleted. You can control where the
|
||||
backup file goes and what (if any) suffix gets appended using the
|
||||
--backup-dir and --suffix options.
|
||||
|
||||
dit(bf(--backup-dir=DIR)) In combination with the --backup option, this
|
||||
tells rsync to store all backups in the specified directory. This is
|
||||
very useful for incremental backups.
|
||||
very useful for incremental backups. You can additionally
|
||||
specify a backup suffix using the --suffix option
|
||||
(otherwise the files backed up in the specified directory
|
||||
will keep their original filenames).
|
||||
|
||||
dit(bf(--suffix=SUFFIX)) This option allows you to override the default
|
||||
backup suffix used with the -b option. The default is a ~.
|
||||
backup suffix used with the --backup (-b) option. The default suffix is a ~
|
||||
if no --backup-dir was specified, otherwise it is an empty string.
|
||||
|
||||
dit(bf(-u, --update)) This forces rsync to skip any files for which the
|
||||
destination file already exists and has a date later than the source
|
||||
@@ -410,12 +509,22 @@ target machines is higher than the bandwidth to disk (especially when the
|
||||
"disk" is actually a networked file system). This is the default when both
|
||||
the source and target are on the local machine.
|
||||
|
||||
dit(bf(-p, --perms)) This option causes rsync to update the remote
|
||||
permissions to be the same as the local permissions.
|
||||
dit(bf(--no-whole-file)) Turn off --whole-file, for use when it is the
|
||||
default.
|
||||
|
||||
dit(bf(-p, --perms)) This option causes rsync to set the destination
|
||||
permissions to be the same as the source permissions.
|
||||
|
||||
Without this option, each new file gets its permissions set based on the
|
||||
source file's permissions and the umask at the receiving end, while all
|
||||
other files (including updated files) retain their existing permissions
|
||||
(which is the same behavior as other file-copy utilities, such as cp).
|
||||
|
||||
dit(bf(-o, --owner)) This option causes rsync to set the owner of the
|
||||
destination file to be the same as the source file. On most systems,
|
||||
only the super-user can set file ownership.
|
||||
only the super-user can set file ownership. Note that if the remote system
|
||||
is a daemon using chroot, the --numeric-ids option is implied because the
|
||||
remote system cannot get access to the usernames from /etc/passwd.
|
||||
|
||||
dit(bf(-g, --group)) This option causes rsync to set the group of the
|
||||
destination file to be the same as the source file. If the receiving
|
||||
@@ -452,6 +561,10 @@ contents of only one filesystem.
|
||||
dit(bf(--existing)) This tells rsync not to create any new files -
|
||||
only update files that already exist on the destination.
|
||||
|
||||
dit(bf(--ignore-existing))
|
||||
This tells rsync not to update files that already exist on
|
||||
the destination.
|
||||
|
||||
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
|
||||
files or directories. This is useful when mirroring very large trees
|
||||
to prevent disasters.
|
||||
@@ -475,33 +588,46 @@ destination. You can override this with the --ignore-errors option.
|
||||
dit(bf(--delete-excluded)) In addition to deleting the files on the
|
||||
receiving side that are not on the sending side, this tells rsync to also
|
||||
delete any files on the receiving side that are excluded (see --exclude).
|
||||
Implies --delete.
|
||||
|
||||
dit(bf(--delete-after)) By default rsync does file deletions before
|
||||
transferring files to try to ensure that there is sufficient space on
|
||||
the receiving filesystem. If you want to delete after transferring
|
||||
then use the --delete-after switch.
|
||||
then use the --delete-after switch. Implies --delete.
|
||||
|
||||
dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
|
||||
even when there are IO errors.
|
||||
|
||||
dit(bf(--force)) This options tells rsync to delete directories even if
|
||||
they are not empty. This applies to both the --delete option and to
|
||||
cases where rsync tries to copy a normal file but the destination
|
||||
contains a directory of the same name.
|
||||
|
||||
Since this option was added, deletions were reordered to be done depth-first
|
||||
so it is hardly ever needed anymore except in very obscure cases.
|
||||
they are not empty when they are to be replaced by non-directories. This
|
||||
is only relevant without --delete because deletions are now done depth-first.
|
||||
Requires the --recursive option (which is implied by -a) to have any effect.
|
||||
|
||||
dit(bf(-B , --block-size=BLOCKSIZE)) This controls the block size used in
|
||||
the rsync algorithm. See the technical report for details.
|
||||
|
||||
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
|
||||
remote shell program to use for communication between the local and
|
||||
remote copies of rsync. By default, rsync will use rsh, but you may
|
||||
like to instead use ssh because of its high security.
|
||||
remote copies of rsync. Typically, rsync is configured to use rsh by
|
||||
default, but you may prefer to use ssh because of its high security.
|
||||
|
||||
If this option is used with bf([user@]host::module/path), then the
|
||||
remote shell em(COMMMAND) will be used to run an rsync server on the
|
||||
remote host, and all data will be transmitted through that remote
|
||||
shell connection, rather than through a direct socket connection to a
|
||||
running rsync server on the remote host. See the section "CONNECTING
|
||||
TO AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM" above.
|
||||
|
||||
Command-line arguments are permitted in COMMAND provided that COMMAND is
|
||||
presented to rsync as a single argument. For example:
|
||||
|
||||
quote(-e "ssh -p 2234")
|
||||
|
||||
(Note that ssh users can alternately customize site-specific connect
|
||||
options in their .ssh/config file.)
|
||||
|
||||
You can also choose the remote shell program using the RSYNC_RSH
|
||||
environment variable.
|
||||
environment variable, which accepts the same range of values as -e.
|
||||
|
||||
See also the --blocking-io option which is affected by this option.
|
||||
|
||||
@@ -510,31 +636,6 @@ rsync on the remote machine. Useful when it's not in your path. Note
|
||||
that this is the full path to the binary, not just the directory that
|
||||
the binary is in.
|
||||
|
||||
dit(bf(--exclude=PATTERN)) This option allows you to selectively exclude
|
||||
certain files from the list of files to be transferred. This is most
|
||||
useful in combination with a recursive transfer.
|
||||
|
||||
You may use as many --exclude options on the command line as you like
|
||||
to build up the list of files to exclude.
|
||||
|
||||
See the section on exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--exclude-from=FILE)) This option is similar to the --exclude
|
||||
option, but instead it adds all exclude patterns listed in the file
|
||||
FILE to the exclude list. Blank lines in FILE and lines starting with
|
||||
';' or '#' are ignored.
|
||||
|
||||
dit(bf(--include=PATTERN)) This option tells rsync to not exclude the
|
||||
specified pattern of filenames. This is useful as it allows you to
|
||||
build up quite complex exclude/include rules.
|
||||
|
||||
See the section of exclude patterns for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--include-from=FILE)) This specifies a list of include patterns
|
||||
from a file.
|
||||
|
||||
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
|
||||
broad range of files that you often don't want to transfer between
|
||||
systems. It uses the same algorithm that CVS uses to determine if
|
||||
@@ -542,7 +643,7 @@ a file should be ignored.
|
||||
|
||||
The exclude list is initialized to:
|
||||
|
||||
quote(RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
|
||||
quote(RCS/ SCCS/ CVS/ .svn/ CVS.adm RCSLOG cvslog.* tags TAGS .make.state
|
||||
.nse_depinfo *~ #* .#* ,* *.old *.bak *.BAK *.orig *.rej .del-*
|
||||
*.a *.o *.obj *.so *.Z *.elc *.ln core)
|
||||
|
||||
@@ -553,24 +654,73 @@ Finally, any file is ignored if it is in the same directory as a
|
||||
.cvsignore file and matches one of the patterns listed therein. See
|
||||
the bf(cvs(1)) manual for more information.
|
||||
|
||||
dit(bf(--csum-length=LENGTH)) By default the primary checksum used in
|
||||
rsync is a very strong 16 byte MD4 checksum. In most cases you will
|
||||
find that a truncated version of this checksum is quite efficient, and
|
||||
this will decrease the size of the checksum data sent over the link,
|
||||
making things faster.
|
||||
dit(bf(--exclude=PATTERN)) This option allows you to selectively exclude
|
||||
certain files from the list of files to be transferred. This is most
|
||||
useful in combination with a recursive transfer.
|
||||
|
||||
You can choose the number of bytes in the truncated checksum using the
|
||||
--csum-length option. Any value less than or equal to 16 is valid.
|
||||
You may use as many --exclude options on the command line as you like
|
||||
to build up the list of files to exclude.
|
||||
|
||||
Note that if you use this option then you run the risk of ending up
|
||||
with an incorrect target file. The risk with a value of 16 is
|
||||
microscopic and can be safely ignored (the universe will probably end
|
||||
before it fails) but with smaller values the risk is higher.
|
||||
See the EXCLUDE PATTERNS section for information on the syntax of
|
||||
this option.
|
||||
|
||||
Current versions of rsync actually use an adaptive algorithm for the
|
||||
checksum length by default, using a 16 byte file checksum to determine
|
||||
if a 2nd pass is required with a longer block checksum. Only use this
|
||||
option if you have read the source code and know what you are doing.
|
||||
dit(bf(--exclude-from=FILE)) This option is similar to the --exclude
|
||||
option, but instead it adds all exclude patterns listed in the file
|
||||
FILE to the exclude list. Blank lines in FILE and lines starting with
|
||||
';' or '#' are ignored.
|
||||
If em(FILE) is bf(-) the list will be read from standard input.
|
||||
|
||||
dit(bf(--include=PATTERN)) This option tells rsync to not exclude the
|
||||
specified pattern of filenames. This is useful as it allows you to
|
||||
build up quite complex exclude/include rules.
|
||||
|
||||
See the EXCLUDE PATTERNS section for information on the syntax of
|
||||
this option.
|
||||
|
||||
dit(bf(--include-from=FILE)) This specifies a list of include patterns
|
||||
from a file.
|
||||
If em(FILE) is bf(-) the list will be read from standard input.
|
||||
|
||||
dit(bf(--files-from=FILE)) Using this option allows you to specify the
|
||||
exact list of files to transfer (as read from the specified FILE or "-"
|
||||
for stdin). It also tweaks the default behavior of rsync to make
|
||||
transferring just the specified files and directories easier. For
|
||||
instance, the --relative option is enabled by default when this option
|
||||
is used (use --no-relative if you want to turn that off), all
|
||||
directories specified in the list are created on the destination (rather
|
||||
than being noisily skipped without -r), and the -a (--archive) option's
|
||||
behavior does not imply -r (--recursive) -- specify it explicitly, if
|
||||
you want it.
|
||||
|
||||
The file names that are read from the FILE are all relative to the
|
||||
source dir -- any leading slashes are removed and no ".." references are
|
||||
allowed to go higher than the source dir. For example, take this
|
||||
command:
|
||||
|
||||
quote(rsync -a --files-from=/tmp/foo /usr remote:/backup)
|
||||
|
||||
If /tmp/foo contains the string "bin" (or even "/bin"), the /usr/bin
|
||||
directory will be created as /backup/bin on the remote host (but the
|
||||
contents of the /usr/bin dir would not be sent unless you specified -r
|
||||
or the names were explicitly listed in /tmp/foo). Also keep in mind
|
||||
that the effect of the (enabled by default) --relative option is to
|
||||
duplicate only the path info that is read from the file -- it does not
|
||||
force the duplication of the source-spec path (/usr in this case).
|
||||
|
||||
In addition, the --files-from file can be read from the remote host
|
||||
instead of the local host if you specify a "host:" in front of the file
|
||||
(the host must match one end of the transfer). As a short-cut, you can
|
||||
specify just a prefix of ":" to mean "use the remote end of the
|
||||
transfer". For example:
|
||||
|
||||
quote(rsync -a --files-from=:/path/file-list src:/ /tmp/copy)
|
||||
|
||||
This would copy all the files specified in the /path/file-list file that
|
||||
was located on the remote "src" host.
|
||||
|
||||
dit(bf(-0, --from0)) This tells rsync that the filenames it reads from a
|
||||
file are terminated by a null ('\0') character, not a NL, CR, or CR+LF.
|
||||
This affects --exclude-from, --include-from, and --files-from.
|
||||
|
||||
dit(bf(-T, --temp-dir=DIR)) This option instructs rsync to use DIR as a
|
||||
scratch directory when creating temporary copies of the files
|
||||
@@ -579,19 +729,27 @@ the temporary files in the receiving directory.
|
||||
|
||||
dit(bf(--compare-dest=DIR)) This option instructs rsync to use DIR on
|
||||
the destination machine as an additional directory to compare destination
|
||||
files against when doing transfers. This is useful for doing transfers to
|
||||
a new destination while leaving existing files intact, and then doing a
|
||||
files against when doing transfers if the files are missing in the
|
||||
destination directory. This is useful for doing transfers to a new
|
||||
destination while leaving existing files intact, and then doing a
|
||||
flash-cutover when all files have been successfully transferred (for
|
||||
example by moving directories around and removing the old directory,
|
||||
although this requires also doing the transfer with -I to avoid skipping
|
||||
files that haven't changed). This option increases the usefulness of
|
||||
--partial because partially transferred files will remain in the new
|
||||
temporary destination until they have a chance to be completed. If DIR is
|
||||
a relative path, it is relative to the destination directory.
|
||||
although this skips files that haven't changed; see also --link-dest).
|
||||
This option increases the usefulness of --partial because partially
|
||||
transferred files will remain in the new temporary destination until they
|
||||
have a chance to be completed. If DIR is a relative path, it is relative
|
||||
to the destination directory.
|
||||
|
||||
dit(bf(--link-dest=DIR)) This option behaves like bf(--compare-dest) but
|
||||
also will create hard links from em(DIR) to the destination directory for
|
||||
unchanged files. Files with changed ownership or permissions will not be
|
||||
linked.
|
||||
Like bf(--compare-dest) if DIR is a relative path, it is relative
|
||||
to the destination directory.
|
||||
|
||||
dit(bf(-z, --compress)) With this option, rsync compresses any data from
|
||||
the files that it sends to the destination machine. This
|
||||
option is useful on slow links. The compression method used is the
|
||||
option is useful on slow connections. The compression method used is the
|
||||
same method that gzip uses.
|
||||
|
||||
Note this this option typically achieves better compression ratios
|
||||
@@ -623,7 +781,7 @@ bf(rsync://host/module/) syntax.
|
||||
If standard input is a socket then rsync will assume that it is being
|
||||
run via inetd, otherwise it will detach from the current terminal and
|
||||
become a background daemon. The daemon will read the config file
|
||||
(/etc/rsyncd.conf) on each connect made by a client and respond to
|
||||
(rsyncd.conf) on each connect made by a client and respond to
|
||||
requests accordingly. See the rsyncd.conf(5) man page for more
|
||||
details.
|
||||
|
||||
@@ -643,8 +801,10 @@ address (or hostname) to bind to. This makes virtual hosting possible
|
||||
in conjunction with the --config option.
|
||||
|
||||
dit(bf(--config=FILE)) This specifies an alternate config file than
|
||||
the default /etc/rsyncd.conf. This is only relevant when --daemon is
|
||||
specified.
|
||||
the default. This is only relevant when --daemon is specified.
|
||||
The default is /etc/rsyncd.conf unless the daemon is running over
|
||||
a remote shell program and the remote user is not root; in that case
|
||||
the default is rsyncd.conf in the current directory (typically $HOME).
|
||||
|
||||
dit(bf(--port=PORT)) This specifies an alternate TCP port number to use
|
||||
rather than the default port 873.
|
||||
@@ -653,7 +813,11 @@ dit(bf(--blocking-io)) This tells rsync to use blocking IO when launching
|
||||
a remote shell transport. If -e or --rsh are not specified or are set to
|
||||
the default "rsh", this defaults to blocking IO, otherwise it defaults to
|
||||
non-blocking IO. You may find the --blocking-io option is needed for some
|
||||
remote shells that can't handle non-blocking IO. Ssh prefers blocking IO.
|
||||
remote shells that can't handle non-blocking IO. (Note that ssh prefers
|
||||
non-blocking IO.)
|
||||
|
||||
dit(bf(--no-blocking-io)) Turn off --blocking-io, for use when it is the
|
||||
default.
|
||||
|
||||
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
|
||||
rsync client logs to stdout on a per-file basis. The log format is
|
||||
@@ -673,9 +837,7 @@ make a subsequent transfer of the rest of the file much faster.
|
||||
dit(bf(--progress)) This option tells rsync to print information
|
||||
showing the progress of the transfer. This gives a bored user
|
||||
something to watch.
|
||||
|
||||
This option is normally combined with -v. Using this option without
|
||||
the -v option will produce weird results on your display.
|
||||
Implies --verbose without incrementing verbosity.
|
||||
|
||||
dit(bf(-P)) The -P option is equivalent to --partial --progress. I
|
||||
found myself typing that combination quite often so I created an
|
||||
@@ -696,10 +858,13 @@ transfer was too fast, it will wait before sending the next data block. The
|
||||
result is an average transfer rate equalling the specified limit. A value
|
||||
of zero specifies no limit.
|
||||
|
||||
dit(bf(--read-batch)) Apply a previously generated change batch.
|
||||
dit(bf(--write-batch=PREFIX)) Generate a set of files that can be
|
||||
transferred as a batch update. Each filename in the set starts with
|
||||
PREFIX. See the "BATCH MODE" section for details.
|
||||
|
||||
dit(bf(--write-batch)) Generate a set of files that can be transferred
|
||||
as a batch update.
|
||||
dit(bf(--read-batch=PREFIX)) Apply a previously generated change batch,
|
||||
using the fileset whose filenames start with PREFIX. See the "BATCH
|
||||
MODE" section for details.
|
||||
|
||||
enddit()
|
||||
|
||||
@@ -709,13 +874,20 @@ The exclude and include patterns specified to rsync allow for flexible
|
||||
selection of which files to transfer and which files to skip.
|
||||
|
||||
rsync builds an ordered list of include/exclude options as specified on
|
||||
the command line. When a filename is encountered, rsync checks the
|
||||
the command line. Rsync checks each file and directory
|
||||
name against each exclude/include pattern in turn. The first matching
|
||||
pattern is acted on. If it is an exclude pattern, then that file is
|
||||
skipped. If it is an include pattern then that filename is not
|
||||
skipped. If no matching include/exclude pattern is found then the
|
||||
filename is not skipped.
|
||||
|
||||
The filenames matched against the exclude/include patterns
|
||||
are relative to the destination directory, or "top
|
||||
directory", so patterns should not include the path elements
|
||||
of the source or destination directories. The only way in
|
||||
which a pattern will match the absolute path of a file or
|
||||
directory is if the source path is the root directory.
|
||||
|
||||
Note that when used with -r (which is implied by -a), every subcomponent of
|
||||
every path is visited from top down, so include/exclude patterns get
|
||||
applied recursively to each subcomponent.
|
||||
@@ -727,13 +899,18 @@ each. To add multiple patterns use the --include-from and
|
||||
The patterns can take several forms. The rules are:
|
||||
|
||||
itemize(
|
||||
|
||||
it() if the pattern starts with a / then it is matched against the
|
||||
start of the filename, otherwise it is matched against the end of
|
||||
the filename. Thus "/foo" would match a file called "foo" at the base of
|
||||
the tree. On the other hand, "foo" would match any file called "foo"
|
||||
the filename.
|
||||
This is the equivalent of a leading ^ in regular expressions.
|
||||
Thus "/foo" would match a file called "foo" at the top of the
|
||||
transferred tree.
|
||||
On the other hand, "foo" would match any file called "foo"
|
||||
anywhere in the tree because the algorithm is applied recursively from
|
||||
top down; it behaves as if each path component gets a turn at being the
|
||||
end of the file name.
|
||||
The leading / does not make the pattern an absolute pathname.
|
||||
|
||||
it() if the pattern ends with a / then it will only match a
|
||||
directory, not a file, link or device.
|
||||
@@ -742,15 +919,15 @@ itemize(
|
||||
*?[ then expression matching is applied using the shell filename
|
||||
matching rules. Otherwise a simple string match is used.
|
||||
|
||||
it() if the pattern includes a double asterisk "**" then all wildcards in
|
||||
the pattern will match slashes, otherwise they will stop at slashes.
|
||||
it() the double asterisk pattern "**" will match slashes while a
|
||||
single asterisk pattern "*" will stop at slashes.
|
||||
|
||||
it() if the pattern contains a / (not counting a trailing /) then it
|
||||
is matched against the full filename, including any leading
|
||||
directory. If the pattern doesn't contain a / then it is matched
|
||||
only against the final component of the filename. Again, remember
|
||||
that the algorithm is applied recursively so "full filename" can
|
||||
actually be any portion of a path.
|
||||
it() if the pattern contains a / (not counting a trailing /) or a "**"
|
||||
then it is matched against the full filename, including any leading
|
||||
directory. If the pattern doesn't contain a / or a "**", then it is
|
||||
matched only against the final component of the filename. Again,
|
||||
remember that the algorithm is applied recursively so "full filename" can
|
||||
actually be any portion of a path below the starting directory.
|
||||
|
||||
it() if the pattern starts with "+ " (a plus followed by a space)
|
||||
then it is always considered an include pattern, even if specified as
|
||||
@@ -764,8 +941,9 @@ itemize(
|
||||
include/exclude list is reset, removing all previously defined patterns.
|
||||
)
|
||||
|
||||
The +/- rules are most useful in exclude lists, allowing you to have a
|
||||
single exclude list that contains both include and exclude options.
|
||||
The +/- rules are most useful in a list that was read from a file, allowing
|
||||
you to have a single exclude list that contains both include and exclude
|
||||
options.
|
||||
|
||||
If you end an exclude list with --exclude '*', note that since the
|
||||
algorithm is applied recursively that unless you explicitly include
|
||||
@@ -778,12 +956,12 @@ Here are some exclude/include examples:
|
||||
|
||||
itemize(
|
||||
it() --exclude "*.o" would exclude all filenames matching *.o
|
||||
it() --exclude "/foo" would exclude a file in the base directory called foo
|
||||
it() --exclude "/foo" would exclude a file called foo in the top directory
|
||||
it() --exclude "foo/" would exclude any directory called foo
|
||||
it() --exclude "/foo/*/bar" would exclude any file called bar two
|
||||
levels below a base directory called foo
|
||||
levels below a directory called foo in the top directory
|
||||
it() --exclude "/foo/**/bar" would exclude any file called bar two
|
||||
or more levels below a base directory called foo
|
||||
or more levels below a directory called foo in the top directory
|
||||
it() --include "*/" --include "*.c" --exclude "*" would include all
|
||||
directories and C source files
|
||||
it() --include "foo/" --include "foo/bar.c" --exclude "*" would include
|
||||
@@ -794,26 +972,83 @@ itemize(
|
||||
manpagesection(BATCH MODE)
|
||||
|
||||
bf(Note:) Batch mode should be considered experimental in this version
|
||||
of rsync. The interface or behaviour may change before it stabilizes.
|
||||
of rsync. The interface or behaviour may change before it stabilizes.
|
||||
|
||||
The following call generates 4 files that encapsulate the information
|
||||
for synchronizing the contents of bf(target_dir) with the updates found in
|
||||
bf(src_dir)
|
||||
Batch mode can be used to apply the same set of updates to many
|
||||
identical systems. Suppose one has a tree which is replicated on a
|
||||
number of hosts. Now suppose some changes have been made to this
|
||||
source tree and those changes need to be propagated to the other
|
||||
hosts. In order to do this using batch mode, rsync is run with the
|
||||
write-batch option to apply the changes made to the source tree to one
|
||||
of the destination trees. The write-batch option causes the rsync
|
||||
client to store the information needed to repeat this operation against
|
||||
other destination trees in a batch update fileset (see below). The
|
||||
filename of each file in the fileset starts with a prefix specified by
|
||||
the user as an argument to the write-batch option. This fileset is
|
||||
then copied to each remote host, where rsync is run with the read-batch
|
||||
option, again specifying the same prefix, and the destination tree.
|
||||
Rsync updates the destination tree using the information stored in the
|
||||
batch update fileset.
|
||||
|
||||
quote(
|
||||
$ rsync --write-batch [other rsync options here] \nl()
|
||||
/somewhere/src_dir /somewhere/target_dir
|
||||
)
|
||||
|
||||
The generated files are labeled with a common timestamp:
|
||||
The fileset consists of 4 files:
|
||||
|
||||
itemize(
|
||||
it() bf(rsync_argvs.<timestamp>) command-line arguments
|
||||
it() bf(rsync_flist.<timestamp>) rsync internal file metadata
|
||||
it() bf(rsync_csums.<timestamp>) rsync checksums
|
||||
it() bf(rsync_delta.<timestamp>) data blocks for file update & change
|
||||
it() bf(<prefix>.rsync_argvs) command-line arguments
|
||||
it() bf(<prefix>.rsync_flist) rsync internal file metadata
|
||||
it() bf(<prefix>.rsync_csums) rsync checksums
|
||||
it() bf(<prefix>.rsync_delta) data blocks for file update & change
|
||||
)
|
||||
|
||||
The .rsync_argvs file contains a command-line suitable for updating a
|
||||
destination tree using that batch update fileset. It can be executed
|
||||
using a Bourne(-like) shell, optionally passing in an alternate
|
||||
destination tree pathname which is then used instead of the original
|
||||
path. This is useful when the destination tree path differs from the
|
||||
original destination tree path.
|
||||
|
||||
Generating the batch update fileset once saves having to perform the
|
||||
file status, checksum and data block generation more than once when
|
||||
updating multiple destination trees. Multicast transport protocols can
|
||||
be used to transfer the batch update files in parallel to many hosts at
|
||||
once, instead of sending the same data to every host individually.
|
||||
|
||||
Example:
|
||||
|
||||
verb(
|
||||
$ rsync --write-batch=pfx -a /source/dir/ /adest/dir/
|
||||
$ rcp pfx.rsync_* remote:
|
||||
$ rsh remote rsync --read-batch=pfx -a /bdest/dir/
|
||||
# or alternatively
|
||||
$ rsh remote ./pfx.rsync_argvs /bdest/dir/
|
||||
)
|
||||
|
||||
In this example, rsync is used to update /adest/dir/ with /source/dir/
|
||||
and the information to repeat this operation is stored in the files
|
||||
pfx.rsync_*. These files are then copied to the machine named "remote".
|
||||
Rsync is then invoked on "remote" to update /bdest/dir/ the same way as
|
||||
/adest/dir/. The last line shows the rsync_argvs file being used to
|
||||
invoke rsync.
|
||||
|
||||
Caveats:
|
||||
|
||||
The read-batch option expects the destination tree it is meant to update
|
||||
to be identical to the destination tree that was used to create the
|
||||
batch update fileset. When a difference between the destination trees
|
||||
is encountered the update will fail at that point, leaving the
|
||||
destination tree in a partially updated state. In that case, rsync can
|
||||
be used in its regular (non-batch) mode of operation to fix up the
|
||||
destination tree.
|
||||
|
||||
The rsync version used on all destinations should be identical to the
|
||||
one used on the original destination.
|
||||
|
||||
The -z/--compress option does not work in batch mode and yields a usage
|
||||
error. A separate compression tool can be used instead to reduce the
|
||||
size of the batch update files for transport to the destination.
|
||||
|
||||
The -n/--dryrun option does not work in batch mode and yields a runtime
|
||||
error.
|
||||
|
||||
See bf(http://www.ils.unc.edu/i2dsi/unc_rsync+.html) for papers and technical
|
||||
reports.
|
||||
|
||||
@@ -840,6 +1075,10 @@ bf(--copy-unsafe-links) will cause any links to be copied as the file
|
||||
they point to on the destination. Using bf(--safe-links) will cause
|
||||
unsafe links to be ommitted altogether.
|
||||
|
||||
Symbolic links are considered unsafe if they are absolute symlinks
|
||||
(start with bf(/)), empty, or if they contain enough bf("..")
|
||||
components to ascend from the directory being copied.
|
||||
|
||||
manpagesection(DIAGNOSTICS)
|
||||
|
||||
rsync occasionally produces error messages that may seem a little
|
||||
@@ -870,24 +1109,25 @@ show why each individual file is included or excluded.
|
||||
manpagesection(EXIT VALUES)
|
||||
|
||||
startdit()
|
||||
dit(bf(RERR_SYNTAX 1)) Syntax or usage error
|
||||
dit(bf(RERR_PROTOCOL 2)) Protocol incompatibility
|
||||
dit(bf(RERR_FILESELECT 3)) Errors selecting input/output files, dirs
|
||||
|
||||
dit(bf(RERR_UNSUPPORTED 4)) Requested action not supported: an attempt
|
||||
dit(bf(0)) Success
|
||||
dit(bf(1)) Syntax or usage error
|
||||
dit(bf(2)) Protocol incompatibility
|
||||
dit(bf(3)) Errors selecting input/output files, dirs
|
||||
dit(bf(4)) Requested action not supported: an attempt
|
||||
was made to manipulate 64-bit files on a platform that cannot support
|
||||
them; or an option was speciifed that is supported by the client and
|
||||
not by the server.
|
||||
|
||||
dit(bf(RERR_SOCKETIO 10)) Error in socket IO
|
||||
dit(bf(RERR_FILEIO 11)) Error in file IO
|
||||
dit(bf(RERR_STREAMIO 12)) Error in rsync protocol data stream
|
||||
dit(bf(RERR_MESSAGEIO 13)) Errors with program diagnostics
|
||||
dit(bf(RERR_IPC 14)) Error in IPC code
|
||||
dit(bf(RERR_SIGNAL 20)) Received SIGUSR1 or SIGINT
|
||||
dit(bf(RERR_WAITCHILD 21)) Some error returned by waitpid()
|
||||
dit(bf(RERR_MALLOC 22)) Error allocating core memory buffers
|
||||
dit(bf(RERR_TIMEOUT 30)) Timeout in data send/receive
|
||||
dit(bf(5)) Error starting client-server protocol
|
||||
dit(bf(10)) Error in socket IO
|
||||
dit(bf(11)) Error in file IO
|
||||
dit(bf(12)) Error in rsync protocol data stream
|
||||
dit(bf(13)) Errors with program diagnostics
|
||||
dit(bf(14)) Error in IPC code
|
||||
dit(bf(20)) Received SIGUSR1 or SIGINT
|
||||
dit(bf(21)) Some error returned by waitpid()
|
||||
dit(bf(22)) Error allocating core memory buffers
|
||||
dit(bf(23)) Partial transfer
|
||||
dit(bf(30)) Timeout in data send/receive
|
||||
enddit()
|
||||
|
||||
manpagesection(ENVIRONMENT VARIABLES)
|
||||
@@ -899,8 +1139,8 @@ ignore patterns in .cvsignore files. See the --cvs-exclude option for
|
||||
more details.
|
||||
|
||||
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
|
||||
override the default shell used as the transport for rsync. This can
|
||||
be used instead of the -e option.
|
||||
override the default shell used as the transport for rsync. Command line
|
||||
options are permitted after the command name, just as in the -e option.
|
||||
|
||||
dit(bf(RSYNC_PROXY)) The RSYNC_PROXY environment variable allows you to
|
||||
redirect your rsync client to use a web proxy when connecting to a
|
||||
@@ -921,7 +1161,7 @@ enddit()
|
||||
|
||||
manpagefiles()
|
||||
|
||||
/etc/rsyncd.conf
|
||||
/etc/rsyncd.conf or rsyncd.conf
|
||||
|
||||
manpageseealso()
|
||||
|
||||
@@ -933,16 +1173,17 @@ manpagebugs()
|
||||
|
||||
times are transferred as unix time_t values
|
||||
|
||||
When transferring to FAT filesystmes rsync may resync
|
||||
unmodified files.
|
||||
See the comments on the --modify-window option.
|
||||
|
||||
file permissions, devices etc are transferred as native numerical
|
||||
values
|
||||
|
||||
see also the comments on the --delete option
|
||||
|
||||
Please report bugs! The rsync bug tracking system is online at
|
||||
url(http://rsync.samba.org/rsync/)(http://rsync.samba.org/rsync/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
This man page is current for version 2.0 of rsync
|
||||
Please report bugs! See the website at
|
||||
url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
|
||||
118
rsyncd.conf.yo
118
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(12 Feb 1999)()()
|
||||
manpage(rsyncd.conf)(5)(26 Jan 2003)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync server)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -8,9 +8,7 @@ rsyncd.conf
|
||||
manpagedescription()
|
||||
|
||||
The rsyncd.conf file is the runtime configuration file for rsync when
|
||||
run with the --daemon option. When run in this way rsync becomes a
|
||||
rsync server listening on TCP port 873. Connections from rsync clients
|
||||
are accepted for either anonymous or authenticated rsync sessions.
|
||||
run as an rsync server.
|
||||
|
||||
The rsyncd.conf file controls authentication, access, logging and
|
||||
available modules.
|
||||
@@ -51,9 +49,12 @@ bind to a port numbered under 1024 (as is the default 873), or to set
|
||||
file ownership. Otherwise, it must just have permission to read and
|
||||
write the appropriate data, log, and lock files.
|
||||
|
||||
You can launch it either via inetd or as a stand-alone daemon. If run
|
||||
as a daemon then just run the command "rsync --daemon" from a suitable
|
||||
startup script.
|
||||
You can launch it either via inetd, as a stand-alone daemon, or from
|
||||
an rsync client via a remote shell. If run as a stand-alone daemon then
|
||||
just run the command "rsync --daemon" from a suitable startup script.
|
||||
If run from an rsync client via a remote shell (by specifying both the
|
||||
"-e/--rsh" option and server mode with "::" or "rsync://"), the --daemon
|
||||
option is automatically passed to the remote side.
|
||||
|
||||
When run via inetd you should add a line like this to /etc/services:
|
||||
|
||||
@@ -68,7 +69,7 @@ your system. You will then need to send inetd a HUP signal to tell it to
|
||||
reread its config file.
|
||||
|
||||
Note that you should not send the rsync server a HUP signal to force
|
||||
it to reread the tt(/etc/rsyncd.conf). The file is re-read on each client
|
||||
it to reread the tt(rsyncd.conf) file. The file is re-read on each client
|
||||
connection.
|
||||
|
||||
manpagesection(GLOBAL OPTIONS)
|
||||
@@ -127,28 +128,30 @@ of available modules. The default is no comment.
|
||||
|
||||
dit(bf(path)) The "path" option specifies the directory in the servers
|
||||
filesystem to make available in this module. You must specify this option
|
||||
for each module in tt(/etc/rsyncd.conf).
|
||||
for each module in tt(rsyncd.conf).
|
||||
|
||||
dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
|
||||
to the "path" before starting the file transfer with the client. This has
|
||||
the advantage of extra protection against possible implementation security
|
||||
holes, but it has the disadvantages of requiring super-user privileges and
|
||||
holes, but it has the disadvantages of requiring super-user privileges,
|
||||
of not being able to follow symbolic links outside of the new root path
|
||||
when reading. When "use chroot" is false, for security reasons
|
||||
symlinks may only be relative paths pointing to other files within the
|
||||
root path, and leading slashes are removed from absolute paths. The
|
||||
default for "use chroot" is true.
|
||||
when reading, and of implying the --numeric-ids option because /etc/passwd
|
||||
becomes inaccessible. When "use chroot" is false, for security reasons
|
||||
symlinks may only be relative paths pointing to other files within the root
|
||||
path, and leading slashes are removed from absolute paths. The default for
|
||||
"use chroot" is true.
|
||||
|
||||
dit(bf(max connections)) The "max connections" option allows you to
|
||||
specify the maximum number of simultaneous connections you will allow
|
||||
to this module of your rsync server. Any clients connecting when the
|
||||
maximum has been reached will receive a message telling them to try
|
||||
later. The default is 0 which means no limit.
|
||||
specify the maximum number of simultaneous connections you will allow.
|
||||
Any clients connecting when the maximum has been reached will receive a
|
||||
message telling them to try later. The default is 0 which means no limit.
|
||||
See also the "lock file" option.
|
||||
|
||||
dit(bf(lock file)) The "lock file" option specifies the file to use to
|
||||
support the "max connections" option. The rsync server uses record
|
||||
locking on this file to ensure that the max connections limit is not
|
||||
exceeded. The default is tt(/var/run/rsyncd.lock).
|
||||
exceeded for the modules sharing the lock file.
|
||||
The default is tt(/var/run/rsyncd.lock).
|
||||
|
||||
dit(bf(read only)) The "read only" option determines whether clients
|
||||
will be able to upload files or not. If "read only" is true then any
|
||||
@@ -173,12 +176,17 @@ was run as root. This complements the "uid" option. The default is gid -2,
|
||||
which is normally the group "nobody".
|
||||
|
||||
dit(bf(exclude)) The "exclude" option allows you to specify a space
|
||||
separated list of patterns to add to the exclude list. This is
|
||||
equivalent to the client specifying these patterns with the --exclude
|
||||
option except that the exclude list is not passed to the client and
|
||||
thus only apply on the server. Only one "exclude" option may be
|
||||
specified, but you can use "-" and "+" before patterns to specify
|
||||
exclude/include.
|
||||
separated list of patterns to add to the exclude list.
|
||||
This is only superficially equivalent
|
||||
to the client specifying these patterns with the --exclude option.
|
||||
Only one "exclude" option may be specified, but
|
||||
you can use "-" and "+" before patterns to specify exclude/include.
|
||||
|
||||
Because this exclude list is not passed to the client it only applies on
|
||||
the server: that is, it excludes files received by a client when receiving
|
||||
from a server and files deleted on a server when sending to a server, but
|
||||
it doesn't exclude files sent from a client when sending to a server or
|
||||
files deleted on a client when receiving from a server.
|
||||
|
||||
Note that this option is not designed with strong security in
|
||||
mind, it is quite possible that a client may find a way to bypass this
|
||||
@@ -187,26 +195,25 @@ cannot be accessed then use the uid/gid options in combination with
|
||||
file permissions.
|
||||
|
||||
dit(bf(exclude from)) The "exclude from" option specifies a filename
|
||||
on the server that contains exclude patterns, one per line. This is
|
||||
equivalent to the client specifying the --exclude-from option with a
|
||||
equivalent file except that the resulting exclude patterns are not
|
||||
passed to the client and thus only apply on the server. See also the
|
||||
note about security for the exclude option above.
|
||||
on the server that contains exclude patterns, one per line.
|
||||
This is only superficially equivalent
|
||||
to the client specifying the --exclude-from option with an equivalent file.
|
||||
See the "exclude" option above.
|
||||
|
||||
dit(bf(include)) The "include" option allows you to specify a space
|
||||
separated list of patterns which rsync should not exclude. This is
|
||||
equivalent to the client specifying these patterns with the --include
|
||||
option. This is useful as it allows you to build up quite complex
|
||||
exclude/include rules. Only one "include" option may be specified, but you
|
||||
can use "+" and "-" before patterns to switch include/exclude.
|
||||
|
||||
See the section of exclude patterns in the rsync man page for information
|
||||
on the syntax of this option.
|
||||
only superficially equivalent to the client specifying these patterns
|
||||
with the --include option because it applies only on the server.
|
||||
This is useful as it
|
||||
allows you to build up quite complex exclude/include rules. Only one
|
||||
"include" option may be specified, but you can use "+" and "-" before
|
||||
patterns to switch include/exclude. See the "exclude" option above.
|
||||
|
||||
dit(bf(include from)) The "include from" option specifies a filename
|
||||
on the server that contains include patterns, one per line. This is
|
||||
equivalent to the client specifying the --include-from option with a
|
||||
equivalent file.
|
||||
only superficially equivalent to the client specifying the
|
||||
--include-from option with a equivalent file.
|
||||
See the "exclude" option above.
|
||||
|
||||
dit(bf(auth users)) The "auth users" option specifies a comma and
|
||||
space separated list of usernames that will be allowed to connect to
|
||||
@@ -219,6 +226,11 @@ usernames are passwords are stored in the file specified by the
|
||||
"secrets file" option. The default is for all users to be able to
|
||||
connect without a password (this is called "anonymous rsync").
|
||||
|
||||
See also the bf(CONNECTING TO AN RSYNC SERVER OVER A REMOTE SHELL
|
||||
PROGRAM) section in rsync(1) for information on how handle an
|
||||
rsyncd.conf-level username that differs from the remote-shell-level
|
||||
username when using a remote shell to connect to a rsync server.
|
||||
|
||||
dit(bf(secrets file)) The "secrets file" option specifies the name of
|
||||
a file that contains the username:password pairs used for
|
||||
authenticating this module. This file is only consulted if the "auth
|
||||
@@ -248,16 +260,18 @@ connection is rejected.
|
||||
Each pattern can be in one of five forms:
|
||||
|
||||
itemize(
|
||||
it() a dotted decimal IP address. In this case the incoming machines
|
||||
IP address must match exactly.
|
||||
it() a dotted decimal IPv4 address of the form a.b.c.d, or an IPv6 address
|
||||
of the form a:b:c::d:e:f. In this case the incoming machine's IP address
|
||||
must match exactly.
|
||||
|
||||
it() a address/mask in the form a.b.c.d/n were n is the number of
|
||||
one bits in in the netmask. All IP addresses which match the masked
|
||||
IP address will be allowed in.
|
||||
it() an address/mask in the form ipaddr/n where ipaddr is the IP address
|
||||
and n is the number of one bits in the netmask. All IP addresses which
|
||||
match the masked IP address will be allowed in.
|
||||
|
||||
it() a address/mask in the form a.b.c.d/e.f.g.h where e.f.g.h is a
|
||||
netmask in dotted decimal notation. All IP addresses which match the masked
|
||||
IP address will be allowed in.
|
||||
it() an address/mask in the form ipaddr/maskaddr where ipaddr is the
|
||||
IP address and maskaddr is the netmask in dotted decimal notation for IPv4,
|
||||
or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
|
||||
addresses which match the masked IP address will be allowed in.
|
||||
|
||||
it() a hostname. The hostname as determined by a reverse lookup will
|
||||
be matched (case insensitive) against the pattern. Only an exact
|
||||
@@ -268,6 +282,12 @@ itemize(
|
||||
then the client is allowed in.
|
||||
)
|
||||
|
||||
Note IPv6 link-local addresses can have a scope in the address specification:
|
||||
|
||||
quote(fe80::1%link1)
|
||||
quote(fe80::%link1/64)
|
||||
quote(fe80::%link1/ffff:ffff:ffff:ffff::)
|
||||
|
||||
You can also combine "hosts allow" with a separate "hosts deny"
|
||||
option. If both options are specified then the "hosts allow" option s
|
||||
checked first and a match results in the client being able to
|
||||
@@ -372,7 +392,7 @@ It should be good enough for most purposes but if you want really top
|
||||
quality security then I recommend that you run rsync over ssh.
|
||||
|
||||
Also note that the rsync server protocol does not currently provide any
|
||||
encryption of the data that is transferred over the link. Only
|
||||
encryption of the data that is transferred over the connection. Only
|
||||
authentication is provided. Use ssh as the transport if you want
|
||||
encryption.
|
||||
|
||||
@@ -430,7 +450,7 @@ susan:herpass
|
||||
|
||||
manpagefiles()
|
||||
|
||||
/etc/rsyncd.conf
|
||||
/etc/rsyncd.conf or rsyncd.conf
|
||||
|
||||
manpageseealso()
|
||||
|
||||
|
||||
39
runtests.sh
39
runtests.sh
@@ -125,6 +125,9 @@ set -e
|
||||
|
||||
RUNSHFLAGS='-e'
|
||||
|
||||
# for Solaris
|
||||
PATH="/usr/xpg4/bin/:$PATH"
|
||||
|
||||
if [ -n "$loglevel" ] && [ "$loglevel" -gt 8 ]
|
||||
then
|
||||
if set -x
|
||||
@@ -139,6 +142,20 @@ echo "$0 running in `pwd`"
|
||||
echo " rsync_bin=$rsync_bin"
|
||||
echo " srcdir=$srcdir"
|
||||
|
||||
testuser=`whoami || echo UNKNOWN`
|
||||
|
||||
echo " testuser=$testuser"
|
||||
echo " os=`uname -a`"
|
||||
|
||||
# It must be "yes", not just nonnull
|
||||
if test "x$preserve_scratch" = xyes
|
||||
then
|
||||
echo " preserve_scratch=yes"
|
||||
else
|
||||
echo " preserve_scratch=no"
|
||||
fi
|
||||
|
||||
|
||||
if test ! -f $rsync_bin
|
||||
then
|
||||
echo "rsync_bin $rsync_bin is not a file" >&2
|
||||
@@ -176,8 +193,8 @@ prep_scratch() {
|
||||
return 0
|
||||
}
|
||||
|
||||
discard_scratch() {
|
||||
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
maybe_discard_scratch() {
|
||||
[ x"$preserve_scratch" != xyes ] && [ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -198,16 +215,25 @@ do
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
if [ "x$always_log" = xyes -o \( $result != 0 -a $result != 77 -a $result != 78 \) ]
|
||||
then
|
||||
echo "----- $testbase log follows"
|
||||
cat "$scratchdir/test.log"
|
||||
echo "----- $testbase log ends"
|
||||
fi
|
||||
|
||||
case $result in
|
||||
0)
|
||||
echo "PASS $testbase"
|
||||
passed=`expr $passed + 1`
|
||||
discard_scratch
|
||||
maybe_discard_scratch
|
||||
;;
|
||||
77)
|
||||
echo "SKIP $testbase"
|
||||
# backticks will fill the whole file onto one line, which is a feature
|
||||
whyskipped=`cat "$scratchdir/whyskipped"`
|
||||
echo "SKIP $testbase ($whyskipped)"
|
||||
skipped=`expr $skipped + 1`
|
||||
discard_scratch
|
||||
maybe_discard_scratch
|
||||
;;
|
||||
78)
|
||||
# It failed, but we expected that. don't dump out error logs,
|
||||
@@ -218,9 +244,6 @@ do
|
||||
;;
|
||||
*)
|
||||
echo "FAIL $testbase"
|
||||
echo "----- $testbase failed: log follows"
|
||||
cat "$scratchdir/test.log"
|
||||
echo "----- $testbase log ends"
|
||||
failed=`expr $failed + 1`
|
||||
if [ "x$nopersist" = "xyes" ]
|
||||
then
|
||||
|
||||
27
sender.c
27
sender.c
@@ -28,16 +28,25 @@ extern int dry_run;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/*
|
||||
receive the checksums for a buffer
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The sender gets checksums from the generator, calculates deltas,
|
||||
* and transmits them to the receiver. The sender process runs on the
|
||||
* machine holding the source files.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Receive the checksums for a buffer
|
||||
**/
|
||||
static struct sum_struct *receive_sums(int f)
|
||||
{
|
||||
struct sum_struct *s;
|
||||
int i;
|
||||
OFF_T offset = 0;
|
||||
|
||||
s = (struct sum_struct *)malloc(sizeof(*s));
|
||||
s = new(struct sum_struct);
|
||||
if (!s) out_of_memory("receive_sums");
|
||||
|
||||
s->count = read_int(f);
|
||||
@@ -46,23 +55,23 @@ static struct sum_struct *receive_sums(int f)
|
||||
s->sums = NULL;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d n=%d rem=%d\n",
|
||||
s->count,s->n,s->remainder);
|
||||
rprintf(FINFO,"count=%ld n=%ld rem=%ld\n",
|
||||
(long) s->count, (long) s->n, (long) s->remainder);
|
||||
|
||||
if (s->count == 0)
|
||||
return(s);
|
||||
|
||||
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
|
||||
s->sums = new_array(struct sum_buf, s->count);
|
||||
if (!s->sums) out_of_memory("receive_sums");
|
||||
|
||||
for (i=0;i<s->count;i++) {
|
||||
for (i=0; i < (int) s->count;i++) {
|
||||
s->sums[i].sum1 = read_int(f);
|
||||
read_buf(f,s->sums[i].sum2,csum_length);
|
||||
|
||||
s->sums[i].offset = offset;
|
||||
s->sums[i].i = i;
|
||||
|
||||
if (i == s->count-1 && s->remainder != 0) {
|
||||
if (i == (int) s->count-1 && s->remainder != 0) {
|
||||
s->sums[i].len = s->remainder;
|
||||
} else {
|
||||
s->sums[i].len = s->n;
|
||||
|
||||
303
socket.c
303
socket.c
@@ -33,11 +33,11 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
|
||||
|
||||
/* Establish a proxy connection on an open socket to a web roxy by
|
||||
* using the CONNECT method. */
|
||||
/**
|
||||
* Establish a proxy connection on an open socket to a web proxy by
|
||||
* using the HTTP CONNECT method.
|
||||
**/
|
||||
static int establish_proxy_connection(int fd, char *host, int port)
|
||||
{
|
||||
char buffer[1024];
|
||||
@@ -70,7 +70,7 @@ static int establish_proxy_connection(int fd, char *host, int port)
|
||||
buffer);
|
||||
return -1;
|
||||
}
|
||||
for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
|
||||
for (cp = &buffer[5]; isdigit(* (unsigned char *) cp) || (*cp == '.'); cp++)
|
||||
;
|
||||
while (*cp == ' ')
|
||||
cp++;
|
||||
@@ -124,12 +124,14 @@ int try_bind_local(int s,
|
||||
for (r = bres_all; r; r = r->ai_next) {
|
||||
if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
|
||||
continue;
|
||||
freeaddrinfo(bres_all);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* no error message; there might be some problem that allows
|
||||
* creation of the socket but not binding, perhaps if the
|
||||
* machine has no ipv6 address of this name. */
|
||||
freeaddrinfo(bres_all);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -184,6 +186,10 @@ int open_socket_out(char *host, int port, const char *bind_address,
|
||||
*cp++ = '\0';
|
||||
strcpy(portbuf, cp);
|
||||
h = buffer;
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "connection via http proxy %s port %s\n",
|
||||
h, portbuf);
|
||||
}
|
||||
} else {
|
||||
snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
h = host;
|
||||
@@ -327,7 +333,8 @@ static int open_socket_in(int type, int port, const char *bind_address,
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
freeaddrinfo(all_ai);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -367,7 +374,16 @@ int is_a_socket(int fd)
|
||||
}
|
||||
|
||||
|
||||
void start_accept_loop(int port, int (*fn)(int ))
|
||||
static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
{
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
#ifdef WNOHANG
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void start_accept_loop(int port, int (*fn)(int, int))
|
||||
{
|
||||
int s;
|
||||
extern char *bind_address;
|
||||
@@ -389,6 +405,7 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
for each incoming connection */
|
||||
while (1) {
|
||||
fd_set fds;
|
||||
pid_t pid;
|
||||
int fd;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof addr;
|
||||
@@ -411,24 +428,31 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
|
||||
if (fd == -1) continue;
|
||||
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
|
||||
/* we shouldn't have any children left hanging around
|
||||
but I have had reports that on Digital Unix zombies
|
||||
are produced, so this ensures that they are reaped */
|
||||
#ifdef WNOHANG
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||
#endif
|
||||
|
||||
if (fork()==0) {
|
||||
if ((pid = fork()) == 0) {
|
||||
int ret;
|
||||
close(s);
|
||||
/* open log file in child before possibly giving
|
||||
up privileges */
|
||||
log_open();
|
||||
_exit(fn(fd));
|
||||
ret = fn(fd, fd);
|
||||
close_all();
|
||||
_exit(ret);
|
||||
} else if (pid < 0) {
|
||||
rprintf(FERROR,
|
||||
RSYNC_NAME
|
||||
": could not create child server process: %s\n",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
/* This might have happened because we're
|
||||
* overloaded. Sleep briefly before trying to
|
||||
* accept again. */
|
||||
sleep(2);
|
||||
} else {
|
||||
/* Parent doesn't need this fd anymore. */
|
||||
close(fd);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,9 +501,9 @@ struct
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
set user socket options
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Set user socket options
|
||||
**/
|
||||
void set_socket_options(int fd, char *options)
|
||||
{
|
||||
char *tok;
|
||||
@@ -537,9 +561,9 @@ void set_socket_options(int fd, char *options)
|
||||
free(options);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
become a daemon, discarding the controlling terminal
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Become a daemon, discarding the controlling terminal
|
||||
**/
|
||||
void become_daemon(void)
|
||||
{
|
||||
int i;
|
||||
@@ -568,229 +592,16 @@ void become_daemon(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IP addr of the client as a string
|
||||
**/
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
|
||||
if (initialised) return addr_buf;
|
||||
|
||||
initialised = 1;
|
||||
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
|
||||
getnameinfo((struct sockaddr *)&ss, length,
|
||||
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
|
||||
static int get_sockaddr_family(const struct sockaddr_storage *ss)
|
||||
{
|
||||
return ((struct sockaddr *) ss)->sa_family;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This is like socketpair but uses tcp. It is used by the Samba
|
||||
* regression test code.
|
||||
*
|
||||
* The function guarantees that nobody else can attach to the socket,
|
||||
* or if they do that this function fails and the socket gets closed
|
||||
* returns 0 on success, -1 on failure the resulting file descriptors
|
||||
* are symmetrical.
|
||||
**/
|
||||
char *client_name(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len = sizeof ss;
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
static int initialised;
|
||||
|
||||
if (initialised) return name_buf;
|
||||
|
||||
strcpy(name_buf, default_name);
|
||||
initialised = 1;
|
||||
|
||||
client_sockaddr(fd, &ss, &ss_len);
|
||||
|
||||
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
|
||||
check_name(fd, &ss, ss_len, name_buf, port_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the sockaddr for the client.
|
||||
**/
|
||||
void client_sockaddr(int fd,
|
||||
struct sockaddr_storage *ss,
|
||||
socklen_t *ss_len)
|
||||
{
|
||||
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
fd, strerror(errno));
|
||||
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_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
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up a name from @p ss into @p name_buf.
|
||||
**/
|
||||
int lookup_name(int fd, const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
char *name_buf, size_t name_buf_len,
|
||||
char *port_buf, size_t port_buf_len)
|
||||
{
|
||||
int name_err;
|
||||
|
||||
/* reverse lookup */
|
||||
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
|
||||
name_buf, name_buf_len,
|
||||
port_buf, port_buf_len,
|
||||
NI_NAMEREQD | NI_NUMERICSERV);
|
||||
if (name_err != 0) {
|
||||
strcpy(name_buf, default_name);
|
||||
rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
|
||||
client_addr(fd),
|
||||
gai_strerror(name_err));
|
||||
return name_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Do a forward lookup on name_buf and make sure it corresponds to ss
|
||||
* -- otherwise we may be being spoofed. If we suspect we are, then
|
||||
* we don't abort the connection but just emit a warning. */
|
||||
int check_name(int fd,
|
||||
const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
char *name_buf,
|
||||
const char *port_buf)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
int error;
|
||||
int ss_family = get_sockaddr_family(ss);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_flags = ss_family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
|
||||
if (error) {
|
||||
rprintf(FERROR,
|
||||
RSYNC_NAME ": forward name lookup for %s:%s failed: %s\n",
|
||||
name_buf, port_buf,
|
||||
gai_strerror(error));
|
||||
strcpy(name_buf, default_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* We expect that one of the results will be the same as ss. */
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
if (res->ai_family != ss_family) {
|
||||
rprintf(FERROR,
|
||||
"check_name: response family %d != %d\n",
|
||||
res->ai_family, ss_family);
|
||||
continue;
|
||||
}
|
||||
if (res->ai_addrlen != ss_len) {
|
||||
rprintf(FERROR,
|
||||
"check_name: addrlen %d != %d\n",
|
||||
res->ai_addrlen, ss_len);
|
||||
continue;
|
||||
}
|
||||
if (memcmp(res->ai_addr, ss, res->ai_addrlen) == 0) {
|
||||
rprintf(FERROR,
|
||||
"check_name: %d bytes of address identical\n",
|
||||
res->ai_addrlen);
|
||||
break;
|
||||
} else{
|
||||
rprintf(FERROR,
|
||||
"check_name: %d bytes of address NOT identical\n",
|
||||
res->ai_addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (!res0) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": no known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
}
|
||||
if (res == NULL) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": %s is not a known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
client_addr(fd),
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
this is like socketpair but uses tcp. It is used by the Samba
|
||||
regression test code
|
||||
The function guarantees that nobody else can attach to the socket,
|
||||
or if they do that this function fails and the socket gets closed
|
||||
returns 0 on success, -1 on failure
|
||||
the resulting file descriptors are symmetrical
|
||||
******************************************************************/
|
||||
static int socketpair_tcp(int fd[2])
|
||||
{
|
||||
int listener;
|
||||
@@ -806,7 +617,7 @@ static int socketpair_tcp(int fd[2])
|
||||
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
|
||||
|
||||
memset(&sock2, 0, sizeof(sock2));
|
||||
#ifdef HAVE_SOCK_SIN_LEN
|
||||
#ifdef HAVE_SOCKADDR_LEN
|
||||
sock2.sin_len = sizeof(sock2);
|
||||
#endif
|
||||
sock2.sin_family = PF_INET;
|
||||
|
||||
52
syscall.c
52
syscall.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -16,15 +17,19 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
syscall wrappers to ensure that nothing gets done in dry_run mode
|
||||
*/
|
||||
/**
|
||||
* @file syscall.c
|
||||
*
|
||||
* Syscall wrappers to ensure that nothing gets done in dry_run mode
|
||||
* and to handle system peculiarities.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int dry_run;
|
||||
extern int read_only;
|
||||
extern int list_only;
|
||||
extern int preserve_perms;
|
||||
|
||||
#define CHECK_RO if (read_only || list_only) {errno = EROFS; return -1;}
|
||||
|
||||
@@ -80,22 +85,22 @@ int do_open(char *pathname, int flags, mode_t mode)
|
||||
if (dry_run) return -1;
|
||||
CHECK_RO
|
||||
}
|
||||
#ifdef O_BINARY
|
||||
/* for Windows */
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
/* some systems can't handle a double / */
|
||||
if (pathname[0] == '/' && pathname[1] == '/') pathname++;
|
||||
|
||||
return open(pathname, flags, mode);
|
||||
return open(pathname, flags | O_BINARY, mode);
|
||||
}
|
||||
|
||||
#if HAVE_CHMOD
|
||||
int do_chmod(const char *path, mode_t mode)
|
||||
{
|
||||
int code;
|
||||
if (dry_run) return 0;
|
||||
CHECK_RO
|
||||
return chmod(path, mode);
|
||||
code = chmod(path, mode);
|
||||
if ((code != 0) && preserve_perms)
|
||||
return code;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -106,13 +111,36 @@ int do_rename(char *fname1, char *fname2)
|
||||
return rename(fname1, fname2);
|
||||
}
|
||||
|
||||
|
||||
void trim_trailing_slashes(char *name)
|
||||
{
|
||||
int l;
|
||||
/* Some BSD systems cannot make a directory if the name
|
||||
* contains a trailing slash.
|
||||
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
|
||||
|
||||
/* Don't change empty string; and also we can't improve on
|
||||
* "/" */
|
||||
|
||||
l = strlen(name);
|
||||
while (l > 1) {
|
||||
if (name[--l] != '/')
|
||||
break;
|
||||
name[l] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int do_mkdir(char *fname, mode_t mode)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
CHECK_RO
|
||||
if (dry_run)
|
||||
return 0;
|
||||
CHECK_RO;
|
||||
trim_trailing_slashes(fname);
|
||||
return mkdir(fname, mode);
|
||||
}
|
||||
|
||||
|
||||
/* like mkstemp but forces permissions */
|
||||
int do_mkstemp(char *template, mode_t perms)
|
||||
{
|
||||
@@ -123,7 +151,7 @@ int do_mkstemp(char *template, mode_t perms)
|
||||
{
|
||||
int fd = mkstemp(template);
|
||||
if (fd == -1) return -1;
|
||||
if (fchmod(fd, perms) != 0) {
|
||||
if ((fchmod(fd, perms) != 0) && preserve_perms) {
|
||||
close(fd);
|
||||
unlink(template);
|
||||
return -1;
|
||||
|
||||
70
t_stub.c
Normal file
70
t_stub.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* @file t_stub.c
|
||||
*
|
||||
* This file contains really simple implementations for rsync global
|
||||
* functions, so that module test harnesses can run standalone.
|
||||
**/
|
||||
|
||||
int modify_window = 0;
|
||||
int module_id = -1;
|
||||
struct exclude_struct **server_exclude_list;
|
||||
|
||||
void rprintf(UNUSED(enum logcode code), const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
fprintf(stderr, "exit(%d): %s(%d)\n",
|
||||
code, file, line);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int check_exclude(UNUSED(struct exclude_struct **list), UNUSED(char *name),
|
||||
UNUSED(int name_is_dir))
|
||||
{
|
||||
/* This function doesn't really get called in this test context, so
|
||||
* just return 0. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *lp_name(UNUSED(int mod))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL lp_use_chroot(UNUSED(int mod))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *lp_path(UNUSED(int mod))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
46
t_unsafe.c
Normal file
46
t_unsafe.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Test harness for unsafe_symlink(). Not linked into @c rsync itself.
|
||||
*
|
||||
* Prints either "safe" or "unsafe" depending on the two arguments.
|
||||
* Always returns 0 unless something extraordinary happens.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int dry_run, read_only, list_only, verbose;
|
||||
int preserve_perms = 0;
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: t_unsafe LINKDEST SRCDIR\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s\n",
|
||||
unsafe_symlink(argv[1], argv[2]) ? "unsafe" : "safe");
|
||||
|
||||
return 0;
|
||||
}
|
||||
133
testhelp/maketree.py
Normal file
133
testhelp/maketree.py
Normal file
@@ -0,0 +1,133 @@
|
||||
#! /usr/bin/python2.2
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version
|
||||
# 2 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
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# Populate a tree with pseudo-randomly distributed files to test
|
||||
# rsync.
|
||||
|
||||
from __future__ import generators
|
||||
import random, string, os, os.path
|
||||
|
||||
nfiles = 10000
|
||||
depth = 5
|
||||
n_children = 20
|
||||
n_files = 20
|
||||
n_symlinks = 10
|
||||
|
||||
name_chars = string.digits + string.letters
|
||||
|
||||
abuffer = 'a' * 1024
|
||||
|
||||
def random_name_chars():
|
||||
a = ""
|
||||
for i in range(10):
|
||||
a = a + random.choice(name_chars)
|
||||
return a
|
||||
|
||||
|
||||
def generate_names():
|
||||
n = 0
|
||||
while 1:
|
||||
yield "%05d_%s" % (n, random_name_chars())
|
||||
n += 1
|
||||
|
||||
|
||||
class TreeBuilder:
|
||||
def __init__(self):
|
||||
self.n_children = 20
|
||||
self.n_files = 100
|
||||
self.total_entries = 100000 # long(1e8)
|
||||
self.actual_size = 0
|
||||
self.name_gen = generate_names()
|
||||
self.all_files = []
|
||||
self.all_dirs = []
|
||||
self.all_symlinks = []
|
||||
|
||||
|
||||
def random_size(self):
|
||||
return random.lognormvariate(4, 4)
|
||||
|
||||
|
||||
def random_symlink_target(self):
|
||||
what = random.choice(['directory', 'file', 'symlink', 'none'])
|
||||
try:
|
||||
if what == 'directory':
|
||||
return random.choice(self.all_dirs)
|
||||
elif what == 'file':
|
||||
return random.choice(self.all_files)
|
||||
elif what == 'symlink':
|
||||
return random.choice(self.all_symlinks)
|
||||
elif what == 'none':
|
||||
return self.name_gen.next()
|
||||
except IndexError:
|
||||
return self.name_gen.next()
|
||||
|
||||
|
||||
def can_continue(self):
|
||||
self.total_entries -= 1
|
||||
return self.total_entries > 0
|
||||
|
||||
|
||||
def build_tree(self, prefix, depth):
|
||||
"""Generate a breadth-first tree"""
|
||||
for count, function in [[n_files, self.make_file],
|
||||
[n_children, self.make_child_recurse],
|
||||
[n_symlinks, self.make_symlink]]:
|
||||
for i in range(count):
|
||||
if not self.can_continue():
|
||||
return
|
||||
name = os.path.join(prefix, self.name_gen.next())
|
||||
function(name, depth)
|
||||
|
||||
|
||||
def print_summary(self):
|
||||
print "total bytes: %d" % self.actual_size
|
||||
|
||||
|
||||
def make_child_recurse(self, dname, depth):
|
||||
if depth > 1:
|
||||
self.make_dir(dname)
|
||||
self.build_tree(dname, depth-1)
|
||||
|
||||
|
||||
def make_dir(self, dname, depth='ignore'):
|
||||
print "%s/" % (dname)
|
||||
os.mkdir(dname)
|
||||
self.all_dirs.append(dname)
|
||||
|
||||
|
||||
def make_symlink(self, lname, depth='ignore'):
|
||||
print "%s -> %s" % (lname, self.random_symlink_target())
|
||||
|
||||
|
||||
def make_file(self, fname, depth='ignore'):
|
||||
size = long(self.random_size())
|
||||
print "%-70s %d" % (fname, size)
|
||||
f = open(fname, 'w')
|
||||
f.truncate(size)
|
||||
self.fill_file(f, size)
|
||||
self.all_files.append(fname)
|
||||
self.actual_size += size
|
||||
|
||||
def fill_file(self, f, size):
|
||||
while size > 0:
|
||||
f.write(abuffer[:size])
|
||||
size -= len(abuffer)
|
||||
|
||||
|
||||
tb = TreeBuilder()
|
||||
tb.build_tree('/tmp/foo', 3)
|
||||
tb.print_summary()
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
echo $0 running
|
||||
|
||||
"$rsync_bin" --version || exit 1
|
||||
$RSYNC --version || exit 1
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
This directory contains automatic test cases for rsync. You can run
|
||||
them yourself if you want, preferably by doing "make check" in the
|
||||
top-level source directory. (Not implemented yet.)
|
||||
|
||||
They also run automatically on the build farm, and you can see the
|
||||
results on http://build.samba.org/. That's controlled by the file
|
||||
./runlist.
|
||||
30
testsuite/README.testsuite
Normal file
30
testsuite/README.testsuite
Normal file
@@ -0,0 +1,30 @@
|
||||
automatic testsuite for rsync -*- text -*-
|
||||
|
||||
We're trying to develop some more substantial tests to prevent rsync
|
||||
regressions. Ideally, all code changes or bug reports would come with
|
||||
an appropriate test suite.
|
||||
|
||||
You can run these tests by typing "make check" in the build directory.
|
||||
The tests will run using the rsync binary in the build directory, so
|
||||
you do not need to do "make install" first. Indeed, you probably
|
||||
should not install rsync before running the tests.
|
||||
|
||||
If you instead type "make installcheck" then the suite will test the
|
||||
rsync binary from its installed location (e.g. /usr/local/bin/rsync).
|
||||
You can use this to test a distribution build, or perhaps to run a new
|
||||
test suite against an old version of rsync. Note that in accordance
|
||||
with the GNU Standards, installcheck does not look for rsync on the
|
||||
path.
|
||||
|
||||
If the tests pass, you should see a report to that effect. Some tests
|
||||
require being root or some other precondition, and so will normally be
|
||||
checked -- look at the test scripts for more information.
|
||||
|
||||
If the tests fail, you will see rather more output. The scratch
|
||||
directory will remain in the build directory. It would be useful if
|
||||
you could include the log messages when reporting a failure.
|
||||
|
||||
These tests also run automatically on the build farm, and you can see
|
||||
the results on http://build.samba.org/.
|
||||
|
||||
|
||||
38
testsuite/chgrp.test
Normal file
38
testsuite/chgrp.test
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that rsync with -gr will preserve groups when the user running
|
||||
# the test is a member of them. Hopefully they're in at least one
|
||||
# test.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
# TODO: I guess some systems will not have 'id', and therefore we have
|
||||
# to ship or emulate it.
|
||||
mygrps="`rsync_getgroups`" || fail "Can't get groups"
|
||||
mkdir "$fromdir"
|
||||
|
||||
for g in $mygrps
|
||||
do
|
||||
name="$fromdir/foo-$g"
|
||||
date > "$name"
|
||||
chgrp "$g" "$name" || fail "Can't chgrp"
|
||||
done
|
||||
sleep 2
|
||||
|
||||
checkit "$RSYNC -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
38
testsuite/chown.test
Normal file
38
testsuite/chown.test
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that when rsync is running as root and has -a it correctly sets
|
||||
# the ownership of the destination.
|
||||
|
||||
# We don't know what users will be present on this system, so we just
|
||||
# use random numeric uids and gids.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
mkdir "$fromdir"
|
||||
name1="$fromdir/name1"
|
||||
name2="$fromdir/name2"
|
||||
echo "This is the file" > "$name1"
|
||||
echo "This is the other file" > "$name2"
|
||||
|
||||
chown 5000 "$name1" || test_skipped "Can't chown (probably need root)"
|
||||
chown 5001 "$name2" || test_skipped "Can't chown (probably need root)"
|
||||
chgrp 5002 "$name1" || test_skipped "Can't chgrp (probably need root)"
|
||||
chgrp 5003 "$name2" || test_skipped "Can't chgrp (probably need root)"
|
||||
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
31
testsuite/daemon-gzip-download.test
Normal file
31
testsuite/daemon-gzip-download.test
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# This test tries to download a tree over a compressed connection from
|
||||
# the server. This ought to exercise (exorcise?) a bug in 2.5.3.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
hands_setup
|
||||
checkit "$RSYNC -avvz localhost::test-from/ \"$TO/\"" "$FROM" "$TO"
|
||||
|
||||
25
testsuite/daemon-gzip-upload.test
Normal file
25
testsuite/daemon-gzip-upload.test
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING)
|
||||
|
||||
# We don't really want to start the server listening, because that
|
||||
# might interfere with the security or operation of the test machine.
|
||||
# Instead we use the fake-connect feature to dynamically assign a pair
|
||||
# of ports.
|
||||
|
||||
# This test tries to upload a file over a compressed connection to the
|
||||
# server. This ought to exercise (exorcise?) a bug in 2.5.3.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
hands_setup
|
||||
checkit "$RSYNC -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
$rsync_bin -v localhost::
|
||||
$RSYNC -v localhost::
|
||||
|
||||
29
testsuite/devices.test
Normal file
29
testsuite/devices.test
Normal file
@@ -0,0 +1,29 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of devices. This can only run if you're root.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
|
||||
|
||||
mkdir "$fromdir"
|
||||
mknod "$fromdir/char" c 42 69 || test_skipped "Can't create char device node unless root"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node unless root"
|
||||
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
echo "SKIP THIS FOR NOW; It's a known bug"
|
||||
exit 77
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
@@ -39,19 +36,18 @@ ln -s "$name1" "$name2" || fail "can't create symlink"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
checkit "rsync -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
# Make sure each file was only copied once...
|
||||
if [ `grep -c '^name1$' "$outfile"` != 1 ]
|
||||
then
|
||||
test_xfail "name1 was not copied exactly once"
|
||||
test_fail "name1 was not copied exactly once"
|
||||
fi
|
||||
if [ `grep -c '^name2$' "$outfile"` != 1 ]
|
||||
if [ `grep -c '^name2 -> ' "$outfile"` != 1 ]
|
||||
then
|
||||
test_xfail "name2 was not copied exactly once"
|
||||
test_fail "name2 was not copied exactly once"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
|
||||
75
testsuite/exclude.test
Normal file
75
testsuite/exclude.test
Normal file
@@ -0,0 +1,75 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2003 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of exclude/include directives.
|
||||
|
||||
# Test some of the more obscure wildcard handling of exclude/include
|
||||
# processing.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
# Build some files/dirs/links to copy
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
chkdir="$scratchdir/chk"
|
||||
|
||||
makepath "$fromdir/foo/down/to/you"
|
||||
makepath "$fromdir/bar/down/to/foo/too"
|
||||
makepath "$fromdir/mid/for/foo/and/that/is/who"
|
||||
echo kept >"$fromdir/foo/file1"
|
||||
echo removed >"$fromdir/foo/file2"
|
||||
echo keeper >"$fromdir/bar/down/to/foo/file1"
|
||||
echo gone >"$fromdir/bar/down/to/foo/file3"
|
||||
echo lost >"$fromdir/bar/down/to/foo/file4"
|
||||
echo smashed >"$fromdir/bar/down/to/foo/to"
|
||||
echo expunged >"$fromdir/mid/for/foo/extra"
|
||||
echo retained >"$fromdir/mid/for/foo/keep"
|
||||
ln -s too "$fromdir/bar/down/to/foo/sym"
|
||||
|
||||
# Setup our test exclude/include file.
|
||||
|
||||
excl="$scratchdir/exclude-from"
|
||||
cat >"$excl" <<EOF
|
||||
# If the second line of these two lines does anything, it's a bug.
|
||||
+ **/bar
|
||||
- /bar
|
||||
# This should match against the whole path, not just the name.
|
||||
+ foo**too
|
||||
# This should float at the end of the path.
|
||||
- foo/*/
|
||||
# Test some normal excludes. Competing lines are paired.
|
||||
+ t[o]/
|
||||
- to
|
||||
+ file4
|
||||
- file[2-9]
|
||||
- /mid/for/foo/extra
|
||||
EOF
|
||||
|
||||
# Create the chk dir with what we expect to be excluded
|
||||
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
|
||||
|
||||
sleep 1 # Ensures that the rm commands will tweak the directory times.
|
||||
|
||||
rm -r "$chkdir"/foo/down
|
||||
rm -r "$chkdir"/mid/for/foo/and
|
||||
rm "$chkdir"/foo/file[235-9]
|
||||
rm "$chkdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo/file[235-9]
|
||||
rm "$chkdir"/mid/for/foo/extra
|
||||
|
||||
# Un-tweak the directory times in our first (weak) exclude test (though
|
||||
# it's a good test of the --existing option).
|
||||
$RSYNC -av --existing --include='*/' --exclude='*' "$fromdir/" "$chkdir/"
|
||||
|
||||
# Now, test if rsync excludes the same files.
|
||||
|
||||
checkit "$RSYNC -avv --exclude-from=$excl \"$fromdir/\" \"$todir/\"" "$chkdir" "$todir"
|
||||
|
||||
exit 0
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) 1998,1999 Philip Hands <phil@hands.com>
|
||||
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
# Copyright (C) 1998, 1999 by Philip Hands <phil@hands.com>
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
#
|
||||
# This program is distributable under the terms of the GNU GPL (see COPYING)
|
||||
|
||||
@@ -25,6 +25,4 @@ runtest "extra data" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
|
||||
cp ${FROM}/text ${TO}/ThisShouldGo
|
||||
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
checkforlogs ${LOG}.?
|
||||
|
||||
hands_cleanup
|
||||
exit 0
|
||||
|
||||
@@ -31,7 +31,7 @@ ln "$name1" "$name2" || fail "Can't create hardlink"
|
||||
ln "$name2" "$name3" || fail "Can't create hardlink"
|
||||
cp "$name2" "$name4" || fail "Can't copy file"
|
||||
|
||||
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
|
||||
hands_setup
|
||||
|
||||
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
LONGNAME=This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
LONGDIR=$FROM/$LONGNAME/$LONGNAME/$LONGNAME
|
||||
|
||||
makepath ${LONGDIR}
|
||||
makepath $LONGDIR || test_skipped "unable to create long directory"
|
||||
touch $LONGDIR/1 || test_skipped "unable to create files in long directory"
|
||||
date > ${LONGDIR}/1
|
||||
ls -la / > ${LONGDIR}/2
|
||||
checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}
|
||||
|
||||
@@ -24,6 +24,15 @@ TO=${TMP}/to
|
||||
LOG=${TMP}/log
|
||||
RSYNC="$rsync_bin"
|
||||
|
||||
# Berkley's nice.
|
||||
PATH="$PATH:/usr/ucb"
|
||||
|
||||
if diff -u $srcdir/testsuite/rsync.fns $srcdir/testsuite/rsync.fns >/dev/null 2>&1; then
|
||||
diffopt="-u"
|
||||
else
|
||||
diffopt="-c"
|
||||
fi
|
||||
|
||||
runtest() {
|
||||
echo $ECHO_N "Test $1: $ECHO_C"
|
||||
if eval "$2"
|
||||
@@ -42,7 +51,11 @@ printmsg() {
|
||||
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | xargs $TLS
|
||||
find "$@" -print | sort | xargs "$TOOLDIR/tls"
|
||||
}
|
||||
|
||||
rsync_getgroups() {
|
||||
"$TOOLDIR/getgroups"
|
||||
}
|
||||
|
||||
|
||||
@@ -95,13 +108,6 @@ hands_setup() {
|
||||
}
|
||||
|
||||
|
||||
hands_cleanup() {
|
||||
rm -r "$TMP"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
####################
|
||||
# Many machines do not have "mkdir -p", so we have to build up long paths.
|
||||
# How boring.
|
||||
@@ -134,6 +140,11 @@ makepath () {
|
||||
# Run a test (in '$1') then compare directories $2 and $3 to see if
|
||||
# there are any difference. If there are, explain them.
|
||||
|
||||
# So normally basically $1 should be an rsync command, and $2 and $3
|
||||
# the source and destination directories. This is only good when you
|
||||
# expect to transfer the whole directory exactly as is. If some files
|
||||
# should be excluded, you might need to use something else.
|
||||
|
||||
checkit() {
|
||||
failed=
|
||||
|
||||
@@ -150,13 +161,17 @@ checkit() {
|
||||
echo "-------------"
|
||||
echo "check how the files compare with diff:"
|
||||
echo ""
|
||||
diff -cr $2 $3 || failed=YES
|
||||
for f in `cd "$2"; find . -type f -print `
|
||||
do
|
||||
diff $diffopt "$2"/"$f" "$3"/"$f" || failed=YES
|
||||
done
|
||||
|
||||
echo "-------------"
|
||||
echo "check how the directory listings compare with diff:"
|
||||
echo ""
|
||||
( cd "$2" && rsync_ls_lR . ) > ${TMP}/ls-from
|
||||
( cd "$3" && rsync_ls_lR . ) > ${TMP}/ls-to
|
||||
diff -c ${TMP}/ls-from ${TMP}/ls-to || failed=YES
|
||||
diff $diffopt ${TMP}/ls-from ${TMP}/ls-to || failed=YES
|
||||
if [ -z "${failed}" ] ; then
|
||||
return 0
|
||||
else
|
||||
@@ -165,21 +180,6 @@ checkit() {
|
||||
}
|
||||
|
||||
|
||||
# In fact, we need a more general feature of capturing all stderr/log files,
|
||||
# and dumping them if something goes wrong.
|
||||
|
||||
checkforlogs() {
|
||||
# skip it if we're under debian-test
|
||||
if test -n "${Debian}" ; then return 0 ; fi
|
||||
|
||||
if [ -f $1 -a -s $1 ] ; then
|
||||
echo "Failures have occurred. $1 follows:" >&2
|
||||
cat $1 >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
build_rsyncd_conf() {
|
||||
# Build an appropriate configuration file
|
||||
conf="$scratchdir/test-rsyncd.conf"
|
||||
@@ -197,10 +197,15 @@ use chroot = no
|
||||
hosts allow = localhost, 127.0.0.1
|
||||
log file = $logfile
|
||||
|
||||
[test-from] = $scratchdir/daemon-from/
|
||||
uid = 0
|
||||
gid = 0
|
||||
|
||||
[test-from]
|
||||
path = $FROM
|
||||
read only = yes
|
||||
|
||||
[test-to] = $scratchdir/daemon-to/
|
||||
[test-to]
|
||||
path = $TO
|
||||
read only = no
|
||||
EOF
|
||||
}
|
||||
@@ -222,6 +227,12 @@ test_fail() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
test_skipped() {
|
||||
echo "$@" >&2
|
||||
echo "$@" > "$TMP/whyskipped"
|
||||
exit 77
|
||||
}
|
||||
|
||||
# It failed, but we expected that. don't dump out error logs,
|
||||
# because most users won't want to see them. But do leave
|
||||
# the working directory around.
|
||||
@@ -230,5 +241,44 @@ test_xfail() {
|
||||
exit 78
|
||||
}
|
||||
|
||||
# be reproducible
|
||||
umask 077
|
||||
# Determine what shell command will appropriately test for links.
|
||||
ln -s foo "$scratchdir/testlink"
|
||||
for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test
|
||||
do
|
||||
for switch in -h -L
|
||||
do
|
||||
if $cmd $switch "$scratchdir/testlink" 2>/dev/null
|
||||
then
|
||||
# how nice
|
||||
TEST_SYMLINK_CMD="$cmd $switch"
|
||||
# i wonder if break 2 is portable?
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
# ok, now get rid of it
|
||||
rm "$scratchdir/testlink"
|
||||
|
||||
|
||||
if [ "x$TEST_SYMLINK_CMD" = 'x' ]
|
||||
then
|
||||
test_fail "Couldn't determine how to test for symlinks"
|
||||
else
|
||||
echo "Testing for symlinks using '$TEST_SYMLINK_CMD'"
|
||||
fi
|
||||
|
||||
|
||||
# Test whether something is a link, allowing for shell peculiarities
|
||||
is_a_link() {
|
||||
# note the variable contains the first option and therefore is not quoted
|
||||
$TEST_SYMLINK_CMD "$1"
|
||||
}
|
||||
|
||||
|
||||
# We need to set the umask to be reproducible. Note also that when we
|
||||
# do some daemon tests as root, we will setuid() and therefore the
|
||||
# directory has to be writable by the nobody user in some cases. The
|
||||
# best thing is probably to explicitly chmod those directories after
|
||||
# creation.
|
||||
|
||||
umask 022
|
||||
|
||||
@@ -12,22 +12,32 @@
|
||||
|
||||
if [ "x$rsync_enable_ssh_tests" != xyes ]
|
||||
then
|
||||
echo "Skipping SSH tests because \$rsync_enable_ssh_tests is not set"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because \$rsync_enable_ssh_tests is not set"
|
||||
fi
|
||||
|
||||
if ! type ssh >/dev/null ; then
|
||||
echo "Skipping SSH tests because ssh is not in the path"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because ssh is not in the path"
|
||||
fi
|
||||
|
||||
if ! [ "`ssh -o'BatchMode yes' localhost echo yes`" = "yes" ]; then
|
||||
echo "Skipping SSH tests because ssh conection to localhost not authorised"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because ssh conection to localhost not authorised"
|
||||
fi
|
||||
|
||||
# Added by Steve Bonds Feb 2 2003
|
||||
# Without this, there are no files in the ${FROM} directory, so rsync has
|
||||
# nothing to do.
|
||||
hands_setup
|
||||
|
||||
runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
# Added by Steve Bonds Feb 2 2003
|
||||
# I assumed that "F1" was intended to hold a single file for testing if
|
||||
# rsync could detect a renamed file over ssh. Without this line below
|
||||
# it was unset so the "mv" tried to move a parent directory into a
|
||||
# subdirectory of itself. There is probably a better way of pulling out
|
||||
# a sample file to rename.
|
||||
F1=`ls ${TO} | head -5 | tail -1`
|
||||
|
||||
mv ${TO}/${F1} ${TO}/ThisShouldGo
|
||||
|
||||
runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user