Compare commits
758 Commits
curl-7_17_
...
curl-7_18_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdd731177e | ||
|
|
abd1c526f0 | ||
|
|
a050a5fa9b | ||
|
|
7f7b643c0d | ||
|
|
cd2814725a | ||
|
|
342fa1cf06 | ||
|
|
b425e851fb | ||
|
|
7c6a026230 | ||
|
|
2c9763da3e | ||
|
|
a782c3e368 | ||
|
|
95bd901efe | ||
|
|
98c9a5b7f6 | ||
|
|
516192e7f2 | ||
|
|
c37cdbe2cf | ||
|
|
c0a30b04c2 | ||
|
|
86cbb23282 | ||
|
|
e9a460411f | ||
|
|
a57098ea9b | ||
|
|
6f3166c15b | ||
|
|
1380c9af9f | ||
|
|
942daece00 | ||
|
|
040a4443a1 | ||
|
|
641d5c4111 | ||
|
|
ad4a9955c5 | ||
|
|
553ed99e3b | ||
|
|
b74cdee6ab | ||
|
|
f3c0afa5b8 | ||
|
|
a69ba639ba | ||
|
|
fc9ad03e66 | ||
|
|
b9d66dca51 | ||
|
|
ecf1c6ca5d | ||
|
|
9b48991ebd | ||
|
|
7a8a20416f | ||
|
|
458925ae0b | ||
|
|
e44dc92197 | ||
|
|
9bb51d767e | ||
|
|
82e095a275 | ||
|
|
0e40261a11 | ||
|
|
8e9e33ae52 | ||
|
|
40e1a016f9 | ||
|
|
1cf559492a | ||
|
|
4957a838ef | ||
|
|
91aeebed26 | ||
|
|
b16ea66cec | ||
|
|
80cec5a62a | ||
|
|
6c2c281a7e | ||
|
|
0836893335 | ||
|
|
590f0358d8 | ||
|
|
115446be37 | ||
|
|
d83606ee3a | ||
|
|
8f4fda1d6f | ||
|
|
18cbb4d7d6 | ||
|
|
22e84d92b7 | ||
|
|
3d74649908 | ||
|
|
ed63d9d4de | ||
|
|
8adc7038fe | ||
|
|
b12fef3f31 | ||
|
|
6cc8df95dd | ||
|
|
f105e23444 | ||
|
|
7513d29a48 | ||
|
|
97a41f3646 | ||
|
|
84de433e62 | ||
|
|
724ad15dad | ||
|
|
79aa6c841e | ||
|
|
058e764af8 | ||
|
|
0d09f342c4 | ||
|
|
9682c2037e | ||
|
|
74241e7d85 | ||
|
|
3154f04fb9 | ||
|
|
6982ed4db7 | ||
|
|
9dd3e4d481 | ||
|
|
1d95109ffa | ||
|
|
e9bb7b7712 | ||
|
|
5e9c564883 | ||
|
|
3bb4602227 | ||
|
|
064eebeaf1 | ||
|
|
4ae644e427 | ||
|
|
d208e56b16 | ||
|
|
e6170eb20d | ||
|
|
2c80bcbc81 | ||
|
|
b60dbfa9e9 | ||
|
|
9019fc5671 | ||
|
|
5db0f70491 | ||
|
|
53a549000c | ||
|
|
55700cb01f | ||
|
|
f9a6062081 | ||
|
|
0cae201044 | ||
|
|
9df37b93df | ||
|
|
7b5c86033a | ||
|
|
ade0890746 | ||
|
|
7a5596bf02 | ||
|
|
d2125cf501 | ||
|
|
c9eb41c056 | ||
|
|
0d722204c3 | ||
|
|
e829d5643f | ||
|
|
1093287494 | ||
|
|
6398f71cc4 | ||
|
|
e2b50b203d | ||
|
|
ab0de23d83 | ||
|
|
ec54fbd9ed | ||
|
|
074bd2a19b | ||
|
|
fb23b85770 | ||
|
|
3458ce9ae5 | ||
|
|
ba3e7a8656 | ||
|
|
240bae4eb2 | ||
|
|
4180ca7638 | ||
|
|
0e73361a06 | ||
|
|
23547fa2a0 | ||
|
|
550d6f74b9 | ||
|
|
f7b71c2abe | ||
|
|
0da90b5d91 | ||
|
|
f20c94ced9 | ||
|
|
3e635a2334 | ||
|
|
e78652d850 | ||
|
|
48918c3047 | ||
|
|
dc42d6fb8d | ||
|
|
d2ad98d8c5 | ||
|
|
d25aab2704 | ||
|
|
cfaf88aab4 | ||
|
|
ecc75be6f3 | ||
|
|
13ebf61850 | ||
|
|
b3fafe9b3a | ||
|
|
c66943bd89 | ||
|
|
11fae450fa | ||
|
|
cf9259dd92 | ||
|
|
6634e3c3a3 | ||
|
|
533ae704a1 | ||
|
|
fcc320ee40 | ||
|
|
dc9fe9c361 | ||
|
|
75c369dcca | ||
|
|
019f6a1926 | ||
|
|
44fba11b34 | ||
|
|
df07c87b89 | ||
|
|
8f9e0357dd | ||
|
|
736af32b49 | ||
|
|
6942d313ff | ||
|
|
940c075bd8 | ||
|
|
08e5c0812f | ||
|
|
a8c71961e0 | ||
|
|
d6f47cc60c | ||
|
|
63d595a047 | ||
|
|
15e56c3284 | ||
|
|
fc1443dcfc | ||
|
|
59e3651af3 | ||
|
|
4c841a1f0c | ||
|
|
339ebdf08b | ||
|
|
f01d324c83 | ||
|
|
405e192b8c | ||
|
|
1a340de0e5 | ||
|
|
05c191199d | ||
|
|
1fd7085ef1 | ||
|
|
c3a7a757f7 | ||
|
|
dca46e6470 | ||
|
|
7edd13822c | ||
|
|
a2bff51ede | ||
|
|
5dc1240c49 | ||
|
|
c764331dd9 | ||
|
|
586444b6b8 | ||
|
|
ce1649564c | ||
|
|
d76a74cc5e | ||
|
|
1b701c746f | ||
|
|
15bf168527 | ||
|
|
20e9fc73e2 | ||
|
|
bad6410d08 | ||
|
|
fecb67b246 | ||
|
|
2c0956200f | ||
|
|
acd9d72466 | ||
|
|
cd63a461d7 | ||
|
|
7bd098f670 | ||
|
|
4b5c504bd4 | ||
|
|
ffae4f6b48 | ||
|
|
454e840590 | ||
|
|
ed0a413711 | ||
|
|
ff812ccdc9 | ||
|
|
03bbf4de48 | ||
|
|
a62e155ca4 | ||
|
|
b620e62f0f | ||
|
|
b3186dee17 | ||
|
|
ea3f63281c | ||
|
|
7b9435890d | ||
|
|
1bfbd25027 | ||
|
|
ceb5a8ca7b | ||
|
|
ddc98c6fc9 | ||
|
|
ff6ff66e50 | ||
|
|
a7b98f5f6b | ||
|
|
6bae091c1b | ||
|
|
33d68653f0 | ||
|
|
267836e83c | ||
|
|
87fdfe770d | ||
|
|
8fca5c2e69 | ||
|
|
5f2055729e | ||
|
|
c6df788866 | ||
|
|
e67b2524d1 | ||
|
|
d7bcc26179 | ||
|
|
69e540dfa6 | ||
|
|
2198869eb1 | ||
|
|
fb07259e0d | ||
|
|
9d28a0252c | ||
|
|
d54c14ccf9 | ||
|
|
41def4be6e | ||
|
|
2d38d0d515 | ||
|
|
e796c79d18 | ||
|
|
c93ba48da2 | ||
|
|
e322513698 | ||
|
|
6fa72e6417 | ||
|
|
c914e6ea5d | ||
|
|
79cb74f03a | ||
|
|
34cf35051a | ||
|
|
9bd28a021f | ||
|
|
5ee3f41e0d | ||
|
|
64e88ff6a7 | ||
|
|
acd7c94598 | ||
|
|
bdb2beb8e4 | ||
|
|
727e23322f | ||
|
|
ef0ed9b720 | ||
|
|
a674654f83 | ||
|
|
3caeb0a91f | ||
|
|
a4eddf0d0d | ||
|
|
fcf9029179 | ||
|
|
e40327ba00 | ||
|
|
bdd0e3d3f5 | ||
|
|
e9490fdbd9 | ||
|
|
bd40b3ff3f | ||
|
|
8c66811e09 | ||
|
|
daadcfd1de | ||
|
|
62df0ff025 | ||
|
|
01d95b56a0 | ||
|
|
f6adae8d35 | ||
|
|
bcaadb4284 | ||
|
|
8d963aa0e2 | ||
|
|
0530b0a5ca | ||
|
|
5396121595 | ||
|
|
bcfc7d90d1 | ||
|
|
47246eb401 | ||
|
|
3620e71010 | ||
|
|
c522f349fe | ||
|
|
6893fcaa9b | ||
|
|
301ae1ae1b | ||
|
|
ddaa78f08b | ||
|
|
3d55877764 | ||
|
|
3ee32d7920 | ||
|
|
b3de497d83 | ||
|
|
ed6466d176 | ||
|
|
991505e077 | ||
|
|
56f17d2c9f | ||
|
|
19ae96f4d0 | ||
|
|
53108806af | ||
|
|
1d620a3df4 | ||
|
|
69f685056d | ||
|
|
9c7d4394f9 | ||
|
|
bcc3c9279a | ||
|
|
5d63404966 | ||
|
|
a8ae8087c4 | ||
|
|
502da27d65 | ||
|
|
4ab8ebb232 | ||
|
|
f866af912d | ||
|
|
4f00a8db73 | ||
|
|
5004529685 | ||
|
|
2b63eb8511 | ||
|
|
f09fe4b49f | ||
|
|
22c76df44d | ||
|
|
35be09cf58 | ||
|
|
3564aec388 | ||
|
|
a042090467 | ||
|
|
148d727525 | ||
|
|
08adf67969 | ||
|
|
e2c817731a | ||
|
|
8df7e0bdba | ||
|
|
14ff7e75e0 | ||
|
|
d270d6518a | ||
|
|
18faa50940 | ||
|
|
0ce484eed9 | ||
|
|
bce5ae9a07 | ||
|
|
15f832d1c2 | ||
|
|
c249a8aa1b | ||
|
|
fc794ae012 | ||
|
|
07227e8089 | ||
|
|
32cc75d6cb | ||
|
|
1c0a19ad53 | ||
|
|
de23b98522 | ||
|
|
5e1c9e90d9 | ||
|
|
59b4bdf78d | ||
|
|
34d02d1969 | ||
|
|
2408b236ca | ||
|
|
4acd437952 | ||
|
|
314f62958d | ||
|
|
c616d56e96 | ||
|
|
f111c9edae | ||
|
|
7138296633 | ||
|
|
195e94c0fa | ||
|
|
cadd08f36a | ||
|
|
7306b7829b | ||
|
|
423309541a | ||
|
|
9c6533d287 | ||
|
|
b430576436 | ||
|
|
65008a4e55 | ||
|
|
3df484088f | ||
|
|
2912189875 | ||
|
|
fcb2595ed6 | ||
|
|
0878af3ec0 | ||
|
|
fe0d7aee49 | ||
|
|
2e42b0a252 | ||
|
|
fcc485092a | ||
|
|
a4945fe687 | ||
|
|
88d89b2177 | ||
|
|
61a2d5ea75 | ||
|
|
c479c64333 | ||
|
|
7a2177dc42 | ||
|
|
bf6e2f28ba | ||
|
|
f5da1e5484 | ||
|
|
fd8d862c37 | ||
|
|
083d3190e5 | ||
|
|
6787d1ed35 | ||
|
|
d9023c16ab | ||
|
|
193d33fd4a | ||
|
|
a46b40b7fd | ||
|
|
0b9b8acb08 | ||
|
|
bf98b635cd | ||
|
|
7795eb6db8 | ||
|
|
31674559d3 | ||
|
|
04e4d9a0b3 | ||
|
|
f277124a0f | ||
|
|
6adf5880f5 | ||
|
|
4e8c4fc80b | ||
|
|
fc1d1ea934 | ||
|
|
9cd30c2012 | ||
|
|
d639ed1aaf | ||
|
|
c3a02f5407 | ||
|
|
674845f239 | ||
|
|
07a1857d59 | ||
|
|
f4ffa85f60 | ||
|
|
bcd7d03b3b | ||
|
|
82c9379b6c | ||
|
|
c1730dc50a | ||
|
|
20695098c8 | ||
|
|
ee52ae001c | ||
|
|
26115aac5d | ||
|
|
ca6b27aed2 | ||
|
|
4fabe22173 | ||
|
|
7b1a22147e | ||
|
|
dc24540ed1 | ||
|
|
92eae30f4d | ||
|
|
79ef08f631 | ||
|
|
e3c5f8374b | ||
|
|
6dc68b4193 | ||
|
|
afab4d888f | ||
|
|
c751dfd65d | ||
|
|
dbca1347f1 | ||
|
|
3b6315ce1f | ||
|
|
3c1db5f250 | ||
|
|
562e9b7bf3 | ||
|
|
a83e72692f | ||
|
|
bd99a7dc8c | ||
|
|
db2d52a792 | ||
|
|
24602edc17 | ||
|
|
b0b40d9a00 | ||
|
|
71b105ceb1 | ||
|
|
ccb4956145 | ||
|
|
3d09cb0a88 | ||
|
|
a03c2d825b | ||
|
|
06fb242e23 | ||
|
|
a086952244 | ||
|
|
2b314064ae | ||
|
|
439990be88 | ||
|
|
41d8186c7e | ||
|
|
6e9276229f | ||
|
|
636f5eb882 | ||
|
|
963ef5414c | ||
|
|
975812d246 | ||
|
|
089668ec73 | ||
|
|
cc0ce38acc | ||
|
|
8cdff55b80 | ||
|
|
662bee7193 | ||
|
|
f8172f85b1 | ||
|
|
7d3ea12b62 | ||
|
|
59dc9085d1 | ||
|
|
4e4f33a297 | ||
|
|
8fa599215b | ||
|
|
31e2409d6b | ||
|
|
15c304225f | ||
|
|
e1998e3b58 | ||
|
|
5c447f2499 | ||
|
|
9d0ffb9cc6 | ||
|
|
2be50baf97 | ||
|
|
a1772ca406 | ||
|
|
30eda92a53 | ||
|
|
1f058f1014 | ||
|
|
84d0477cb9 | ||
|
|
1c93e75375 | ||
|
|
380ed8bebf | ||
|
|
98e8978857 | ||
|
|
56ddfbea6e | ||
|
|
45a2240ead | ||
|
|
f75ba55b51 | ||
|
|
46e6115d72 | ||
|
|
800a72878a | ||
|
|
649f7b7fd3 | ||
|
|
c1b734a3e1 | ||
|
|
cf806748ec | ||
|
|
b28dc011e0 | ||
|
|
ee4fef3768 | ||
|
|
058a023fae | ||
|
|
0c367fef94 | ||
|
|
a418d290f1 | ||
|
|
08cb30801c | ||
|
|
788de4f7ba | ||
|
|
ebce0a16f6 | ||
|
|
df546bd58c | ||
|
|
05221e9056 | ||
|
|
e963714de6 | ||
|
|
dc11239ff1 | ||
|
|
d59841618d | ||
|
|
8d3964782a | ||
|
|
162c039e9d | ||
|
|
13648f8ccd | ||
|
|
5b809a3104 | ||
|
|
3daa54d636 | ||
|
|
8f1829d1d2 | ||
|
|
6efb6addf2 | ||
|
|
d789097af0 | ||
|
|
4bd2d49ca1 | ||
|
|
ecfede9b3c | ||
|
|
cb04619de2 | ||
|
|
61e2e86aef | ||
|
|
9b86eecb94 | ||
|
|
35212da048 | ||
|
|
755e743cdd | ||
|
|
1a323390ec | ||
|
|
23559fd118 | ||
|
|
d994a873a4 | ||
|
|
b6575ce0b0 | ||
|
|
e2b2a84497 | ||
|
|
86956c2261 | ||
|
|
ef6dfdc7fd | ||
|
|
f3b85ef79d | ||
|
|
1d7e42ee9f | ||
|
|
6dfb5b4e1f | ||
|
|
930085751c | ||
|
|
258c4686b2 | ||
|
|
600d0b1303 | ||
|
|
2f928797cf | ||
|
|
f3f06e823c | ||
|
|
58292f49c5 | ||
|
|
5376d1047c | ||
|
|
1746b57161 | ||
|
|
0561bffab3 | ||
|
|
968e943eac | ||
|
|
5be00c95a7 | ||
|
|
c80b9c3778 | ||
|
|
536f98a766 | ||
|
|
c4e5613a7d | ||
|
|
bff962398d | ||
|
|
2b15823dab | ||
|
|
59dcc7e191 | ||
|
|
ea3fe98867 | ||
|
|
4f05613fbb | ||
|
|
22e52ddd6e | ||
|
|
1125d45397 | ||
|
|
44d408204a | ||
|
|
50feea3eef | ||
|
|
ca95f58ac0 | ||
|
|
ed636cbe44 | ||
|
|
738e4f410c | ||
|
|
4e731a0189 | ||
|
|
5cf6a539fe | ||
|
|
17fde12fb8 | ||
|
|
5c8b973d4f | ||
|
|
b22e03b2b2 | ||
|
|
a2926ebe7c | ||
|
|
c508d70258 | ||
|
|
f5971f54ff | ||
|
|
c5b16d4468 | ||
|
|
3c71a1bab7 | ||
|
|
3ec322685b | ||
|
|
9a39839a43 | ||
|
|
e87c996fe0 | ||
|
|
32195c673d | ||
|
|
b99a61c5b0 | ||
|
|
c960cd41e8 | ||
|
|
a29471d0f7 | ||
|
|
ba6f20a244 | ||
|
|
61572a1f97 | ||
|
|
dee3844f13 | ||
|
|
cbd1a77ec2 | ||
|
|
33f7ac06c3 | ||
|
|
70f10f1ac9 | ||
|
|
775b60fa09 | ||
|
|
66e4d391d3 | ||
|
|
caf880be18 | ||
|
|
c8355c27e9 | ||
|
|
c2d7e2ae17 | ||
|
|
98ecad0da6 | ||
|
|
bbc4e05434 | ||
|
|
ad6e28073c | ||
|
|
af29dcbafb | ||
|
|
b9a7f4e502 | ||
|
|
51009a40b4 | ||
|
|
2ec8f77f21 | ||
|
|
7f62028d66 | ||
|
|
d34fe06fb0 | ||
|
|
2f3d520571 | ||
|
|
48dd0c5673 | ||
|
|
8be493296d | ||
|
|
6f33531861 | ||
|
|
16897354bc | ||
|
|
823a0454a6 | ||
|
|
6790c559af | ||
|
|
c56c4a0a47 | ||
|
|
45064c5778 | ||
|
|
7aba59f577 | ||
|
|
59b05ac383 | ||
|
|
9b15f1be26 | ||
|
|
38cd2d781f | ||
|
|
2f285b3f16 | ||
|
|
57d2fb41d0 | ||
|
|
0f77fe55b6 | ||
|
|
68ee002ad0 | ||
|
|
1fc3b18592 | ||
|
|
5a5287ef2a | ||
|
|
30c85c327b | ||
|
|
ed3cc86390 | ||
|
|
e5f1499f62 | ||
|
|
848f40fd65 | ||
|
|
5adf53dc01 | ||
|
|
15feb8217f | ||
|
|
59dccb34b0 | ||
|
|
e8057241c6 | ||
|
|
d3ee83747c | ||
|
|
3f55ed0ef7 | ||
|
|
f9cfef3599 | ||
|
|
07dbfa25a0 | ||
|
|
1d49c04545 | ||
|
|
faaaf62655 | ||
|
|
43885493ea | ||
|
|
1230422181 | ||
|
|
6a17cae4f6 | ||
|
|
1eac702c1a | ||
|
|
4b96ac504c | ||
|
|
0678a51d3b | ||
|
|
b7dd186d36 | ||
|
|
26c1c8b2ad | ||
|
|
824aa5f918 | ||
|
|
ca67dcbc05 | ||
|
|
9dbc2c827d | ||
|
|
91e27ce755 | ||
|
|
65ed696625 | ||
|
|
3e3eaaada7 | ||
|
|
8997d258f7 | ||
|
|
a3f958aaaa | ||
|
|
38649d1362 | ||
|
|
4f00a02ba3 | ||
|
|
edef367e9c | ||
|
|
08c5e2a194 | ||
|
|
c67c54d4b3 | ||
|
|
23b05e8473 | ||
|
|
949ff9715a | ||
|
|
b9a305983f | ||
|
|
8e7da9464a | ||
|
|
e550df675a | ||
|
|
f614fe4946 | ||
|
|
e6ad066ed1 | ||
|
|
5b358603bd | ||
|
|
3910a61b61 | ||
|
|
45d9772667 | ||
|
|
268eebca01 | ||
|
|
1056dc9a26 | ||
|
|
053654dc4d | ||
|
|
7fe89c5d29 | ||
|
|
5c8fc7dce9 | ||
|
|
e8d3710aff | ||
|
|
d0fe681a28 | ||
|
|
9a70a6d0c0 | ||
|
|
ee19b44fe0 | ||
|
|
8f0bef2fa0 | ||
|
|
33ddeb6dcc | ||
|
|
e0dc7d6fc8 | ||
|
|
8f5909b664 | ||
|
|
bef2e7f2ff | ||
|
|
8cfb0e26bb | ||
|
|
0164f0cf81 | ||
|
|
420ea83ef3 | ||
|
|
223e470e93 | ||
|
|
e7387f7557 | ||
|
|
582bad89ef | ||
|
|
92433e596b | ||
|
|
5360f88393 | ||
|
|
949073d448 | ||
|
|
85877dae9a | ||
|
|
c6ef31955a | ||
|
|
92aaff009d | ||
|
|
65ba6e3337 | ||
|
|
fbb5518ab6 | ||
|
|
a83b5d1b67 | ||
|
|
add90abfa4 | ||
|
|
a005243908 | ||
|
|
001a2d9b67 | ||
|
|
95446f694b | ||
|
|
4db954f802 | ||
|
|
a171f60bf7 | ||
|
|
887e8f9265 | ||
|
|
07625fe243 | ||
|
|
61ffcd7815 | ||
|
|
a9f47b9364 | ||
|
|
7831c1ae44 | ||
|
|
5ce3eb066e | ||
|
|
07b6e7363d | ||
|
|
2741f97a69 | ||
|
|
d7fbe07ee2 | ||
|
|
2fce1f3e97 | ||
|
|
d09bac137a | ||
|
|
43e8f00861 | ||
|
|
3337be81c8 | ||
|
|
0cc9122093 | ||
|
|
54bcde0a14 | ||
|
|
660c86ce95 | ||
|
|
50b3545ada | ||
|
|
baac8065cf | ||
|
|
257e38d5c5 | ||
|
|
fc70b2f916 | ||
|
|
33a8e6c30c | ||
|
|
3c875e0112 | ||
|
|
59136ece19 | ||
|
|
08fd1829e0 | ||
|
|
43a4604639 | ||
|
|
83f385acf3 | ||
|
|
606af3024b | ||
|
|
4449bd9b4d | ||
|
|
bffa835573 | ||
|
|
6dd6b4d1fa | ||
|
|
67d94514b0 | ||
|
|
91b38857ef | ||
|
|
6d5f899761 | ||
|
|
77a3e3c7f7 | ||
|
|
81249965f7 | ||
|
|
45c6db9ac4 | ||
|
|
06be8bc389 | ||
|
|
0ac5fd354b | ||
|
|
a11c8a6ea0 | ||
|
|
2858935187 | ||
|
|
43b10339ab | ||
|
|
3f3a38f9c6 | ||
|
|
4bf28cb904 | ||
|
|
1abde9009a | ||
|
|
db85a941d0 | ||
|
|
1bfb0fc5da | ||
|
|
ce1cfcb7a6 | ||
|
|
ce81cd21d3 | ||
|
|
51c6a5d43b | ||
|
|
15b8da1980 | ||
|
|
c1c257d19a | ||
|
|
08b9f73219 | ||
|
|
94162d62ac | ||
|
|
059707be32 | ||
|
|
048bfeaaef | ||
|
|
a137109a0c | ||
|
|
17c01d21a9 | ||
|
|
f5cad68d22 | ||
|
|
119364741e | ||
|
|
8d1239c091 | ||
|
|
30a39fe877 | ||
|
|
0489081d3f | ||
|
|
19c8da85d8 | ||
|
|
b03abddb28 | ||
|
|
ccf083e26d | ||
|
|
dbd4abf0ff | ||
|
|
9ca2644429 | ||
|
|
ec08e2f9f2 | ||
|
|
38dd0ede9d | ||
|
|
62c264bcdb | ||
|
|
b108c664ac | ||
|
|
64db60397b | ||
|
|
d243908a01 | ||
|
|
c145fbea49 | ||
|
|
84fcff79f4 | ||
|
|
f58ba5ab1c | ||
|
|
2694b970e8 | ||
|
|
23f5d145ec | ||
|
|
b01ab65225 | ||
|
|
7a7f490efa | ||
|
|
95c15fce0c | ||
|
|
c788efffd4 | ||
|
|
c1a475e708 | ||
|
|
d0de9663e2 | ||
|
|
d6dd848523 | ||
|
|
9fc66e4dd9 | ||
|
|
6ecea9453b | ||
|
|
2c105af910 | ||
|
|
bb667c8ac6 | ||
|
|
8179743cee | ||
|
|
3d59a3855a | ||
|
|
8388366849 | ||
|
|
ef3b425b11 | ||
|
|
026d93b4f6 | ||
|
|
36710c4586 | ||
|
|
63ac6156aa | ||
|
|
08a70d117c | ||
|
|
6ce589c3ee | ||
|
|
d426c20c0a | ||
|
|
54ca7d8cb2 | ||
|
|
0819c3a8cf | ||
|
|
ad05b22de3 | ||
|
|
9fc8800b6d | ||
|
|
a4d6611d26 | ||
|
|
015fc6aa17 | ||
|
|
a739b9bc45 | ||
|
|
0bd2d54814 | ||
|
|
16b95fc773 | ||
|
|
9c5cd6c413 | ||
|
|
9b55056423 | ||
|
|
fd4cf78f36 | ||
|
|
a6315359d7 | ||
|
|
966130132f | ||
|
|
a19de6e9ac | ||
|
|
bdfeaa0f95 | ||
|
|
c478200766 | ||
|
|
775f86cb5a | ||
|
|
db1c92ceac | ||
|
|
0f4664d27f | ||
|
|
0f89a2e639 | ||
|
|
05b26e7566 | ||
|
|
6c511abf43 | ||
|
|
bb6d0771c2 | ||
|
|
75f6c36e51 | ||
|
|
015d5869d7 | ||
|
|
4686adb433 | ||
|
|
785a4899f5 | ||
|
|
da62aff6bb | ||
|
|
322308e298 | ||
|
|
b53e326828 | ||
|
|
0885d787ab | ||
|
|
2620d78e94 | ||
|
|
8c3f40ee32 | ||
|
|
b1aafbd957 | ||
|
|
45fd6685bd | ||
|
|
0159636373 | ||
|
|
7ac7c119be | ||
|
|
4f067b1d1c | ||
|
|
ae60745e3e | ||
|
|
7f496d8c3f | ||
|
|
048c74f2fa | ||
|
|
0ed57d370d | ||
|
|
551abba277 | ||
|
|
9b11a84e74 | ||
|
|
26f8de459a | ||
|
|
ceff98fd49 | ||
|
|
e04151ed76 | ||
|
|
cdb2552424 | ||
|
|
b41e65a8e3 | ||
|
|
be8c219ec2 | ||
|
|
099c011059 | ||
|
|
245a780711 | ||
|
|
05e4a3026d | ||
|
|
39a416f12a | ||
|
|
9b23b31071 | ||
|
|
8412d1e493 | ||
|
|
2ee41a5ffc | ||
|
|
a18f599482 | ||
|
|
6d27647b61 |
923
CHANGES
923
CHANGES
@@ -6,6 +6,929 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Version 7.18.1 (30 March 2008)
|
||||||
|
|
||||||
|
Daniel Stenberg (28 Mar 2008)
|
||||||
|
- Stephen Collyer pointed out that configure --with-libssh2 without a given
|
||||||
|
path didn't work properly.
|
||||||
|
|
||||||
|
Daniel Stenberg (27 Mar 2008)
|
||||||
|
- As found out and reported by Dan Petitt, libcurl didn't show progress/call
|
||||||
|
the progress callback for the first (potentially huge) piece of body data
|
||||||
|
sent together with the POST request headers in the initial send().
|
||||||
|
|
||||||
|
Daniel Stenberg (25 Mar 2008)
|
||||||
|
- Made setting the CURLOPT_SSL_CTX_FUNCTION option return a failure in case
|
||||||
|
libcurl wasn't built to use OpenSSL as that is a prerequisite for this
|
||||||
|
option to function!
|
||||||
|
|
||||||
|
Daniel Stenberg (22 Mar 2008)
|
||||||
|
- Fixed the problem with doing a zero byte SCP transfer, verified with test
|
||||||
|
case 617 (which was added by Daniel Fandrich 5 Mar 2008).
|
||||||
|
|
||||||
|
Daniel Fandrich (20 Mar 2008)
|
||||||
|
- Fixed a problem where curl-config --protocols could erroneously show LDAPS
|
||||||
|
support when curl didn't even have regular LDAP support. It looks like
|
||||||
|
this could happen when the --enable-ldaps configure switch is given but
|
||||||
|
configure couldn't find the LDAP headers or libraries.
|
||||||
|
|
||||||
|
Michal Marek (20 Mar 2008)
|
||||||
|
- Added --with-ca-path=DIRECTORY configure option to use an openSSL CApath by
|
||||||
|
default instead of a ca bundle. The configure script will also look for a
|
||||||
|
ca path if no ca bundle is found and no option given.
|
||||||
|
|
||||||
|
- Fixed detection of previously installed curl-ca-bundle.crt
|
||||||
|
|
||||||
|
Daniel Fandrich (18 Mar 2008)
|
||||||
|
- Added test 626 to reproduce an infinite loop when given an invalid
|
||||||
|
SFTP quote command reported by Vincent Le Normand, and fixed it.
|
||||||
|
|
||||||
|
Michal Marek (18 Mar 2008)
|
||||||
|
- Added curl_easy_getinfo typechecker.
|
||||||
|
|
||||||
|
- Added macros for curl_share_setopt and curl_multi_setopt to check at least
|
||||||
|
the correct number of arguments.
|
||||||
|
|
||||||
|
Daniel Fandrich (13 Mar 2008)
|
||||||
|
- Added tests 622-625 to test SFTP/SCP uploads. Test 625 was an attempt to
|
||||||
|
reproduce the --ftp-create-dirs problem reported by Brian Ulm, but that
|
||||||
|
seems to need a call curl_easy_reset() which this test case doesn't do.
|
||||||
|
|
||||||
|
Daniel Stenberg (13 Mar 2008)
|
||||||
|
- Brian Ulm figured out that if you did an SFTP upload with
|
||||||
|
CURLOPT_FTP_CREATE_MISSING_DIRS to create a directory, and then re-used the
|
||||||
|
handle and uploaded another file to another directory that needed to be
|
||||||
|
created, the second upload would fail. Another case of a state variable that
|
||||||
|
wasn't properly reset between requests.
|
||||||
|
|
||||||
|
- I rewrote the 100-continue code to use a single state variable instead of
|
||||||
|
the previous two ones. I think it made the logic somewhat clearer.
|
||||||
|
|
||||||
|
Daniel Stenberg (11 Mar 2008)
|
||||||
|
- Dmitry Popov filed bug report #1911069
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1911069) that identified a race
|
||||||
|
condition in the name resolver code when the DNS cache is shared between
|
||||||
|
multiple easy handles, each running in simultaneous threads that could cause
|
||||||
|
crashes.
|
||||||
|
|
||||||
|
- Added a macro for curl_easy_setopt() that accepts three arguments and simply
|
||||||
|
does nothing with them, just to make sure libcurl users always use three
|
||||||
|
arguments to this function. Due to its use of ... for the third argument, it
|
||||||
|
is otherwise hard to detect abuse.
|
||||||
|
|
||||||
|
Michal Marek (11 Mar 2008)
|
||||||
|
- Added a type checking macro for curl_easy_setopt(), needs gcc-4.3 and only
|
||||||
|
works in C mode atm (http://curl.haxx.se/mail/lib-2008-02/0267.html ,
|
||||||
|
http://curl.haxx.se/mail/lib-2008-02/0292.html )
|
||||||
|
|
||||||
|
Daniel Fandrich (10 Mar 2008)
|
||||||
|
- Added tests 618-621 to test SFTP/SCP transfers of more than one file
|
||||||
|
(test 620 tests the just-fixed problem reported by Brian Ulm).
|
||||||
|
|
||||||
|
Daniel Stenberg (9 Mar 2008)
|
||||||
|
- Brian Ulm reported a crash when doing a second SFTP transfer on a re-used
|
||||||
|
easy handle if curl_easy_reset() was used between them. I fixed it and Brian
|
||||||
|
verified that it cured his problem.
|
||||||
|
|
||||||
|
- Brian Ulm reported that if you first tried to download a non-existing SFTP
|
||||||
|
file and then fetched an existing one and re-used the handle, libcurl would
|
||||||
|
still report the second one as non-existing as well! I fixed it and Brian
|
||||||
|
verified that it cured his problem.
|
||||||
|
|
||||||
|
Michal Marek (6 Mar 2008)
|
||||||
|
- Fix the gssapi configure check to detect newer MIT Kerberos (patch by
|
||||||
|
Michael Calmer)
|
||||||
|
|
||||||
|
Yang Tse (6 Mar 2008)
|
||||||
|
- Fix regression on Curl_socket_ready() and Curl_poll() so that these will
|
||||||
|
again fail on select/poll errors different than EINTR.
|
||||||
|
|
||||||
|
Daniel Fandrich (5 Mar 2008)
|
||||||
|
- Fixed the test harness so it will write out zero-length data files.
|
||||||
|
|
||||||
|
- Added tests 616 and 617 to see how SFTP and SCP cope with zero-length
|
||||||
|
files, as questioned by Mike Protts. SFTP does for me but SCP doesn't
|
||||||
|
so test 617 is disabled for now.
|
||||||
|
|
||||||
|
Daniel S (4 Mar 2008)
|
||||||
|
- Mike Protts brought a patch that makes resumed transfers work with SFTP.
|
||||||
|
|
||||||
|
Daniel S (1 Mar 2008)
|
||||||
|
- Anatoli Tubman found and fixed a crash with Negotiate authentication used on
|
||||||
|
a re-used connection where both requests used Negotiate.
|
||||||
|
|
||||||
|
Guenter Knauf (26 Feb 2008)
|
||||||
|
- Kaspar Brand provided a patch to support server name indication (RFC 4366).
|
||||||
|
|
||||||
|
Daniel S (25 Feb 2008)
|
||||||
|
- Kaspar Brand made GnuTLS-built libcurl properly acknowledge the option that
|
||||||
|
forces it to prefer SSLv3.
|
||||||
|
|
||||||
|
Daniel S (23 Feb 2008)
|
||||||
|
- Sam Listopad provided a patch in feature-request #1900014
|
||||||
|
http://curl.haxx.se/bug/feature.cgi?id=1900014 that makes libcurl (built to
|
||||||
|
use OpenSSL) support a full chain of certificates in a given PKCS12
|
||||||
|
certificate.
|
||||||
|
|
||||||
|
Daniel S (22 Feb 2008)
|
||||||
|
- Georg Lippitsch made the src/Makefile.vc6 makefile use the same memory model
|
||||||
|
options as the lib/Makefile.vc6 already did.
|
||||||
|
|
||||||
|
Daniel S (21 Feb 2008)
|
||||||
|
- Zmey Petroff found a crash when libcurl accessed a NULL pointer, which
|
||||||
|
happened if you set the connection cache size to 1 and for example failed to
|
||||||
|
login to an FTP site. Bug report #1896698
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1896698)
|
||||||
|
|
||||||
|
Daniel S (20 Feb 2008)
|
||||||
|
- Fixed test case 405 to not fail when libcurl is built with GnuTLS
|
||||||
|
|
||||||
|
- Based on initial work done by Gautam Kachroo to address a bug, we now keep
|
||||||
|
better control at the exact state of the connection's SSL status so that we
|
||||||
|
know exactly when it has completed the SSL negotiation or not so that there
|
||||||
|
won't be accidental re-uses of connections that are wrongly believed to be
|
||||||
|
in SSL-completed-negotiate state.
|
||||||
|
|
||||||
|
- We no longer support setting the CURLOPT_URL option from inside a callback
|
||||||
|
such as the CURLOPT_SSL_CTX_FUNCTION one treat that as if it was a Location:
|
||||||
|
following. The patch that introduced this feature was done for 7.11.0, but
|
||||||
|
this code and functionality has been broken since about 7.15.4 (March 2006)
|
||||||
|
with the introduction of non-blocking OpenSSL "connects".
|
||||||
|
|
||||||
|
It was a hack to begin with and since it doesn't work and hasn't worked
|
||||||
|
correctly for a long time and nobody has even noticed, I consider it a very
|
||||||
|
suitable subject for plain removal. And so it was done.
|
||||||
|
|
||||||
|
Guenter Knauf (19 Feb 2008)
|
||||||
|
- We do no longer support SSLv2 by default since it has known flaws.
|
||||||
|
Kaspar Brand provided a patch for all supported SSL toolkits.
|
||||||
|
|
||||||
|
Daniel Fandrich (19 Feb 2008)
|
||||||
|
- Added test309 to test HTTP redirect to HTTPS URL
|
||||||
|
|
||||||
|
Daniel S (18 Feb 2008)
|
||||||
|
- We're no longer providing a very old ca-bundle in the curl tarball. You can
|
||||||
|
get a fresh one downloaded and created with 'make ca-bundle' or you can get
|
||||||
|
one from here => http://curl.haxx.se/docs/caextract.html if you want a fresh
|
||||||
|
new one extracted from Mozilla's recent list of ca certs.
|
||||||
|
|
||||||
|
The configure option --with-ca-bundle now lets you specify what file to use
|
||||||
|
as default ca bundle for your build. If not specified, the configure script
|
||||||
|
will check a few known standard places for a global ca cert to use.
|
||||||
|
|
||||||
|
Daniel S (17 Feb 2008)
|
||||||
|
- Jerome Muffat-Meridol helped me fix Curl_done() to close the current
|
||||||
|
connection by force when it was called before the entire request is
|
||||||
|
completed, simply because we can't know if the connection really can be
|
||||||
|
re-used safely at that point.
|
||||||
|
|
||||||
|
- Based on the same debugging logic, I've also made Curl_http_done() not
|
||||||
|
return CURLE_GOT_NOTHING if called "prematurely". This should have no real
|
||||||
|
effect to anything but the code makes more sense like this.
|
||||||
|
|
||||||
|
Daniel S (15 Feb 2008)
|
||||||
|
- Made the gnutls code path not even try to get the server cert if no peer
|
||||||
|
verification is requested. Previously it would even return failure if gnutls
|
||||||
|
failed to get the server cert even though no verification was asked for.
|
||||||
|
Public server showing the problem: https://www.net222.caisse-epargne.fr
|
||||||
|
|
||||||
|
- Fix my Curl_timeleft() leftover mistake in the gnutls code
|
||||||
|
|
||||||
|
- Pooyan McSporran found and fixed a flaw where you first would do a normal
|
||||||
|
http request and then you'd reuse the handle and replace the Accept: header,
|
||||||
|
as then libcurl would send two Accept: headers!
|
||||||
|
|
||||||
|
Daniel S (11 Feb 2008)
|
||||||
|
- Yang Tse pointed out a few remaining quirks from my timeout refactoring from
|
||||||
|
Feb 7 that didn't abort properly on timeouts. These are actually old
|
||||||
|
problems but now they should be fixed.
|
||||||
|
|
||||||
|
Yang Tse (10 Feb 2008)
|
||||||
|
- Bug report #1888932 (http://curl.haxx.se/bug/view.cgi?id=1888932) points out
|
||||||
|
and provides test program that demonstrates that libcurl might not set error
|
||||||
|
description message for error CURLE_COULDNT_RESOLVE_HOST for Windows threaded
|
||||||
|
name resolver builds. Fixed now.
|
||||||
|
|
||||||
|
Daniel Fandrich (8 Feb 2007)
|
||||||
|
- Added key words to all SSL-using tests so they can be skipped if necessary.
|
||||||
|
Removed a few unnecessary requires SSL statements.
|
||||||
|
|
||||||
|
Daniel S (8 Feb 2008)
|
||||||
|
- Mike Hommey filed and fixed bug report #1889856
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1889856): When using the gnutls ssl
|
||||||
|
layer, cleaning-up and reinitializing curl ends up with https requests
|
||||||
|
failing with "ASN1 parser: Element was not found" errors. Obviously a
|
||||||
|
regression added in 7.16.3.
|
||||||
|
|
||||||
|
Yang Tse (8 Feb 2008)
|
||||||
|
- Improved test harness SCP/SFTP start up server verification, doing a real
|
||||||
|
connection to the sftp server, authenticating and running a simple sftp
|
||||||
|
pwd command using the test harness generated configuration and key files.
|
||||||
|
|
||||||
|
Daniel S (8 Feb 2008)
|
||||||
|
- G<>nter Knauf added lib/mk-ca-bundle.pl which gets the Firefox ca bundle and
|
||||||
|
creates a suitable ca-bundle.crt file in PEM format for use with curl. The
|
||||||
|
recommended way to run it is to use 'make ca-bundle' in the build tree root.
|
||||||
|
|
||||||
|
Daniel Fandrich (7 Feb 2007)
|
||||||
|
- Added tests 1022 and 1023 to validate output of curl-config --version and
|
||||||
|
--vernum
|
||||||
|
|
||||||
|
Daniel S (7 Feb 2008)
|
||||||
|
- Refactored a lot of timeout code into a few functions in an attempt to make
|
||||||
|
them all use the same (hopefully correct) logic to make it less error-prone
|
||||||
|
and easier to introduce library-wide where it should be used.
|
||||||
|
|
||||||
|
Yang Tse (6 Feb 2008)
|
||||||
|
- Fix an issue in strdup replacement function when dealing with absolutely
|
||||||
|
huge strings. Only systems without a standard strdup would be affected.
|
||||||
|
|
||||||
|
Daniel S (3 Feb 2008)
|
||||||
|
- Dmitry Kurochkin cleaned up the pipelining code and removed the need for and
|
||||||
|
use of the "is_in_pipeline" struct field.
|
||||||
|
|
||||||
|
- I wrote up and added the threaded-ssl.c example source code that shows how
|
||||||
|
to do multi-threaded downloads of HTTPS files with a libcurl that is built
|
||||||
|
with OpenSSL. It uses pthreads for the threading.
|
||||||
|
|
||||||
|
Daniel S (31 Jan 2008)
|
||||||
|
- Niklas Angebrand made the cookie support in libcurl properly deal with the
|
||||||
|
"HttpOnly" feature introduced by Microsoft and apparently also supported by
|
||||||
|
Firefox: http://msdn2.microsoft.com/en-us/library/ms533046.aspx . HttpOnly
|
||||||
|
is now supported when received from servers in HTTP headers, when written to
|
||||||
|
cookie jars and when read from existing cookie jars.
|
||||||
|
|
||||||
|
I modified test case 31 and 46 to also do some basic HttpOnly testing.
|
||||||
|
|
||||||
|
- Dmitry Kurochkin moved several struct fields from the connectdata struct to
|
||||||
|
the SingleRequest one to make pipelining better. It is a bit tricky to keep
|
||||||
|
them in the right place, to keep things related to the actual request or to
|
||||||
|
the actual connection in the right place.
|
||||||
|
|
||||||
|
Daniel S (29 Jan 2008)
|
||||||
|
- Dmitry Kurochkin fixed Curl_done() for pipelining, as it could previously
|
||||||
|
crash!
|
||||||
|
|
||||||
|
- Michal Marek fixed minor mistake in test case 553 that prevented it from
|
||||||
|
working on other IP-addresses or port numbers.
|
||||||
|
|
||||||
|
Version 7.18.0 (28 January 2008)
|
||||||
|
|
||||||
|
Daniel S (27 Jan 2008)
|
||||||
|
- Dmitry Kurochkin: In "real world" testing I found more bugs in
|
||||||
|
pipelining. Broken connection is not restored and we get into infinite
|
||||||
|
loop. It happens because of wrong is_in_pipeline values.
|
||||||
|
|
||||||
|
Daniel S (26 Jan 2008)
|
||||||
|
- Kevin Reed filed bug report #1879375
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1879375) which describes how libcurl
|
||||||
|
got lost in this scenario: proxy tunnel (or HTTPS over proxy), ask to do any
|
||||||
|
proxy authentication and the proxy replies with an auth (like NTLM) and then
|
||||||
|
closes the connection after that initial informational response.
|
||||||
|
|
||||||
|
libcurl would not properly re-initialize the connection to the proxy and
|
||||||
|
continue the auth negotiation like supposed. It does now however, as it will
|
||||||
|
now detect if one or more authentication methods were available and asked
|
||||||
|
for, and will thus retry the connection and continue from there.
|
||||||
|
|
||||||
|
- I made the progress callback get called properly during proxy CONNECT.
|
||||||
|
|
||||||
|
Daniel S (23 Jan 2008)
|
||||||
|
- Igor Franchuk pointed out that CURLOPT_COOKIELIST set to "ALL" leaked
|
||||||
|
memory, and so did "SESS". Fixed now.
|
||||||
|
|
||||||
|
Yang Tse (22 Jan 2008)
|
||||||
|
- Check poll.h at configuration time, and use it when sys/poll.h unavailable
|
||||||
|
|
||||||
|
Daniel S (22 Jan 2008)
|
||||||
|
- Dmitry Kurochkin removed the cancelled state for pipelining, as we agreed
|
||||||
|
that it is bad anyway. Starting now, removing a handle that is in used in a
|
||||||
|
pipeline will break the pipeline - it'll be set back up again but still...
|
||||||
|
|
||||||
|
Yang Tse (21 Jan 2008)
|
||||||
|
- Disable ldap support for cygwin builds, since it breaks whole build process.
|
||||||
|
Fixing it will affect other platforms, so it is postponed for another release.
|
||||||
|
|
||||||
|
Daniel S (18 Jan 2008)
|
||||||
|
- Lau Hang Kin found and fixed a problem with the multi interface when doing
|
||||||
|
CONNECT over a proxy. curl_multi_fdset() didn't report back the socket
|
||||||
|
properly during that state, due to a missing case in the switch in the
|
||||||
|
multi_getsock() function.
|
||||||
|
|
||||||
|
Yang Tse (17 Jan 2008)
|
||||||
|
- Don't abort tests 518 and 537 when unable to raise the open-file soft limit.
|
||||||
|
|
||||||
|
Daniel S (16 Jan 2008)
|
||||||
|
- Nathan Coulter's patch that makes runtests.pl respect the PATH when figuring
|
||||||
|
out what valgrind to run.
|
||||||
|
|
||||||
|
Yang Tse (16 Jan 2008)
|
||||||
|
- Improved handling of out of memory in the command line tool that afected
|
||||||
|
data url encoded HTTP POSTs when reading it from a file.
|
||||||
|
|
||||||
|
Daniel S (16 Jan 2008)
|
||||||
|
- Dmitry Kurochkin worked a lot on improving the HTTP Pipelining support that
|
||||||
|
previously had a number of flaws, perhaps most notably when an application
|
||||||
|
fired up N transfers at once as then they wouldn't pipeline at all that
|
||||||
|
nicely as anyone would think... Test case 530 was also updated to take the
|
||||||
|
improved functionality into account.
|
||||||
|
|
||||||
|
- Calls to Curl_failf() are not supposed to provide a trailing newline as the
|
||||||
|
function itself adds that. Fixed on 50 or something strings!
|
||||||
|
|
||||||
|
Daniel S (15 Jan 2008)
|
||||||
|
- I made the torture test on test 530 go through. This was actually due to
|
||||||
|
silly code left from when we switched to let the multi handle "hold" the dns
|
||||||
|
cache when using the multi interface... Of course this only triggered when a
|
||||||
|
certain function call returned error at the correct moment.
|
||||||
|
|
||||||
|
Daniel S (14 Jan 2008)
|
||||||
|
- Joe Malicki filed bug report #1871269
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1871269) and we could fix his hang-
|
||||||
|
problem that occurred when doing a large HTTP POST request with the
|
||||||
|
response-body read from a callback.
|
||||||
|
|
||||||
|
Daniel S (12 Jan 2008)
|
||||||
|
- I re-arranged the curl --help output. All the options are now sorted on
|
||||||
|
their long option names and all descriptions are one-liners.
|
||||||
|
|
||||||
|
- Eric Landes provided the patch (edited by me) that introduces the
|
||||||
|
--keepalive-time to curl to set the keepalive probe interval. I also took
|
||||||
|
the opportunity to rename the recently added no-keep-alive option to
|
||||||
|
no-keepalive to keep a consistent naming and to avoid getting two dashes in
|
||||||
|
these option names. Eric also provided an update to the man page for the new
|
||||||
|
option.
|
||||||
|
|
||||||
|
Daniel S (11 Jan 2008)
|
||||||
|
- Daniel Egger made CURLOPT_RANGE work on file:// URLs the very same way it
|
||||||
|
already worked for FTP:// URLs.
|
||||||
|
|
||||||
|
- I made the curl tool switch from using CURLOPT_IOCTLFUNCTION to now use the
|
||||||
|
spanking new CURLOPT_SEEKFUNCTION simply to take advantage of the improved
|
||||||
|
performance for the upload resume cases where you want to upload the last
|
||||||
|
few bytes of a very large file. To implement this decently, I had to switch
|
||||||
|
the client code for uploading from fopen()/fread() to plain open()/read() so
|
||||||
|
that we can use lseek() to do >32bit seeks (as fseek() doesn't allow that)
|
||||||
|
on systems that offer support for that.
|
||||||
|
|
||||||
|
Daniel S (10 Jan 2008)
|
||||||
|
- Michal Marek made curl-config --libs not include /usr/lib64 in the output
|
||||||
|
(it already before skipped /usr/lib). /usr/lib64 is the default library
|
||||||
|
directory on many 64bit systems and it's unlikely that anyone would use the
|
||||||
|
path privately on systems where it's not.
|
||||||
|
|
||||||
|
- Georg Lippitsch brought CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA to allow
|
||||||
|
libcurl to seek in a given input stream. This is particularly important when
|
||||||
|
doing upload resumes when there's already a huge part of the file present
|
||||||
|
remotely. Before, and still if this callback isn't used, libcurl will read
|
||||||
|
and through away the entire file up to the point to where the resuming
|
||||||
|
begins (which of course can be a slow opereration depending on file size,
|
||||||
|
I/O bandwidth and more). This new function will also be preferred to get
|
||||||
|
used instead of the CURLOPT_IOCTLFUNCTION for seeking back in a stream when
|
||||||
|
doing multi-stage HTTP auth with POST/PUT.
|
||||||
|
|
||||||
|
- Nikitinskit Dmitriy filed bug report #1868255
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1868255) with a patch. It identifies
|
||||||
|
and fixes a problem with parsing WWW-Authenticate: headers with additional
|
||||||
|
spaces in the line that the parser wasn't written to deal with.
|
||||||
|
|
||||||
|
Daniel S (8 Jan 2008)
|
||||||
|
- Introducing curl_easy_pause() and new magic return codes for both the read
|
||||||
|
and the write callbacks that now can make a connection's reading and/or
|
||||||
|
writing get paused.
|
||||||
|
|
||||||
|
Daniel S (6 Jan 2008)
|
||||||
|
- Jeff Johnson filed bug report #1863171
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1863171) where he pointed out that
|
||||||
|
libcurl's date parser didn't accept a +1300 time zone which actually is used
|
||||||
|
fairly often (like New Zealand's Dailight Savings Time), so I modified the
|
||||||
|
parser to now accept up to and including -1400 to +1400.
|
||||||
|
|
||||||
|
Daniel S (5 Jan 2008)
|
||||||
|
- Based on further discussion on curl-library, I reverted yesterday's SOCKS5
|
||||||
|
code to instead introduce support for a new proxy type called
|
||||||
|
CURLPROXY_SOCKS5_HOSTNAME that is used to send the host name to the proxy
|
||||||
|
instead of IP address and there's thus no longer any need for a new
|
||||||
|
curl_easy_setopt() option.
|
||||||
|
|
||||||
|
The default SOCKS5 proxy is again back to sending the IP address to the
|
||||||
|
proxy. The new curl command line option for enabling sending host name to a
|
||||||
|
SOCKS5 proxy is now --socks5-hostname.
|
||||||
|
|
||||||
|
Daniel S (4 Jan 2008)
|
||||||
|
- Based on Maxim Perenesenko's patch, we now do SOCKS5 operations and let the
|
||||||
|
proxy do the host name resolving and only if --socks5ip (or
|
||||||
|
CURLOPT_SOCKS5_RESOLVE_LOCAL) is used we resolve the host name locally and
|
||||||
|
pass on the IP address only to the proxy.
|
||||||
|
|
||||||
|
Yang Tse (3 Jan 2008)
|
||||||
|
- Modified test harness to allow SCP, SFTP and SOCKS4 tests to run with
|
||||||
|
OpenSSH 2.9.9, SunSSH 1.0 or later versions. SOCKS5 tests need OpenSSH
|
||||||
|
3.7, SunSSH 1.0 or later.
|
||||||
|
|
||||||
|
Daniel S (2 Jan 2008)
|
||||||
|
- I fixed two cases of missing return code checks when handling chunked
|
||||||
|
decoding where a write error (or abort return from a callback) didn't stop
|
||||||
|
libcurl's processing.
|
||||||
|
|
||||||
|
- I removed the socklen_t use from the public curl/curl.h header and instead
|
||||||
|
made it an unsigned int. The type was only used in the curl_sockaddr struct
|
||||||
|
definition (only used by the curl_opensocket_callback). On all platforms I
|
||||||
|
could find information about, socklen_t is 32 unsigned bits large so I don't
|
||||||
|
think this will break the API or ABI. The main reason for this change is of
|
||||||
|
course for all the platforms that don't have a socklen_t definition in their
|
||||||
|
headers to build fine again. Providing our own configure magic and custom
|
||||||
|
definition of socklen_t on those systems proved to work but was a lot of
|
||||||
|
cruft, code and extra magic needed - when this very small change of type
|
||||||
|
seems harmless and still solves the missing socklen_t problem.
|
||||||
|
|
||||||
|
- Richard Atterer brought a patch that added support for SOCKS4a proxies,
|
||||||
|
which is an inofficial PROXY4 variant that sends the hostname to the proxy
|
||||||
|
instead of the resolved address (which is already supported by SOCKS5).
|
||||||
|
--socks4a is the curl command line option for it and CURLOPT_PROXYTYPE can
|
||||||
|
now be set to CURLPROXY_SOCKS4A as well.
|
||||||
|
|
||||||
|
Daniel S (1 Jan 2008)
|
||||||
|
- Mohun Biswas pointed out that --libcurl generated a source code with an int
|
||||||
|
function but without a return statement. While fixing that, I also took care
|
||||||
|
about adding some better comments for the generated code.
|
||||||
|
|
||||||
|
Daniel S (27 Dec 2007)
|
||||||
|
- Dmitry Kurochkin mentioned a flaw
|
||||||
|
(http://curl.haxx.se/mail/lib-2007-12/0252.html) in detect_proxy() which
|
||||||
|
failed to set the bits.proxy variable properly when an environment variable
|
||||||
|
told libcurl to use a http proxy.
|
||||||
|
|
||||||
|
Daniel S (26 Dec 2007)
|
||||||
|
- In an attempt to repeat the problem in bug report #1850730
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1850730) I wrote up test case 552. The
|
||||||
|
test is doing a 70K POST with a read callback and an ioctl callback over a
|
||||||
|
proxy requiring Digest auth. The test case code is more or less identical to
|
||||||
|
the test recipe code provided by Spacen Jasset (who submitted the bug
|
||||||
|
report).
|
||||||
|
|
||||||
|
Daniel S (25 Dec 2007)
|
||||||
|
- Gary Maxwell filed bug report #1856628
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1856628) and provided a fix for the
|
||||||
|
(small) memory leak in the SSL session ID caching code. It happened when a
|
||||||
|
previous entry in the cache was re-used.
|
||||||
|
|
||||||
|
Daniel Fandrich (19 Dec 2007)
|
||||||
|
- Ensure that nroff doesn't put anything but ASCII characters into the
|
||||||
|
--manual text.
|
||||||
|
|
||||||
|
Yang Tse (18 Dec 2007)
|
||||||
|
- MSVC 9.0 (VS2008) does not support Windows build targets prior to WinXP,
|
||||||
|
and makes wrong asumptions of build target when it isn't specified. So,
|
||||||
|
if no build target has been defined we will target WinXP when building
|
||||||
|
curl/libcurl with MSVC 9.0 (VS2008).
|
||||||
|
|
||||||
|
- (http://curl.haxx.se/mail/archive-2007-12/0039.html) reported and fixed
|
||||||
|
a file truncation problem on Windows build targets triggered when retrying
|
||||||
|
a download with curl.
|
||||||
|
|
||||||
|
Daniel S (17 Dec 2007)
|
||||||
|
- Mateusz Loskot pointed out that MSVC 9.0 (VS2008) has the pollfd struct and
|
||||||
|
defines in winsock2.h somehow differently than previous versions and that
|
||||||
|
curl 7.17.1 would fail to compile out of the box.
|
||||||
|
|
||||||
|
Daniel S (13 Dec 2007)
|
||||||
|
- David Wright filed bug report #1849764
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1849764) with an included fix. He
|
||||||
|
identified a problem for re-used connections that previously had sent
|
||||||
|
Expect: 100-continue and in some situations the subsequent POST (that didn't
|
||||||
|
use Expect:) still had the internal flag set for its use. David's fix (that
|
||||||
|
makes the setting of the flag in every single request unconditionally) is
|
||||||
|
fine and is now used!
|
||||||
|
|
||||||
|
Daniel S (12 Dec 2007)
|
||||||
|
- Gilles Blanc made the curl tool enable SO_KEEPALIVE for the connections and
|
||||||
|
added the --no-keep-alive option that can disable that on demand.
|
||||||
|
|
||||||
|
Daniel S (9 Dec 2007)
|
||||||
|
- Andrew Moise filed bug report #1847501
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1847501) and pointed out a memcpy()
|
||||||
|
that should be memmove() in the convert_lineends() function.
|
||||||
|
|
||||||
|
Daniel S (8 Dec 2007)
|
||||||
|
- Renamed all internal static functions that had Curl_ prefixes to no longer
|
||||||
|
have them. The Curl_ prefix is exclusively used for library internal global
|
||||||
|
symbols. Static functions can be named anything, except for using Curl_ or
|
||||||
|
curl_ prefixes. This is for consistency and for easier maintainance and
|
||||||
|
overview.
|
||||||
|
|
||||||
|
- Cleaned up and reformatted the TODO document to look like the FAQ and
|
||||||
|
CONTRIBUTE, which makes nicer web pages
|
||||||
|
|
||||||
|
- Added test cases 549 and 550 that test CURLOPT_PROXY_TRANSFER_MODE.
|
||||||
|
|
||||||
|
- Added keywords on a bunch of test cases
|
||||||
|
|
||||||
|
- Fixed an OOM problem in the curl code that would lead to fclose on a bad
|
||||||
|
handle and crash
|
||||||
|
|
||||||
|
Daniel S (5 Dec 2007)
|
||||||
|
- Spacen Jasset reported a problem with doing POST (with data read with a
|
||||||
|
callback) over a proxy when NTLM is used as auth with the proxy. The bug
|
||||||
|
also concerned Digest and was limited to using callback only. Spacen worked
|
||||||
|
with us to provide a useful patch. I added the test case 547 and 548 to
|
||||||
|
verify two variations of POST over proxy with NTLM.
|
||||||
|
|
||||||
|
Daniel S (3 Dec 2007)
|
||||||
|
- Ray Pekowski filed bug report #1842029
|
||||||
|
(http://curl.haxx.se/bug/view.cgi?id=1842029) in which he identified a
|
||||||
|
problem with SSL session caching that prevent it from working, and provided
|
||||||
|
the associated fix!
|
||||||
|
|
||||||
|
- Now libcurl (built with OpenSSL) doesn't return error anymore if the remote
|
||||||
|
SSL-based server doesn't present a certificate when the request is told to
|
||||||
|
ignore certificate verification anyway.
|
||||||
|
|
||||||
|
- Michal Marek introduced CURLOPT_PROXY_TRANSFER_MODE which is used to control
|
||||||
|
the appending of the "type=" thing on FTP URLs when they are passed to a
|
||||||
|
HTTP proxy. Some proxies just don't like that appending (which is done
|
||||||
|
unconditionally in 7.17.1), and some proxies treat binary/ascii transfers
|
||||||
|
better with the appending done!
|
||||||
|
|
||||||
|
Daniel S (29 Nov 2007)
|
||||||
|
- A bug report on the curl-library list showed a HTTP Digest session going on
|
||||||
|
with a 700+ letter nonce. Previously libcurl only support 127 letter ones
|
||||||
|
and now I bumped it to 1023.
|
||||||
|
|
||||||
|
- Fixed the resumed FTP upload loop to not require that the read callback
|
||||||
|
returns a full buffer on each invoke.
|
||||||
|
|
||||||
|
Daniel S (25 Nov 2007)
|
||||||
|
- Added test case 1015 that tests --data-urlencode in multiple ways
|
||||||
|
|
||||||
|
- Fixed --data-urlencode for when no @ or = are used
|
||||||
|
|
||||||
|
- Extended the user-agent buffer curl uses, since we can hit the 128 byte
|
||||||
|
border with plenty development libraries used. Like my current set: "curl
|
||||||
|
7.17.2-CVS (i686-pc-linux-gnu) libcurl/7.17.2-CVS OpenSSL/0.9.8g
|
||||||
|
zlib/1.2.3.3 c-ares/1.5.2-CVS libidn/1.1 libssh2/0.19.0-CVS"
|
||||||
|
|
||||||
|
Daniel S (24 Nov 2007)
|
||||||
|
- Internal rearrangements, so that the previous struct HandleData is no more.
|
||||||
|
It is now known as SingleRequest and the Curl_transfer_keeper struct within
|
||||||
|
that was remove entirely. This has the upside that there are less duplicate
|
||||||
|
struct members that made it hard to see and remember what struct that was
|
||||||
|
used to store what data. The transfer_keeper thing was once stored on a
|
||||||
|
per-connection basis and then it made sense to have the duplicate info but
|
||||||
|
since it was moved to the SessionHandle (in 7.16.0) it just added weirdness.
|
||||||
|
The SingleRequest struct is used by data that only is valid for this single
|
||||||
|
request.
|
||||||
|
|
||||||
|
Yang Tse (22 Nov 2007)
|
||||||
|
- Provide a socklen_t definition in curl.h for Win32 API build targets
|
||||||
|
which don't have one.
|
||||||
|
|
||||||
|
Daniel S (22 Nov 2007)
|
||||||
|
- Alessandro Vesely helped me improve the --data-urlencode's syntax, parser
|
||||||
|
and documentation.
|
||||||
|
|
||||||
|
Daniel S (21 Nov 2007)
|
||||||
|
- While inspecting the Negotiate code, I noticed how the proxy auth was using
|
||||||
|
the same state struct as the host auth, so both could never be used at the
|
||||||
|
same time! I fixed it (without being able to check) to use two separate
|
||||||
|
structs to allow authentication using Negotiate on host and proxy
|
||||||
|
simultaneously.
|
||||||
|
|
||||||
|
Daniel S (20 Nov 2007)
|
||||||
|
- Emil Romanus pointed out a bug that made an easy handle get the cookie
|
||||||
|
engine activated when set to use a share (even if the share doesn't share
|
||||||
|
cookies). I fixed it.
|
||||||
|
|
||||||
|
- Fixed a very long-lasting mprintf() bug that occurred when we did "%.*s%s",
|
||||||
|
since the second %s would then wrongly used the numerical precision argument
|
||||||
|
instead and crash.
|
||||||
|
|
||||||
|
- Introduced --data-urlencode to the curl tool for easier url encoding of the
|
||||||
|
data sent in a post.
|
||||||
|
|
||||||
|
Daniel S (18 Nov 2007)
|
||||||
|
- Rob Crittenden fixed SSL connections with NSS done with the multi-interface
|
||||||
|
|
||||||
|
Daniel S (17 Nov 2007)
|
||||||
|
- Michal Marek made the test suite remember what test servers that fail to
|
||||||
|
start so that subsequent tries are simply skipped.
|
||||||
|
|
||||||
|
- Andres Garcia made the examples build fine on Windows (mingw + msys) when
|
||||||
|
the lib was built staticly.
|
||||||
|
|
||||||
|
Daniel S (16 Nov 2007)
|
||||||
|
- Ates Goral identified a problem in http.c:add_buffer_send() when a debug
|
||||||
|
callback was used, as it could wrongly pass on a bad size for the outgoing
|
||||||
|
HTTP header. The bad size would be a very large value as it was a wrapped
|
||||||
|
size_t content. This happened when the whole HTTP request failed to get sent
|
||||||
|
in one single send. http://curl.haxx.se/mail/lib-2007-11/0165.html
|
||||||
|
|
||||||
|
Daniel S (15 Nov 2007)
|
||||||
|
- Fixed yet another remaining problem with doing SFTP directory listings on a
|
||||||
|
re-used persistent connection. Mentioned by Immanuel Gregoire on the mailing
|
||||||
|
list.
|
||||||
|
|
||||||
|
- Michal Marek fixed the test suite to better deal with the case when the HTTP
|
||||||
|
ipv6 server can't run.
|
||||||
|
|
||||||
|
Yang Tse (14 Nov 2007)
|
||||||
|
- Fix a variable potential wrapping in add_buffer() when using absolutely
|
||||||
|
huge send buffer sizes.
|
||||||
|
|
||||||
|
Daniel S (13 Nov 2007)
|
||||||
|
- Fixed a remaining problem with doing SFTP directory listings on a re-used
|
||||||
|
persistent connection. Mentioned by Immanuel Gregoire on the mailing list.
|
||||||
|
|
||||||
|
Daniel S (12 Nov 2007)
|
||||||
|
- Bug report #1830637 (http://curl.haxx.se/bug/view.cgi?id=1830637), which was
|
||||||
|
forwarded from the Gentoo bug tracker by Daniel Black and was originally
|
||||||
|
submitted by Robin Johnson, pointed out that libcurl would do bad memory
|
||||||
|
references when it failed and bailed out before the handler thing was
|
||||||
|
setup. My fix is not done like the provided patch does it, but instead I
|
||||||
|
make sure that there's never any chance for a NULL pointer in that struct
|
||||||
|
member.
|
||||||
|
|
||||||
|
Yang Tse (10 Nov 2007)
|
||||||
|
- Vikram Saxena (http://curl.haxx.se/mail/lib-2007-11/0096.html) pointed out
|
||||||
|
that the pollfd struct was being multi defined when using VS2008. This is
|
||||||
|
now fixed in /curl/lib/select.h
|
||||||
|
|
||||||
|
Daniel S (8 Nov 2007)
|
||||||
|
- Bug report #1823487 (http://curl.haxx.se/bug/view.cgi?id=1823487) pointed
|
||||||
|
out that SFTP requests didn't use persistent connections. Neither did SCP
|
||||||
|
ones. I gave the SSH code a good beating and now both SCP and SFTP should
|
||||||
|
use persistent connections fine. I also did a bunch of indent changes as
|
||||||
|
well as a bug fix for the "keyboard interactive" auth.
|
||||||
|
|
||||||
|
Dan F (6 Nov 2007)
|
||||||
|
- Improved telnet support by drastically reducing the number of write
|
||||||
|
callbacks needed to pass a buffer to the user. Instead one per byte it
|
||||||
|
is now as little as one per segment.
|
||||||
|
|
||||||
|
Yang Tse (6 Nov 2007)
|
||||||
|
- Bug report #1824894 (http://curl.haxx.se/bug/view.cgi?id=1824894) pointed
|
||||||
|
out a problem in curl.h when building C++ apps with MSVC. To fix it, the
|
||||||
|
inclusion of header files in curl.h is moved outside of the C++ extern "C"
|
||||||
|
linkage block.
|
||||||
|
|
||||||
|
Daniel S (1 Nov 2007)
|
||||||
|
- Toby Peterson patched a memory problem in the command line tool that
|
||||||
|
happened when a user had a home dir as an empty string. curl would then do
|
||||||
|
free() on a wrong area.
|
||||||
|
|
||||||
|
Dan F (1 Nov 2007)
|
||||||
|
- Fixed curl-config --features to not display libz when it wasn't used
|
||||||
|
due to a missing header file.
|
||||||
|
|
||||||
|
Dan F (31 October 2007)
|
||||||
|
- Fixed the output of curl-config --protocols which showed SCP and SFTP
|
||||||
|
always, except when --without-libssh2 was given
|
||||||
|
|
||||||
|
- Added test cases 1013 and 1014 to check that curl-config --protocols and
|
||||||
|
curl-config --features matches the output of curl --version
|
||||||
|
|
||||||
|
Dan F (30 October 2007)
|
||||||
|
- Fixed an OOM problem with file: URLs
|
||||||
|
|
||||||
|
- Moved Curl_file_connect into the protocol handler struct
|
||||||
|
|
||||||
|
Dan F (29 October 2007)
|
||||||
|
- Added test case 546 to check that subsequent FTP transfers work after a
|
||||||
|
failed one using the multi interface
|
||||||
|
|
||||||
|
Daniel S (29 October 2007)
|
||||||
|
- Based on one of those bug reports that are intercepted by a distro's bug
|
||||||
|
tracker (https://bugzilla.redhat.com/show_bug.cgi?id=316191), I now made
|
||||||
|
curl-config --features and --protocols show the correct output when built
|
||||||
|
with NSS.
|
||||||
|
|
||||||
|
Version 7.17.1 (29 October 2007)
|
||||||
|
|
||||||
|
Dan F (25 October 2007)
|
||||||
|
- Added the --static-libs option to curl-config
|
||||||
|
|
||||||
|
Daniel S (25 October 2007)
|
||||||
|
- Made libcurl built with NSS possible to ignore the peer verification.
|
||||||
|
Previously it would fail if the ca bundle wasn't present, even if the code
|
||||||
|
ignored the verification results.
|
||||||
|
|
||||||
|
Patrick M (25 October 2007)
|
||||||
|
- Fixed test server to allow null bytes in binary posts.
|
||||||
|
_ Added tests 35, 544 & 545 to check binary data posts, both static (in place)
|
||||||
|
and dynamic (copied).
|
||||||
|
|
||||||
|
Daniel S (25 October 2007)
|
||||||
|
- Michal Marek fixed the test script to be able to use valgrind even when the
|
||||||
|
lib is built shared with libtool.
|
||||||
|
|
||||||
|
- Fixed a few memory leaks when the same easy handle is re-used to request
|
||||||
|
URLs with different protocols. FTP and TFTP related leaks. Caught thanks to
|
||||||
|
Dan F's new test cases.
|
||||||
|
|
||||||
|
Dan F (24 October 2007)
|
||||||
|
- Fixed the test FTP and TFTP servers to support the >10000 test number
|
||||||
|
notation
|
||||||
|
|
||||||
|
- Added test cases 2000 through 2003 which test multiple protocols using the
|
||||||
|
same easy handle
|
||||||
|
|
||||||
|
- Fixed the filecheck: make target to work outside the source tree
|
||||||
|
|
||||||
|
Daniel S (24 October 2007)
|
||||||
|
- Vladimir Lazarenko pointed out that we should do some 'mt' magic when
|
||||||
|
building with VC8 to get the "manifest" embedded to make fine stand-alone
|
||||||
|
binaries. The maketgz and the src/Makefile.vc6 files were adjusted
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
Daniel S (23 October 2007)
|
||||||
|
- Bug report #1812190 (http://curl.haxx.se/bug/view.cgi?id=1812190) points out
|
||||||
|
that libcurl tried to re-use connections a bit too much when using non-SSL
|
||||||
|
protocols tunneled over a HTTP proxy.
|
||||||
|
|
||||||
|
Daniel S (22 October 2007)
|
||||||
|
- Michal Marek forwarded the bug report
|
||||||
|
https://bugzilla.novell.com/show_bug.cgi?id=332917 about a HTTP redirect to
|
||||||
|
FTP that caused memory havoc. His work together with my efforts created two
|
||||||
|
fixes:
|
||||||
|
|
||||||
|
#1 - FTP::file was moved to struct ftp_conn, because is has to be dealt with
|
||||||
|
at connection cleanup, at which time the struct HandleData could be
|
||||||
|
used by another connection.
|
||||||
|
Also, the unused char *urlpath member is removed from struct FTP.
|
||||||
|
|
||||||
|
#2 - provide a Curl_reset_reqproto() function that frees
|
||||||
|
data->reqdata.proto.* on connection setup if needed (that is if the
|
||||||
|
SessionHandle was used by a different connection).
|
||||||
|
|
||||||
|
A long-term goal is of course to somehow get rid of how the reqdata struct
|
||||||
|
is used, as it is too error-prone.
|
||||||
|
|
||||||
|
- Bug report #1815530 (http://curl.haxx.se/bug/view.cgi?id=1815530) points out
|
||||||
|
that specifying a proxy with a trailing slash didn't work (unless it also
|
||||||
|
contained a port number).
|
||||||
|
|
||||||
|
Patrick M (15 October 2007)
|
||||||
|
- Fixed the dynamic CURLOPT_POSTFIELDS problem: this option is now static again
|
||||||
|
and option CURLOPT_COPYPOSTFIELDS has been added to support dynamic mode.
|
||||||
|
|
||||||
|
Patrick M (12 October 2007)
|
||||||
|
- Added per-protocol callback static tables, replacing callback ptr storage
|
||||||
|
in the connectdata structure by a single handler table ptr.
|
||||||
|
|
||||||
|
Dan F (11 October 2007)
|
||||||
|
- Fixed the -l option of runtests.pl
|
||||||
|
|
||||||
|
- Added support for skipping tests based on key words.
|
||||||
|
|
||||||
|
Daniel S (9 October 2007)
|
||||||
|
- Michal Marek removed the no longer existing return codes from the curl.1
|
||||||
|
man page.
|
||||||
|
|
||||||
|
Daniel S (7 October 2007)
|
||||||
|
- Known bug #47, which confused libcurl if doing NTLM auth over a proxy with
|
||||||
|
a response that was larger than 16KB is now improved slightly so that now
|
||||||
|
the restriction at 16KB is for the headers only and it should be a rare
|
||||||
|
situation where the response-headers exceed 16KB. Thus, I consider #47 fixed
|
||||||
|
and the header limitation is now known as known bug #48.
|
||||||
|
|
||||||
|
Daniel S (5 October 2007)
|
||||||
|
- Michael Wallner made the CULROPT_COOKIELIST option support a new magic
|
||||||
|
string: "FLUSH". Using that will cause libcurl to flush its cookies to the
|
||||||
|
CURLOPT_COOKIEJAR file.
|
||||||
|
|
||||||
|
- The new file docs/libcurl/ABI describes how we view ABI breakages, soname
|
||||||
|
bumps and what the version number's significance to all that is.
|
||||||
|
|
||||||
|
Daniel S (4 October 2007)
|
||||||
|
- I enabled test 1009 and made the --local-port use a wide range to reduce the
|
||||||
|
risk of failures.
|
||||||
|
|
||||||
|
- Kim Rinnewitz reported that --local-port didn't work with TFTP transfers.
|
||||||
|
This happened because the tftp code always uncondionally did a bind()
|
||||||
|
without caring if one already had been done and then it failed. I wrote a
|
||||||
|
test case (1009) to verify this, but it is a bit error-prone since it will
|
||||||
|
have to pick a fixed local port number and since the tests are run on so
|
||||||
|
many different hosts in different situations I'll add it in disabled state.
|
||||||
|
|
||||||
|
Yang Tse (3 October 2007)
|
||||||
|
- Fixed issue related with the use of ares_timeout() result.
|
||||||
|
|
||||||
|
Daniel S (3 October 2007)
|
||||||
|
- Alexey Pesternikov introduced CURLOPT_OPENSOCKETFUNCTION and
|
||||||
|
CURLOPT_OPENSOCKETDATA to set a callback that allows an application to
|
||||||
|
replace the socket() call used by libcurl. It basically allows the app to
|
||||||
|
change address, protocol or whatever of the socket.
|
||||||
|
|
||||||
|
- I renamed the CURLE_SSL_PEER_CERTIFICATE error code to
|
||||||
|
CURLE_PEER_FAILED_VERIFICATION (standard CURL_NO_OLDIES style), and made
|
||||||
|
this return code get used by the previous SSH MD5 fingerprint check in case
|
||||||
|
it fails.
|
||||||
|
|
||||||
|
- Based on a patch brought by Johnny Luong, libcurl now offers
|
||||||
|
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and the curl tool --hostpubmd5. They both
|
||||||
|
make the SCP or SFTP connection verify the remote host's md5 checksum of the
|
||||||
|
public key before doing a connect, to reduce the risk of a man-in-the-middle
|
||||||
|
attack.
|
||||||
|
|
||||||
|
Daniel S (2 October 2007)
|
||||||
|
- libcurl now handles chunked-encoded CONNECT responses
|
||||||
|
|
||||||
|
Daniel S (1 October 2007)
|
||||||
|
- Alex Fishman reported a curl_easy_escape() problem that was made the
|
||||||
|
function do wrong on all input bytes that are >= 0x80 (decimal 128) due to a
|
||||||
|
signed / unsigned mistake in the code. I fixed it and added test case 543 to
|
||||||
|
verify.
|
||||||
|
|
||||||
|
Daniel S (29 September 2007)
|
||||||
|
- Immanuel Gregoire fixed a problem with persistent transfers over SFTP.
|
||||||
|
|
||||||
|
Daniel S (28 September 2007)
|
||||||
|
- Adapted the c-ares code to the API change c-ares 1.5.0 brings in the
|
||||||
|
notifier callback(s).
|
||||||
|
|
||||||
|
Dan F (26 September 2007)
|
||||||
|
- Enabled a few more gcc warnings with --enable-debug. Renamed a few
|
||||||
|
variables to avoid shadowing global declarations.
|
||||||
|
|
||||||
|
Daniel S (26 September 2007)
|
||||||
|
- Philip Langdale provided the new CURLOPT_POST301 option for
|
||||||
|
curl_easy_setopt() that alters how libcurl functions when following
|
||||||
|
redirects. It makes libcurl obey the RFC2616 when a 301 response is received
|
||||||
|
after a non-GET request is made. Default libcurl behaviour is to change
|
||||||
|
method to GET in the subsequent request (like it does for response code 302
|
||||||
|
- because that's what many/most browsers do), but with this CURLOPT_POST301
|
||||||
|
option enabled it will do what the spec says and do the next request using
|
||||||
|
the same method again. I.e keep POST after 301.
|
||||||
|
|
||||||
|
The curl tool got this option as --post301
|
||||||
|
|
||||||
|
Test case 1011 and 1012 were added to verify.
|
||||||
|
|
||||||
|
- Max Katsev reported that when doing a libcurl FTP request with
|
||||||
|
CURLOPT_NOBODY enabled but not CURLOPT_HEADER, libcurl wouldn't do TYPE
|
||||||
|
before it does SIZE which makes it less useful. I walked over the code and
|
||||||
|
made it do this properly, and added test case 542 to verify it.
|
||||||
|
|
||||||
|
Daniel S (24 September 2007)
|
||||||
|
- Immanuel Gregoire fixed KNOWN_BUGS #44: --ftp-method nocwd did not handle
|
||||||
|
URLs ending with a slash properly (it should list the contents of that
|
||||||
|
directory). Test case 351 brought back and also test 1010 was added.
|
||||||
|
|
||||||
|
Daniel S (21 September 2007)
|
||||||
|
- Mark Davies fixed Negotiate authentication over proxy, and also introduced
|
||||||
|
the --proxy-negotiate command line option to allow a user to explicitly
|
||||||
|
select it.
|
||||||
|
|
||||||
|
Daniel S (19 September 2007)
|
||||||
|
- Rob Crittenden provided an NSS update with the following highlights:
|
||||||
|
|
||||||
|
o It looks for the NSS database first in the environment variable SSL_DIR,
|
||||||
|
then in /etc/pki/nssdb, then it initializes with no database if neither of
|
||||||
|
those exist.
|
||||||
|
|
||||||
|
o If the NSS PKCS#11 libnspsem.so driver is available then PEM files may be
|
||||||
|
loaded, including the ca-bundle. If it is not available then only
|
||||||
|
certificates already in the NSS database are used.
|
||||||
|
|
||||||
|
o Tries to detect whether a file or nickname is being passed in so the right
|
||||||
|
thing is done
|
||||||
|
|
||||||
|
o Added a bit of code to make the output more like the OpenSSL module,
|
||||||
|
including displaying the certificate information when connecting in
|
||||||
|
verbose mode
|
||||||
|
|
||||||
|
o Improved handling of certificate errors (expired, untrusted, etc)
|
||||||
|
|
||||||
|
The libnsspem.so PKCS#11 module is currently only available in Fedora
|
||||||
|
8/rawhide. Work will be done soon to upstream it. The NSS module will work
|
||||||
|
with or without it, all that changes is the source of the certificates and
|
||||||
|
keys.
|
||||||
|
|
||||||
|
Daniel S (18 September 2007)
|
||||||
|
- Immanuel Gregoire pointed out that public key SSH auth failed if no
|
||||||
|
public/private key was specified and there was no HOME environment variable,
|
||||||
|
and then it didn't continue to try the other auth methods. Now it will
|
||||||
|
instead try to get the files id_dsa.pub and id_dsa from the current
|
||||||
|
directory if none of the two conditions were met.
|
||||||
|
|
||||||
|
Dan F (17 September 2007)
|
||||||
|
- Added hooks to the test suite to make it possible to test a curl running
|
||||||
|
on a remote host.
|
||||||
|
|
||||||
|
- Changed some FTP tests to validate the format of the PORT and EPRT commands
|
||||||
|
sent by curl, if not the addresses themselves.
|
||||||
|
|
||||||
|
Daniel S (15 September 2007)
|
||||||
|
- Michal Marek made libcurl automatically append ";type=<a|i>" when using HTTP
|
||||||
|
proxies for FTP urls.
|
||||||
|
|
||||||
|
- G<>nter Knauf fixed LDAP builds in the Windows makefiles and fixed LDAPv3
|
||||||
|
support on Windows.
|
||||||
|
|
||||||
|
Dan F (13 September 2007)
|
||||||
|
- Added LDAPS, SCP and SFTP to curl-config --protocols. Removed and
|
||||||
|
fixed some AC_SUBST configure entries.
|
||||||
|
|
||||||
Version 7.17.0 (13 September 2007)
|
Version 7.17.0 (13 September 2007)
|
||||||
|
|
||||||
Daniel S (12 September 2007)
|
Daniel S (12 September 2007)
|
||||||
|
|||||||
@@ -10864,7 +10864,7 @@ Version 6.2
|
|||||||
the configure script to leave SSL alone. The previous functionality has
|
the configure script to leave SSL alone. The previous functionality has
|
||||||
been retained. Troy Engel helped test this new one.
|
been retained. Troy Engel helped test this new one.
|
||||||
|
|
||||||
Version 6.1
|
Version 6.1 (October 17 1999)
|
||||||
|
|
||||||
Daniel (17 October 1999):
|
Daniel (17 October 1999):
|
||||||
- I ifdef'ed or commented all the zlib stuff in the sources and configure
|
- I ifdef'ed or commented all the zlib stuff in the sources and configure
|
||||||
@@ -10939,7 +10939,7 @@ Version 6.1beta
|
|||||||
- Made the -F option allow stdin when specifying files. By using '-' instead
|
- Made the -F option allow stdin when specifying files. By using '-' instead
|
||||||
of file name, the data will be read from stdin.
|
of file name, the data will be read from stdin.
|
||||||
|
|
||||||
Version 6.0
|
Version 6.0 (September 14 1999)
|
||||||
|
|
||||||
Daniel (13 September 1999)
|
Daniel (13 September 1999)
|
||||||
- Added -X/--http-request <request> to enable any HTTP command to be sent.
|
- Added -X/--http-request <request> to enable any HTTP command to be sent.
|
||||||
@@ -11201,7 +11201,7 @@ Version 5.9.1
|
|||||||
with form posting where the variable shouldn't have any content, as in curl
|
with form posting where the variable shouldn't have any content, as in curl
|
||||||
-F "form=" www.site.com. It was now fixed.
|
-F "form=" www.site.com. It was now fixed.
|
||||||
|
|
||||||
Version 5.9
|
Version 5.9 (May 22 1999)
|
||||||
|
|
||||||
Daniel (22 May 1999)
|
Daniel (22 May 1999)
|
||||||
- I've got a bug report from Aaron Scarisbrick in which he states he has some
|
- I've got a bug report from Aaron Scarisbrick in which he states he has some
|
||||||
@@ -11939,7 +11939,7 @@ Version 4.8.1
|
|||||||
had nothing but header. Appearantly Solaris deals with negative sizes in
|
had nothing but header. Appearantly Solaris deals with negative sizes in
|
||||||
fwrite() calls a lot better than Linux does... =B-]
|
fwrite() calls a lot better than Linux does... =B-]
|
||||||
|
|
||||||
Version 4.8
|
Version 4.8 (Aug 31, 1998)
|
||||||
Daniel Stenberg
|
Daniel Stenberg
|
||||||
- Continue FTP file transfer. -c is the switch. Note that you need to
|
- Continue FTP file transfer. -c is the switch. Note that you need to
|
||||||
specify a file name if you wanna resume a download (you can't resume a
|
specify a file name if you wanna resume a download (you can't resume a
|
||||||
|
|||||||
2
COPYING
2
COPYING
@@ -1,6 +1,6 @@
|
|||||||
COPYRIGHT AND PERMISSION NOTICE
|
COPYRIGHT AND PERMISSION NOTICE
|
||||||
|
|
||||||
Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>.
|
Copyright (c) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se>.
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|||||||
9
CVS-INFO
9
CVS-INFO
@@ -12,8 +12,8 @@ inner sanctum.
|
|||||||
|
|
||||||
Compile and build instructions follow below.
|
Compile and build instructions follow below.
|
||||||
|
|
||||||
CHANGES.0 contains ancient changes.
|
CHANGES.0 contains ancient changes
|
||||||
CHANGES.$year contains changes for the particular year.
|
CHANGES contains the most recent changes
|
||||||
|
|
||||||
Makefile.dist is included as the root Makefile in distribution archives
|
Makefile.dist is included as the root Makefile in distribution archives
|
||||||
|
|
||||||
@@ -49,9 +49,8 @@ installed:
|
|||||||
|
|
||||||
If you don't have nroff and perl and you for some reason don't want to
|
If you don't have nroff and perl and you for some reason don't want to
|
||||||
install them, you can rename the source file src/hugehelp.c.cvs to
|
install them, you can rename the source file src/hugehelp.c.cvs to
|
||||||
src/hugehelp.c and avoid having to generate this file. This will of course
|
src/hugehelp.c and avoid having to generate this file. This will give you
|
||||||
give you an older version of the file that isn't up-to-date. That file was
|
a stubbed version of the file that doesn't contain actual content.
|
||||||
checked in once and won't be updated very regularly.
|
|
||||||
|
|
||||||
MAC OS X
|
MAC OS X
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -131,3 +131,7 @@ install-data-hook:
|
|||||||
uninstall-hook:
|
uninstall-hook:
|
||||||
cd include && $(MAKE) uninstall
|
cd include && $(MAKE) uninstall
|
||||||
cd docs && $(MAKE) uninstall
|
cd docs && $(MAKE) uninstall
|
||||||
|
|
||||||
|
ca-bundle: lib/mk-ca-bundle.pl
|
||||||
|
@echo "generate a fresh ca-bundle.crt"
|
||||||
|
@perl $< -b -l -u lib/ca-bundle.crt
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -128,6 +128,12 @@ vc:
|
|||||||
cd ..\src
|
cd ..\src
|
||||||
nmake /f Makefile.$(VC)
|
nmake /f Makefile.$(VC)
|
||||||
|
|
||||||
|
vc-x64:
|
||||||
|
cd lib
|
||||||
|
MACHINE=x64 nmake /f Makefile.$(VC) cfg=release
|
||||||
|
cd ..\src
|
||||||
|
MACHINE=x64 nmake /f Makefile.$(VC)
|
||||||
|
|
||||||
vc-zlib:
|
vc-zlib:
|
||||||
cd lib
|
cd lib
|
||||||
nmake /f Makefile.$(VC) cfg=release-zlib
|
nmake /f Makefile.$(VC) cfg=release-zlib
|
||||||
@@ -251,6 +257,12 @@ linux: all
|
|||||||
linux-ssl: ssl
|
linux-ssl: ssl
|
||||||
|
|
||||||
vc8:
|
vc8:
|
||||||
echo "generate VC8 makefiles"
|
@echo "generate VC8 makefiles"
|
||||||
sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8
|
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8
|
||||||
sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8
|
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8
|
||||||
|
|
||||||
|
ca-bundle: lib/mk-ca-bundle.pl
|
||||||
|
@echo "generate a fresh ca-bundle.crt"
|
||||||
|
@perl $< -b -l -u lib/ca-bundle.crt
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
121
RELEASE-NOTES
121
RELEASE-NOTES
@@ -1,58 +1,59 @@
|
|||||||
Curl and libcurl 7.17.0
|
Curl and libcurl 7.18.1
|
||||||
|
|
||||||
Public curl release number: 101
|
Public curl releases: 104
|
||||||
Releases counted from the very beginning: 127
|
Command line options: 126
|
||||||
Available command line options: 118
|
curl_easy_setopt() options: 150
|
||||||
Available curl_easy_setopt() options: 143
|
Public functions in libcurl: 56
|
||||||
Number of public functions in libcurl: 55
|
Public web site mirrors: 39
|
||||||
Amount of public web site mirrors: 42
|
Known libcurl bindings: 36
|
||||||
Number of known libcurl bindings: 36
|
Contributors: 621
|
||||||
Number of contributors: 572
|
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o support for OS/400 Secure Sockets Layer library
|
o added support for HttpOnly cookies
|
||||||
o curl_easy_setopt() now allocates strings passed to it
|
o 'make ca-bundle' downloads and generates an updated ca bundle file
|
||||||
o SCP and SFTP support now requires libssh2 0.16 or later
|
o we no longer distribute or install a ca cert bundle
|
||||||
o LDAP libraries are now linked "regularly" and not with dlopen
|
o SSLv2 is now disabled by default for SSL operations
|
||||||
o HTTP transfers have the download size info "available" earlier
|
o the test509-style setting URL in callback is officially no longer supported
|
||||||
o FTP transfers have the download size info "available" earlier
|
o support a full chain of certificates in a given PKCS12 certificate
|
||||||
o builds and runs on OS/400
|
o resumed transfers work with SFTP
|
||||||
o several error codes and options were marked as obsolete and subject to
|
o added type checking macros for curl_easy_setopt() and curl_easy_getinfo(),
|
||||||
future removal (set CURL_NO_OLDIES to see if your application is using them)
|
watch out for new warnings in code using libcurl (needs gcc-4.3 and
|
||||||
o SFTP errors can return more specific error codes
|
currently only works in C mode)
|
||||||
|
o curl_easy_setopt(), curl_easy_getinfo(), curl_share_setopt() and
|
||||||
|
curl_multi_setopt() uses are now checked to use exactly three arguments
|
||||||
|
o --with-ca-path=DIR configure option allows to set an openSSL CApath instead
|
||||||
|
of a default ca bundle.
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o test cases 31, 46, 61, 506, 517 now work in time zones that use leap seconds
|
o improved pipelining
|
||||||
o problem with closed proxy connection during HTTP CONNECT auth negotiation
|
o improved strdup replacement
|
||||||
o transfer-encoding skipping didn't ignore the 407 response bodies properly
|
o GnuTLS-built libcurl failed when doing global cleanup and reinit
|
||||||
o CURLOPT_SSL_VERIFYHOST set to 1
|
o error message problem when unable to resolve a host on Windows
|
||||||
o CONNECT endless loop
|
o Accept: header replacing
|
||||||
o krb5 support builds with Heimdal
|
o not verifying server certs with GnuTLS still failed if gnutls had
|
||||||
o added returned error string for connection refused case
|
problems with the cert
|
||||||
o re-use of dead FTP control connections
|
o when using the multi interface and a handle is removed while still having
|
||||||
o login to FTP servers that don't require (nor understand) PASS after the
|
a transfer going on, the connection is now closed by force
|
||||||
USER command
|
o bad re-use of SSL connections in non-complete state
|
||||||
o bad free of memory from libssh2
|
o test case 405 failures with GnuTLS builds
|
||||||
o the SFTP PWD command works
|
o crash when connection cache size is 1 and Curl_do() failed
|
||||||
o HTTP Digest auth on a re-used connection
|
o GnuTLS-built libcurl can now be forced to prefer SSLv3
|
||||||
o FTPS data connection close
|
o crash when doing Negotiate again on a re-used connection
|
||||||
o AIX 4 and 5 get to use non-blocking sockets
|
o select/poll regression
|
||||||
o small POST with NTLM
|
o better MIT kerberos configure check
|
||||||
o resumed file:// transfers
|
o curl_easy_reset() + SFTP re-used connection download crash
|
||||||
o CURLOPT_DNS_CACHE_TIMEOUT and CURLOPT_DNS_USE_GLOBAL_CACHE are 64 bit
|
o SFTP non-existing file + SFTP existing file error
|
||||||
"clean"
|
o sharing DNS cache between easy handles running in multiple threads could
|
||||||
o memory leak when handling compressed data streams from broken servers
|
lead to crash
|
||||||
o no NTLM unicode response
|
o SFTP upload with CURLOPT_FTP_CREATE_MISSING_DIRS on re-used connection
|
||||||
o resume HTTP PUT using Digest authentication
|
o SFTP infinite loop when given an invalid quote command
|
||||||
o FTP NOBODY requests on directories sent "SIZE (null)"
|
o curl-config erroneously reported LDAPS support with missing LDAP libraries
|
||||||
o FTP NOBODY request on file crash
|
o SCP infinite loop when downloading a zero byte file
|
||||||
o excessively long FTP server responses and response lines
|
o setting the CURLOPT_SSL_CTX_FUNCTION with libcurl built without OpenSSL
|
||||||
o file:// upload then FTP:// upload crash
|
now makes curl_easy_setopt() properly return failure
|
||||||
o TFTP error 0 is no longer treated as success
|
o configure --with-libssh2 (with no given path)
|
||||||
o uploading empty file over FTP on re-used connection
|
|
||||||
o superfluous CWD command on re-used FTP connections without subdirs used
|
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@@ -60,29 +61,19 @@ This release includes the following known bugs:
|
|||||||
|
|
||||||
Other curl-related news:
|
Other curl-related news:
|
||||||
|
|
||||||
o pycurl 7.16.4 was released http://pycurl.sf.net
|
o
|
||||||
o TclCurl 7.16.4 was released
|
|
||||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
|
||||||
o curlpp 0.7.1 was released
|
|
||||||
http://rrette.com/textpattern/index.php?s=cURLpp
|
|
||||||
o A brand new binding for SP-Forth was written by ygrek:
|
|
||||||
http://www.forth.org.ru/~ac/lib/lin/curl/
|
|
||||||
|
|
||||||
New curl mirrors:
|
New curl mirrors:
|
||||||
|
|
||||||
o http://curl.freeby.pctools.cl is a new mirror in Santiago, Chile
|
o http://curl.cuendet.com/ is a new mirror in Atlanta, USA
|
||||||
o http://curl.site2nd.org is a new mirror in Dallas, Texas, USA
|
|
||||||
o http://curl.cheap.co.il is a new mirror in Tel-Aviv, Israel
|
|
||||||
o http://curl.digimirror.nl is a new mirror in Amsterdam, the Netherlands
|
|
||||||
|
|
||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Dan Fandrich, Song Ma, Daniel Black, Giancarlo Formicuccia, Shmulik Regev,
|
Michal Marek, Dmitry Kurochkin, Niklas Angebrand, G<>nter Knauf, Yang Tse,
|
||||||
Daniel Cater, Colin Hogben, Jofell Gallardo, Daniel Johnson,
|
Dan Fandrich, Mike Hommey, Pooyan McSporran, Jerome Muffat-Meridol,
|
||||||
Ralf S. Engelschall, James Housley, Chris Flerackers, Patrick Monnerat,
|
Kaspar Brand, Gautam Kachroo, Zmey Petroff, Georg Lippitsch, Sam Listopad,
|
||||||
Jayesh A Shah, Greg Zavertnik, Peter O'Gorman, Greg Morse, Dmitriy Sergeyev,
|
Anatoli Tubman, Mike Protts, Michael Calmer, Brian Ulm, Dmitry Popov,
|
||||||
Scott Cantor, Allen Pulsifer, Andrew Wansink, Robson Braga Araujo,
|
Jes Badwal, Dan Petitt, Stephen Collyer
|
||||||
Christian Vogt
|
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
|||||||
16
TODO-RELEASE
16
TODO-RELEASE
@@ -1,5 +1,17 @@
|
|||||||
To be addressed before 7.16.3 (planned release: June 2007)
|
To be addressed before 7.18.2 (planned release: June 2008)
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
93 -
|
128 - Phil Blundell's ares and ipv6 fix (feedback lacking)
|
||||||
|
|
||||||
|
129 - Pierre Reiss' libcurl + https + multi = lost information (awaiting
|
||||||
|
better example/clarification on how to figure out when the claimed
|
||||||
|
problem occurs)
|
||||||
|
|
||||||
|
130 - Vincent Le Normand's SFTP patch for touch
|
||||||
|
|
||||||
|
131 - Scott Barrett's Support for CURLOPT_NOBODY with SFTP
|
||||||
|
|
||||||
|
132 - Xponaut's CURLFORM_STREAM option to curl_formadd()
|
||||||
|
|
||||||
|
133 -
|
||||||
|
|
||||||
|
|||||||
619
acinclude.m4
619
acinclude.m4
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -171,6 +171,515 @@ AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINLDAP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winldap.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINLDAP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for winldap.h], [ac_cv_header_winldap_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <winldap.h>
|
||||||
|
],[
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
HAVE_WINLDAP_H shall not be defined.
|
||||||
|
#else
|
||||||
|
LDAP *ldp = ldap_init("dummy", LDAP_PORT);
|
||||||
|
ULONG res = ldap_unbind(ldp);
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winldap_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winldap_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$ac_cv_header_winldap_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINLDAP_H, 1,
|
||||||
|
[Define to 1 if you have the winldap.h header file.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINBER
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winber.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINBER], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINLDAP])dnl
|
||||||
|
AC_CACHE_CHECK([for winber.h], [ac_cv_header_winber_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <winldap.h>
|
||||||
|
#include <winber.h>
|
||||||
|
],[
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
HAVE_WINBER_H shall not be defined.
|
||||||
|
#else
|
||||||
|
BERVAL *bvp = NULL;
|
||||||
|
BerElement *bep = ber_init(bvp);
|
||||||
|
ber_free(bep, 1);
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winber_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winber_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$ac_cv_header_winber_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINBER_H, 1,
|
||||||
|
[Define to 1 if you have the winber.h header file.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_LBER
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid lber.h header,
|
||||||
|
dnl and check if it is needed even with ldap.h
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_LBER], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for lber.h], [ac_cv_header_lber_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
#include <lber.h>
|
||||||
|
],[
|
||||||
|
BerValue *bvp = NULL;
|
||||||
|
BerElement *bep = ber_init(bvp);
|
||||||
|
ber_free(bep, 1);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_lber_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_lber_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "$ac_cv_header_lber_h" = "yes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_LBER_H, 1,
|
||||||
|
[Define to 1 if you have the lber.h header file.])
|
||||||
|
#
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
#ifndef LDAP_DEPRECATED
|
||||||
|
#define LDAP_DEPRECATED 1
|
||||||
|
#endif
|
||||||
|
#include <ldap.h>
|
||||||
|
],[
|
||||||
|
BerValue *bvp = NULL;
|
||||||
|
BerElement *bep = ber_init(bvp);
|
||||||
|
ber_free(bep, 1);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_need_header_lber_h="no"
|
||||||
|
],[
|
||||||
|
curl_cv_need_header_lber_h="yes"
|
||||||
|
])
|
||||||
|
#
|
||||||
|
case "$curl_cv_need_header_lber_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(NEED_LBER_H, 1,
|
||||||
|
[Define to 1 if you need the lber.h header file even with ldap.h])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_LDAP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid ldap.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_LDAP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_LBER])dnl
|
||||||
|
AC_CACHE_CHECK([for ldap.h], [ac_cv_header_ldap_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef LDAP_DEPRECATED
|
||||||
|
#define LDAP_DEPRECATED 1
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_LBER_H
|
||||||
|
#include <lber.h>
|
||||||
|
#endif
|
||||||
|
#include <ldap.h>
|
||||||
|
],[
|
||||||
|
LDAP *ldp = ldap_init("dummy", LDAP_PORT);
|
||||||
|
int res = ldap_unbind(ldp);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldap_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldap_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$ac_cv_header_ldap_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_LDAP_H, 1,
|
||||||
|
[Define to 1 if you have the ldap.h header file.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_LDAP_SSL
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid ldap_ssl.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_LDAP_SSL], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl
|
||||||
|
AC_CACHE_CHECK([for ldap_ssl.h], [ac_cv_header_ldap_ssl_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef LDAP_DEPRECATED
|
||||||
|
#define LDAP_DEPRECATED 1
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_LBER_H
|
||||||
|
#include <lber.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LDAP_H
|
||||||
|
#include <ldap.h>
|
||||||
|
#endif
|
||||||
|
#include <ldap_ssl.h>
|
||||||
|
],[
|
||||||
|
LDAP *ldp = ldapssl_init("dummy", LDAPS_PORT, 1);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldap_ssl_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldap_ssl_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$ac_cv_header_ldap_ssl_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_LDAP_SSL_H, 1,
|
||||||
|
[Define to 1 if you have the ldap_ssl.h header file.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_LDAPSSL
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid ldapssl.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_LDAPSSL], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl
|
||||||
|
AC_CACHE_CHECK([for ldapssl.h], [ac_cv_header_ldapssl_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
#ifndef LDAP_DEPRECATED
|
||||||
|
#define LDAP_DEPRECATED 1
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_LBER_H
|
||||||
|
#include <lber.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LDAP_H
|
||||||
|
#include <ldap.h>
|
||||||
|
#endif
|
||||||
|
#include <ldapssl.h>
|
||||||
|
],[
|
||||||
|
char *cert_label = NULL;
|
||||||
|
LDAP *ldp = ldap_ssl_init("dummy", LDAPS_PORT, cert_label);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldapssl_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_ldapssl_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$ac_cv_header_ldapssl_h" in
|
||||||
|
yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_LDAPSSL_H, 1,
|
||||||
|
[Define to 1 if you have the ldapssl.h header file.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_LIBS_WINLDAP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for libraries needed for WINLDAP support,
|
||||||
|
dnl and prepended to LIBS any needed libraries.
|
||||||
|
dnl This macro can take an optional parameter with a
|
||||||
|
dnl white space separated list of libraries to check
|
||||||
|
dnl before the WINLDAP default ones.
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_LIBS_WINLDAP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINBER])dnl
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for WINLDAP libraries])
|
||||||
|
#
|
||||||
|
u_libs=""
|
||||||
|
#
|
||||||
|
ifelse($1,,,[
|
||||||
|
for x_lib in $1; do
|
||||||
|
case "$x_lib" in
|
||||||
|
-l*)
|
||||||
|
l_lib="$x_lib"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
l_lib="-l$x_lib"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if test -z "$u_libs"; then
|
||||||
|
u_libs="$l_lib"
|
||||||
|
else
|
||||||
|
u_libs="$u_libs $l_lib"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
])
|
||||||
|
#
|
||||||
|
curl_cv_save_LIBS="$LIBS"
|
||||||
|
curl_cv_ldap_LIBS="unknown"
|
||||||
|
#
|
||||||
|
for x_nlibs in '' "$u_libs" \
|
||||||
|
'-lwldap32' ; do
|
||||||
|
if test -z "$x_nlibs"; then
|
||||||
|
LIBS="$curl_cv_save_LIBS"
|
||||||
|
else
|
||||||
|
LIBS="$x_nlibs $curl_cv_save_LIBS"
|
||||||
|
fi
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINLDAP_H
|
||||||
|
#include <winldap.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINBER_H
|
||||||
|
#include <winber.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
BERVAL *bvp = NULL;
|
||||||
|
BerElement *bep = ber_init(bvp);
|
||||||
|
LDAP *ldp = ldap_init("dummy", LDAP_PORT);
|
||||||
|
ULONG res = ldap_unbind(ldp);
|
||||||
|
ber_free(bep, 1);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_ldap_LIBS="$x_nlibs"
|
||||||
|
break
|
||||||
|
])
|
||||||
|
done
|
||||||
|
#
|
||||||
|
LIBS="$curl_cv_save_LIBS"
|
||||||
|
#
|
||||||
|
case X-"$curl_cv_ldap_LIBS" in
|
||||||
|
X-unknown)
|
||||||
|
AC_MSG_RESULT([cannot find WINLDAP libraries])
|
||||||
|
;;
|
||||||
|
X-)
|
||||||
|
AC_MSG_RESULT([no additional lib required])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test -z "$curl_cv_save_LIBS"; then
|
||||||
|
LIBS="$curl_cv_ldap_LIBS"
|
||||||
|
else
|
||||||
|
LIBS="$curl_cv_ldap_LIBS $curl_cv_save_LIBS"
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([$curl_cv_ldap_LIBS])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
#
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_LIBS_LDAP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for libraries needed for LDAP support,
|
||||||
|
dnl and prepended to LIBS any needed libraries.
|
||||||
|
dnl This macro can take an optional parameter with a
|
||||||
|
dnl white space separated list of libraries to check
|
||||||
|
dnl before the default ones.
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_LIBS_LDAP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_LDAP])dnl
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for LDAP libraries])
|
||||||
|
#
|
||||||
|
u_libs=""
|
||||||
|
#
|
||||||
|
ifelse($1,,,[
|
||||||
|
for x_lib in $1; do
|
||||||
|
case "$x_lib" in
|
||||||
|
-l*)
|
||||||
|
l_lib="$x_lib"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
l_lib="-l$x_lib"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if test -z "$u_libs"; then
|
||||||
|
u_libs="$l_lib"
|
||||||
|
else
|
||||||
|
u_libs="$u_libs $l_lib"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
])
|
||||||
|
#
|
||||||
|
curl_cv_save_LIBS="$LIBS"
|
||||||
|
curl_cv_ldap_LIBS="unknown"
|
||||||
|
#
|
||||||
|
for x_nlibs in '' "$u_libs" \
|
||||||
|
'-lldap' \
|
||||||
|
'-llber -lldap' \
|
||||||
|
'-lldap -llber' \
|
||||||
|
'-lldapssl -lldapx -lldapsdk' \
|
||||||
|
'-lldapsdk -lldapx -lldapssl' ; do
|
||||||
|
if test -z "$x_nlibs"; then
|
||||||
|
LIBS="$curl_cv_save_LIBS"
|
||||||
|
else
|
||||||
|
LIBS="$x_nlibs $curl_cv_save_LIBS"
|
||||||
|
fi
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
#ifndef LDAP_DEPRECATED
|
||||||
|
#define LDAP_DEPRECATED 1
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_LBER_H
|
||||||
|
#include <lber.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LDAP_H
|
||||||
|
#include <ldap.h>
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
BerValue *bvp = NULL;
|
||||||
|
BerElement *bep = ber_init(bvp);
|
||||||
|
LDAP *ldp = ldap_init("dummy", LDAP_PORT);
|
||||||
|
int res = ldap_unbind(ldp);
|
||||||
|
ber_free(bep, 1);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_ldap_LIBS="$x_nlibs"
|
||||||
|
break
|
||||||
|
])
|
||||||
|
done
|
||||||
|
#
|
||||||
|
LIBS="$curl_cv_save_LIBS"
|
||||||
|
#
|
||||||
|
case X-"$curl_cv_ldap_LIBS" in
|
||||||
|
X-unknown)
|
||||||
|
AC_MSG_RESULT([cannot find LDAP libraries])
|
||||||
|
;;
|
||||||
|
X-)
|
||||||
|
AC_MSG_RESULT([no additional lib required])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test -z "$curl_cv_save_LIBS"; then
|
||||||
|
LIBS="$curl_cv_ldap_LIBS"
|
||||||
|
else
|
||||||
|
LIBS="$curl_cv_ldap_LIBS $curl_cv_save_LIBS"
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([$curl_cv_ldap_LIBS])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
#
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl CURL_CHECK_HEADER_MALLOC
|
dnl CURL_CHECK_HEADER_MALLOC
|
||||||
dnl -------------------------------------------------
|
dnl -------------------------------------------------
|
||||||
dnl Check for compilable and valid malloc.h header,
|
dnl Check for compilable and valid malloc.h header,
|
||||||
@@ -1316,6 +1825,9 @@ AC_TRY_RUN([
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL (void *)0
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main () {
|
main () {
|
||||||
@@ -1762,7 +2274,7 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
|||||||
dnl only if the compiler is newer than 2.95 since we got lots of
|
dnl only if the compiler is newer than 2.95 since we got lots of
|
||||||
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
|
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
|
||||||
dnl gcc 2.95.4 on FreeBSD 4.9!
|
dnl gcc 2.95.4 on FreeBSD 4.9!
|
||||||
WARN="$WARN -Wundef -Wno-long-long -Wsign-compare"
|
WARN="$WARN -Wundef -Wno-long-long -Wsign-compare -Wshadow -Wno-multichar"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$gccnum" -ge "296"; then
|
if test "$gccnum" -ge "296"; then
|
||||||
@@ -1979,3 +2491,106 @@ AC_DEFUN([CURL_CHECK_NATIVE_WINDOWS], [
|
|||||||
esac
|
esac
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_CA_BUNDLE
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check if a default ca-bundle should be used
|
||||||
|
dnl
|
||||||
|
dnl regarding the paths this will scan:
|
||||||
|
dnl /etc/ssl/certs/ca-certificates.crt Debian systems
|
||||||
|
dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva
|
||||||
|
dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat
|
||||||
|
dnl /etc/ssl/certs/ (ca path) SUSE
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_CA_BUNDLE], [
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([default CA cert bundle/path])
|
||||||
|
|
||||||
|
AC_ARG_WITH(ca-bundle,
|
||||||
|
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to use as CA bundle])
|
||||||
|
AC_HELP_STRING([--without-ca-bundle], [Don't use a default CA bundle]),
|
||||||
|
[
|
||||||
|
want_ca="$withval"
|
||||||
|
if test "x$want_ca" = "xyes"; then
|
||||||
|
AC_MSG_ERROR([--with-ca-bundle=FILE requires a path to the CA bundle])
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[ want_ca="unset" ])
|
||||||
|
AC_ARG_WITH(ca-path,
|
||||||
|
AC_HELP_STRING([--with-ca-path=DIRECTORY], [Directory to use as CA path])
|
||||||
|
AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
|
||||||
|
[
|
||||||
|
want_capath="$withval"
|
||||||
|
if test "x$want_capath" = "xyes"; then
|
||||||
|
AC_MSG_ERROR([--with-ca-path=DIRECTORY requires a path to the CA path directory])
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[ want_capath="unset"])
|
||||||
|
|
||||||
|
if test "x$want_ca" != "xno" -a "x$want_ca" != "xunset" -a \
|
||||||
|
"x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then
|
||||||
|
dnl both given
|
||||||
|
AC_MSG_ERROR([Can't specify both --with-ca-bundle and --with-ca-path.])
|
||||||
|
elif test "x$want_ca" != "xno" -a "x$want_ca" != "xunset"; then
|
||||||
|
dnl --with-ca-bundle given
|
||||||
|
ca="$want_ca"
|
||||||
|
capath="no"
|
||||||
|
elif test "x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then
|
||||||
|
dnl --with-ca-path given
|
||||||
|
if test "x$OPENSSL_ENABLED" != "x1"; then
|
||||||
|
AC_MSG_ERROR([--with-ca-path only works with openSSL])
|
||||||
|
fi
|
||||||
|
capath="$want_capath"
|
||||||
|
ca="no"
|
||||||
|
else
|
||||||
|
dnl neither of --with-ca-* given
|
||||||
|
dnl first try autodetecting a CA bundle , then a CA path
|
||||||
|
dnl both autodetections can be skipped by --without-ca-*
|
||||||
|
ca="no"
|
||||||
|
capath="no"
|
||||||
|
if test "x$want_ca" = "xunset"; then
|
||||||
|
dnl the path we previously would have installed the curl ca bundle
|
||||||
|
dnl to, and thus we now check for an already existing cert in that place
|
||||||
|
dnl in case we find no other
|
||||||
|
if test "x$prefix" != xNONE; then
|
||||||
|
cac="${prefix}/share/curl/curl-ca-bundle.crt"
|
||||||
|
else
|
||||||
|
cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for a in /etc/ssl/certs/ca-certificates.crt \
|
||||||
|
/etc/pki/tls/certs/ca-bundle.crt \
|
||||||
|
/usr/share/ssl/certs/ca-bundle.crt \
|
||||||
|
"$cac"; do
|
||||||
|
if test -f "$a"; then
|
||||||
|
ca="$a"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \
|
||||||
|
"x$OPENSSL_ENABLED" = "x1"; then
|
||||||
|
for a in /etc/ssl/certs/; do
|
||||||
|
if test -d "$a" && ls "$a"/[[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]].0 >/dev/null 2>/dev/null; then
|
||||||
|
capath="$a"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test "x$ca" != "xno"; then
|
||||||
|
CURL_CA_BUNDLE='"'$ca'"'
|
||||||
|
AC_SUBST(CURL_CA_BUNDLE)
|
||||||
|
AC_MSG_RESULT([$ca])
|
||||||
|
elif test "x$capath" != "xno"; then
|
||||||
|
CURL_CA_PATH="\"$capath\""
|
||||||
|
AC_SUBST(CURL_CA_PATH)
|
||||||
|
AC_MSG_RESULT([$capath (capath)])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|||||||
70
ares/CHANGES
70
ares/CHANGES
@@ -1,10 +1,78 @@
|
|||||||
Changelog for the c-ares project
|
Changelog for the c-ares project
|
||||||
|
|
||||||
|
* December 11 2007 (Gisle Vanem)
|
||||||
|
|
||||||
|
- Added another sample application; acountry.c which converts an
|
||||||
|
IPv4-address(es) and/or host-name(s) to country-name and country-code.
|
||||||
|
This uses the service of the DNSBL at countries.nerd.dk.
|
||||||
|
|
||||||
|
* December 3 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
|
- Brad Spencer fixed the configure script to assume that there's no
|
||||||
|
/dev/urandom when built cross-compiled as then the script cannot check for
|
||||||
|
it.
|
||||||
|
|
||||||
|
- Erik Kline cleaned up ares_gethostbyaddr.c:next_lookup() somewhat
|
||||||
|
|
||||||
|
Version 1.5.1 (Nov 21, 2007)
|
||||||
|
|
||||||
|
* November 21 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
|
- Robin Cornelius pointed out that ares_llist.h was missing in the release
|
||||||
|
archive for 1.5.0
|
||||||
|
|
||||||
|
Version 1.5.0 (Nov 21, 2007)
|
||||||
|
|
||||||
|
* October 2 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
|
- ares_strerror() segfaulted if the input error number was out of the currently
|
||||||
|
supported range.
|
||||||
|
|
||||||
|
- Yang Tse: Avoid a segfault when generating a DNS "Transaction ID" in
|
||||||
|
internal function init_id_key() under low memory conditions.
|
||||||
|
|
||||||
|
* September 28 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
|
- Bumped version to 1.5.0 for next release and soname bumped to 2 due to ABI
|
||||||
|
and API changes in the progress callback (and possibly more coming up from
|
||||||
|
Steinar)
|
||||||
|
|
||||||
|
* September 28 2007 (Steinar H. Gunderson)
|
||||||
|
|
||||||
|
- Don't skip a server if it's the only one. (Bugfix from the Google tree.)
|
||||||
|
|
||||||
|
- Made the query callbacks receive the number of timeouts that happened during
|
||||||
|
the execution of a query, and updated documentation accordingly. (Patch from
|
||||||
|
the Google tree.)
|
||||||
|
|
||||||
|
- Support a few more socket options: ARES_OPT_SOCK_SNDBUF and
|
||||||
|
ARES_OPT_SOCK_RCVBUF
|
||||||
|
|
||||||
|
- Always register for TCP events even if there are no outstanding queries, as
|
||||||
|
the other side could always close the connection, which is a valid event
|
||||||
|
which should be responded to.
|
||||||
|
|
||||||
|
* September 22 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
|
- Steinar H. Gunderson fixed: Correctly clear sockets from the fd_set on in
|
||||||
|
several functions (write_tcp_data, read_tcp_data, read_udp_packets) so that
|
||||||
|
if it fails and the socket is closed the following code doesn't try to use
|
||||||
|
the file descriptor.
|
||||||
|
|
||||||
|
- Steinar H. Gunderson modified c-ares to now also do to DNS retries even when
|
||||||
|
TCP is used since there are several edge cases where it still makes sense.
|
||||||
|
|
||||||
|
- Brad House provided a fix for ares_save_options():
|
||||||
|
|
||||||
|
Apparently I overlooked something with the ares_save_options() where it
|
||||||
|
would try to do a malloc(0) when no options of that type needed to be saved.
|
||||||
|
On most platforms, this was fine because malloc(0) doesn't actually return
|
||||||
|
NULL, but on AIX it does, so ares_save_options would return ARES_ENOMEM.
|
||||||
|
|
||||||
* July 14 2007 (Daniel Stenberg)
|
* July 14 2007 (Daniel Stenberg)
|
||||||
|
|
||||||
- Vlad Dinulescu fixed two outstanding valgrind reports:
|
- Vlad Dinulescu fixed two outstanding valgrind reports:
|
||||||
|
|
||||||
|
|
||||||
1. In ares_query.c , in find_query_by_id we compare q->qid (which is a short
|
1. In ares_query.c , in find_query_by_id we compare q->qid (which is a short
|
||||||
int variable) with qid, which is declared as an int variable. Moreover,
|
int variable) with qid, which is declared as an int variable. Moreover,
|
||||||
DNS_HEADER_SET_QID is used to set the value of qid, but DNS_HEADER_SET_QID
|
DNS_HEADER_SET_QID is used to set the value of qid, but DNS_HEADER_SET_QID
|
||||||
|
|||||||
@@ -8,13 +8,24 @@ MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/vc.dsw vc/ahost/ahost.dep \
|
|||||||
vc/ahost/ahost.dsp vc/areslib/areslib.dep vc/areslib/areslib.dsp \
|
vc/ahost/ahost.dsp vc/areslib/areslib.dep vc/areslib/areslib.dsp \
|
||||||
vc/areslib/areslib.dsw
|
vc/areslib/areslib.dsw
|
||||||
|
|
||||||
|
if DEBUGBUILD
|
||||||
|
PROGS =
|
||||||
|
else
|
||||||
|
PROGS = ahost adig acountry
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_PROGRAMS =$(PROGS)
|
||||||
|
|
||||||
# adig and ahost are just sample programs and thus not mentioned with the
|
# adig and ahost are just sample programs and thus not mentioned with the
|
||||||
# regular sources and headers
|
# regular sources and headers
|
||||||
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
|
EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj \
|
||||||
$(MSVCFILES) AUTHORS config-win32.h RELEASE-NOTES libcares.pc.in
|
Makefile.m32 Makefile.netware Makefile.vc6 adig.c ahost.c $(man_MANS) \
|
||||||
|
$(MSVCFILES) config-win32.h RELEASE-NOTES libcares.pc.in
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libcares.pc
|
||||||
|
|
||||||
VER=-version-info 1:0:0
|
VER=-version-info 2:0:0
|
||||||
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||||
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
|
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
|
||||||
# 1.
|
# 1.
|
||||||
@@ -61,6 +72,15 @@ libcares_ladir = $(includedir)
|
|||||||
# what headers to install on 'make install':
|
# what headers to install on 'make install':
|
||||||
libcares_la_HEADERS = ares.h ares_version.h ares_dns.h
|
libcares_la_HEADERS = ares.h ares_version.h ares_dns.h
|
||||||
|
|
||||||
|
ahost_SOURCES = ahost.c ares_getopt.c
|
||||||
|
ahost_LDADD = $(top_builddir)/$(lib_LTLIBRARIES)
|
||||||
|
|
||||||
|
adig_SOURCES = adig.c ares_getopt.c
|
||||||
|
adig_LDADD = $(top_builddir)/$(lib_LTLIBRARIES)
|
||||||
|
|
||||||
|
acountry_SOURCES = acountry.c ares_getopt.c
|
||||||
|
acountry_LDADD = $(top_builddir)/$(lib_LTLIBRARIES)
|
||||||
|
|
||||||
# Make files named *.dist replace the file without .dist extension
|
# Make files named *.dist replace the file without .dist extension
|
||||||
dist-hook:
|
dist-hook:
|
||||||
find $(distdir) -name "*.dist" -exec rm {} \;
|
find $(distdir) -name "*.dist" -exec rm {} \;
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_FIONBIO \
|
|||||||
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
|
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
|
||||||
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
||||||
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' -DHAVE_PROCESS_H \
|
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' -DHAVE_PROCESS_H \
|
||||||
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND \
|
-DHAVE_ARPA_NAMESER_H -DHAVE_SYS_SOCKET_H -DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H \
|
||||||
|
-DHAVE_NETINET_TCP_H -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND \
|
||||||
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
|
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
|
||||||
-DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \
|
-DSEND_TYPE_ARG2='void*' -DSEND_TYPE_ARG3='int' \
|
||||||
-DSEND_TYPE_ARG4='int' -DSEND_TYPE_RETV='int' \
|
-DSEND_TYPE_ARG4='int' -DSEND_TYPE_RETV='int' \
|
||||||
-DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \
|
-DRECV_TYPE_ARG1='int' -DRECV_TYPE_ARG2='void*' \
|
||||||
-DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \
|
-DRECV_TYPE_ARG3='int' -DRECV_TYPE_ARG4='int' \
|
||||||
-DRECV_TYPE_RETV='int' -DHAVE_STRUCT_TIMEVAL \
|
-DRECV_TYPE_RETV='int' -DHAVE_STRUCT_TIMEVAL \
|
||||||
-Dselect=select_s -UHAVE_CONFIG_H
|
-Dselect=select_s -Dsocklen_t=int -UHAVE_CONFIG_H
|
||||||
|
|
||||||
LDFLAGS = -s
|
LDFLAGS = -s
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a
|
|||||||
|
|
||||||
OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o))
|
OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o))
|
||||||
|
|
||||||
all: $(OBJ_DIR) libcares.a ahost.exe adig.exe
|
all: $(OBJ_DIR) libcares.a ahost.exe adig.exe acountry.exe
|
||||||
@echo Welcome to c-ares.
|
@echo Welcome to c-ares.
|
||||||
|
|
||||||
libcares.a: $(OBJECTS)
|
libcares.a: $(OBJECTS)
|
||||||
@@ -60,11 +61,14 @@ ahost.exe: ahost.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
|
|||||||
adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
|
adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
|
||||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS)
|
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS)
|
||||||
|
|
||||||
|
acountry.exe: acountry.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK)
|
||||||
|
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJECTS) libcares.a
|
rm -f $(OBJECTS) libcares.a
|
||||||
|
|
||||||
vclean realclean: clean
|
vclean realclean: clean
|
||||||
rm -f ahost.exe adig.exe depend.dj
|
rm -f ahost.exe adig.exe acountry.exe depend.dj
|
||||||
- rmdir $(OBJ_DIR)
|
- rmdir $(OBJ_DIR)
|
||||||
|
|
||||||
-include depend.dj
|
-include depend.dj
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c \
|
|||||||
ares_expand_name.c ares_parse_a_reply.c windows_port.c \
|
ares_expand_name.c ares_parse_a_reply.c windows_port.c \
|
||||||
ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c \
|
ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c \
|
||||||
ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c \
|
ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c \
|
||||||
ares_parse_ns_reply.c
|
ares_parse_ns_reply.c ares_llist.c
|
||||||
|
|
||||||
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \
|
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \
|
||||||
nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h \
|
nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h \
|
||||||
setup_once.h
|
setup_once.h ares_llist.h
|
||||||
|
|
||||||
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
||||||
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ $(LIB): $(OBJLIB)
|
|||||||
|
|
||||||
all: $(LIB) demos
|
all: $(LIB) demos
|
||||||
|
|
||||||
demos: adig.exe ahost.exe
|
demos: adig.exe ahost.exe acountry.exe
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
etags *.[ch]
|
etags *.[ch]
|
||||||
@@ -61,7 +61,7 @@ install:
|
|||||||
done)
|
done)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe
|
$(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe acountry.exe
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
$(RM) config.cache config.log config.status Makefile
|
$(RM) config.cache config.log config.status Makefile
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ NDKBASE = c:/novell
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INSTDIR
|
ifndef INSTDIR
|
||||||
INSTDIR = ../curl-$(LIBCURL_VERSION_STR)-bin-nw
|
INSTDIR = ../ares-$(LIBCARES_VERSION_STR)-bin-nw
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the vars below to change NLM target settings.
|
# Edit the vars below to change NLM target settings.
|
||||||
TARGETS = adig.nlm ahost.nlm
|
TARGETS = adig.nlm ahost.nlm acountry.nlm
|
||||||
LTARGET = libcares.$(LIBEXT)
|
LTARGET = libcares.$(LIBEXT)
|
||||||
VERSION = $(LIBCARES_VERSION)
|
VERSION = $(LIBCARES_VERSION)
|
||||||
COPYR = Copyright (C) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>
|
COPYR = Copyright (C) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se>
|
||||||
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
|
DESCR = cURL $(subst .def,,$(notdir $@)) $(LIBCARES_VERSION_STR) - http://curl.haxx.se
|
||||||
MTSAFE = YES
|
MTSAFE = YES
|
||||||
STACK = 64000
|
STACK = 64000
|
||||||
@@ -63,14 +63,15 @@ else
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
endif
|
endif
|
||||||
# a native win32 awk can be downloaded from here:
|
# a native win32 awk can be downloaded from here:
|
||||||
# http://www.gknw.net/development/prgtools/awk-20050424.zip
|
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||||
AWK = awk
|
AWK = awk
|
||||||
YACC = bison -y
|
YACC = bison -y
|
||||||
CP = cp -afv
|
CP = cp -afv
|
||||||
|
MKDIR = mkdir
|
||||||
# RM = rm -f
|
# RM = rm -f
|
||||||
# if you want to mark the target as MTSAFE you will need a tool for
|
# if you want to mark the target as MTSAFE you will need a tool for
|
||||||
# generating the xdc data for the linker; here's a minimal tool:
|
# generating the xdc data for the linker; here's a minimal tool:
|
||||||
# http://www.gknw.com/development/prgtools/mkxdc.zip
|
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||||
MPKXDC = mkxdc
|
MPKXDC = mkxdc
|
||||||
|
|
||||||
# Global flags for all compilers
|
# Global flags for all compilers
|
||||||
@@ -161,10 +162,6 @@ nlm: prebuild $(TARGETS)
|
|||||||
|
|
||||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h
|
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h arpa/nameser.h
|
||||||
|
|
||||||
dist: all
|
|
||||||
-$(RM) $(OBJLIB) $(OBJDIR)/*.map $(OBJDIR)/*.ncv
|
|
||||||
-$(RM) $(OBJDIR)/*.def $(OBJDIR)/*.xdc $(OBJDIR)/version.inc
|
|
||||||
|
|
||||||
install: $(INSTDIR) all
|
install: $(INSTDIR) all
|
||||||
@$(CP) *.nlm $(INSTDIR)
|
@$(CP) *.nlm $(INSTDIR)
|
||||||
@$(CP) ../CHANGES $(INSTDIR)
|
@$(CP) ../CHANGES $(INSTDIR)
|
||||||
@@ -190,11 +187,8 @@ endif
|
|||||||
@-$(RM) $@
|
@-$(RM) $@
|
||||||
@$(LD) $(LDFLAGS) $<
|
@$(LD) $(LDFLAGS) $<
|
||||||
|
|
||||||
$(INSTDIR):
|
$(OBJDIR) $(INSTDIR):
|
||||||
@mkdir $(INSTDIR)
|
@$(MKDIR) $@
|
||||||
|
|
||||||
$(OBJDIR):
|
|
||||||
@mkdir $(OBJDIR)
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
$(OBJDIR)/%.o: %.c
|
||||||
# @echo Compiling $<
|
# @echo Compiling $<
|
||||||
@@ -202,7 +196,7 @@ $(OBJDIR)/%.o: %.c
|
|||||||
|
|
||||||
$(OBJDIR)/version.inc: ares_version.h $(OBJDIR)
|
$(OBJDIR)/version.inc: ares_version.h $(OBJDIR)
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@
|
@$(AWK) -f get_ver.awk $< > $@
|
||||||
|
|
||||||
$(OBJDIR)/%.xdc: Makefile.netware
|
$(OBJDIR)/%.xdc: Makefile.netware
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@@ -269,8 +263,9 @@ ifdef IMPORTS
|
|||||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
ifeq ($(LD),nlmconv)
|
ifeq ($(LD),nlmconv)
|
||||||
@echo $(DL)input $(OBJEXE)$(DL) >> $@
|
|
||||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||||
|
@echo $(DL)input $(OBJEXE)$(DL) >> $@
|
||||||
|
@echo $(DL)input $(@:.def=.o)$(DL) >> $@
|
||||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -300,7 +295,6 @@ ifeq ($(LIBARCH),CLIB)
|
|||||||
@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@
|
@echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@
|
||||||
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
||||||
@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@
|
@echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@
|
||||||
@echo $(DL)#define DL_LDAP_FILE "ldapsdk.nlm"$(DL) >> $@
|
|
||||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||||
@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@
|
@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@
|
||||||
@echo $(DL)#define strcasecmp stricmp$(DL) >> $@
|
@echo $(DL)#define strcasecmp stricmp$(DL) >> $@
|
||||||
@@ -338,7 +332,6 @@ else
|
|||||||
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
@echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@
|
||||||
@echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@
|
@echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@
|
||||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||||
@echo $(DL)#define DL_LDAP_FILE "lldapsdk.nlm"$(DL) >> $@
|
|
||||||
endif
|
endif
|
||||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj \
|
|||||||
$(OBJ_DIR)\ares_strerror.obj \
|
$(OBJ_DIR)\ares_strerror.obj \
|
||||||
$(OBJ_DIR)\ares_cancel.obj \
|
$(OBJ_DIR)\ares_cancel.obj \
|
||||||
$(OBJ_DIR)\ares_init.obj \
|
$(OBJ_DIR)\ares_init.obj \
|
||||||
|
$(OBJ_DIR)\ares_llist.obj \
|
||||||
$(OBJ_DIR)\ares_timeout.obj \
|
$(OBJ_DIR)\ares_timeout.obj \
|
||||||
$(OBJ_DIR)\ares_destroy.obj \
|
$(OBJ_DIR)\ares_destroy.obj \
|
||||||
$(OBJ_DIR)\ares_mkquery.obj \
|
$(OBJ_DIR)\ares_mkquery.obj \
|
||||||
@@ -75,7 +76,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj \
|
|||||||
$(OBJ_DIR)\inet_net_pton.obj \
|
$(OBJ_DIR)\inet_net_pton.obj \
|
||||||
$(OBJ_DIR)\inet_ntop.obj
|
$(OBJ_DIR)\inet_ntop.obj
|
||||||
|
|
||||||
all: $(OBJ_DIR) cares.lib cares.dll cares_imp.lib ahost.exe adig.exe
|
all: $(OBJ_DIR) cares.lib cares.dll cares_imp.lib ahost.exe adig.exe acountry.exe
|
||||||
@echo Welcome to c-ares library and examples
|
@echo Welcome to c-ares library and examples
|
||||||
|
|
||||||
$(OBJ_DIR):
|
$(OBJ_DIR):
|
||||||
@@ -130,6 +131,9 @@ ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.
|
|||||||
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
|
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
|
||||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
|
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
|
||||||
|
|
||||||
|
acountry.exe: $(OBJ_DIR) $(OBJ_DIR)\acountry.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
|
||||||
|
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\acountry.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
- del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map
|
- del $(OBJ_DIR)\*.obj *.ilk *.pdb *.pbt *.pbi *.pbo *._xe *.map
|
||||||
|
|
||||||
@@ -231,3 +235,6 @@ $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h setup_once.h nameser.h \
|
|||||||
ares_ipv6.h inet_ntop.h
|
ares_ipv6.h inet_ntop.h
|
||||||
|
|
||||||
$(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h
|
$(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h
|
||||||
|
|
||||||
|
$(OBJ_DIR)\ares_llist.obj: ares_llist.c setup.h setup_once.h ares.h \
|
||||||
|
ares_private.h ares_llist.h
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
This is what's new and changed in the c-ares 1.4.1 release:
|
This is what's new and changed in the c-ares 1.5.2 release:
|
||||||
|
|
||||||
o
|
o
|
||||||
|
|
||||||
|
|||||||
@@ -1085,7 +1085,7 @@ AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET],
|
|||||||
# define PLATFORM_SUNOS4
|
# define PLATFORM_SUNOS4
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
|
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||||
# define PLATFORM_AIX_V3
|
# define PLATFORM_AIX_V3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1369,7 +1369,7 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
|||||||
dnl only if the compiler is newer than 2.95 since we got lots of
|
dnl only if the compiler is newer than 2.95 since we got lots of
|
||||||
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
|
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
|
||||||
dnl gcc 2.95.4 on FreeBSD 4.9!
|
dnl gcc 2.95.4 on FreeBSD 4.9!
|
||||||
WARN="$WARN -Wundef -Wno-long-long -Wsign-compare"
|
WARN="$WARN -Wundef -Wno-long-long -Wsign-compare -Wshadow -Wno-multichar"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$gccnum" -ge "296"; then
|
if test "$gccnum" -ge "296"; then
|
||||||
|
|||||||
589
ares/acountry.c
Normal file
589
ares/acountry.c
Normal file
@@ -0,0 +1,589 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* IP-address/hostname to country converter.
|
||||||
|
*
|
||||||
|
* Problem; you want to know where IP a.b.c.d is located.
|
||||||
|
*
|
||||||
|
* Use ares_gethostbyname ("d.c.b.a.zz.countries.nerd.dk")
|
||||||
|
* and get the CNAME (host->h_name). Result will be:
|
||||||
|
* CNAME = zz<CC>.countries.nerd.dk with address 127.0.x.y (ver 1) or
|
||||||
|
* CNAME = <a.b.c.d>.zz.countries.nerd.dk with address 127.0.x.y (ver 2)
|
||||||
|
*
|
||||||
|
* The 2 letter country code in <CC> and the ISO-3166 country
|
||||||
|
* number in x.y (number = x*256 + y). Version 2 of the protocol is missing
|
||||||
|
* the <CC> number.
|
||||||
|
*
|
||||||
|
* Ref: http://countries.nerd.dk/more.html
|
||||||
|
*
|
||||||
|
* Written by G. Vanem <gvanem@broadpark.no> 2006, 2007
|
||||||
|
*
|
||||||
|
* NB! This program may not be big-endian aware.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose and without
|
||||||
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
* notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of M.I.T. not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* M.I.T. makes no representations about the suitability of
|
||||||
|
* this software for any purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <winsock.h>
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ares.h"
|
||||||
|
#include "ares_getopt.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
#include "inet_ntop.h"
|
||||||
|
|
||||||
|
static const char *usage = "acountry [-vh?] {host|addr} ...\n";
|
||||||
|
static const char nerd_fmt[] = "%u.%u.%u.%u.zz.countries.nerd.dk";
|
||||||
|
static const char *nerd_ver1 = nerd_fmt + 14;
|
||||||
|
static const char *nerd_ver2 = nerd_fmt + 11;
|
||||||
|
static int verbose = 0;
|
||||||
|
|
||||||
|
#define TRACE(fmt) do { \
|
||||||
|
if (verbose > 0) \
|
||||||
|
printf fmt ; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void wait_ares(ares_channel channel);
|
||||||
|
static void callback(void *arg, int status, int timeouts, struct hostent *host);
|
||||||
|
static void callback2(void *arg, int status, int timeouts, struct hostent *host);
|
||||||
|
static void find_country_from_cname(const char *cname, struct in_addr addr);
|
||||||
|
|
||||||
|
static void Abort(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ares_channel channel;
|
||||||
|
int ch, status;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
|
||||||
|
WSADATA wsaData;
|
||||||
|
WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ((ch = ares_getopt(argc, argv, "dvh?")) != -1)
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
#ifdef WATT32
|
||||||
|
dbug_init();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose++;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
default:
|
||||||
|
Abort(usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
if (argc < 1)
|
||||||
|
Abort(usage);
|
||||||
|
|
||||||
|
status = ares_init(&channel);
|
||||||
|
if (status != ARES_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ares_init: %s\n", ares_strerror(status));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initiate the queries, one per command-line argument. */
|
||||||
|
for ( ; *argv; argv++)
|
||||||
|
{
|
||||||
|
struct in_addr addr;
|
||||||
|
char buf[100];
|
||||||
|
|
||||||
|
/* If this fails, assume '*argv' is a host-name that
|
||||||
|
* must be resolved first
|
||||||
|
*/
|
||||||
|
if (ares_inet_pton(AF_INET, *argv, &addr) != 1)
|
||||||
|
{
|
||||||
|
ares_gethostbyname(channel, *argv, AF_INET, callback2, &addr);
|
||||||
|
wait_ares(channel);
|
||||||
|
if (addr.s_addr == INADDR_NONE)
|
||||||
|
{
|
||||||
|
printf("Failed to lookup %s\n", *argv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buf, nerd_fmt,
|
||||||
|
(unsigned int)(addr.s_addr >> 24),
|
||||||
|
(unsigned int)((addr.s_addr >> 16) & 255),
|
||||||
|
(unsigned int)((addr.s_addr >> 8) & 255),
|
||||||
|
(unsigned int)(addr.s_addr & 255));
|
||||||
|
TRACE(("Looking up %s...", buf));
|
||||||
|
fflush(stdout);
|
||||||
|
ares_gethostbyname(channel, buf, AF_INET, callback, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_ares(channel);
|
||||||
|
ares_destroy(channel);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the queries to complete.
|
||||||
|
*/
|
||||||
|
static void wait_ares(ares_channel channel)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
struct timeval *tvp, tv;
|
||||||
|
fd_set read_fds, write_fds;
|
||||||
|
int nfds;
|
||||||
|
|
||||||
|
FD_ZERO(&read_fds);
|
||||||
|
FD_ZERO(&write_fds);
|
||||||
|
nfds = ares_fds(channel, &read_fds, &write_fds);
|
||||||
|
if (nfds == 0)
|
||||||
|
break;
|
||||||
|
tvp = ares_timeout(channel, NULL, &tv);
|
||||||
|
select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||||
|
ares_process(channel, &read_fds, &write_fds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the callback used when we have the IP-address of interest.
|
||||||
|
* Extract the CNAME and figure out the country-code from it.
|
||||||
|
*/
|
||||||
|
static void callback(void *arg, int status, int timeouts, struct hostent *host)
|
||||||
|
{
|
||||||
|
const char *name = (const char*)arg;
|
||||||
|
const char *cname;
|
||||||
|
char buf[20];
|
||||||
|
|
||||||
|
(void)timeouts;
|
||||||
|
|
||||||
|
if (!host || status != ARES_SUCCESS)
|
||||||
|
{
|
||||||
|
printf("Failed to lookup %s: %s\n", name, ares_strerror(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE(("\nFound address %s, name %s\n",
|
||||||
|
ares_inet_ntop(AF_INET,(const char*)host->h_addr,buf,sizeof(buf)),
|
||||||
|
host->h_name));
|
||||||
|
|
||||||
|
cname = host->h_name; /* CNAME gets put here */
|
||||||
|
if (!cname)
|
||||||
|
printf("Failed to get CNAME for %s\n", name);
|
||||||
|
else
|
||||||
|
find_country_from_cname(cname, *(struct in_addr*)host->h_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the callback used to obtain the IP-address of the host of interest.
|
||||||
|
*/
|
||||||
|
static void callback2(void *arg, int status, int timeouts, struct hostent *host)
|
||||||
|
{
|
||||||
|
struct in_addr *addr = (struct in_addr*) arg;
|
||||||
|
|
||||||
|
(void)timeouts;
|
||||||
|
if (!host || status != ARES_SUCCESS)
|
||||||
|
memset(addr, INADDR_NONE, sizeof(*addr));
|
||||||
|
else
|
||||||
|
memcpy(addr, host->h_addr, sizeof(*addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct search_list {
|
||||||
|
int country_number; /* ISO-3166 country number */
|
||||||
|
char short_name[3]; /* A2 short country code */
|
||||||
|
const char *long_name; /* normal country name */
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct search_list *list_lookup(int number, const struct search_list *list, int num)
|
||||||
|
{
|
||||||
|
while (num > 0 && list->long_name)
|
||||||
|
{
|
||||||
|
if (list->country_number == number)
|
||||||
|
return (list);
|
||||||
|
num--;
|
||||||
|
list++;
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ref: ftp://ftp.ripe.net/iso3166-countrycodes.txt
|
||||||
|
*/
|
||||||
|
static const struct search_list country_list[] = {
|
||||||
|
{ 4, "af", "Afghanistan" },
|
||||||
|
{ 248, "ax", "<EFBFBD>land Island" },
|
||||||
|
{ 8, "al", "Albania" },
|
||||||
|
{ 12, "dz", "Algeria" },
|
||||||
|
{ 16, "as", "American Samoa" },
|
||||||
|
{ 20, "ad", "Andorra" },
|
||||||
|
{ 24, "ao", "Angola" },
|
||||||
|
{ 660, "ai", "Anguilla" },
|
||||||
|
{ 10, "aq", "Antarctica" },
|
||||||
|
{ 28, "ag", "Antigua & Barbuda" },
|
||||||
|
{ 32, "ar", "Argentina" },
|
||||||
|
{ 51, "am", "Armenia" },
|
||||||
|
{ 533, "aw", "Aruba" },
|
||||||
|
{ 36, "au", "Australia" },
|
||||||
|
{ 40, "at", "Austria" },
|
||||||
|
{ 31, "az", "Azerbaijan" },
|
||||||
|
{ 44, "bs", "Bahamas" },
|
||||||
|
{ 48, "bh", "Bahrain" },
|
||||||
|
{ 50, "bd", "Bangladesh" },
|
||||||
|
{ 52, "bb", "Barbados" },
|
||||||
|
{ 112, "by", "Belarus" },
|
||||||
|
{ 56, "be", "Belgium" },
|
||||||
|
{ 84, "bz", "Belize" },
|
||||||
|
{ 204, "bj", "Benin" },
|
||||||
|
{ 60, "bm", "Bermuda" },
|
||||||
|
{ 64, "bt", "Bhutan" },
|
||||||
|
{ 68, "bo", "Bolivia" },
|
||||||
|
{ 70, "ba", "Bosnia & Herzegowina" },
|
||||||
|
{ 72, "bw", "Botswana" },
|
||||||
|
{ 74, "bv", "Bouvet Island" },
|
||||||
|
{ 76, "br", "Brazil" },
|
||||||
|
{ 86, "io", "British Indian Ocean Territory" },
|
||||||
|
{ 96, "bn", "Brunei Darussalam" },
|
||||||
|
{ 100, "bg", "Bulgaria" },
|
||||||
|
{ 854, "bf", "Burkina Faso" },
|
||||||
|
{ 108, "bi", "Burundi" },
|
||||||
|
{ 116, "kh", "Cambodia" },
|
||||||
|
{ 120, "cm", "Cameroon" },
|
||||||
|
{ 124, "ca", "Canada" },
|
||||||
|
{ 132, "cv", "Cape Verde" },
|
||||||
|
{ 136, "ky", "Cayman Islands" },
|
||||||
|
{ 140, "cf", "Central African Republic" },
|
||||||
|
{ 148, "td", "Chad" },
|
||||||
|
{ 152, "cl", "Chile" },
|
||||||
|
{ 156, "cn", "China" },
|
||||||
|
{ 162, "cx", "Christmas Island" },
|
||||||
|
{ 166, "cc", "Cocos Islands" },
|
||||||
|
{ 170, "co", "Colombia" },
|
||||||
|
{ 174, "km", "Comoros" },
|
||||||
|
{ 178, "cg", "Congo" },
|
||||||
|
{ 180, "cd", "Congo" },
|
||||||
|
{ 184, "ck", "Cook Islands" },
|
||||||
|
{ 188, "cr", "Costa Rica" },
|
||||||
|
{ 384, "ci", "Cote d'Ivoire" },
|
||||||
|
{ 191, "hr", "Croatia" },
|
||||||
|
{ 192, "cu", "Cuba" },
|
||||||
|
{ 196, "cy", "Cyprus" },
|
||||||
|
{ 203, "cz", "Czech Republic" },
|
||||||
|
{ 208, "dk", "Denmark" },
|
||||||
|
{ 262, "dj", "Djibouti" },
|
||||||
|
{ 212, "dm", "Dominica" },
|
||||||
|
{ 214, "do", "Dominican Republic" },
|
||||||
|
{ 218, "ec", "Ecuador" },
|
||||||
|
{ 818, "eg", "Egypt" },
|
||||||
|
{ 222, "sv", "El Salvador" },
|
||||||
|
{ 226, "gq", "Equatorial Guinea" },
|
||||||
|
{ 232, "er", "Eritrea" },
|
||||||
|
{ 233, "ee", "Estonia" },
|
||||||
|
{ 231, "et", "Ethiopia" },
|
||||||
|
{ 238, "fk", "Falkland Islands" },
|
||||||
|
{ 234, "fo", "Faroe Islands" },
|
||||||
|
{ 242, "fj", "Fiji" },
|
||||||
|
{ 246, "fi", "Finland" },
|
||||||
|
{ 250, "fr", "France" },
|
||||||
|
{ 249, "fx", "France, Metropolitan" },
|
||||||
|
{ 254, "gf", "French Guiana" },
|
||||||
|
{ 258, "pf", "French Polynesia" },
|
||||||
|
{ 260, "tf", "French Southern Territories" },
|
||||||
|
{ 266, "ga", "Gabon" },
|
||||||
|
{ 270, "gm", "Gambia" },
|
||||||
|
{ 268, "ge", "Georgia" },
|
||||||
|
{ 276, "de", "Germany" },
|
||||||
|
{ 288, "gh", "Ghana" },
|
||||||
|
{ 292, "gi", "Gibraltar" },
|
||||||
|
{ 300, "gr", "Greece" },
|
||||||
|
{ 304, "gl", "Greenland" },
|
||||||
|
{ 308, "gd", "Grenada" },
|
||||||
|
{ 312, "gp", "Guadeloupe" },
|
||||||
|
{ 316, "gu", "Guam" },
|
||||||
|
{ 320, "gt", "Guatemala" },
|
||||||
|
{ 324, "gn", "Guinea" },
|
||||||
|
{ 624, "gw", "Guinea-Bissau" },
|
||||||
|
{ 328, "gy", "Guyana" },
|
||||||
|
{ 332, "ht", "Haiti" },
|
||||||
|
{ 334, "hm", "Heard & Mc Donald Islands" },
|
||||||
|
{ 336, "va", "Vatican City" },
|
||||||
|
{ 340, "hn", "Honduras" },
|
||||||
|
{ 344, "hk", "Hong kong" },
|
||||||
|
{ 348, "hu", "Hungary" },
|
||||||
|
{ 352, "is", "Iceland" },
|
||||||
|
{ 356, "in", "India" },
|
||||||
|
{ 360, "id", "Indonesia" },
|
||||||
|
{ 364, "ir", "Iran" },
|
||||||
|
{ 368, "iq", "Iraq" },
|
||||||
|
{ 372, "ie", "Ireland" },
|
||||||
|
{ 376, "il", "Israel" },
|
||||||
|
{ 380, "it", "Italy" },
|
||||||
|
{ 388, "jm", "Jamaica" },
|
||||||
|
{ 392, "jp", "Japan" },
|
||||||
|
{ 400, "jo", "Jordan" },
|
||||||
|
{ 398, "kz", "Kazakhstan" },
|
||||||
|
{ 404, "ke", "Kenya" },
|
||||||
|
{ 296, "ki", "Kiribati" },
|
||||||
|
{ 408, "kp", "Korea (north)" },
|
||||||
|
{ 410, "kr", "Korea (south)" },
|
||||||
|
{ 414, "kw", "Kuwait" },
|
||||||
|
{ 417, "kg", "Kyrgyzstan" },
|
||||||
|
{ 418, "la", "Laos" },
|
||||||
|
{ 428, "lv", "Latvia" },
|
||||||
|
{ 422, "lb", "Lebanon" },
|
||||||
|
{ 426, "ls", "Lesotho" },
|
||||||
|
{ 430, "lr", "Liberia" },
|
||||||
|
{ 434, "ly", "Libya" },
|
||||||
|
{ 438, "li", "Liechtenstein" },
|
||||||
|
{ 440, "lt", "Lithuania" },
|
||||||
|
{ 442, "lu", "Luxembourg" },
|
||||||
|
{ 446, "mo", "Macao" },
|
||||||
|
{ 807, "mk", "Macedonia" },
|
||||||
|
{ 450, "mg", "Madagascar" },
|
||||||
|
{ 454, "mw", "Malawi" },
|
||||||
|
{ 458, "my", "Malaysia" },
|
||||||
|
{ 462, "mv", "Maldives" },
|
||||||
|
{ 466, "ml", "Mali" },
|
||||||
|
{ 470, "mt", "Malta" },
|
||||||
|
{ 584, "mh", "Marshall Islands" },
|
||||||
|
{ 474, "mq", "Martinique" },
|
||||||
|
{ 478, "mr", "Mauritania" },
|
||||||
|
{ 480, "mu", "Mauritius" },
|
||||||
|
{ 175, "yt", "Mayotte" },
|
||||||
|
{ 484, "mx", "Mexico" },
|
||||||
|
{ 583, "fm", "Micronesia" },
|
||||||
|
{ 498, "md", "Moldova" },
|
||||||
|
{ 492, "mc", "Monaco" },
|
||||||
|
{ 496, "mn", "Mongolia" },
|
||||||
|
{ 500, "ms", "Montserrat" },
|
||||||
|
{ 504, "ma", "Morocco" },
|
||||||
|
{ 508, "mz", "Mozambique" },
|
||||||
|
{ 104, "mm", "Myanmar" },
|
||||||
|
{ 516, "na", "Namibia" },
|
||||||
|
{ 520, "nr", "Nauru" },
|
||||||
|
{ 524, "np", "Nepal" },
|
||||||
|
{ 528, "nl", "Netherlands" },
|
||||||
|
{ 530, "an", "Netherlands Antilles" },
|
||||||
|
{ 540, "nc", "New Caledonia" },
|
||||||
|
{ 554, "nz", "New Zealand" },
|
||||||
|
{ 558, "ni", "Nicaragua" },
|
||||||
|
{ 562, "ne", "Niger" },
|
||||||
|
{ 566, "ng", "Nigeria" },
|
||||||
|
{ 570, "nu", "Niue" },
|
||||||
|
{ 574, "nf", "Norfolk Island" },
|
||||||
|
{ 580, "mp", "Northern Mariana Islands" },
|
||||||
|
{ 578, "no", "Norway" },
|
||||||
|
{ 512, "om", "Oman" },
|
||||||
|
{ 586, "pk", "Pakistan" },
|
||||||
|
{ 585, "pw", "Palau" },
|
||||||
|
{ 275, "ps", "Palestinian Territory" },
|
||||||
|
{ 591, "pa", "Panama" },
|
||||||
|
{ 598, "pg", "Papua New Guinea" },
|
||||||
|
{ 600, "py", "Paraguay" },
|
||||||
|
{ 604, "pe", "Peru" },
|
||||||
|
{ 608, "ph", "Philippines" },
|
||||||
|
{ 612, "pn", "Pitcairn" },
|
||||||
|
{ 616, "pl", "Poland" },
|
||||||
|
{ 620, "pt", "Portugal" },
|
||||||
|
{ 630, "pr", "Puerto Rico" },
|
||||||
|
{ 634, "qa", "Qatar" },
|
||||||
|
{ 638, "re", "Reunion" },
|
||||||
|
{ 642, "ro", "Romania" },
|
||||||
|
{ 643, "ru", "Russia" },
|
||||||
|
{ 646, "rw", "Rwanda" },
|
||||||
|
{ 659, "kn", "Saint Kitts & Nevis" },
|
||||||
|
{ 662, "lc", "Saint Lucia" },
|
||||||
|
{ 670, "vc", "Saint Vincent" },
|
||||||
|
{ 882, "ws", "Samoa" },
|
||||||
|
{ 674, "sm", "San Marino" },
|
||||||
|
{ 678, "st", "Sao Tome & Principe" },
|
||||||
|
{ 682, "sa", "Saudi Arabia" },
|
||||||
|
{ 686, "sn", "Senegal" },
|
||||||
|
{ 891, "cs", "Serbia and Montenegro" },
|
||||||
|
{ 690, "sc", "Seychelles" },
|
||||||
|
{ 694, "sl", "Sierra Leone" },
|
||||||
|
{ 702, "sg", "Singapore" },
|
||||||
|
{ 703, "sk", "Slovakia" },
|
||||||
|
{ 705, "si", "Slovenia" },
|
||||||
|
{ 90, "sb", "Solomon Islands" },
|
||||||
|
{ 706, "so", "Somalia" },
|
||||||
|
{ 710, "za", "South Africa" },
|
||||||
|
{ 239, "gs", "South Georgia" },
|
||||||
|
{ 724, "es", "Spain" },
|
||||||
|
{ 144, "lk", "Sri Lanka" },
|
||||||
|
{ 654, "sh", "St. Helena" },
|
||||||
|
{ 666, "pm", "St. Pierre & Miquelon" },
|
||||||
|
{ 736, "sd", "Sudan" },
|
||||||
|
{ 740, "sr", "Suriname" },
|
||||||
|
{ 744, "sj", "Svalbard & Jan Mayen Islands" },
|
||||||
|
{ 748, "sz", "Swaziland" },
|
||||||
|
{ 752, "se", "Sweden" },
|
||||||
|
{ 756, "ch", "Switzerland" },
|
||||||
|
{ 760, "sy", "Syrian Arab Republic" },
|
||||||
|
{ 626, "tl", "Timor-Leste" },
|
||||||
|
{ 158, "tw", "Taiwan" },
|
||||||
|
{ 762, "tj", "Tajikistan" },
|
||||||
|
{ 834, "tz", "Tanzania" },
|
||||||
|
{ 764, "th", "Thailand" },
|
||||||
|
{ 768, "tg", "Togo" },
|
||||||
|
{ 772, "tk", "Tokelau" },
|
||||||
|
{ 776, "to", "Tonga" },
|
||||||
|
{ 780, "tt", "Trinidad & Tobago" },
|
||||||
|
{ 788, "tn", "Tunisia" },
|
||||||
|
{ 792, "tr", "Turkey" },
|
||||||
|
{ 795, "tm", "Turkmenistan" },
|
||||||
|
{ 796, "tc", "Turks & Caicos Islands" },
|
||||||
|
{ 798, "tv", "Tuvalu" },
|
||||||
|
{ 800, "ug", "Uganda" },
|
||||||
|
{ 804, "ua", "Ukraine" },
|
||||||
|
{ 784, "ae", "United Arab Emirates" },
|
||||||
|
{ 826, "gb", "United Kingdom" },
|
||||||
|
{ 840, "us", "United States" },
|
||||||
|
{ 581, "um", "United States Minor Outlying Islands" },
|
||||||
|
{ 858, "uy", "Uruguay" },
|
||||||
|
{ 860, "uz", "Uzbekistan" },
|
||||||
|
{ 548, "vu", "Vanuatu" },
|
||||||
|
{ 862, "ve", "Venezuela" },
|
||||||
|
{ 704, "vn", "Vietnam" },
|
||||||
|
{ 92, "vg", "Virgin Islands (British)" },
|
||||||
|
{ 850, "vi", "Virgin Islands (US)" },
|
||||||
|
{ 876, "wf", "Wallis & Futuna Islands" },
|
||||||
|
{ 732, "eh", "Western Sahara" },
|
||||||
|
{ 887, "ye", "Yemen" },
|
||||||
|
{ 894, "zm", "Zambia" },
|
||||||
|
{ 716, "zw", "Zimbabwe" }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if start of 'str' is simply an IPv4 address.
|
||||||
|
*/
|
||||||
|
#define BYTE_OK(x) ((x) >= 0 && (x) <= 255)
|
||||||
|
|
||||||
|
static int is_addr(char *str, char **end)
|
||||||
|
{
|
||||||
|
int a0, a1, a2, a3, num, rc = 0, length = 0;
|
||||||
|
|
||||||
|
if ((num = sscanf(str,"%3d.%3d.%3d.%3d%n",&a0,&a1,&a2,&a3,&length)) == 4 &&
|
||||||
|
BYTE_OK(a0) && BYTE_OK(a1) && BYTE_OK(a2) && BYTE_OK(a3) &&
|
||||||
|
length >= (3+4))
|
||||||
|
{
|
||||||
|
rc = 1;
|
||||||
|
*end = str + length;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the country-code and name from the CNAME. E.g.:
|
||||||
|
* version 1: CNAME = zzno.countries.nerd.dk with address 127.0.2.66
|
||||||
|
* yields ccode_A" = "no" and cnumber 578 (2.66).
|
||||||
|
* version 2: CNAME = <a.b.c.d>.zz.countries.nerd.dk with address 127.0.2.66
|
||||||
|
* yields cnumber 578 (2.66). ccode_A is "";
|
||||||
|
*/
|
||||||
|
static void find_country_from_cname(const char *cname, struct in_addr addr)
|
||||||
|
{
|
||||||
|
const struct search_list *country;
|
||||||
|
char ccode_A2[3], *ccopy, *dot_4;
|
||||||
|
int cnumber, z0, z1, ver_1, ver_2;
|
||||||
|
u_long ip;
|
||||||
|
|
||||||
|
ip = ntohl(addr.s_addr);
|
||||||
|
z0 = tolower(cname[0]);
|
||||||
|
z1 = tolower(cname[1]);
|
||||||
|
ccopy = strdup(cname);
|
||||||
|
|
||||||
|
ver_1 = (z0 == 'z' && z1 == 'z' && !strcasecmp(cname+4,nerd_ver1));
|
||||||
|
ver_2 = (is_addr(ccopy,&dot_4) && !strcasecmp(dot_4,nerd_ver2));
|
||||||
|
|
||||||
|
if (ver_1)
|
||||||
|
{
|
||||||
|
const char *dot = strchr(cname, '.');
|
||||||
|
if ((z0 != 'z' && z1 != 'z') || dot != cname+4)
|
||||||
|
{
|
||||||
|
printf("Unexpected CNAME %s (ver_1)\n", cname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ver_2)
|
||||||
|
{
|
||||||
|
z0 = tolower(dot_4[1]);
|
||||||
|
z1 = tolower(dot_4[2]);
|
||||||
|
if (z0 != 'z' && z1 != 'z')
|
||||||
|
{
|
||||||
|
printf("Unexpected CNAME %s (ver_2)\n", cname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Unexpected CNAME %s (ver?)\n", cname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ver_1)
|
||||||
|
{
|
||||||
|
ccode_A2[0] = tolower(cname[2]);
|
||||||
|
ccode_A2[1] = tolower(cname[3]);
|
||||||
|
ccode_A2[2] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ccode_A2[0] = '\0';
|
||||||
|
|
||||||
|
cnumber = ip & 0xFFFF;
|
||||||
|
|
||||||
|
TRACE(("Found country-code `%s', number %d\n",
|
||||||
|
ver_1 ? ccode_A2 : "<n/a>", cnumber));
|
||||||
|
|
||||||
|
country = list_lookup(cnumber, country_list,
|
||||||
|
sizeof(country_list) / sizeof(country_list[0]));
|
||||||
|
if (!country)
|
||||||
|
printf("Name for country-number %d not found.\n", cnumber);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ver_1 && *(unsigned short*)&country->short_name != *(unsigned*)&ccode_A2)
|
||||||
|
printf("short-name mismatch; %s vs %s\n", country->short_name, ccode_A2);
|
||||||
|
|
||||||
|
printf("%s (%s), number %d.\n",
|
||||||
|
country->long_name, country->short_name, cnumber);
|
||||||
|
}
|
||||||
|
free(ccopy);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,8 @@ static const char *rcodes[] = {
|
|||||||
"(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
|
"(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void callback(void *arg, int status, unsigned char *abuf, int alen);
|
static void callback(void *arg, int status, int timeouts,
|
||||||
|
unsigned char *abuf, int alen);
|
||||||
static const unsigned char *display_question(const unsigned char *aptr,
|
static const unsigned char *display_question(const unsigned char *aptr,
|
||||||
const unsigned char *abuf,
|
const unsigned char *abuf,
|
||||||
int alen);
|
int alen);
|
||||||
@@ -294,7 +295,8 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callback(void *arg, int status, unsigned char *abuf, int alen)
|
static void callback(void *arg, int status, int timeouts,
|
||||||
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
char *name = (char *) arg;
|
char *name = (char *) arg;
|
||||||
int id, qr, opcode, aa, tc, rd, ra, rcode;
|
int id, qr, opcode, aa, tc, rd, ra, rcode;
|
||||||
|
|||||||
11
ares/ahost.c
11
ares/ahost.c
@@ -40,14 +40,7 @@
|
|||||||
#include "inet_net_pton.h"
|
#include "inet_net_pton.h"
|
||||||
#include "ares_getopt.h"
|
#include "ares_getopt.h"
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
static void callback(void *arg, int status, int timeouts, struct hostent *host);
|
||||||
struct in6_addr
|
|
||||||
{
|
|
||||||
unsigned char s6_addr[16];
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void callback(void *arg, int status, struct hostent *host);
|
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -142,7 +135,7 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callback(void *arg, int status, struct hostent *host)
|
static void callback(void *arg, int status, int timeouts, struct hostent *host)
|
||||||
{
|
{
|
||||||
char **p;
|
char **p;
|
||||||
|
|
||||||
|
|||||||
69
ares/ares.h
69
ares/ares.h
@@ -18,6 +18,14 @@
|
|||||||
#ifndef ARES__H
|
#ifndef ARES__H
|
||||||
#define ARES__H
|
#define ARES__H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define WIN32 when build target is Win32 API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
#if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||||
@@ -35,8 +43,12 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <tcp.h>
|
#include <tcp.h>
|
||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
#include <winsock2.h>
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -98,6 +110,8 @@ extern "C" {
|
|||||||
#define ARES_OPT_LOOKUPS (1 << 8)
|
#define ARES_OPT_LOOKUPS (1 << 8)
|
||||||
#define ARES_OPT_SOCK_STATE_CB (1 << 9)
|
#define ARES_OPT_SOCK_STATE_CB (1 << 9)
|
||||||
#define ARES_OPT_SORTLIST (1 << 10)
|
#define ARES_OPT_SORTLIST (1 << 10)
|
||||||
|
#define ARES_OPT_SOCK_SNDBUF (1 << 11)
|
||||||
|
#define ARES_OPT_SOCK_RCVBUF (1 << 12)
|
||||||
|
|
||||||
/* Nameinfo flag values */
|
/* Nameinfo flag values */
|
||||||
#define ARES_NI_NOFQDN (1 << 0)
|
#define ARES_NI_NOFQDN (1 << 0)
|
||||||
@@ -156,17 +170,10 @@ typedef int ares_socket_t;
|
|||||||
#define ares_socket_typedef
|
#define ares_socket_typedef
|
||||||
#endif /* ares_socket_typedef */
|
#endif /* ares_socket_typedef */
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
typedef void (*ares_sock_state_cb)(void *data,
|
typedef void (*ares_sock_state_cb)(void *data,
|
||||||
SOCKET socket,
|
ares_socket_t socket_fd,
|
||||||
int readable,
|
int readable,
|
||||||
int writable);
|
int writable);
|
||||||
#else
|
|
||||||
typedef void (*ares_sock_state_cb)(void *data,
|
|
||||||
int socket,
|
|
||||||
int readable,
|
|
||||||
int writable);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct apattern;
|
struct apattern;
|
||||||
|
|
||||||
@@ -177,6 +184,8 @@ struct ares_options {
|
|||||||
int ndots;
|
int ndots;
|
||||||
unsigned short udp_port;
|
unsigned short udp_port;
|
||||||
unsigned short tcp_port;
|
unsigned short tcp_port;
|
||||||
|
int socket_send_buffer_size;
|
||||||
|
int socket_receive_buffer_size;
|
||||||
struct in_addr *servers;
|
struct in_addr *servers;
|
||||||
int nservers;
|
int nservers;
|
||||||
char **domains;
|
char **domains;
|
||||||
@@ -193,11 +202,11 @@ struct timeval;
|
|||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
struct ares_channeldata;
|
struct ares_channeldata;
|
||||||
typedef struct ares_channeldata *ares_channel;
|
typedef struct ares_channeldata *ares_channel;
|
||||||
typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf,
|
typedef void (*ares_callback)(void *arg, int status, int timeouts,
|
||||||
int alen);
|
unsigned char *abuf, int alen);
|
||||||
typedef void (*ares_host_callback)(void *arg, int status,
|
typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
|
||||||
struct hostent *hostent);
|
struct hostent *hostent);
|
||||||
typedef void (*ares_nameinfo_callback)(void *arg, int status,
|
typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
|
||||||
char *node, char *service);
|
char *node, char *service);
|
||||||
|
|
||||||
int ares_init(ares_channel *channelptr);
|
int ares_init(ares_channel *channelptr);
|
||||||
@@ -235,10 +244,38 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
|||||||
int alen, char **s, long *enclen);
|
int alen, char **s, long *enclen);
|
||||||
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
|
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
|
||||||
int alen, unsigned char **s, long *enclen);
|
int alen, unsigned char **s, long *enclen);
|
||||||
|
|
||||||
|
#if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr)
|
||||||
|
struct in6_addr {
|
||||||
|
union {
|
||||||
|
unsigned char _S6_u8[16];
|
||||||
|
} _S6_un;
|
||||||
|
};
|
||||||
|
#define s6_addr _S6_un._S6_u8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct addrttl {
|
||||||
|
struct in_addr ipaddr;
|
||||||
|
int ttl;
|
||||||
|
};
|
||||||
|
struct addr6ttl {
|
||||||
|
struct in6_addr ip6addr;
|
||||||
|
int ttl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Parse the buffer, starting at *abuf and of length alen bytes, previously
|
||||||
|
** obtained from an ares_search call. Put the results in *host, if nonnull.
|
||||||
|
** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
|
||||||
|
** their TTLs in that array, and set *naddrttls to the number of addresses
|
||||||
|
** so written.
|
||||||
|
*/
|
||||||
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
||||||
struct hostent **host);
|
struct hostent **host,
|
||||||
|
struct addrttl *addrttls, int *naddrttls);
|
||||||
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
||||||
struct hostent **host);
|
struct hostent **host,
|
||||||
|
struct addr6ttl *addrttls, int *naddrttls);
|
||||||
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
||||||
int addrlen, int family, struct hostent **host);
|
int addrlen, int family, struct hostent **host);
|
||||||
int ares_parse_ns_reply(const unsigned char *abuf, int alen,
|
int ares_parse_ns_reply(const unsigned char *abuf, int alen,
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ void ares__close_sockets(ares_channel channel, struct server_state *server)
|
|||||||
/* Advance server->qhead; pull out query as we go. */
|
/* Advance server->qhead; pull out query as we go. */
|
||||||
sendreq = server->qhead;
|
sendreq = server->qhead;
|
||||||
server->qhead = sendreq->next;
|
server->qhead = sendreq->next;
|
||||||
|
if (sendreq->data_storage != NULL)
|
||||||
|
free(sendreq->data_storage);
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
server->qtail = NULL;
|
server->qtail = NULL;
|
||||||
@@ -45,12 +47,16 @@ void ares__close_sockets(ares_channel channel, struct server_state *server)
|
|||||||
server->tcp_buffer = NULL;
|
server->tcp_buffer = NULL;
|
||||||
server->tcp_lenbuf_pos = 0;
|
server->tcp_lenbuf_pos = 0;
|
||||||
|
|
||||||
|
/* Reset brokenness */
|
||||||
|
server->is_broken = 0;
|
||||||
|
|
||||||
/* Close the TCP and UDP sockets. */
|
/* Close the TCP and UDP sockets. */
|
||||||
if (server->tcp_socket != ARES_SOCKET_BAD)
|
if (server->tcp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0);
|
||||||
closesocket(server->tcp_socket);
|
closesocket(server->tcp_socket);
|
||||||
server->tcp_socket = ARES_SOCKET_BAD;
|
server->tcp_socket = ARES_SOCKET_BAD;
|
||||||
|
server->tcp_connection_generation = ++channel->tcp_connection_generation;
|
||||||
}
|
}
|
||||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
if (server->udp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,29 +14,45 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ares_cancel() cancels a ongoing request/resolve that might be going on on
|
* ares_cancel() cancels all ongoing requests/resolves that might be going on
|
||||||
* the given channel. It does NOT kill the channel, use ares_destroy() for
|
* on the given channel. It does NOT kill the channel, use ares_destroy() for
|
||||||
* that.
|
* that.
|
||||||
*/
|
*/
|
||||||
void ares_cancel(ares_channel channel)
|
void ares_cancel(ares_channel channel)
|
||||||
{
|
{
|
||||||
struct query *query, *next;
|
struct query *query;
|
||||||
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (query = channel->queries; query; query = next)
|
list_head = &(channel->all_queries);
|
||||||
|
for (list_node = list_head->next; list_node != list_head; )
|
||||||
{
|
{
|
||||||
next = query->next;
|
query = list_node->data;
|
||||||
query->callback(query->arg, ARES_ETIMEOUT, NULL, 0);
|
list_node = list_node->next; /* since we're deleting the query */
|
||||||
free(query->tcpbuf);
|
query->callback(query->arg, ARES_ETIMEOUT, 0, NULL, 0);
|
||||||
free(query->skip_server);
|
ares__free_query(query);
|
||||||
free(query);
|
|
||||||
}
|
}
|
||||||
channel->queries = NULL;
|
#ifndef NDEBUG
|
||||||
|
/* Freeing the query should remove it from all the lists in which it sits,
|
||||||
|
* so all query lists should be empty now.
|
||||||
|
*/
|
||||||
|
assert(ares__is_list_empty(&(channel->all_queries)));
|
||||||
|
for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
{
|
{
|
||||||
if (channel->servers)
|
if (channel->servers)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
@@ -37,13 +38,42 @@ void ares_destroy(ares_channel channel)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct query *query;
|
struct query *query;
|
||||||
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
list_head = &(channel->all_queries);
|
||||||
|
for (list_node = list_head->next; list_node != list_head; )
|
||||||
|
{
|
||||||
|
query = list_node->data;
|
||||||
|
list_node = list_node->next; /* since we're deleting the query */
|
||||||
|
query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0);
|
||||||
|
ares__free_query(query);
|
||||||
|
}
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* Freeing the query should remove it from all the lists in which it sits,
|
||||||
|
* so all query lists should be empty now.
|
||||||
|
*/
|
||||||
|
assert(ares__is_list_empty(&(channel->all_queries)));
|
||||||
|
for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
assert(ares__is_list_empty(&(channel->queries_by_qid[i])));
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
assert(ares__is_list_empty(&(channel->queries_by_timeout[i])));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (channel->servers) {
|
if (channel->servers) {
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(channel, &channel->servers[i]);
|
{
|
||||||
|
struct server_state *server = &channel->servers[i];
|
||||||
|
ares__close_sockets(channel, server);
|
||||||
|
assert(ares__is_list_empty(&(server->queries_to_server)));
|
||||||
|
}
|
||||||
free(channel->servers);
|
free(channel->servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,16 +89,5 @@ void ares_destroy(ares_channel channel)
|
|||||||
if (channel->lookups)
|
if (channel->lookups)
|
||||||
free(channel->lookups);
|
free(channel->lookups);
|
||||||
|
|
||||||
while (channel->queries) {
|
|
||||||
query = channel->queries;
|
|
||||||
channel->queries = query->next;
|
|
||||||
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
|
|
||||||
if (query->tcpbuf)
|
|
||||||
free(query->tcpbuf);
|
|
||||||
if (query->skip_server)
|
|
||||||
free(query->skip_server);
|
|
||||||
free(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(channel);
|
free(channel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,15 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
|||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
q = *s;
|
q = *s;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
/* RFC2181 says this should be ".": the root of the DNS tree.
|
||||||
|
* Since this function strips trailing dots though, it becomes ""
|
||||||
|
*/
|
||||||
|
q[0] = '\0';
|
||||||
|
*enclen = 1; /* the caller should move one byte to get past this */
|
||||||
|
return ARES_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* No error-checking necessary; it was all done by name_length(). */
|
/* No error-checking necessary; it was all done by name_length(). */
|
||||||
p = encoded;
|
p = encoded;
|
||||||
while (*p)
|
while (*p)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ ares_expand_string \- Expand a length encoded string
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B ares_expand_string
|
.B ares_expand_string
|
||||||
function converts a length encoded string to a NULL terminated C
|
function converts a length encoded string to a NUL-terminated C
|
||||||
string. The argument
|
string. The argument
|
||||||
.I encoded
|
.I encoded
|
||||||
gives the beginning of the encoded string, and the arguments
|
gives the beginning of the encoded string, and the arguments
|
||||||
|
|||||||
@@ -30,20 +30,26 @@ int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
|
|||||||
ares_socket_t nfds;
|
ares_socket_t nfds;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* No queries, no file descriptors. */
|
/* Are there any active queries? */
|
||||||
if (!channel->queries)
|
int active_queries = !ares__is_list_empty(&(channel->all_queries));
|
||||||
return 0;
|
|
||||||
|
|
||||||
nfds = 0;
|
nfds = 0;
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
{
|
{
|
||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
/* We only need to register interest in UDP sockets if we have
|
||||||
|
* outstanding queries.
|
||||||
|
*/
|
||||||
|
if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
FD_SET(server->udp_socket, read_fds);
|
FD_SET(server->udp_socket, read_fds);
|
||||||
if (server->udp_socket >= nfds)
|
if (server->udp_socket >= nfds)
|
||||||
nfds = server->udp_socket + 1;
|
nfds = server->udp_socket + 1;
|
||||||
}
|
}
|
||||||
|
/* We always register for TCP events, because we want to know
|
||||||
|
* when the other side closes the connection, so we don't waste
|
||||||
|
* time trying to use a broken connection.
|
||||||
|
*/
|
||||||
if (server->tcp_socket != ARES_SOCKET_BAD)
|
if (server->tcp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
FD_SET(server->tcp_socket, read_fds);
|
FD_SET(server->tcp_socket, read_fds);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_gethostbyaddr \- Initiate a host query by address
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B struct hostent *\fIhostent\fP)
|
.B int \fItimeouts\fP, struct hostent *\fIhostent\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP,
|
.B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP,
|
||||||
.B int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP,
|
.B int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP,
|
||||||
@@ -76,6 +76,11 @@ The name service channel
|
|||||||
.I channel
|
.I channel
|
||||||
is being destroyed; the query will not be completed.
|
is being destroyed; the query will not be completed.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
On successful completion of the query, the callback argument
|
On successful completion of the query, the callback argument
|
||||||
.I hostent
|
.I hostent
|
||||||
points to a
|
points to a
|
||||||
|
|||||||
@@ -49,14 +49,16 @@ struct addr_query {
|
|||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
const char *remaining_lookups;
|
const char *remaining_lookups;
|
||||||
|
int timeouts;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void next_lookup(struct addr_query *aquery);
|
static void next_lookup(struct addr_query *aquery);
|
||||||
static void addr_callback(void *arg, int status, unsigned char *abuf,
|
static void addr_callback(void *arg, int status, int timeouts,
|
||||||
int alen);
|
unsigned char *abuf, int alen);
|
||||||
static void end_aquery(struct addr_query *aquery, int status,
|
static void end_aquery(struct addr_query *aquery, int status,
|
||||||
struct hostent *host);
|
struct hostent *host);
|
||||||
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
|
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
|
||||||
|
static void ptr_rr_name(char *name, int family, union ares_addr *addr);
|
||||||
|
|
||||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||||
int family, ares_host_callback callback, void *arg)
|
int family, ares_host_callback callback, void *arg)
|
||||||
@@ -65,21 +67,21 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
|||||||
|
|
||||||
if (family != AF_INET && family != AF_INET6)
|
if (family != AF_INET && family != AF_INET6)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL);
|
callback(arg, ARES_ENOTIMP, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((family == AF_INET && addrlen != sizeof(struct in_addr)) ||
|
if ((family == AF_INET && addrlen != sizeof(struct in_addr)) ||
|
||||||
(family == AF_INET6 && addrlen != sizeof(struct in6_addr)))
|
(family == AF_INET6 && addrlen != sizeof(struct in6_addr)))
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL);
|
callback(arg, ARES_ENOTIMP, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aquery = malloc(sizeof(struct addr_query));
|
aquery = malloc(sizeof(struct addr_query));
|
||||||
if (!aquery)
|
if (!aquery)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL);
|
callback(arg, ARES_ENOMEM, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aquery->channel = channel;
|
aquery->channel = channel;
|
||||||
@@ -91,6 +93,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
|||||||
aquery->callback = callback;
|
aquery->callback = callback;
|
||||||
aquery->arg = arg;
|
aquery->arg = arg;
|
||||||
aquery->remaining_lookups = channel->lookups;
|
aquery->remaining_lookups = channel->lookups;
|
||||||
|
aquery->timeouts = 0;
|
||||||
|
|
||||||
next_lookup(aquery);
|
next_lookup(aquery);
|
||||||
}
|
}
|
||||||
@@ -99,48 +102,26 @@ static void next_lookup(struct addr_query *aquery)
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
char name[128];
|
char name[128];
|
||||||
int a1, a2, a3, a4, status;
|
int status;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
unsigned long addr;
|
|
||||||
|
|
||||||
for (p = aquery->remaining_lookups; *p; p++)
|
for (p = aquery->remaining_lookups; *p; p++)
|
||||||
{
|
{
|
||||||
switch (*p)
|
switch (*p)
|
||||||
{
|
{
|
||||||
case 'b':
|
case 'b':
|
||||||
if (aquery->family == AF_INET)
|
ptr_rr_name(name, aquery->family, &aquery->addr);
|
||||||
{
|
|
||||||
addr = ntohl(aquery->addr.addr4.s_addr);
|
|
||||||
a1 = (int)((addr >> 24) & 0xff);
|
|
||||||
a2 = (int)((addr >> 16) & 0xff);
|
|
||||||
a3 = (int)((addr >> 8) & 0xff);
|
|
||||||
a4 = (int)(addr & 0xff);
|
|
||||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
|
||||||
aquery->remaining_lookups = p + 1;
|
aquery->remaining_lookups = p + 1;
|
||||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||||
aquery);
|
aquery);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *bytes;
|
|
||||||
bytes = (unsigned char *)&aquery->addr.addr6.s6_addr;
|
|
||||||
sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
|
||||||
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
|
|
||||||
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
|
|
||||||
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
|
|
||||||
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
|
|
||||||
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
|
|
||||||
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
|
|
||||||
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
|
|
||||||
bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4);
|
|
||||||
aquery->remaining_lookups = p + 1;
|
|
||||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
|
||||||
aquery);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case 'f':
|
case 'f':
|
||||||
status = file_lookup(&aquery->addr, aquery->family, &host);
|
status = file_lookup(&aquery->addr, aquery->family, &host);
|
||||||
if (status != ARES_ENOTFOUND)
|
|
||||||
|
/* this status check below previously checked for !ARES_ENOTFOUND,
|
||||||
|
but we should not assume that this single error code is the one
|
||||||
|
that can occur, as that is in fact no longer the case */
|
||||||
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
end_aquery(aquery, status, host);
|
end_aquery(aquery, status, host);
|
||||||
return;
|
return;
|
||||||
@@ -151,11 +132,13 @@ static void next_lookup(struct addr_query *aquery)
|
|||||||
end_aquery(aquery, ARES_ENOTFOUND, NULL);
|
end_aquery(aquery, ARES_ENOTFOUND, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addr_callback(void *arg, int status, unsigned char *abuf, int alen)
|
static void addr_callback(void *arg, int status, int timeouts,
|
||||||
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
struct addr_query *aquery = (struct addr_query *) arg;
|
struct addr_query *aquery = (struct addr_query *) arg;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
|
|
||||||
|
aquery->timeouts += timeouts;
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
if (aquery->family == AF_INET)
|
if (aquery->family == AF_INET)
|
||||||
@@ -175,7 +158,7 @@ static void addr_callback(void *arg, int status, unsigned char *abuf, int alen)
|
|||||||
static void end_aquery(struct addr_query *aquery, int status,
|
static void end_aquery(struct addr_query *aquery, int status,
|
||||||
struct hostent *host)
|
struct hostent *host)
|
||||||
{
|
{
|
||||||
aquery->callback(aquery->arg, status, host);
|
aquery->callback(aquery->arg, status, aquery->timeouts, host);
|
||||||
if (host)
|
if (host)
|
||||||
ares_free_hostent(host);
|
ares_free_hostent(host);
|
||||||
free(aquery);
|
free(aquery);
|
||||||
@@ -260,3 +243,31 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
|||||||
*host = NULL;
|
*host = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ptr_rr_name(char *name, int family, union ares_addr *addr)
|
||||||
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
|
{
|
||||||
|
unsigned long laddr = ntohl(addr->addr4.s_addr);
|
||||||
|
int a1 = (int)((laddr >> 24) & 0xff);
|
||||||
|
int a2 = (int)((laddr >> 16) & 0xff);
|
||||||
|
int a3 = (int)((laddr >> 8) & 0xff);
|
||||||
|
int a4 = (int)(laddr & 0xff);
|
||||||
|
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char *bytes = (unsigned char *)&addr->addr6.s6_addr;
|
||||||
|
sprintf(name,
|
||||||
|
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
|
||||||
|
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
||||||
|
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
|
||||||
|
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
|
||||||
|
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
|
||||||
|
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
|
||||||
|
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
|
||||||
|
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
|
||||||
|
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
|
||||||
|
bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_gethostbyname \- Initiate a host query by name
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B struct hostent *\fIhostent\fP)
|
.B int \fItimeouts\fP, struct hostent *\fIhostent\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
.B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP)
|
.B int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
@@ -80,6 +80,11 @@ The name service channel
|
|||||||
.I channel
|
.I channel
|
||||||
is being destroyed; the query will not be completed.
|
is being destroyed; the query will not be completed.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
On successful completion of the query, the callback argument
|
On successful completion of the query, the callback argument
|
||||||
.I hostent
|
.I hostent
|
||||||
points to a
|
points to a
|
||||||
|
|||||||
@@ -54,11 +54,12 @@ struct host_query {
|
|||||||
void *arg;
|
void *arg;
|
||||||
int family;
|
int family;
|
||||||
const char *remaining_lookups;
|
const char *remaining_lookups;
|
||||||
|
int timeouts;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void next_lookup(struct host_query *hquery);
|
static void next_lookup(struct host_query *hquery, int status_code);
|
||||||
static void host_callback(void *arg, int status, unsigned char *abuf,
|
static void host_callback(void *arg, int status, int timeouts,
|
||||||
int alen);
|
unsigned char *abuf, int alen);
|
||||||
static void end_hquery(struct host_query *hquery, int status,
|
static void end_hquery(struct host_query *hquery, int status,
|
||||||
struct hostent *host);
|
struct hostent *host);
|
||||||
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
||||||
@@ -81,7 +82,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
/* Right now we only know how to look up Internet addresses. */
|
/* Right now we only know how to look up Internet addresses. */
|
||||||
if (family != AF_INET && family != AF_INET6)
|
if (family != AF_INET && family != AF_INET6)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL);
|
callback(arg, ARES_ENOTIMP, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
hquery = malloc(sizeof(struct host_query));
|
hquery = malloc(sizeof(struct host_query));
|
||||||
if (!hquery)
|
if (!hquery)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL);
|
callback(arg, ARES_ENOMEM, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hquery->channel = channel;
|
hquery->channel = channel;
|
||||||
@@ -101,22 +102,23 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
if (!hquery->name)
|
if (!hquery->name)
|
||||||
{
|
{
|
||||||
free(hquery);
|
free(hquery);
|
||||||
callback(arg, ARES_ENOMEM, NULL);
|
callback(arg, ARES_ENOMEM, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hquery->callback = callback;
|
hquery->callback = callback;
|
||||||
hquery->arg = arg;
|
hquery->arg = arg;
|
||||||
hquery->remaining_lookups = channel->lookups;
|
hquery->remaining_lookups = channel->lookups;
|
||||||
|
hquery->timeouts = 0;
|
||||||
|
|
||||||
/* Start performing lookups according to channel->lookups. */
|
/* Start performing lookups according to channel->lookups. */
|
||||||
next_lookup(hquery);
|
next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void next_lookup(struct host_query *hquery)
|
static void next_lookup(struct host_query *hquery, int status_code)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
const char *p;
|
const char *p;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
|
int status = status_code;
|
||||||
|
|
||||||
for (p = hquery->remaining_lookups; *p; p++)
|
for (p = hquery->remaining_lookups; *p; p++)
|
||||||
{
|
{
|
||||||
@@ -126,8 +128,8 @@ static void next_lookup(struct host_query *hquery)
|
|||||||
/* DNS lookup */
|
/* DNS lookup */
|
||||||
hquery->remaining_lookups = p + 1;
|
hquery->remaining_lookups = p + 1;
|
||||||
if (hquery->family == AF_INET6)
|
if (hquery->family == AF_INET6)
|
||||||
ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback,
|
ares_search(hquery->channel, hquery->name, C_IN, T_AAAA,
|
||||||
hquery);
|
host_callback, hquery);
|
||||||
else
|
else
|
||||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||||
hquery);
|
hquery);
|
||||||
@@ -136,34 +138,41 @@ static void next_lookup(struct host_query *hquery)
|
|||||||
case 'f':
|
case 'f':
|
||||||
/* Host file lookup */
|
/* Host file lookup */
|
||||||
status = file_lookup(hquery->name, hquery->family, &host);
|
status = file_lookup(hquery->name, hquery->family, &host);
|
||||||
if (status != ARES_ENOTFOUND)
|
|
||||||
|
/* this status check below previously checked for !ARES_ENOTFOUND,
|
||||||
|
but we should not assume that this single error code is the one
|
||||||
|
that can occur, as that is in fact no longer the case */
|
||||||
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
end_hquery(hquery, status, host);
|
end_hquery(hquery, status, host);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
status = status_code; /* Use original status code */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_hquery(hquery, ARES_ENOTFOUND, NULL);
|
end_hquery(hquery, status, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
|
static void host_callback(void *arg, int status, int timeouts,
|
||||||
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
struct host_query *hquery = (struct host_query *) arg;
|
struct host_query *hquery = (struct host_query *) arg;
|
||||||
ares_channel channel = hquery->channel;
|
ares_channel channel = hquery->channel;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
|
|
||||||
|
hquery->timeouts += timeouts;
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
if (hquery->family == AF_INET)
|
if (hquery->family == AF_INET)
|
||||||
{
|
{
|
||||||
status = ares_parse_a_reply(abuf, alen, &host);
|
status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
|
||||||
if (host && channel->nsort)
|
if (host && channel->nsort)
|
||||||
sort_addresses(host, channel->sortlist, channel->nsort);
|
sort_addresses(host, channel->sortlist, channel->nsort);
|
||||||
}
|
}
|
||||||
else if (hquery->family == AF_INET6)
|
else if (hquery->family == AF_INET6)
|
||||||
{
|
{
|
||||||
status = ares_parse_aaaa_reply(abuf, alen, &host);
|
status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
|
||||||
if (host && channel->nsort)
|
if (host && channel->nsort)
|
||||||
sort6_addresses(host, channel->sortlist, channel->nsort);
|
sort6_addresses(host, channel->sortlist, channel->nsort);
|
||||||
}
|
}
|
||||||
@@ -179,13 +188,13 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
|
|||||||
else if (status == ARES_EDESTRUCTION)
|
else if (status == ARES_EDESTRUCTION)
|
||||||
end_hquery(hquery, status, NULL);
|
end_hquery(hquery, status, NULL);
|
||||||
else
|
else
|
||||||
next_lookup(hquery);
|
next_lookup(hquery, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_hquery(struct host_query *hquery, int status,
|
static void end_hquery(struct host_query *hquery, int status,
|
||||||
struct hostent *host)
|
struct hostent *host)
|
||||||
{
|
{
|
||||||
hquery->callback(hquery->arg, status, host);
|
hquery->callback(hquery->arg, status, hquery->timeouts, host);
|
||||||
if (host)
|
if (host)
|
||||||
ares_free_hostent(host);
|
ares_free_hostent(host);
|
||||||
free(hquery->name);
|
free(hquery->name);
|
||||||
@@ -206,7 +215,27 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
|
|||||||
struct in6_addr in6;
|
struct in6_addr in6;
|
||||||
|
|
||||||
if (family == AF_INET)
|
if (family == AF_INET)
|
||||||
|
{
|
||||||
|
/* It only looks like an IP address if it's all numbers and dots. */
|
||||||
|
int numdots = 0;
|
||||||
|
const char *p;
|
||||||
|
for (p = name; *p; p++)
|
||||||
|
{
|
||||||
|
if (!ISDIGIT(*p) && *p != '.') {
|
||||||
|
return 0;
|
||||||
|
} else if (*p == '.') {
|
||||||
|
numdots++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we don't have 3 dots, it is illegal
|
||||||
|
* (although inet_addr doesn't think so).
|
||||||
|
*/
|
||||||
|
if (numdots != 3)
|
||||||
|
result = 0;
|
||||||
|
else
|
||||||
result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
|
result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
|
||||||
|
}
|
||||||
else if (family == AF_INET6)
|
else if (family == AF_INET6)
|
||||||
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
|
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
|
||||||
|
|
||||||
@@ -227,7 +256,7 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
|
|||||||
hostent.h_name = strdup(name);
|
hostent.h_name = strdup(name);
|
||||||
if (!hostent.h_name)
|
if (!hostent.h_name)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL);
|
callback(arg, ARES_ENOMEM, 0, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +265,7 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
|
|||||||
hostent.h_aliases = aliases;
|
hostent.h_aliases = aliases;
|
||||||
hostent.h_addrtype = family;
|
hostent.h_addrtype = family;
|
||||||
hostent.h_addr_list = addrs;
|
hostent.h_addr_list = addrs;
|
||||||
callback(arg, ARES_SUCCESS, &hostent);
|
callback(arg, ARES_SUCCESS, 0, &hostent);
|
||||||
|
|
||||||
free((char *)(hostent.h_name));
|
free((char *)(hostent.h_name));
|
||||||
return 1;
|
return 1;
|
||||||
@@ -416,4 +445,3 @@ static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
|||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_getnameinfo \- Address-to-nodename translation in protocol-independent mann
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B char *\fInode\fP, char *\fIservice\fP)
|
.B int \fItimeouts\fP, char *\fInode\fP, char *\fIservice\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
|
.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
|
||||||
.B socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,
|
.B socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,
|
||||||
@@ -120,6 +120,11 @@ The
|
|||||||
.I flags
|
.I flags
|
||||||
parameter contains an illegal value.
|
parameter contains an illegal value.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
On successful completion of the query, the callback argument
|
On successful completion of the query, the callback argument
|
||||||
.I node
|
.I node
|
||||||
contains a string representing the hostname (assuming
|
contains a string representing the hostname (assuming
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ struct nameinfo_query {
|
|||||||
} addr;
|
} addr;
|
||||||
int family;
|
int family;
|
||||||
int flags;
|
int flags;
|
||||||
|
int timeouts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
@@ -67,7 +68,7 @@ struct nameinfo_query {
|
|||||||
#define IPBUFSIZ 40
|
#define IPBUFSIZ 40
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void nameinfo_callback(void *arg, int status, struct hostent *host);
|
static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host);
|
||||||
static char *lookup_service(unsigned short port, int flags,
|
static char *lookup_service(unsigned short port, int flags,
|
||||||
char *buf, size_t buflen);
|
char *buf, size_t buflen);
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
@@ -90,7 +91,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
addr6 = (struct sockaddr_in6 *)sa;
|
addr6 = (struct sockaddr_in6 *)sa;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL, NULL);
|
callback(arg, ARES_ENOTIMP, 0, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
port = addr6->sin6_port;
|
port = addr6->sin6_port;
|
||||||
service = lookup_service((unsigned short)(port & 0xffff),
|
service = lookup_service((unsigned short)(port & 0xffff),
|
||||||
flags, buf, sizeof(buf));
|
flags, buf, sizeof(buf));
|
||||||
callback(arg, ARES_SUCCESS, NULL, service);
|
callback(arg, ARES_SUCCESS, 0, NULL, service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
*/
|
*/
|
||||||
if (flags & ARES_NI_NAMEREQD)
|
if (flags & ARES_NI_NAMEREQD)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_EBADFLAGS, NULL, NULL);
|
callback(arg, ARES_EBADFLAGS, 0, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (salen == sizeof(struct sockaddr_in6))
|
if (salen == sizeof(struct sockaddr_in6))
|
||||||
@@ -152,7 +153,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
if (flags & ARES_NI_LOOKUPSERVICE)
|
if (flags & ARES_NI_LOOKUPSERVICE)
|
||||||
service = lookup_service((unsigned short)(port & 0xffff),
|
service = lookup_service((unsigned short)(port & 0xffff),
|
||||||
flags, srvbuf, sizeof(srvbuf));
|
flags, srvbuf, sizeof(srvbuf));
|
||||||
callback(arg, ARES_SUCCESS, ipbuf, service);
|
callback(arg, ARES_SUCCESS, 0, ipbuf, service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* This is where a DNS lookup becomes necessary */
|
/* This is where a DNS lookup becomes necessary */
|
||||||
@@ -161,12 +162,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
niquery = malloc(sizeof(struct nameinfo_query));
|
niquery = malloc(sizeof(struct nameinfo_query));
|
||||||
if (!niquery)
|
if (!niquery)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL, NULL);
|
callback(arg, ARES_ENOMEM, 0, NULL, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
niquery->callback = callback;
|
niquery->callback = callback;
|
||||||
niquery->arg = arg;
|
niquery->arg = arg;
|
||||||
niquery->flags = flags;
|
niquery->flags = flags;
|
||||||
|
niquery->timeouts = 0;
|
||||||
if (sa->sa_family == AF_INET)
|
if (sa->sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
niquery->family = AF_INET;
|
niquery->family = AF_INET;
|
||||||
@@ -185,13 +187,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host)
|
||||||
{
|
{
|
||||||
struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
|
struct nameinfo_query *niquery = (struct nameinfo_query *) arg;
|
||||||
char srvbuf[33];
|
char srvbuf[33];
|
||||||
char *service = NULL;
|
char *service = NULL;
|
||||||
|
|
||||||
|
niquery->timeouts += timeouts;
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
/* They want a service too */
|
/* They want a service too */
|
||||||
@@ -220,7 +222,7 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
|||||||
*end = 0;
|
*end = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
niquery->callback(niquery->arg, ARES_SUCCESS, (char *)(host->h_name),
|
niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name),
|
||||||
service);
|
service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -247,10 +249,10 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
|||||||
service = lookup_service(niquery->addr.addr6.sin6_port,
|
service = lookup_service(niquery->addr.addr6.sin6_port,
|
||||||
niquery->flags, srvbuf, sizeof(srvbuf));
|
niquery->flags, srvbuf, sizeof(srvbuf));
|
||||||
}
|
}
|
||||||
niquery->callback(niquery->arg, ARES_SUCCESS, ipbuf, service);
|
niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf, service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
niquery->callback(niquery->arg, status, NULL, NULL);
|
niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL);
|
||||||
free(niquery);
|
free(niquery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,16 +34,18 @@ int ares_getsock(ares_channel channel,
|
|||||||
|
|
||||||
ares_socket_t *socks = (ares_socket_t *)s;
|
ares_socket_t *socks = (ares_socket_t *)s;
|
||||||
|
|
||||||
/* No queries, no file descriptors. */
|
/* Are there any active queries? */
|
||||||
if (!channel->queries)
|
int active_queries = !ares__is_list_empty(&(channel->all_queries));
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
(i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
|
(i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
/* We only need to register interest in UDP sockets if we have
|
||||||
|
* outstanding queries.
|
||||||
|
*/
|
||||||
|
if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
if(sockindex >= numsocks)
|
if(sockindex >= numsocks)
|
||||||
break;
|
break;
|
||||||
@@ -51,6 +53,10 @@ int ares_getsock(ares_channel channel,
|
|||||||
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
||||||
sockindex++;
|
sockindex++;
|
||||||
}
|
}
|
||||||
|
/* We always register for TCP events, because we want to know
|
||||||
|
* when the other side closes the connection, so we don't waste
|
||||||
|
* time trying to use a broken connection.
|
||||||
|
*/
|
||||||
if (server->tcp_socket != ARES_SOCKET_BAD)
|
if (server->tcp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
if(sockindex >= numsocks)
|
if(sockindex >= numsocks)
|
||||||
@@ -58,7 +64,7 @@ int ares_getsock(ares_channel channel,
|
|||||||
socks[sockindex] = server->tcp_socket;
|
socks[sockindex] = server->tcp_socket;
|
||||||
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
||||||
|
|
||||||
if (server->qhead)
|
if (server->qhead && active_queries)
|
||||||
/* then the tcp socket is also writable! */
|
/* then the tcp socket is also writable! */
|
||||||
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
|
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
|||||||
static int set_search(ares_channel channel, const char *str);
|
static int set_search(ares_channel channel, const char *str);
|
||||||
static int set_options(ares_channel channel, const char *str);
|
static int set_options(ares_channel channel, const char *str);
|
||||||
static const char *try_option(const char *p, const char *q, const char *opt);
|
static const char *try_option(const char *p, const char *q, const char *opt);
|
||||||
static void init_id_key(rc4_key* key,int key_data_len);
|
static int init_id_key(rc4_key* key,int key_data_len);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
|
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
|
||||||
@@ -133,17 +133,32 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||||||
channel->ndots = -1;
|
channel->ndots = -1;
|
||||||
channel->udp_port = -1;
|
channel->udp_port = -1;
|
||||||
channel->tcp_port = -1;
|
channel->tcp_port = -1;
|
||||||
|
channel->socket_send_buffer_size = -1;
|
||||||
|
channel->socket_receive_buffer_size = -1;
|
||||||
channel->nservers = -1;
|
channel->nservers = -1;
|
||||||
channel->ndomains = -1;
|
channel->ndomains = -1;
|
||||||
channel->nsort = -1;
|
channel->nsort = -1;
|
||||||
|
channel->tcp_connection_generation = 0;
|
||||||
channel->lookups = NULL;
|
channel->lookups = NULL;
|
||||||
channel->queries = NULL;
|
|
||||||
channel->domains = NULL;
|
channel->domains = NULL;
|
||||||
channel->sortlist = NULL;
|
channel->sortlist = NULL;
|
||||||
channel->servers = NULL;
|
channel->servers = NULL;
|
||||||
channel->sock_state_cb = NULL;
|
channel->sock_state_cb = NULL;
|
||||||
channel->sock_state_cb_data = NULL;
|
channel->sock_state_cb_data = NULL;
|
||||||
|
|
||||||
|
channel->last_timeout_processed = (long)time(NULL);
|
||||||
|
|
||||||
|
/* Initialize our lists of queries */
|
||||||
|
ares__init_list_head(&(channel->all_queries));
|
||||||
|
for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
ares__init_list_head(&(channel->queries_by_qid[i]));
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
ares__init_list_head(&(channel->queries_by_timeout[i]));
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize configuration by each of the four sources, from highest
|
/* Initialize configuration by each of the four sources, from highest
|
||||||
* precedence to lowest.
|
* precedence to lowest.
|
||||||
*/
|
*/
|
||||||
@@ -172,6 +187,18 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||||||
DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
|
DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
|
||||||
ares_strerror(status)));
|
ares_strerror(status)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate random key */
|
||||||
|
|
||||||
|
if (status == ARES_SUCCESS) {
|
||||||
|
status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
|
||||||
|
if (status == ARES_SUCCESS)
|
||||||
|
channel->next_id = ares__generate_new_id(&channel->id_key);
|
||||||
|
else
|
||||||
|
DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
|
||||||
|
ares_strerror(status)));
|
||||||
|
}
|
||||||
|
|
||||||
if (status != ARES_SUCCESS)
|
if (status != ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Something failed; clean up memory we may have allocated. */
|
/* Something failed; clean up memory we may have allocated. */
|
||||||
@@ -201,17 +228,16 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
server->udp_socket = ARES_SOCKET_BAD;
|
server->udp_socket = ARES_SOCKET_BAD;
|
||||||
server->tcp_socket = ARES_SOCKET_BAD;
|
server->tcp_socket = ARES_SOCKET_BAD;
|
||||||
|
server->tcp_connection_generation = ++channel->tcp_connection_generation;
|
||||||
server->tcp_lenbuf_pos = 0;
|
server->tcp_lenbuf_pos = 0;
|
||||||
server->tcp_buffer = NULL;
|
server->tcp_buffer = NULL;
|
||||||
server->qhead = NULL;
|
server->qhead = NULL;
|
||||||
server->qtail = NULL;
|
server->qtail = NULL;
|
||||||
|
ares__init_list_head(&(server->queries_to_server));
|
||||||
|
server->channel = channel;
|
||||||
|
server->is_broken = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
|
|
||||||
|
|
||||||
channel->next_id = ares__generate_new_id(&channel->id_key);
|
|
||||||
channel->queries = NULL;
|
|
||||||
|
|
||||||
*channelptr = channel;
|
*channelptr = channel;
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -238,24 +264,28 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
|||||||
options->timeout = channel->timeout;
|
options->timeout = channel->timeout;
|
||||||
options->tries = channel->tries;
|
options->tries = channel->tries;
|
||||||
options->ndots = channel->ndots;
|
options->ndots = channel->ndots;
|
||||||
options->udp_port = channel->udp_port;
|
options->udp_port = (unsigned short)channel->udp_port;
|
||||||
options->tcp_port = channel->tcp_port;
|
options->tcp_port = (unsigned short)channel->tcp_port;
|
||||||
options->sock_state_cb = channel->sock_state_cb;
|
options->sock_state_cb = channel->sock_state_cb;
|
||||||
options->sock_state_cb_data = channel->sock_state_cb_data;
|
options->sock_state_cb_data = channel->sock_state_cb_data;
|
||||||
|
|
||||||
/* Copy servers */
|
/* Copy servers */
|
||||||
|
if (channel->nservers) {
|
||||||
options->servers =
|
options->servers =
|
||||||
malloc(channel->nservers * sizeof(struct server_state));
|
malloc(channel->nservers * sizeof(struct server_state));
|
||||||
if (!options->servers && channel->nservers != 0)
|
if (!options->servers && channel->nservers != 0)
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
options->servers[i] = channel->servers[i].addr;
|
options->servers[i] = channel->servers[i].addr;
|
||||||
|
}
|
||||||
options->nservers = channel->nservers;
|
options->nservers = channel->nservers;
|
||||||
|
|
||||||
/* copy domains */
|
/* copy domains */
|
||||||
|
if (channel->ndomains) {
|
||||||
options->domains = malloc(channel->ndomains * sizeof(char *));
|
options->domains = malloc(channel->ndomains * sizeof(char *));
|
||||||
if (!options->domains)
|
if (!options->domains)
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < channel->ndomains; i++)
|
for (i = 0; i < channel->ndomains; i++)
|
||||||
{
|
{
|
||||||
options->ndomains = i;
|
options->ndomains = i;
|
||||||
@@ -263,14 +293,18 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
|||||||
if (!options->domains[i])
|
if (!options->domains[i])
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
options->ndomains = channel->ndomains;
|
options->ndomains = channel->ndomains;
|
||||||
|
|
||||||
/* copy lookups */
|
/* copy lookups */
|
||||||
|
if (channel->lookups) {
|
||||||
options->lookups = strdup(channel->lookups);
|
options->lookups = strdup(channel->lookups);
|
||||||
if (!options->lookups)
|
if (!options->lookups && channel->lookups)
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
/* copy sortlist */
|
/* copy sortlist */
|
||||||
|
if (channel->nsort) {
|
||||||
options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
|
options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
|
||||||
if (!options->sortlist)
|
if (!options->sortlist)
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
@@ -279,6 +313,7 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
|||||||
memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
|
memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
|
||||||
sizeof(struct apattern));
|
sizeof(struct apattern));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
options->nsort = channel->nsort;
|
options->nsort = channel->nsort;
|
||||||
|
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
@@ -308,6 +343,12 @@ static int init_by_options(ares_channel channel,
|
|||||||
channel->sock_state_cb = options->sock_state_cb;
|
channel->sock_state_cb = options->sock_state_cb;
|
||||||
channel->sock_state_cb_data = options->sock_state_cb_data;
|
channel->sock_state_cb_data = options->sock_state_cb_data;
|
||||||
}
|
}
|
||||||
|
if ((optmask & ARES_OPT_SOCK_SNDBUF)
|
||||||
|
&& channel->socket_send_buffer_size == -1)
|
||||||
|
channel->socket_send_buffer_size = options->socket_send_buffer_size;
|
||||||
|
if ((optmask & ARES_OPT_SOCK_RCVBUF)
|
||||||
|
&& channel->socket_receive_buffer_size == -1)
|
||||||
|
channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
|
||||||
|
|
||||||
/* Copy the servers, if given. */
|
/* Copy the servers, if given. */
|
||||||
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
|
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
|
||||||
@@ -456,7 +497,7 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
|||||||
FIXED_INFO *fi = alloca (sizeof(*fi));
|
FIXED_INFO *fi = alloca (sizeof(*fi));
|
||||||
DWORD size = sizeof (*fi);
|
DWORD size = sizeof (*fi);
|
||||||
typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
|
typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
|
||||||
get_net_param_func GetNetworkParams; /* available only on Win-98/2000+ */
|
get_net_param_func fpGetNetworkParams; /* available only on Win-98/2000+ */
|
||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
IP_ADDR_STRING *ipAddr;
|
IP_ADDR_STRING *ipAddr;
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
@@ -473,16 +514,16 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
|
|||||||
if (!handle)
|
if (!handle)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
GetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
|
fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
|
||||||
if (!GetNetworkParams)
|
if (!fpGetNetworkParams)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
res = (*GetNetworkParams) (fi, &size);
|
res = (*fpGetNetworkParams) (fi, &size);
|
||||||
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
fi = alloca (size);
|
fi = alloca (size);
|
||||||
if (!fi || (*GetNetworkParams) (fi, &size) != ERROR_SUCCESS)
|
if (!fi || (*fpGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@@ -1306,11 +1347,11 @@ static void randomize_key(unsigned char* key,int key_data_len)
|
|||||||
|
|
||||||
if ( !randomized ) {
|
if ( !randomized ) {
|
||||||
for (;counter<key_data_len;counter++)
|
for (;counter<key_data_len;counter++)
|
||||||
key[counter]=rand() % 256;
|
key[counter]=(unsigned char)(rand() % 256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_id_key(rc4_key* key,int key_data_len)
|
static int init_id_key(rc4_key* key,int key_data_len)
|
||||||
{
|
{
|
||||||
unsigned char index1;
|
unsigned char index1;
|
||||||
unsigned char index2;
|
unsigned char index2;
|
||||||
@@ -1319,25 +1360,28 @@ static void init_id_key(rc4_key* key,int key_data_len)
|
|||||||
unsigned char *key_data_ptr = 0;
|
unsigned char *key_data_ptr = 0;
|
||||||
|
|
||||||
key_data_ptr = calloc(1,key_data_len);
|
key_data_ptr = calloc(1,key_data_len);
|
||||||
|
if (!key_data_ptr)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
|
||||||
randomize_key(key->state,key_data_len);
|
randomize_key(key->state,key_data_len);
|
||||||
state = &key->state[0];
|
state = &key->state[0];
|
||||||
for(counter = 0; counter < 256; counter++)
|
for(counter = 0; counter < 256; counter++)
|
||||||
/* unnecessary AND but it keeps some compilers happier */
|
/* unnecessary AND but it keeps some compilers happier */
|
||||||
state[counter] = counter & 0xff;
|
state[counter] = (unsigned char)(counter & 0xff);
|
||||||
key->x = 0;
|
key->x = 0;
|
||||||
key->y = 0;
|
key->y = 0;
|
||||||
index1 = 0;
|
index1 = 0;
|
||||||
index2 = 0;
|
index2 = 0;
|
||||||
for(counter = 0; counter < 256; counter++)
|
for(counter = 0; counter < 256; counter++)
|
||||||
{
|
{
|
||||||
index2 = (key_data_ptr[index1] + state[counter] +
|
index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
|
||||||
index2) % 256;
|
index2) % 256);
|
||||||
ARES_SWAP_BYTE(&state[counter], &state[index2]);
|
ARES_SWAP_BYTE(&state[counter], &state[index2]);
|
||||||
|
|
||||||
index1 = (index1 + 1) % key_data_len;
|
index1 = (unsigned char)((index1 + 1) % key_data_len);
|
||||||
}
|
}
|
||||||
free(key_data_ptr);
|
free(key_data_ptr);
|
||||||
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
short ares__generate_new_id(rc4_key* key)
|
short ares__generate_new_id(rc4_key* key)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/* Copyright (C) 2005 by Dominick Meglio
|
||||||
|
*
|
||||||
* Permission to use, copy, modify, and distribute this
|
* Permission to use, copy, modify, and distribute this
|
||||||
* software and its documentation for any purpose and without
|
* software and its documentation for any purpose and without
|
||||||
* fee is hereby granted, provided that the above copyright
|
* fee is hereby granted, provided that the above copyright
|
||||||
@@ -21,11 +22,13 @@
|
|||||||
#define PF_INET6 AF_INET6
|
#define PF_INET6 AF_INET6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
#if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr)
|
||||||
struct in6_addr
|
struct in6_addr {
|
||||||
{
|
union {
|
||||||
unsigned char s6_addr[16];
|
unsigned char _S6_u8[16];
|
||||||
|
} _S6_un;
|
||||||
};
|
};
|
||||||
|
#define s6_addr _S6_un._S6_u8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||||
|
|||||||
87
ares/ares_llist.c
Normal file
87
ares/ares_llist.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose and without
|
||||||
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
* notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of M.I.T. not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* M.I.T. makes no representations about the suitability of
|
||||||
|
* this software for any purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#include "ares.h"
|
||||||
|
#include "ares_private.h"
|
||||||
|
|
||||||
|
/* Routines for managing doubly-linked circular linked lists with a
|
||||||
|
* dummy head.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Initialize a new head node */
|
||||||
|
void ares__init_list_head(struct list_node* head) {
|
||||||
|
head->prev = head;
|
||||||
|
head->next = head;
|
||||||
|
head->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize a list node */
|
||||||
|
void ares__init_list_node(struct list_node* node, void* d) {
|
||||||
|
node->prev = NULL;
|
||||||
|
node->next = NULL;
|
||||||
|
node->data = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true iff the given list is empty */
|
||||||
|
int ares__is_list_empty(struct list_node* head) {
|
||||||
|
return ((head->next == head) && (head->prev == head));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inserts new_node before old_node */
|
||||||
|
void ares__insert_in_list(struct list_node* new_node,
|
||||||
|
struct list_node* old_node) {
|
||||||
|
new_node->next = old_node;
|
||||||
|
new_node->prev = old_node->prev;
|
||||||
|
old_node->prev->next = new_node;
|
||||||
|
old_node->prev = new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes the node from the list it's in, if any */
|
||||||
|
void ares__remove_from_list(struct list_node* node) {
|
||||||
|
if (node->next != NULL) {
|
||||||
|
node->prev->next = node->next;
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
node->prev = NULL;
|
||||||
|
node->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Swap the contents of two lists */
|
||||||
|
void ares__swap_lists(struct list_node* head_a,
|
||||||
|
struct list_node* head_b) {
|
||||||
|
int is_a_empty = ares__is_list_empty(head_a);
|
||||||
|
int is_b_empty = ares__is_list_empty(head_b);
|
||||||
|
struct list_node old_a = *head_a;
|
||||||
|
struct list_node old_b = *head_b;
|
||||||
|
|
||||||
|
if (is_a_empty) {
|
||||||
|
ares__init_list_head(head_b);
|
||||||
|
} else {
|
||||||
|
*head_b = old_a;
|
||||||
|
old_a.next->prev = head_b;
|
||||||
|
old_a.prev->next = head_b;
|
||||||
|
}
|
||||||
|
if (is_b_empty) {
|
||||||
|
ares__init_list_head(head_a);
|
||||||
|
} else {
|
||||||
|
*head_a = old_b;
|
||||||
|
old_b.next->prev = head_a;
|
||||||
|
old_b.prev->next = head_a;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
ares/ares_llist.h
Normal file
43
ares/ares_llist.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef __ARES_LLIST_H
|
||||||
|
#define __ARES_LLIST_H
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose and without
|
||||||
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
* notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of M.I.T. not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* M.I.T. makes no representations about the suitability of
|
||||||
|
* this software for any purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Node definition for circular, doubly-linked list */
|
||||||
|
struct list_node {
|
||||||
|
struct list_node *prev;
|
||||||
|
struct list_node *next;
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ares__init_list_head(struct list_node* head);
|
||||||
|
|
||||||
|
void ares__init_list_node(struct list_node* node, void* d);
|
||||||
|
|
||||||
|
int ares__is_list_empty(struct list_node* head);
|
||||||
|
|
||||||
|
void ares__insert_in_list(struct list_node* new_node,
|
||||||
|
struct list_node* old_node);
|
||||||
|
|
||||||
|
void ares__remove_from_list(struct list_node* node);
|
||||||
|
|
||||||
|
void ares__swap_lists(struct list_node* head_a,
|
||||||
|
struct list_node* head_b);
|
||||||
|
|
||||||
|
#endif /* __ARES_LLIST_H */
|
||||||
@@ -88,6 +88,10 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
|
|||||||
unsigned char *q;
|
unsigned char *q;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
|
/* Set our results early, in case we bail out early with an error. */
|
||||||
|
*buflen = 0;
|
||||||
|
*buf = NULL;
|
||||||
|
|
||||||
/* Compute the length of the encoded name so we can check buflen.
|
/* Compute the length of the encoded name so we can check buflen.
|
||||||
* Start counting at 1 for the zero-length label at the end. */
|
* Start counting at 1 for the zero-length label at the end. */
|
||||||
len = 1;
|
len = 1;
|
||||||
@@ -104,6 +108,23 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
|
|||||||
if (*name && *(p - 1) != '.')
|
if (*name && *(p - 1) != '.')
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
|
/* Immediately reject names that are longer than the maximum of 255
|
||||||
|
* bytes that's specified in RFC 1035 ("To simplify implementations,
|
||||||
|
* the total length of a domain name (i.e., label octets and label
|
||||||
|
* length octets) is restricted to 255 octets or less."). We aren't
|
||||||
|
* doing this just to be a stickler about RFCs. For names that are
|
||||||
|
* too long, 'dnscache' closes its TCP connection to us immediately
|
||||||
|
* (when using TCP) and ignores the request when using UDP, and
|
||||||
|
* BIND's named returns ServFail (TCP or UDP). Sending a request
|
||||||
|
* that we know will cause 'dnscache' to close the TCP connection is
|
||||||
|
* painful, since that makes any other outstanding requests on that
|
||||||
|
* connection fail. And sending a UDP request that we know
|
||||||
|
* 'dnscache' will ignore is bad because resources will be tied up
|
||||||
|
* until we time-out the request.
|
||||||
|
*/
|
||||||
|
if (len > MAXCDNAME)
|
||||||
|
return ARES_EBADNAME;
|
||||||
|
|
||||||
*buflen = len + HFIXEDSZ + QFIXEDSZ;
|
*buflen = len + HFIXEDSZ + QFIXEDSZ;
|
||||||
*buf = malloc(*buflen);
|
*buf = malloc(*buflen);
|
||||||
if (!*buf)
|
if (!*buf)
|
||||||
|
|||||||
@@ -22,24 +22,39 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct hostent **\fIhost\fP);
|
.B struct hostent **\fIhost\fP,
|
||||||
|
.B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B ares_parse_a_reply
|
.B ares_parse_a_reply
|
||||||
function parses the response to a query of type A into a
|
function parses the response to a query of type A into a
|
||||||
.BR "struct hostent" .
|
.BR "struct hostent"
|
||||||
|
and/or an array of
|
||||||
|
.BR "struct addrttls" .
|
||||||
The parameters
|
The parameters
|
||||||
.I abuf
|
.I abuf
|
||||||
and
|
and
|
||||||
.I alen
|
.I alen
|
||||||
give the contents of the response. The result is stored in allocated
|
give the contents of the response. The result is stored in allocated
|
||||||
memory and a pointer to it stored into the variable pointed to by
|
memory and a pointer to it stored into the variable pointed to by
|
||||||
.IR host .
|
.IR host ,
|
||||||
|
if host is nonnull.
|
||||||
It is the caller's responsibility to free the resulting host structure
|
It is the caller's responsibility to free the resulting host structure
|
||||||
using
|
using
|
||||||
.BR ares_free_hostent (3)
|
.BR ares_free_hostent (3)
|
||||||
when it is no longer needed.
|
when it is no longer needed.
|
||||||
|
.PP
|
||||||
|
If
|
||||||
|
.IR addrttls
|
||||||
|
and
|
||||||
|
.IR naddrttls
|
||||||
|
are both nonnull,
|
||||||
|
then up to *naddrttls
|
||||||
|
.BR "struct addrttl"
|
||||||
|
records are stored in the array pointed to by addrttls,
|
||||||
|
and then *naddrttls is set to the number of records so stored.
|
||||||
|
Note that the memory for these records is supplied by the caller.
|
||||||
.SH RETURN VALUES
|
.SH RETURN VALUES
|
||||||
.B ares_parse_a_reply
|
.B ares_parse_a_reply
|
||||||
can return any of the following values:
|
can return any of the following values:
|
||||||
|
|||||||
@@ -32,24 +32,32 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_dns.h"
|
#include "ares_dns.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
||||||
struct hostent **host)
|
struct hostent **host,
|
||||||
|
struct addrttl *addrttls, int *naddrttls)
|
||||||
{
|
{
|
||||||
unsigned int qdcount, ancount;
|
unsigned int qdcount, ancount;
|
||||||
int status, i, rr_type, rr_class, rr_len, naddrs;
|
int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
|
||||||
|
int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
|
||||||
int naliases;
|
int naliases;
|
||||||
long len;
|
long len;
|
||||||
const unsigned char *aptr;
|
const unsigned char *aptr;
|
||||||
char *hostname, *rr_name, *rr_data, **aliases;
|
char *hostname, *rr_name, *rr_data, **aliases;
|
||||||
struct in_addr *addrs;
|
struct in_addr *addrs;
|
||||||
struct hostent *hostent;
|
struct hostent *hostent;
|
||||||
|
const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
|
||||||
|
|
||||||
/* Set *host to NULL for all failure cases. */
|
/* Set *host to NULL for all failure cases. */
|
||||||
|
if (host)
|
||||||
*host = NULL;
|
*host = NULL;
|
||||||
|
/* Same with *naddrttls. */
|
||||||
|
if (naddrttls)
|
||||||
|
*naddrttls = 0;
|
||||||
|
|
||||||
/* Give up if abuf doesn't have room for a header. */
|
/* Give up if abuf doesn't have room for a header. */
|
||||||
if (alen < HFIXEDSZ)
|
if (alen < HFIXEDSZ)
|
||||||
@@ -73,6 +81,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
}
|
}
|
||||||
aptr += len + QFIXEDSZ;
|
aptr += len + QFIXEDSZ;
|
||||||
|
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
|
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
|
||||||
addrs = malloc(ancount * sizeof(struct in_addr));
|
addrs = malloc(ancount * sizeof(struct in_addr));
|
||||||
if (!addrs)
|
if (!addrs)
|
||||||
@@ -87,6 +97,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
free(addrs);
|
free(addrs);
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addrs = NULL;
|
||||||
|
aliases = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
naddrs = 0;
|
naddrs = 0;
|
||||||
naliases = 0;
|
naliases = 0;
|
||||||
|
|
||||||
@@ -106,13 +123,33 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
rr_type = DNS_RR_TYPE(aptr);
|
rr_type = DNS_RR_TYPE(aptr);
|
||||||
rr_class = DNS_RR_CLASS(aptr);
|
rr_class = DNS_RR_CLASS(aptr);
|
||||||
rr_len = DNS_RR_LEN(aptr);
|
rr_len = DNS_RR_LEN(aptr);
|
||||||
|
rr_ttl = DNS_RR_TTL(aptr);
|
||||||
aptr += RRFIXEDSZ;
|
aptr += RRFIXEDSZ;
|
||||||
|
|
||||||
if (rr_class == C_IN && rr_type == T_A
|
if (rr_class == C_IN && rr_type == T_A
|
||||||
&& rr_len == sizeof(struct in_addr)
|
&& rr_len == sizeof(struct in_addr)
|
||||||
&& strcasecmp(rr_name, hostname) == 0)
|
&& strcasecmp(rr_name, hostname) == 0)
|
||||||
{
|
{
|
||||||
|
if (addrs)
|
||||||
|
{
|
||||||
|
if (aptr + sizeof(struct in_addr) > abuf + alen)
|
||||||
|
{
|
||||||
|
status = ARES_EBADRESP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
|
memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));
|
||||||
|
}
|
||||||
|
if (naddrs < max_addr_ttls)
|
||||||
|
{
|
||||||
|
struct addrttl * const at = &addrttls[naddrs];
|
||||||
|
if (aptr + sizeof(struct in_addr) > abuf + alen)
|
||||||
|
{
|
||||||
|
status = ARES_EBADRESP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(&at->ipaddr, aptr, sizeof(struct in_addr));
|
||||||
|
at->ttl = rr_ttl;
|
||||||
|
}
|
||||||
naddrs++;
|
naddrs++;
|
||||||
status = ARES_SUCCESS;
|
status = ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -120,7 +157,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
if (rr_class == C_IN && rr_type == T_CNAME)
|
if (rr_class == C_IN && rr_type == T_CNAME)
|
||||||
{
|
{
|
||||||
/* Record the RR name as an alias. */
|
/* Record the RR name as an alias. */
|
||||||
|
if (aliases)
|
||||||
aliases[naliases] = rr_name;
|
aliases[naliases] = rr_name;
|
||||||
|
else
|
||||||
|
free(rr_name);
|
||||||
naliases++;
|
naliases++;
|
||||||
|
|
||||||
/* Decode the RR data and replace the hostname with it. */
|
/* Decode the RR data and replace the hostname with it. */
|
||||||
@@ -129,6 +169,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
break;
|
break;
|
||||||
free(hostname);
|
free(hostname);
|
||||||
hostname = rr_data;
|
hostname = rr_data;
|
||||||
|
|
||||||
|
/* Take the min of the TTLs we see in the CNAME chain. */
|
||||||
|
if (cname_ttl > rr_ttl)
|
||||||
|
cname_ttl = rr_ttl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
free(rr_name);
|
free(rr_name);
|
||||||
@@ -145,8 +189,23 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
status = ARES_ENODATA;
|
status = ARES_ENODATA;
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
/* We got our answer. Allocate memory to build the host entry. */
|
/* We got our answer. */
|
||||||
|
if (naddrttls)
|
||||||
|
{
|
||||||
|
const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
/* Ensure that each A TTL is no larger than the CNAME TTL. */
|
||||||
|
if (addrttls[i].ttl > cname_ttl)
|
||||||
|
addrttls[i].ttl = cname_ttl;
|
||||||
|
}
|
||||||
|
*naddrttls = n;
|
||||||
|
}
|
||||||
|
if (aliases)
|
||||||
aliases[naliases] = NULL;
|
aliases[naliases] = NULL;
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
/* Allocate memory to build the host entry. */
|
||||||
hostent = malloc(sizeof(struct hostent));
|
hostent = malloc(sizeof(struct hostent));
|
||||||
if (hostent)
|
if (hostent)
|
||||||
{
|
{
|
||||||
@@ -168,9 +227,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
|||||||
}
|
}
|
||||||
status = ARES_ENOMEM;
|
status = ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (aliases)
|
||||||
|
{
|
||||||
for (i = 0; i < naliases; i++)
|
for (i = 0; i < naliases; i++)
|
||||||
free(aliases[i]);
|
free(aliases[i]);
|
||||||
free(aliases);
|
free(aliases);
|
||||||
|
}
|
||||||
free(addrs);
|
free(addrs);
|
||||||
free(hostname);
|
free(hostname);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -22,24 +22,39 @@ ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA into a hosten
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
.B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct hostent **\fIhost\fP);
|
.B struct hostent **\fIhost\fP,
|
||||||
|
.B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B ares_parse_aaaa_reply
|
.B ares_parse_aaaa_reply
|
||||||
function parses the response to a query of type AAAA into a
|
function parses the response to a query of type AAAA into a
|
||||||
.BR "struct hostent" .
|
.BR "struct hostent"
|
||||||
|
and/or an array of
|
||||||
|
.BR "struct addrttls" .
|
||||||
The parameters
|
The parameters
|
||||||
.I abuf
|
.I abuf
|
||||||
and
|
and
|
||||||
.I alen
|
.I alen
|
||||||
give the contents of the response. The result is stored in allocated
|
give the contents of the response. The result is stored in allocated
|
||||||
memory and a pointer to it stored into the variable pointed to by
|
memory and a pointer to it stored into the variable pointed to by
|
||||||
.IR host .
|
.IR host ,
|
||||||
|
if host is nonnull.
|
||||||
It is the caller's responsibility to free the resulting host structure
|
It is the caller's responsibility to free the resulting host structure
|
||||||
using
|
using
|
||||||
.BR ares_free_hostent (3)
|
.BR ares_free_hostent (3)
|
||||||
when it is no longer needed.
|
when it is no longer needed.
|
||||||
|
.PP
|
||||||
|
If
|
||||||
|
.IR addrttls
|
||||||
|
and
|
||||||
|
.IR naddrttls
|
||||||
|
are both nonnull,
|
||||||
|
then up to *naddrttls
|
||||||
|
.BR "struct addr6ttl"
|
||||||
|
records are stored in the array pointed to by addrttls,
|
||||||
|
and then *naddrttls is set to the number of records so stored.
|
||||||
|
Note that the memory for these records is supplied by the caller.
|
||||||
.SH RETURN VALUES
|
.SH RETURN VALUES
|
||||||
.B ares_parse_aaaa_reply
|
.B ares_parse_aaaa_reply
|
||||||
can return any of the following values:
|
can return any of the following values:
|
||||||
|
|||||||
@@ -34,25 +34,33 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_dns.h"
|
#include "ares_dns.h"
|
||||||
#include "inet_net_pton.h"
|
#include "inet_net_pton.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
||||||
struct hostent **host)
|
struct hostent **host, struct addr6ttl *addrttls,
|
||||||
|
int *naddrttls)
|
||||||
{
|
{
|
||||||
unsigned int qdcount, ancount;
|
unsigned int qdcount, ancount;
|
||||||
int status, i, rr_type, rr_class, rr_len, naddrs;
|
int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs;
|
||||||
|
int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */
|
||||||
int naliases;
|
int naliases;
|
||||||
long len;
|
long len;
|
||||||
const unsigned char *aptr;
|
const unsigned char *aptr;
|
||||||
char *hostname, *rr_name, *rr_data, **aliases;
|
char *hostname, *rr_name, *rr_data, **aliases;
|
||||||
struct in6_addr *addrs;
|
struct in6_addr *addrs;
|
||||||
struct hostent *hostent;
|
struct hostent *hostent;
|
||||||
|
const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0;
|
||||||
|
|
||||||
/* Set *host to NULL for all failure cases. */
|
/* Set *host to NULL for all failure cases. */
|
||||||
|
if (host)
|
||||||
*host = NULL;
|
*host = NULL;
|
||||||
|
/* Same with *naddrttls. */
|
||||||
|
if (naddrttls)
|
||||||
|
*naddrttls = 0;
|
||||||
|
|
||||||
/* Give up if abuf doesn't have room for a header. */
|
/* Give up if abuf doesn't have room for a header. */
|
||||||
if (alen < HFIXEDSZ)
|
if (alen < HFIXEDSZ)
|
||||||
@@ -77,6 +85,8 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
aptr += len + QFIXEDSZ;
|
aptr += len + QFIXEDSZ;
|
||||||
|
|
||||||
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
|
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
addrs = malloc(ancount * sizeof(struct in6_addr));
|
addrs = malloc(ancount * sizeof(struct in6_addr));
|
||||||
if (!addrs)
|
if (!addrs)
|
||||||
{
|
{
|
||||||
@@ -90,6 +100,12 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
free(addrs);
|
free(addrs);
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addrs = NULL;
|
||||||
|
aliases = NULL;
|
||||||
|
}
|
||||||
naddrs = 0;
|
naddrs = 0;
|
||||||
naliases = 0;
|
naliases = 0;
|
||||||
|
|
||||||
@@ -109,13 +125,33 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
rr_type = DNS_RR_TYPE(aptr);
|
rr_type = DNS_RR_TYPE(aptr);
|
||||||
rr_class = DNS_RR_CLASS(aptr);
|
rr_class = DNS_RR_CLASS(aptr);
|
||||||
rr_len = DNS_RR_LEN(aptr);
|
rr_len = DNS_RR_LEN(aptr);
|
||||||
|
rr_ttl = DNS_RR_TTL(aptr);
|
||||||
aptr += RRFIXEDSZ;
|
aptr += RRFIXEDSZ;
|
||||||
|
|
||||||
if (rr_class == C_IN && rr_type == T_AAAA
|
if (rr_class == C_IN && rr_type == T_AAAA
|
||||||
&& rr_len == sizeof(struct in6_addr)
|
&& rr_len == sizeof(struct in6_addr)
|
||||||
&& strcasecmp(rr_name, hostname) == 0)
|
&& strcasecmp(rr_name, hostname) == 0)
|
||||||
{
|
{
|
||||||
|
if (addrs)
|
||||||
|
{
|
||||||
|
if (aptr + sizeof(struct in6_addr) > abuf + alen)
|
||||||
|
{
|
||||||
|
status = ARES_EBADRESP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr));
|
memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
if (naddrs < max_addr_ttls)
|
||||||
|
{
|
||||||
|
struct addr6ttl * const at = &addrttls[naddrs];
|
||||||
|
if (aptr + sizeof(struct in6_addr) > abuf + alen)
|
||||||
|
{
|
||||||
|
status = ARES_EBADRESP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(&at->ip6addr, aptr, sizeof(struct in6_addr));
|
||||||
|
at->ttl = rr_ttl;
|
||||||
|
}
|
||||||
naddrs++;
|
naddrs++;
|
||||||
status = ARES_SUCCESS;
|
status = ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -123,7 +159,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
if (rr_class == C_IN && rr_type == T_CNAME)
|
if (rr_class == C_IN && rr_type == T_CNAME)
|
||||||
{
|
{
|
||||||
/* Record the RR name as an alias. */
|
/* Record the RR name as an alias. */
|
||||||
|
if (aliases)
|
||||||
aliases[naliases] = rr_name;
|
aliases[naliases] = rr_name;
|
||||||
|
else
|
||||||
|
free(rr_name);
|
||||||
naliases++;
|
naliases++;
|
||||||
|
|
||||||
/* Decode the RR data and replace the hostname with it. */
|
/* Decode the RR data and replace the hostname with it. */
|
||||||
@@ -132,6 +171,10 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
break;
|
break;
|
||||||
free(hostname);
|
free(hostname);
|
||||||
hostname = rr_data;
|
hostname = rr_data;
|
||||||
|
|
||||||
|
/* Take the min of the TTLs we see in the CNAME chain. */
|
||||||
|
if (cname_ttl > rr_ttl)
|
||||||
|
cname_ttl = rr_ttl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
free(rr_name);
|
free(rr_name);
|
||||||
@@ -148,8 +191,23 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
status = ARES_ENODATA;
|
status = ARES_ENODATA;
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
/* We got our answer. Allocate memory to build the host entry. */
|
/* We got our answer. */
|
||||||
|
if (naddrttls)
|
||||||
|
{
|
||||||
|
const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
/* Ensure that each A TTL is no larger than the CNAME TTL. */
|
||||||
|
if (addrttls[i].ttl > cname_ttl)
|
||||||
|
addrttls[i].ttl = cname_ttl;
|
||||||
|
}
|
||||||
|
*naddrttls = n;
|
||||||
|
}
|
||||||
|
if (aliases)
|
||||||
aliases[naliases] = NULL;
|
aliases[naliases] = NULL;
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
/* Allocate memory to build the host entry. */
|
||||||
hostent = malloc(sizeof(struct hostent));
|
hostent = malloc(sizeof(struct hostent));
|
||||||
if (hostent)
|
if (hostent)
|
||||||
{
|
{
|
||||||
@@ -171,9 +229,13 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
|||||||
}
|
}
|
||||||
status = ARES_ENOMEM;
|
status = ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (aliases)
|
||||||
|
{
|
||||||
for (i = 0; i < naliases; i++)
|
for (i = 0; i < naliases; i++)
|
||||||
free(aliases[i]);
|
free(aliases[i]);
|
||||||
free(aliases);
|
free(aliases);
|
||||||
|
}
|
||||||
free(addrs);
|
free(addrs);
|
||||||
free(hostname);
|
free(hostname);
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -18,6 +18,14 @@
|
|||||||
* without express or implied warranty.
|
* without express or implied warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define WIN32 when build target is Win32 API
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@@ -83,12 +91,20 @@
|
|||||||
#define ARES_ID_KEY_LEN 31
|
#define ARES_ID_KEY_LEN 31
|
||||||
|
|
||||||
#include "ares_ipv6.h"
|
#include "ares_ipv6.h"
|
||||||
|
#include "ares_llist.h"
|
||||||
|
|
||||||
|
struct query;
|
||||||
|
|
||||||
struct send_request {
|
struct send_request {
|
||||||
/* Remaining data to send */
|
/* Remaining data to send */
|
||||||
const unsigned char *data;
|
const unsigned char *data;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
/* The query for which we're sending this data */
|
||||||
|
struct query* owner_query;
|
||||||
|
/* The buffer we're using, if we have our own copy of the packet */
|
||||||
|
unsigned char *data_storage;
|
||||||
|
|
||||||
/* Next request in queue */
|
/* Next request in queue */
|
||||||
struct send_request *next;
|
struct send_request *next;
|
||||||
};
|
};
|
||||||
@@ -110,13 +126,42 @@ struct server_state {
|
|||||||
/* TCP output queue */
|
/* TCP output queue */
|
||||||
struct send_request *qhead;
|
struct send_request *qhead;
|
||||||
struct send_request *qtail;
|
struct send_request *qtail;
|
||||||
|
|
||||||
|
/* Which incarnation of this connection is this? We don't want to
|
||||||
|
* retransmit requests into the very same socket, but if the server
|
||||||
|
* closes on us and we re-open the connection, then we do want to
|
||||||
|
* re-send. */
|
||||||
|
int tcp_connection_generation;
|
||||||
|
|
||||||
|
/* Circular, doubly-linked list of outstanding queries to this server */
|
||||||
|
struct list_node queries_to_server;
|
||||||
|
|
||||||
|
/* Link back to owning channel */
|
||||||
|
ares_channel channel;
|
||||||
|
|
||||||
|
/* Is this server broken? We mark connections as broken when a
|
||||||
|
* request that is queued for sending times out.
|
||||||
|
*/
|
||||||
|
int is_broken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* State to represent a DNS query */
|
||||||
struct query {
|
struct query {
|
||||||
/* Query ID from qbuf, for faster lookup, and current timeout */
|
/* Query ID from qbuf, for faster lookup, and current timeout */
|
||||||
unsigned short qid;
|
unsigned short qid;
|
||||||
time_t timeout;
|
time_t timeout;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Links for the doubly-linked lists in which we insert a query.
|
||||||
|
* These circular, doubly-linked lists that are hash-bucketed based
|
||||||
|
* the attributes we care about, help making most important
|
||||||
|
* operations O(1).
|
||||||
|
*/
|
||||||
|
struct list_node queries_by_qid; /* hopefully in same cache line as qid */
|
||||||
|
struct list_node queries_by_timeout;
|
||||||
|
struct list_node queries_to_server;
|
||||||
|
struct list_node all_queries;
|
||||||
|
|
||||||
/* Query buf with length at beginning, for TCP transmission */
|
/* Query buf with length at beginning, for TCP transmission */
|
||||||
unsigned char *tcpbuf;
|
unsigned char *tcpbuf;
|
||||||
int tcplen;
|
int tcplen;
|
||||||
@@ -130,12 +175,16 @@ struct query {
|
|||||||
/* Query status */
|
/* Query status */
|
||||||
int try;
|
int try;
|
||||||
int server;
|
int server;
|
||||||
int *skip_server;
|
struct query_server_info *server_info; /* per-server state */
|
||||||
int using_tcp;
|
int using_tcp;
|
||||||
int error_status;
|
int error_status;
|
||||||
|
int timeouts; /* number of timeouts we saw for this request */
|
||||||
|
};
|
||||||
|
|
||||||
/* Next query in chain */
|
/* Per-server state for a query */
|
||||||
struct query *next;
|
struct query_server_info {
|
||||||
|
int skip_server; /* should we skip server, due to errors, etc? */
|
||||||
|
int tcp_connection_generation; /* into which TCP connection did we send? */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An IP address pattern; matches an IP address X if X & mask == addr */
|
/* An IP address pattern; matches an IP address X if X & mask == addr */
|
||||||
@@ -173,6 +222,8 @@ struct ares_channeldata {
|
|||||||
int ndots;
|
int ndots;
|
||||||
int udp_port;
|
int udp_port;
|
||||||
int tcp_port;
|
int tcp_port;
|
||||||
|
int socket_send_buffer_size;
|
||||||
|
int socket_receive_buffer_size;
|
||||||
char **domains;
|
char **domains;
|
||||||
int ndomains;
|
int ndomains;
|
||||||
struct apattern *sortlist;
|
struct apattern *sortlist;
|
||||||
@@ -188,8 +239,21 @@ struct ares_channeldata {
|
|||||||
/* key to use when generating new ids */
|
/* key to use when generating new ids */
|
||||||
rc4_key id_key;
|
rc4_key id_key;
|
||||||
|
|
||||||
/* Active queries */
|
/* Generation number to use for the next TCP socket open/close */
|
||||||
struct query *queries;
|
int tcp_connection_generation;
|
||||||
|
|
||||||
|
/* The time at which we last called process_timeouts() */
|
||||||
|
time_t last_timeout_processed;
|
||||||
|
|
||||||
|
/* Circular, doubly-linked list of queries, bucketed various ways.... */
|
||||||
|
/* All active queries in a single list: */
|
||||||
|
struct list_node all_queries;
|
||||||
|
/* Queries bucketed by qid, for quickly dispatching DNS responses: */
|
||||||
|
#define ARES_QID_TABLE_SIZE 2048
|
||||||
|
struct list_node queries_by_qid[ARES_QID_TABLE_SIZE];
|
||||||
|
/* Queries bucketed by timeout, for quickly handling timeouts: */
|
||||||
|
#define ARES_TIMEOUT_TABLE_SIZE 1024
|
||||||
|
struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE];
|
||||||
|
|
||||||
ares_sock_state_cb sock_state_cb;
|
ares_sock_state_cb sock_state_cb;
|
||||||
void *sock_state_cb_data;
|
void *sock_state_cb_data;
|
||||||
@@ -200,6 +264,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
|||||||
void ares__close_sockets(ares_channel channel, struct server_state *server);
|
void ares__close_sockets(ares_channel channel, struct server_state *server);
|
||||||
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
||||||
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
||||||
|
void ares__free_query(struct query *query);
|
||||||
short ares__generate_new_id(rc4_key* key);
|
short ares__generate_new_id(rc4_key* key);
|
||||||
|
|
||||||
#define ARES_SWAP_BYTE(a,b) \
|
#define ARES_SWAP_BYTE(a,b) \
|
||||||
@@ -220,4 +285,3 @@ short ares__generate_new_id(rc4_key* key);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ARES_PRIVATE_H */
|
#endif /* __ARES_PRIVATE_H */
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,24 @@
|
|||||||
#include "nameser.h"
|
#include "nameser.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_UIO_H
|
#ifdef HAVE_SYS_UIO_H
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/in.h>
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_TCP_H
|
||||||
|
#include <netinet/tcp.h> /* for TCP_NODELAY */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
#include <arpa/nameser_compat.h>
|
#include <arpa/nameser_compat.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -43,6 +54,7 @@
|
|||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -61,16 +73,22 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
|
|||||||
ares_socket_t read_fd, time_t now);
|
ares_socket_t read_fd, time_t now);
|
||||||
static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
||||||
ares_socket_t read_fd, time_t now);
|
ares_socket_t read_fd, time_t now);
|
||||||
|
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
|
||||||
|
ssize_t num_bytes);
|
||||||
static void process_timeouts(ares_channel channel, time_t now);
|
static void process_timeouts(ares_channel channel, time_t now);
|
||||||
|
static void process_broken_connections(ares_channel channel, time_t now);
|
||||||
static void process_answer(ares_channel channel, unsigned char *abuf,
|
static void process_answer(ares_channel channel, unsigned char *abuf,
|
||||||
int alen, int whichserver, int tcp, time_t now);
|
int alen, int whichserver, int tcp, time_t now);
|
||||||
static void handle_error(ares_channel channel, int whichserver, time_t now);
|
static void handle_error(ares_channel channel, int whichserver, time_t now);
|
||||||
static struct query *next_server(ares_channel channel, struct query *query, time_t now);
|
static void skip_server(ares_channel channel, struct query *query,
|
||||||
|
int whichserver);
|
||||||
|
static void next_server(ares_channel channel, struct query *query, time_t now);
|
||||||
|
static int configure_socket(int s, ares_channel channel);
|
||||||
static int open_tcp_socket(ares_channel channel, struct server_state *server);
|
static int open_tcp_socket(ares_channel channel, struct server_state *server);
|
||||||
static int open_udp_socket(ares_channel channel, struct server_state *server);
|
static int open_udp_socket(ares_channel channel, struct server_state *server);
|
||||||
static int same_questions(const unsigned char *qbuf, int qlen,
|
static int same_questions(const unsigned char *qbuf, int qlen,
|
||||||
const unsigned char *abuf, int alen);
|
const unsigned char *abuf, int alen);
|
||||||
static struct query *end_query(ares_channel channel, struct query *query, int status,
|
static void end_query(ares_channel channel, struct query *query, int status,
|
||||||
unsigned char *abuf, int alen);
|
unsigned char *abuf, int alen);
|
||||||
|
|
||||||
/* Something interesting happened on the wire, or there was a timeout.
|
/* Something interesting happened on the wire, or there was a timeout.
|
||||||
@@ -85,6 +103,7 @@ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
|
|||||||
read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, now);
|
read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, now);
|
||||||
read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, now);
|
read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, now);
|
||||||
process_timeouts(channel, now);
|
process_timeouts(channel, now);
|
||||||
|
process_broken_connections(channel, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Something interesting happened on the wire, or there was a timeout.
|
/* Something interesting happened on the wire, or there was a timeout.
|
||||||
@@ -155,7 +174,7 @@ static void write_tcp_data(ares_channel channel,
|
|||||||
/* Make sure server has data to send and is selected in write_fds or
|
/* Make sure server has data to send and is selected in write_fds or
|
||||||
write_fd. */
|
write_fd. */
|
||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD)
|
if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(write_fds) {
|
if(write_fds) {
|
||||||
@@ -167,6 +186,14 @@ static void write_tcp_data(ares_channel channel,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(write_fds)
|
||||||
|
/* If there's an error and we close this socket, then open
|
||||||
|
* another with the same fd to talk to another server, then we
|
||||||
|
* don't want to think that it was the new socket that was
|
||||||
|
* ready. This is not disastrous, but is likely to result in
|
||||||
|
* extra system calls and confusion. */
|
||||||
|
FD_CLR(server->tcp_socket, write_fds);
|
||||||
|
|
||||||
/* Count the number of send queue items. */
|
/* Count the number of send queue items. */
|
||||||
n = 0;
|
n = 0;
|
||||||
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
|
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
|
||||||
@@ -194,27 +221,7 @@ static void write_tcp_data(ares_channel channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Advance the send queue by as many bytes as we sent. */
|
/* Advance the send queue by as many bytes as we sent. */
|
||||||
while (wcount)
|
advance_tcp_send_queue(channel, i, wcount);
|
||||||
{
|
|
||||||
sendreq = server->qhead;
|
|
||||||
if ((size_t)wcount >= sendreq->len)
|
|
||||||
{
|
|
||||||
wcount -= sendreq->len;
|
|
||||||
server->qhead = sendreq->next;
|
|
||||||
if (server->qhead == NULL)
|
|
||||||
{
|
|
||||||
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
|
|
||||||
server->qtail = NULL;
|
|
||||||
}
|
|
||||||
free(sendreq);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sendreq->data += wcount;
|
|
||||||
sendreq->len -= wcount;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -230,21 +237,38 @@ static void write_tcp_data(ares_channel channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Advance the send queue by as many bytes as we sent. */
|
/* Advance the send queue by as many bytes as we sent. */
|
||||||
if ((size_t)scount == sendreq->len)
|
advance_tcp_send_queue(channel, i, scount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consume the given number of bytes from the head of the TCP send queue. */
|
||||||
|
static void advance_tcp_send_queue(ares_channel channel, int whichserver,
|
||||||
|
ssize_t num_bytes)
|
||||||
|
{
|
||||||
|
struct send_request *sendreq;
|
||||||
|
struct server_state *server = &channel->servers[whichserver];
|
||||||
|
while (num_bytes > 0)
|
||||||
{
|
{
|
||||||
|
sendreq = server->qhead;
|
||||||
|
if ((size_t)num_bytes >= sendreq->len)
|
||||||
|
{
|
||||||
|
num_bytes -= sendreq->len;
|
||||||
server->qhead = sendreq->next;
|
server->qhead = sendreq->next;
|
||||||
if (server->qhead == NULL)
|
if (server->qhead == NULL)
|
||||||
{
|
{
|
||||||
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
|
||||||
server->qtail = NULL;
|
server->qtail = NULL;
|
||||||
}
|
}
|
||||||
|
if (sendreq->data_storage != NULL)
|
||||||
|
free(sendreq->data_storage);
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendreq->data += scount;
|
sendreq->data += num_bytes;
|
||||||
sendreq->len -= scount;
|
sendreq->len -= num_bytes;
|
||||||
}
|
num_bytes = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,7 +292,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
|
|||||||
{
|
{
|
||||||
/* Make sure the server has a socket and is selected in read_fds. */
|
/* Make sure the server has a socket and is selected in read_fds. */
|
||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
if (server->tcp_socket == ARES_SOCKET_BAD)
|
if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(read_fds) {
|
if(read_fds) {
|
||||||
@@ -280,6 +304,14 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(read_fds)
|
||||||
|
/* If there's an error and we close this socket, then open
|
||||||
|
* another with the same fd to talk to another server, then we
|
||||||
|
* don't want to think that it was the new socket that was
|
||||||
|
* ready. This is not disastrous, but is likely to result in
|
||||||
|
* extra system calls and confusion. */
|
||||||
|
FD_CLR(server->tcp_socket, read_fds);
|
||||||
|
|
||||||
if (server->tcp_lenbuf_pos != 2)
|
if (server->tcp_lenbuf_pos != 2)
|
||||||
{
|
{
|
||||||
/* We haven't yet read a length word, so read that (or
|
/* We haven't yet read a length word, so read that (or
|
||||||
@@ -358,7 +390,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
|||||||
/* Make sure the server has a socket and is selected in read_fds. */
|
/* Make sure the server has a socket and is selected in read_fds. */
|
||||||
server = &channel->servers[i];
|
server = &channel->servers[i];
|
||||||
|
|
||||||
if (server->udp_socket == ARES_SOCKET_BAD)
|
if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(read_fds) {
|
if(read_fds) {
|
||||||
@@ -370,30 +402,58 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(read_fds)
|
||||||
|
/* If there's an error and we close this socket, then open
|
||||||
|
* another with the same fd to talk to another server, then we
|
||||||
|
* don't want to think that it was the new socket that was
|
||||||
|
* ready. This is not disastrous, but is likely to result in
|
||||||
|
* extra system calls and confusion. */
|
||||||
|
FD_CLR(server->udp_socket, read_fds);
|
||||||
|
|
||||||
|
/* To reduce event loop overhead, read and process as many
|
||||||
|
* packets as we can. */
|
||||||
|
do {
|
||||||
count = sread(server->udp_socket, buf, sizeof(buf));
|
count = sread(server->udp_socket, buf, sizeof(buf));
|
||||||
if (count == -1 && try_again(SOCKERRNO))
|
if (count == -1 && try_again(SOCKERRNO))
|
||||||
continue;
|
continue;
|
||||||
else if (count <= 0)
|
else if (count <= 0)
|
||||||
handle_error(channel, i, now);
|
handle_error(channel, i, now);
|
||||||
|
else
|
||||||
process_answer(channel, buf, (int)count, i, 0, now);
|
process_answer(channel, buf, (int)count, i, 0, now);
|
||||||
|
} while (count > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If any queries have timed out, note the timeout and move them on. */
|
/* If any queries have timed out, note the timeout and move them on. */
|
||||||
static void process_timeouts(ares_channel channel, time_t now)
|
static void process_timeouts(ares_channel channel, time_t now)
|
||||||
{
|
{
|
||||||
struct query *query, *next;
|
time_t t; /* the time of the timeouts we're processing */
|
||||||
|
struct query *query;
|
||||||
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
|
|
||||||
for (query = channel->queries; query; query = next)
|
/* Process all the timeouts that have fired since the last time we
|
||||||
|
* processed timeouts. If things are going well, then we'll have
|
||||||
|
* hundreds/thousands of queries that fall into future buckets, and
|
||||||
|
* only a handful of requests that fall into the "now" bucket, so
|
||||||
|
* this should be quite quick.
|
||||||
|
*/
|
||||||
|
for (t = channel->last_timeout_processed; t <= now; t++)
|
||||||
{
|
{
|
||||||
next = query->next;
|
list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]);
|
||||||
|
for (list_node = list_head->next; list_node != list_head; )
|
||||||
|
{
|
||||||
|
query = list_node->data;
|
||||||
|
list_node = list_node->next; /* in case the query gets deleted */
|
||||||
if (query->timeout != 0 && now >= query->timeout)
|
if (query->timeout != 0 && now >= query->timeout)
|
||||||
{
|
{
|
||||||
query->error_status = ARES_ETIMEOUT;
|
query->error_status = ARES_ETIMEOUT;
|
||||||
next = next_server(channel, query, now);
|
++query->timeouts;
|
||||||
|
next_server(channel, query, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
channel->last_timeout_processed = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle an answer from a server. */
|
/* Handle an answer from a server. */
|
||||||
@@ -403,6 +463,8 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
|
|||||||
int tc, rcode;
|
int tc, rcode;
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
struct query *query;
|
struct query *query;
|
||||||
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
|
|
||||||
/* If there's no room in the answer for a header, we can't do much
|
/* If there's no room in the answer for a header, we can't do much
|
||||||
* with it. */
|
* with it. */
|
||||||
@@ -414,12 +476,25 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
|
|||||||
tc = DNS_HEADER_TC(abuf);
|
tc = DNS_HEADER_TC(abuf);
|
||||||
rcode = DNS_HEADER_RCODE(abuf);
|
rcode = DNS_HEADER_RCODE(abuf);
|
||||||
|
|
||||||
/* Find the query corresponding to this packet. */
|
/* Find the query corresponding to this packet. The queries are
|
||||||
for (query = channel->queries; query; query = query->next)
|
* hashed/bucketed by query id, so this lookup should be quick.
|
||||||
|
* Note that both the query id and the questions must be the same;
|
||||||
|
* when the query id wraps around we can have multiple outstanding
|
||||||
|
* queries with the same query id, so we need to check both the id and
|
||||||
|
* question.
|
||||||
|
*/
|
||||||
|
query = NULL;
|
||||||
|
list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]);
|
||||||
|
for (list_node = list_head->next; list_node != list_head;
|
||||||
|
list_node = list_node->next)
|
||||||
{
|
{
|
||||||
if (query->qid == id)
|
struct query *q = list_node->data;
|
||||||
|
if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen))
|
||||||
|
{
|
||||||
|
query = q;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!query)
|
if (!query)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -450,13 +525,7 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
|
|||||||
{
|
{
|
||||||
if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
|
if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
|
||||||
{
|
{
|
||||||
query->skip_server[whichserver] = 1;
|
skip_server(channel, query, whichserver);
|
||||||
if (query->server == whichserver)
|
|
||||||
next_server(channel, query, now);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!same_questions(query->qbuf, query->qlen, abuf, alen))
|
|
||||||
{
|
|
||||||
if (query->server == whichserver)
|
if (query->server == whichserver)
|
||||||
next_server(channel, query, now);
|
next_server(channel, query, now);
|
||||||
return;
|
return;
|
||||||
@@ -466,29 +535,72 @@ static void process_answer(ares_channel channel, unsigned char *abuf,
|
|||||||
end_query(channel, query, ARES_SUCCESS, abuf, alen);
|
end_query(channel, query, ARES_SUCCESS, abuf, alen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_error(ares_channel channel, int whichserver, time_t now)
|
/* Close all the connections that are no longer usable. */
|
||||||
|
static void process_broken_connections(ares_channel channel, time_t now)
|
||||||
{
|
{
|
||||||
struct query *query, *next;
|
int i;
|
||||||
|
for (i = 0; i < channel->nservers; i++)
|
||||||
/* Reset communications with this server. */
|
|
||||||
ares__close_sockets(channel, &channel->servers[whichserver]);
|
|
||||||
|
|
||||||
/* Tell all queries talking to this server to move on and not try
|
|
||||||
* this server again.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (query = channel->queries; query; query = next)
|
|
||||||
{
|
{
|
||||||
next = query->next;
|
struct server_state *server = &channel->servers[i];
|
||||||
if (query->server == whichserver)
|
if (server->is_broken)
|
||||||
{
|
{
|
||||||
query->skip_server[whichserver] = 1;
|
handle_error(channel, i, now);
|
||||||
next = next_server(channel, query, now);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct query *next_server(ares_channel channel, struct query *query, time_t now)
|
static void handle_error(ares_channel channel, int whichserver, time_t now)
|
||||||
|
{
|
||||||
|
struct server_state *server;
|
||||||
|
struct query *query;
|
||||||
|
struct list_node list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
|
|
||||||
|
server = &channel->servers[whichserver];
|
||||||
|
|
||||||
|
/* Reset communications with this server. */
|
||||||
|
ares__close_sockets(channel, server);
|
||||||
|
|
||||||
|
/* Tell all queries talking to this server to move on and not try
|
||||||
|
* this server again. We steal the current list of queries that were
|
||||||
|
* in-flight to this server, since when we call next_server this can
|
||||||
|
* cause the queries to be re-sent to this server, which will
|
||||||
|
* re-insert these queries in that same server->queries_to_server
|
||||||
|
* list.
|
||||||
|
*/
|
||||||
|
ares__init_list_head(&list_head);
|
||||||
|
ares__swap_lists(&list_head, &(server->queries_to_server));
|
||||||
|
for (list_node = list_head.next; list_node != &list_head; )
|
||||||
|
{
|
||||||
|
query = list_node->data;
|
||||||
|
list_node = list_node->next; /* in case the query gets deleted */
|
||||||
|
assert(query->server == whichserver);
|
||||||
|
skip_server(channel, query, whichserver);
|
||||||
|
next_server(channel, query, now);
|
||||||
|
}
|
||||||
|
/* Each query should have removed itself from our temporary list as
|
||||||
|
* it re-sent itself or finished up...
|
||||||
|
*/
|
||||||
|
assert(ares__is_list_empty(&list_head));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_server(ares_channel channel, struct query *query,
|
||||||
|
int whichserver) {
|
||||||
|
/* The given server gave us problems with this query, so if we have
|
||||||
|
* the luxury of using other servers, then let's skip the
|
||||||
|
* potentially broken server and just use the others. If we only
|
||||||
|
* have one server and we need to retry then we should just go ahead
|
||||||
|
* and re-use that server, since it's our only hope; perhaps we
|
||||||
|
* just got unlucky, and retrying will work (eg, the server timed
|
||||||
|
* out our TCP connection just as we were sending another request).
|
||||||
|
*/
|
||||||
|
if (channel->nservers > 1)
|
||||||
|
{
|
||||||
|
query->server_info[whichserver].skip_server = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void next_server(ares_channel channel, struct query *query, time_t now)
|
||||||
{
|
{
|
||||||
/* Advance to the next server or try. */
|
/* Advance to the next server or try. */
|
||||||
query->server++;
|
query->server++;
|
||||||
@@ -496,19 +608,33 @@ static struct query *next_server(ares_channel channel, struct query *query, time
|
|||||||
{
|
{
|
||||||
for (; query->server < channel->nservers; query->server++)
|
for (; query->server < channel->nservers; query->server++)
|
||||||
{
|
{
|
||||||
if (!query->skip_server[query->server])
|
struct server_state *server = &channel->servers[query->server];
|
||||||
|
/* We don't want to use this server if (1) we decided this
|
||||||
|
* connection is broken, and thus about to be closed, (2)
|
||||||
|
* we've decided to skip this server because of earlier
|
||||||
|
* errors we encountered, or (3) we already sent this query
|
||||||
|
* over this exact connection.
|
||||||
|
*/
|
||||||
|
if (!server->is_broken &&
|
||||||
|
!query->server_info[query->server].skip_server &&
|
||||||
|
!(query->using_tcp &&
|
||||||
|
(query->server_info[query->server].tcp_connection_generation ==
|
||||||
|
server->tcp_connection_generation)))
|
||||||
{
|
{
|
||||||
ares__send_query(channel, query, now);
|
ares__send_query(channel, query, now);
|
||||||
return (query->next);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
query->server = 0;
|
query->server = 0;
|
||||||
|
|
||||||
/* Only one try if we're using TCP. */
|
/* You might think that with TCP we only need one try. However,
|
||||||
if (query->using_tcp)
|
* even when using TCP, servers can time-out our connection just
|
||||||
break;
|
* as we're sending a request, or close our connection because
|
||||||
|
* they die, or never send us a reply because they get wedged or
|
||||||
|
* tickle a bug that drops our request.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return end_query(channel, query, query->error_status, NULL, 0);
|
end_query(channel, query, query->error_status, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
||||||
@@ -526,7 +652,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
{
|
{
|
||||||
if (open_tcp_socket(channel, server) == -1)
|
if (open_tcp_socket(channel, server) == -1)
|
||||||
{
|
{
|
||||||
query->skip_server[query->server] = 1;
|
skip_server(channel, query, query->server);
|
||||||
next_server(channel, query, now);
|
next_server(channel, query, now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -537,8 +663,16 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
end_query(channel, query, ARES_ENOMEM, NULL, 0);
|
end_query(channel, query, ARES_ENOMEM, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* To make the common case fast, we avoid copies by using the
|
||||||
|
* query's tcpbuf for as long as the query is alive. In the rare
|
||||||
|
* case where the query ends while it's queued for transmission,
|
||||||
|
* then we give the sendreq its own copy of the request packet
|
||||||
|
* and put it in sendreq->data_storage.
|
||||||
|
*/
|
||||||
|
sendreq->data_storage = NULL;
|
||||||
sendreq->data = query->tcpbuf;
|
sendreq->data = query->tcpbuf;
|
||||||
sendreq->len = query->tcplen;
|
sendreq->len = query->tcplen;
|
||||||
|
sendreq->owner_query = query;
|
||||||
sendreq->next = NULL;
|
sendreq->next = NULL;
|
||||||
if (server->qtail)
|
if (server->qtail)
|
||||||
server->qtail->next = sendreq;
|
server->qtail->next = sendreq;
|
||||||
@@ -548,7 +682,8 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
server->qhead = sendreq;
|
server->qhead = sendreq;
|
||||||
}
|
}
|
||||||
server->qtail = sendreq;
|
server->qtail = sendreq;
|
||||||
query->timeout = 0;
|
query->server_info[query->server].tcp_connection_generation =
|
||||||
|
server->tcp_connection_generation;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -556,7 +691,7 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
{
|
{
|
||||||
if (open_udp_socket(channel, server) == -1)
|
if (open_udp_socket(channel, server) == -1)
|
||||||
{
|
{
|
||||||
query->skip_server[query->server] = 1;
|
skip_server(channel, query, query->server);
|
||||||
next_server(channel, query, now);
|
next_server(channel, query, now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -564,21 +699,36 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
|
if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
|
||||||
{
|
{
|
||||||
/* FIXME: Handle EAGAIN here since it likely can happen. */
|
/* FIXME: Handle EAGAIN here since it likely can happen. */
|
||||||
query->skip_server[query->server] = 1;
|
skip_server(channel, query, query->server);
|
||||||
next_server(channel, query, now);
|
next_server(channel, query, now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
query->timeout = now
|
query->timeout = now
|
||||||
+ ((query->try == 0) ? channel->timeout
|
+ ((query->try == 0) ? channel->timeout
|
||||||
: channel->timeout << query->try / channel->nservers);
|
: channel->timeout << query->try / channel->nservers);
|
||||||
}
|
/* Keep track of queries bucketed by timeout, so we can process
|
||||||
|
* timeout events quickly.
|
||||||
|
*/
|
||||||
|
ares__remove_from_list(&(query->queries_by_timeout));
|
||||||
|
ares__insert_in_list(
|
||||||
|
&(query->queries_by_timeout),
|
||||||
|
&(channel->queries_by_timeout[query->timeout %
|
||||||
|
ARES_TIMEOUT_TABLE_SIZE]));
|
||||||
|
|
||||||
|
/* Keep track of queries bucketed by server, so we can process server
|
||||||
|
* errors quickly.
|
||||||
|
*/
|
||||||
|
ares__remove_from_list(&(query->queries_to_server));
|
||||||
|
ares__insert_in_list(&(query->queries_to_server),
|
||||||
|
&(server->queries_to_server));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nonblock() set the given socket to either blocking or non-blocking mode
|
* setsocknonblock sets the given socket to either blocking or non-blocking mode
|
||||||
* based on the 'nonblock' boolean argument. This function is highly portable.
|
* based on the 'nonblock' boolean argument. This function is highly portable.
|
||||||
*/
|
*/
|
||||||
static int nonblock(ares_socket_t sockfd, /* operate on this */
|
static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
|
||||||
int nonblock /* TRUE or FALSE */)
|
int nonblock /* TRUE or FALSE */)
|
||||||
{
|
{
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
@@ -646,9 +796,36 @@ static int nonblock(ares_socket_t sockfd, /* operate on this */
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int configure_socket(int s, ares_channel channel)
|
||||||
|
{
|
||||||
|
setsocknonblock(s, TRUE);
|
||||||
|
|
||||||
|
#if defined(FD_CLOEXEC) && !defined(MSDOS)
|
||||||
|
/* Configure the socket fd as close-on-exec. */
|
||||||
|
if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set the socket's send and receive buffer sizes. */
|
||||||
|
if ((channel->socket_send_buffer_size > 0) &&
|
||||||
|
setsockopt(s, SOL_SOCKET, SO_SNDBUF,
|
||||||
|
(void *)&channel->socket_send_buffer_size,
|
||||||
|
sizeof(channel->socket_send_buffer_size)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((channel->socket_receive_buffer_size > 0) &&
|
||||||
|
setsockopt(s, SOL_SOCKET, SO_RCVBUF,
|
||||||
|
(void *)&channel->socket_receive_buffer_size,
|
||||||
|
sizeof(channel->socket_receive_buffer_size)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
||||||
{
|
{
|
||||||
ares_socket_t s;
|
ares_socket_t s;
|
||||||
|
int opt;
|
||||||
struct sockaddr_in sockin;
|
struct sockaddr_in sockin;
|
||||||
|
|
||||||
/* Acquire a socket. */
|
/* Acquire a socket. */
|
||||||
@@ -656,8 +833,26 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||||||
if (s == ARES_SOCKET_BAD)
|
if (s == ARES_SOCKET_BAD)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Set the socket non-blocking. */
|
/* Configure it. */
|
||||||
nonblock(s, TRUE);
|
if (configure_socket(s, channel) < 0)
|
||||||
|
{
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in
|
||||||
|
* configure_socket). In general, in DNS lookups we're pretty much interested
|
||||||
|
* in firing off a single request and then waiting for a reply, so batching
|
||||||
|
* isn't very interesting in general.
|
||||||
|
*/
|
||||||
|
opt = 1;
|
||||||
|
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
|
||||||
|
(void *)&opt, sizeof(opt)) == -1)
|
||||||
|
{
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Connect to the server. */
|
/* Connect to the server. */
|
||||||
memset(&sockin, 0, sizeof(sockin));
|
memset(&sockin, 0, sizeof(sockin));
|
||||||
@@ -676,6 +871,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||||||
SOCK_STATE_CALLBACK(channel, s, 1, 0);
|
SOCK_STATE_CALLBACK(channel, s, 1, 0);
|
||||||
server->tcp_buffer_pos = 0;
|
server->tcp_buffer_pos = 0;
|
||||||
server->tcp_socket = s;
|
server->tcp_socket = s;
|
||||||
|
server->tcp_connection_generation = ++channel->tcp_connection_generation;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,7 +886,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Set the socket non-blocking. */
|
/* Set the socket non-blocking. */
|
||||||
nonblock(s, TRUE);
|
if (configure_socket(s, channel) < 0)
|
||||||
|
{
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Connect to the server. */
|
/* Connect to the server. */
|
||||||
memset(&sockin, 0, sizeof(sockin));
|
memset(&sockin, 0, sizeof(sockin));
|
||||||
@@ -788,34 +988,92 @@ static int same_questions(const unsigned char *qbuf, int qlen,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct query *end_query (ares_channel channel, struct query *query, int status,
|
static void end_query (ares_channel channel, struct query *query, int status,
|
||||||
unsigned char *abuf, int alen)
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
struct query **q, *next;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
query->callback(query->arg, status, abuf, alen);
|
/* First we check to see if this query ended while one of our send
|
||||||
for (q = &channel->queries; *q; q = &(*q)->next)
|
* queues still has pointers to it.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < channel->nservers; i++)
|
||||||
{
|
{
|
||||||
if (*q == query)
|
struct server_state *server = &channel->servers[i];
|
||||||
break;
|
struct send_request *sendreq;
|
||||||
|
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
|
||||||
|
if (sendreq->owner_query == query)
|
||||||
|
{
|
||||||
|
sendreq->owner_query = NULL;
|
||||||
|
assert(sendreq->data_storage == NULL);
|
||||||
|
if (status == ARES_SUCCESS)
|
||||||
|
{
|
||||||
|
/* We got a reply for this query, but this queued
|
||||||
|
* sendreq points into this soon-to-be-gone query's
|
||||||
|
* tcpbuf. Probably this means we timed out and queued
|
||||||
|
* the query for retransmission, then received a
|
||||||
|
* response before actually retransmitting. This is
|
||||||
|
* perfectly fine, so we want to keep the connection
|
||||||
|
* running smoothly if we can. But in the worst case
|
||||||
|
* we may have sent only some prefix of the query,
|
||||||
|
* with some suffix of the query left to send. Also,
|
||||||
|
* the buffer may be queued on multiple queues. To
|
||||||
|
* prevent dangling pointers to the query's tcpbuf and
|
||||||
|
* handle these cases, we just give such sendreqs
|
||||||
|
* their own copy of the query packet.
|
||||||
|
*/
|
||||||
|
sendreq->data_storage = malloc(sendreq->len);
|
||||||
|
if (sendreq->data_storage != NULL)
|
||||||
|
{
|
||||||
|
memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
|
||||||
|
sendreq->data = sendreq->data_storage;
|
||||||
}
|
}
|
||||||
*q = query->next;
|
}
|
||||||
if (*q)
|
if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL))
|
||||||
next = (*q)->next;
|
{
|
||||||
else
|
/* We encountered an error (probably a timeout,
|
||||||
next = NULL;
|
* suggesting the DNS server we're talking to is
|
||||||
free(query->tcpbuf);
|
* probably unreachable, wedged, or severely
|
||||||
free(query->skip_server);
|
* overloaded) or we couldn't copy the request, so
|
||||||
free(query);
|
* mark the connection as broken. When we get to
|
||||||
|
* process_broken_connections() we'll close the
|
||||||
|
* connection and try to re-send requests to another
|
||||||
|
* server.
|
||||||
|
*/
|
||||||
|
server->is_broken = 1;
|
||||||
|
/* Just to be paranoid, zero out this sendreq... */
|
||||||
|
sendreq->data = NULL;
|
||||||
|
sendreq->len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invoke the callback */
|
||||||
|
query->callback(query->arg, status, query->timeouts, abuf, alen);
|
||||||
|
ares__free_query(query);
|
||||||
|
|
||||||
/* Simple cleanup policy: if no queries are remaining, close all
|
/* Simple cleanup policy: if no queries are remaining, close all
|
||||||
* network sockets unless STAYOPEN is set.
|
* network sockets unless STAYOPEN is set.
|
||||||
*/
|
*/
|
||||||
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!(channel->flags & ARES_FLAG_STAYOPEN) &&
|
||||||
|
ares__is_list_empty(&(channel->all_queries)))
|
||||||
{
|
{
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(channel, &channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
}
|
}
|
||||||
return (next);
|
}
|
||||||
|
|
||||||
|
void ares__free_query(struct query *query)
|
||||||
|
{
|
||||||
|
/* Remove the query from all the lists in which it is linked */
|
||||||
|
ares__remove_from_list(&(query->queries_by_qid));
|
||||||
|
ares__remove_from_list(&(query->queries_by_timeout));
|
||||||
|
ares__remove_from_list(&(query->queries_to_server));
|
||||||
|
ares__remove_from_list(&(query->all_queries));
|
||||||
|
/* Zero out some important stuff, to help catch bugs */
|
||||||
|
query->callback = NULL;
|
||||||
|
query->arg = NULL;
|
||||||
|
/* Deallocate the memory associated with the query */
|
||||||
|
free(query->tcpbuf);
|
||||||
|
free(query->server_info);
|
||||||
|
free(query);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_query \- Initiate a single-question DNS query
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP)
|
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
.B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
||||||
@@ -124,6 +124,11 @@ The name service channel
|
|||||||
.I channel
|
.I channel
|
||||||
is being destroyed; the query will not be completed.
|
is being destroyed; the query will not be completed.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
If the query completed (even if there was something wrong with it, as
|
If the query completed (even if there was something wrong with it, as
|
||||||
indicated by some of the above error codes), the callback argument
|
indicated by some of the above error codes), the callback argument
|
||||||
.I abuf
|
.I abuf
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct qquery {
|
|||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void qcallback(void *arg, int status, unsigned char *abuf, int alen);
|
static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen);
|
||||||
|
|
||||||
void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
|
void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
|
||||||
{
|
{
|
||||||
@@ -53,13 +53,13 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
|
|||||||
state = &key->state[0];
|
state = &key->state[0];
|
||||||
for(counter = 0; counter < buffer_len; counter ++)
|
for(counter = 0; counter < buffer_len; counter ++)
|
||||||
{
|
{
|
||||||
x = (x + 1) % 256;
|
x = (unsigned char)((x + 1) % 256);
|
||||||
y = (state[x] + y) % 256;
|
y = (unsigned char)((state[x] + y) % 256);
|
||||||
ARES_SWAP_BYTE(&state[x], &state[y]);
|
ARES_SWAP_BYTE(&state[x], &state[y]);
|
||||||
|
|
||||||
xorIndex = (state[x] + state[y]) % 256;
|
xorIndex = (unsigned char)((state[x] + state[y]) % 256);
|
||||||
|
|
||||||
buffer_ptr[counter] ^= state[xorIndex];
|
buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]);
|
||||||
}
|
}
|
||||||
key->x = x;
|
key->x = x;
|
||||||
key->y = y;
|
key->y = y;
|
||||||
@@ -68,12 +68,16 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
|
|||||||
static struct query* find_query_by_id(ares_channel channel, int id)
|
static struct query* find_query_by_id(ares_channel channel, int id)
|
||||||
{
|
{
|
||||||
unsigned short qid;
|
unsigned short qid;
|
||||||
struct query* q;
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
DNS_HEADER_SET_QID(((unsigned char*)&qid), id);
|
DNS_HEADER_SET_QID(((unsigned char*)&qid), id);
|
||||||
|
|
||||||
/* Find the query corresponding to this packet. */
|
/* Find the query corresponding to this packet. */
|
||||||
for (q = channel->queries; q; q = q->next)
|
list_head = &(channel->queries_by_qid[qid % ARES_QID_TABLE_SIZE]);
|
||||||
|
for (list_node = list_head->next; list_node != list_head;
|
||||||
|
list_node = list_node->next)
|
||||||
{
|
{
|
||||||
|
struct query *q = list_node->data;
|
||||||
if (q->qid == qid)
|
if (q->qid == qid)
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
@@ -110,7 +114,8 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
|
|||||||
&qlen);
|
&qlen);
|
||||||
if (status != ARES_SUCCESS)
|
if (status != ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
callback(arg, status, NULL, 0);
|
if (qbuf != NULL) free(qbuf);
|
||||||
|
callback(arg, status, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +126,7 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
|
|||||||
if (!qquery)
|
if (!qquery)
|
||||||
{
|
{
|
||||||
ares_free_string(qbuf);
|
ares_free_string(qbuf);
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qquery->callback = callback;
|
qquery->callback = callback;
|
||||||
@@ -132,14 +137,14 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
|
|||||||
ares_free_string(qbuf);
|
ares_free_string(qbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qcallback(void *arg, int status, unsigned char *abuf, int alen)
|
static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
struct qquery *qquery = (struct qquery *) arg;
|
struct qquery *qquery = (struct qquery *) arg;
|
||||||
unsigned int ancount;
|
unsigned int ancount;
|
||||||
int rcode;
|
int rcode;
|
||||||
|
|
||||||
if (status != ARES_SUCCESS)
|
if (status != ARES_SUCCESS)
|
||||||
qquery->callback(qquery->arg, status, abuf, alen);
|
qquery->callback(qquery->arg, status, timeouts, abuf, alen);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Pull the response code and answer count from the packet. */
|
/* Pull the response code and answer count from the packet. */
|
||||||
@@ -168,7 +173,7 @@ static void qcallback(void *arg, int status, unsigned char *abuf, int alen)
|
|||||||
status = ARES_EREFUSED;
|
status = ARES_EREFUSED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qquery->callback(qquery->arg, status, abuf, alen);
|
qquery->callback(qquery->arg, status, timeouts, abuf, alen);
|
||||||
}
|
}
|
||||||
free(qquery);
|
free(qquery);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_search \- Initiate a DNS query with domain search
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP)
|
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
.B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
||||||
@@ -125,6 +125,11 @@ The name service channel
|
|||||||
.I channel
|
.I channel
|
||||||
is being destroyed; the query will not be completed.
|
is being destroyed; the query will not be completed.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
If a query completed successfully, the callback argument
|
If a query completed successfully, the callback argument
|
||||||
.I abuf
|
.I abuf
|
||||||
points to a result buffer of length
|
points to a result buffer of length
|
||||||
|
|||||||
@@ -41,10 +41,12 @@ struct search_query {
|
|||||||
int status_as_is; /* error status from trying as-is */
|
int status_as_is; /* error status from trying as-is */
|
||||||
int next_domain; /* next search domain to try */
|
int next_domain; /* next search domain to try */
|
||||||
int trying_as_is; /* current query is for name as-is */
|
int trying_as_is; /* current query is for name as-is */
|
||||||
|
int timeouts; /* number of timeouts we saw for this request */
|
||||||
|
int ever_got_nodata; /* did we ever get ARES_ENODATA along the way? */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void search_callback(void *arg, int status, unsigned char *abuf,
|
static void search_callback(void *arg, int status, int timeouts,
|
||||||
int alen);
|
unsigned char *abuf, int alen);
|
||||||
static void end_squery(struct search_query *squery, int status,
|
static void end_squery(struct search_query *squery, int status,
|
||||||
unsigned char *abuf, int alen);
|
unsigned char *abuf, int alen);
|
||||||
static int cat_domain(const char *name, const char *domain, char **s);
|
static int cat_domain(const char *name, const char *domain, char **s);
|
||||||
@@ -64,7 +66,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
|||||||
status = single_domain(channel, name, &s);
|
status = single_domain(channel, name, &s);
|
||||||
if (status != ARES_SUCCESS)
|
if (status != ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
callback(arg, status, NULL, 0);
|
callback(arg, status, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (s)
|
if (s)
|
||||||
@@ -80,7 +82,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
|||||||
squery = malloc(sizeof(struct search_query));
|
squery = malloc(sizeof(struct search_query));
|
||||||
if (!squery)
|
if (!squery)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
squery->channel = channel;
|
squery->channel = channel;
|
||||||
@@ -88,7 +90,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
|||||||
if (!squery->name)
|
if (!squery->name)
|
||||||
{
|
{
|
||||||
free(squery);
|
free(squery);
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
squery->dnsclass = dnsclass;
|
squery->dnsclass = dnsclass;
|
||||||
@@ -96,6 +98,8 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
|||||||
squery->status_as_is = -1;
|
squery->status_as_is = -1;
|
||||||
squery->callback = callback;
|
squery->callback = callback;
|
||||||
squery->arg = arg;
|
squery->arg = arg;
|
||||||
|
squery->timeouts = 0;
|
||||||
|
squery->ever_got_nodata = 0;
|
||||||
|
|
||||||
/* Count the number of dots in name. */
|
/* Count the number of dots in name. */
|
||||||
ndots = 0;
|
ndots = 0;
|
||||||
@@ -132,18 +136,20 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
|||||||
/* failed, free the malloc()ed memory */
|
/* failed, free the malloc()ed memory */
|
||||||
free(squery->name);
|
free(squery->name);
|
||||||
free(squery);
|
free(squery);
|
||||||
callback(arg, status, NULL, 0);
|
callback(arg, status, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void search_callback(void *arg, int status, unsigned char *abuf,
|
static void search_callback(void *arg, int status, int timeouts,
|
||||||
int alen)
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
struct search_query *squery = (struct search_query *) arg;
|
struct search_query *squery = (struct search_query *) arg;
|
||||||
ares_channel channel = squery->channel;
|
ares_channel channel = squery->channel;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
|
squery->timeouts += timeouts;
|
||||||
|
|
||||||
/* Stop searching unless we got a non-fatal error. */
|
/* Stop searching unless we got a non-fatal error. */
|
||||||
if (status != ARES_ENODATA && status != ARES_ESERVFAIL
|
if (status != ARES_ENODATA && status != ARES_ESERVFAIL
|
||||||
&& status != ARES_ENOTFOUND)
|
&& status != ARES_ENOTFOUND)
|
||||||
@@ -153,6 +159,17 @@ static void search_callback(void *arg, int status, unsigned char *abuf,
|
|||||||
/* Save the status if we were trying as-is. */
|
/* Save the status if we were trying as-is. */
|
||||||
if (squery->trying_as_is)
|
if (squery->trying_as_is)
|
||||||
squery->status_as_is = status;
|
squery->status_as_is = status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we ever get ARES_ENODATA along the way, record that; if the search
|
||||||
|
* should run to the very end and we got at least one ARES_ENODATA,
|
||||||
|
* then callers like ares_gethostbyname() may want to try a T_A search
|
||||||
|
* even if the last domain we queried for T_AAAA resource records
|
||||||
|
* returned ARES_ENOTFOUND.
|
||||||
|
*/
|
||||||
|
if (status == ARES_ENODATA)
|
||||||
|
squery->ever_got_nodata = 1;
|
||||||
|
|
||||||
if (squery->next_domain < channel->ndomains)
|
if (squery->next_domain < channel->ndomains)
|
||||||
{
|
{
|
||||||
/* Try the next domain. */
|
/* Try the next domain. */
|
||||||
@@ -176,15 +193,20 @@ static void search_callback(void *arg, int status, unsigned char *abuf,
|
|||||||
ares_query(channel, squery->name, squery->dnsclass, squery->type,
|
ares_query(channel, squery->name, squery->dnsclass, squery->type,
|
||||||
search_callback, squery);
|
search_callback, squery);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (squery->status_as_is == ARES_ENOTFOUND && squery->ever_got_nodata) {
|
||||||
|
end_squery(squery, ARES_ENODATA, NULL, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
end_squery(squery, squery->status_as_is, NULL, 0);
|
end_squery(squery, squery->status_as_is, NULL, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_squery(struct search_query *squery, int status,
|
static void end_squery(struct search_query *squery, int status,
|
||||||
unsigned char *abuf, int alen)
|
unsigned char *abuf, int alen)
|
||||||
{
|
{
|
||||||
squery->callback(squery->arg, status, abuf, alen);
|
squery->callback(squery->arg, status, squery->timeouts, abuf, alen);
|
||||||
free(squery->name);
|
free(squery->name);
|
||||||
free(squery);
|
free(squery);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ares_send \- Initiate a DNS query
|
|||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP)
|
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
||||||
.PP
|
.PP
|
||||||
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
||||||
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
@@ -79,6 +79,11 @@ The name service channel
|
|||||||
.I channel
|
.I channel
|
||||||
is being destroyed; the query will not be completed.
|
is being destroyed; the query will not be completed.
|
||||||
.PP
|
.PP
|
||||||
|
The callback argument
|
||||||
|
.I timeouts
|
||||||
|
reports how many times a query timed out during the execution of the
|
||||||
|
given request.
|
||||||
|
.PP
|
||||||
If the query completed, the callback argument
|
If the query completed, the callback argument
|
||||||
.I abuf
|
.I abuf
|
||||||
points to a result buffer of length
|
points to a result buffer of length
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
|||||||
/* Verify that the query is at least long enough to hold the header. */
|
/* Verify that the query is at least long enough to hold the header. */
|
||||||
if (qlen < HFIXEDSZ || qlen >= (1 << 16))
|
if (qlen < HFIXEDSZ || qlen >= (1 << 16))
|
||||||
{
|
{
|
||||||
callback(arg, ARES_EBADQUERY, NULL, 0);
|
callback(arg, ARES_EBADQUERY, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,22 +52,23 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
|||||||
query = malloc(sizeof(struct query));
|
query = malloc(sizeof(struct query));
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
query->tcpbuf = malloc(qlen + 2);
|
query->tcpbuf = malloc(qlen + 2);
|
||||||
if (!query->tcpbuf)
|
if (!query->tcpbuf)
|
||||||
{
|
{
|
||||||
free(query);
|
free(query);
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
query->skip_server = malloc(channel->nservers * sizeof(int));
|
query->server_info = malloc(channel->nservers *
|
||||||
if (!query->skip_server)
|
sizeof(query->server_info[0]));
|
||||||
|
if (!query->server_info)
|
||||||
{
|
{
|
||||||
free(query->tcpbuf);
|
free(query->tcpbuf);
|
||||||
free(query);
|
free(query);
|
||||||
callback(arg, ARES_ENOMEM, NULL, 0);
|
callback(arg, ARES_ENOMEM, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,13 +94,28 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
|||||||
query->try = 0;
|
query->try = 0;
|
||||||
query->server = 0;
|
query->server = 0;
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
query->skip_server[i] = 0;
|
{
|
||||||
|
query->server_info[i].skip_server = 0;
|
||||||
|
query->server_info[i].tcp_connection_generation = 0;
|
||||||
|
}
|
||||||
query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ;
|
query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ;
|
||||||
query->error_status = ARES_ECONNREFUSED;
|
query->error_status = ARES_ECONNREFUSED;
|
||||||
|
query->timeouts = 0;
|
||||||
|
|
||||||
/* Chain the query into this channel's query list. */
|
/* Initialize our list nodes. */
|
||||||
query->next = channel->queries;
|
ares__init_list_node(&(query->queries_by_qid), query);
|
||||||
channel->queries = query;
|
ares__init_list_node(&(query->queries_by_timeout), query);
|
||||||
|
ares__init_list_node(&(query->queries_to_server), query);
|
||||||
|
ares__init_list_node(&(query->all_queries), query);
|
||||||
|
|
||||||
|
/* Chain the query into the list of all queries. */
|
||||||
|
ares__insert_in_list(&(query->all_queries), &(channel->all_queries));
|
||||||
|
/* Keep track of queries bucketed by qid, so we can process DNS
|
||||||
|
* responses quickly.
|
||||||
|
*/
|
||||||
|
ares__insert_in_list(
|
||||||
|
&(query->queries_by_qid),
|
||||||
|
&(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE]));
|
||||||
|
|
||||||
/* Perform the first query action. */
|
/* Perform the first query action. */
|
||||||
time(&now);
|
time(&now);
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ const char *ares_strerror(int code)
|
|||||||
"Illegal hints flags specified"
|
"Illegal hints flags specified"
|
||||||
};
|
};
|
||||||
|
|
||||||
DEBUGASSERT(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));
|
if(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)))
|
||||||
return errtext[code];
|
return errtext[code];
|
||||||
|
else
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,23 +26,34 @@
|
|||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
|
/* WARNING: Beware that this is linear in the number of outstanding
|
||||||
|
* requests! You are probably far better off just calling ares_process()
|
||||||
|
* once per second, rather than calling ares_timeout() to figure out
|
||||||
|
* when to next call ares_process().
|
||||||
|
*/
|
||||||
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
|
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
|
||||||
struct timeval *tvbuf)
|
struct timeval *tvbuf)
|
||||||
{
|
{
|
||||||
struct query *query;
|
struct query *query;
|
||||||
|
struct list_node* list_head;
|
||||||
|
struct list_node* list_node;
|
||||||
time_t now;
|
time_t now;
|
||||||
time_t offset, min_offset; /* these use time_t since some 32 bit systems
|
time_t offset, min_offset; /* these use time_t since some 32 bit systems
|
||||||
still use 64 bit time_t! (like VS2005) */
|
still use 64 bit time_t! (like VS2005) */
|
||||||
|
|
||||||
/* No queries, no timeout (and no fetch of the current time). */
|
/* No queries, no timeout (and no fetch of the current time). */
|
||||||
if (!channel->queries)
|
if (ares__is_list_empty(&(channel->all_queries)))
|
||||||
return maxtv;
|
return maxtv;
|
||||||
|
|
||||||
/* Find the minimum timeout for the current set of queries. */
|
/* Find the minimum timeout for the current set of queries. */
|
||||||
time(&now);
|
time(&now);
|
||||||
min_offset = -1;
|
min_offset = -1;
|
||||||
for (query = channel->queries; query; query = query->next)
|
|
||||||
|
list_head = &(channel->all_queries);
|
||||||
|
for (list_node = list_head->next; list_node != list_head;
|
||||||
|
list_node = list_node->next)
|
||||||
{
|
{
|
||||||
|
query = list_node->data;
|
||||||
if (query->timeout == 0)
|
if (query->timeout == 0)
|
||||||
continue;
|
continue;
|
||||||
offset = query->timeout - now;
|
offset = query->timeout - now;
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#define ARES__VERSION_H
|
#define ARES__VERSION_H
|
||||||
|
|
||||||
#define ARES_VERSION_MAJOR 1
|
#define ARES_VERSION_MAJOR 1
|
||||||
#define ARES_VERSION_MINOR 4
|
#define ARES_VERSION_MINOR 5
|
||||||
#define ARES_VERSION_PATCH 1
|
#define ARES_VERSION_PATCH 2
|
||||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||||
(ARES_VERSION_MINOR<<8)|\
|
(ARES_VERSION_MINOR<<8)|\
|
||||||
(ARES_VERSION_PATCH))
|
(ARES_VERSION_PATCH))
|
||||||
#define ARES_VERSION_STR "1.4.1-CVS"
|
#define ARES_VERSION_STR "1.5.2-CVS"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/* Copyright (C) 2005 by Dominick Meglio
|
||||||
|
*
|
||||||
* Permission to use, copy, modify, and distribute this
|
* Permission to use, copy, modify, and distribute this
|
||||||
* software and its documentation for any purpose and without
|
* software and its documentation for any purpose and without
|
||||||
* fee is hereby granted, provided that the above copyright
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
|||||||
@@ -146,11 +146,6 @@
|
|||||||
#define ssize_t int
|
#define ssize_t int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define to 'int' if socklen_t is not an available 'typedefed' type */
|
|
||||||
#ifndef HAVE_WS2TCPIP_H
|
|
||||||
#define socklen_t int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* STRUCT RELATED */
|
/* STRUCT RELATED */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
@@ -164,24 +159,58 @@
|
|||||||
/* Define this if you have struct timeval */
|
/* Define this if you have struct timeval */
|
||||||
#define HAVE_STRUCT_TIMEVAL 1
|
#define HAVE_STRUCT_TIMEVAL 1
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* COMPILER SPECIFIC */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Define to avoid VS2005 complaining about portable C functions */
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* VS2008 does not support Windows build targets prior to WinXP, */
|
||||||
|
/* so, if no build target has been defined we will target WinXP. */
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||||
|
# ifndef _WIN32_WINNT
|
||||||
|
# define _WIN32_WINNT 0x0501
|
||||||
|
# endif
|
||||||
|
# ifndef WINVER
|
||||||
|
# define WINVER 0x0501
|
||||||
|
# endif
|
||||||
|
# if (_WIN32_WINNT < 0x0501) || (WINVER < 0x0501)
|
||||||
|
# error VS2008 does not support Windows build targets prior to WinXP
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* IPV6 COMPATIBILITY */
|
/* IPV6 COMPATIBILITY */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Define this if you have address family AF_INET6 */
|
/* Define this if you have address family AF_INET6 */
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#define HAVE_AF_INET6 1
|
#define HAVE_AF_INET6 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define this if you have protocol family PF_INET6 */
|
/* Define this if you have protocol family PF_INET6 */
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#define HAVE_PF_INET6 1
|
#define HAVE_PF_INET6 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define this if you have struct in6_addr */
|
/* Define this if you have struct in6_addr */
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#define HAVE_STRUCT_IN6_ADDR 1
|
#define HAVE_STRUCT_IN6_ADDR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define this if you have struct sockaddr_in6 */
|
/* Define this if you have struct sockaddr_in6 */
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#define HAVE_STRUCT_SOCKADDR_IN6 1
|
#define HAVE_STRUCT_SOCKADDR_IN6 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define this if you have sockaddr_in6 with scopeid */
|
/* Define this if you have sockaddr_in6 with scopeid */
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* __ARES_CONFIG_WIN32_H */
|
#endif /* __ARES_CONFIG_WIN32_H */
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
dnl when doing the debug stuff, use static library only
|
dnl when doing the debug stuff, use static library only
|
||||||
AC_DISABLE_SHARED
|
AC_DISABLE_SHARED
|
||||||
|
|
||||||
|
debugbuild="yes"
|
||||||
|
|
||||||
dnl the entire --enable-debug is a hack that lives and runs on top of
|
dnl the entire --enable-debug is a hack that lives and runs on top of
|
||||||
dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier
|
dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier
|
||||||
AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl])
|
AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl])
|
||||||
@@ -70,6 +72,7 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
esac ],
|
esac ],
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
)
|
)
|
||||||
|
AM_CONDITIONAL(DEBUGBUILD, test x$debugbuild = xyes)
|
||||||
|
|
||||||
dnl skip libtool C++ and Fortran compiler checks
|
dnl skip libtool C++ and Fortran compiler checks
|
||||||
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
|
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
|
||||||
@@ -117,6 +120,43 @@ dnl gethostbyname_r() version
|
|||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"])
|
CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"])
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl platform/compiler/architecture specific checks/flags
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
case $host in
|
||||||
|
#
|
||||||
|
x86_64*linux*)
|
||||||
|
#
|
||||||
|
dnl find out if icc is being used
|
||||||
|
if test "z$ICC" = "z"; then
|
||||||
|
CURL_DETECT_ICC
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$ICC" = "yes"; then
|
||||||
|
dnl figure out icc version
|
||||||
|
AC_MSG_CHECKING([icc version])
|
||||||
|
iccver=`$CC -dumpversion`
|
||||||
|
iccnhi=`echo $iccver | cut -d . -f1`
|
||||||
|
iccnlo=`echo $iccver | cut -d . -f2`
|
||||||
|
iccnum=`(expr $iccnhi "*" 100 + $iccnlo) 2>/dev/null`
|
||||||
|
AC_MSG_RESULT($iccver)
|
||||||
|
#
|
||||||
|
if test "$iccnum" -ge "900" && test "$iccnum" -lt "1000"; then
|
||||||
|
dnl icc 9.X specific
|
||||||
|
CFLAGS="$CFLAGS -i-dynamic"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$iccnum" -ge "1000"; then
|
||||||
|
dnl icc 10.X or later
|
||||||
|
CFLAGS="$CFLAGS -shared-intel"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
#
|
||||||
|
esac
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -221,9 +261,6 @@ fi
|
|||||||
dnl socket lib?
|
dnl socket lib?
|
||||||
AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ])
|
AC_CHECK_FUNC(connect, , [ AC_CHECK_LIB(socket, connect) ])
|
||||||
|
|
||||||
dnl dl lib?
|
|
||||||
AC_CHECK_FUNC(dlclose, , [ AC_CHECK_LIB(dl, dlopen) ])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to use libgcc])
|
AC_MSG_CHECKING([whether to use libgcc])
|
||||||
AC_ARG_ENABLE(libgcc,
|
AC_ARG_ENABLE(libgcc,
|
||||||
AC_HELP_STRING([--enable-libgcc],[use libgcc when linking]),
|
AC_HELP_STRING([--enable-libgcc],[use libgcc when linking]),
|
||||||
@@ -305,6 +342,9 @@ if test "x$RECENTAIX" = "xyes"; then
|
|||||||
dnl the optimizer assumes that pointers can only point to
|
dnl the optimizer assumes that pointers can only point to
|
||||||
dnl an object of the same type.
|
dnl an object of the same type.
|
||||||
CFLAGS="$CFLAGS -qnoansialias"
|
CFLAGS="$CFLAGS -qnoansialias"
|
||||||
|
dnl Force AIX xlc to stop after the compilation phase, and not
|
||||||
|
dnl generate object code, when the source compiles with errors.
|
||||||
|
CFLAGS="$CFLAGS -qhalt=e"
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -340,6 +380,7 @@ AC_CHECK_HEADERS(
|
|||||||
sys/param.h \
|
sys/param.h \
|
||||||
netdb.h \
|
netdb.h \
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
|
netinet/tcp.h \
|
||||||
net/if.h \
|
net/if.h \
|
||||||
errno.h \
|
errno.h \
|
||||||
stdbool.h \
|
stdbool.h \
|
||||||
@@ -793,8 +834,15 @@ AC_HELP_STRING([--with-random=FILE],
|
|||||||
[read randomness from FILE (default=/dev/urandom)]),
|
[read randomness from FILE (default=/dev/urandom)]),
|
||||||
[ RANDOM_FILE="$withval" ],
|
[ RANDOM_FILE="$withval" ],
|
||||||
[
|
[
|
||||||
dnl Check for random device
|
dnl Check for random device. If we're cross compiling, we can't
|
||||||
|
dnl check, and it's better to assume it doesn't exist than it is
|
||||||
|
dnl to fail on AC_CHECK_FILE or later.
|
||||||
|
if test "$cross_compiling" = "no"; then
|
||||||
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
|
AC_CHECK_FILE("/dev/urandom", [ RANDOM_FILE="/dev/urandom"] )
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([cannot check for /dev/urandom while cross compiling; assuming none])
|
||||||
|
fi
|
||||||
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
|
if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
|
||||||
|
|||||||
36
ares/get_ver.awk
Normal file
36
ares/get_ver.awk
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# ***************************************************************************
|
||||||
|
# * Project: c-ares
|
||||||
|
# *
|
||||||
|
# * $Id$
|
||||||
|
# ***************************************************************************
|
||||||
|
# awk script which fetches c-ares version number and string from input
|
||||||
|
# file and writes them to STDOUT. Here you can get an awk version for Win32:
|
||||||
|
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||||
|
#
|
||||||
|
BEGIN {
|
||||||
|
if (match (ARGV[1], /ares_version.h/)) {
|
||||||
|
while ((getline < ARGV[1]) > 0) {
|
||||||
|
if (match ($0, /^#define ARES_COPYRIGHT "[^"]+"$/)) {
|
||||||
|
libcares_copyright_str = substr($0, 25, length($0)-25);
|
||||||
|
}
|
||||||
|
else if (match ($0, /^#define ARES_VERSION_STR "[^"]+"$/)) {
|
||||||
|
libcares_ver_str = substr($3, 2, length($3)-2);
|
||||||
|
}
|
||||||
|
else if (match ($0, /^#define ARES_VERSION_MAJOR [0-9]+$/)) {
|
||||||
|
libcares_ver_major = substr($3, 1, length($3));
|
||||||
|
}
|
||||||
|
else if (match ($0, /^#define ARES_VERSION_MINOR [0-9]+$/)) {
|
||||||
|
libcares_ver_minor = substr($3, 1, length($3));
|
||||||
|
}
|
||||||
|
else if (match ($0, /^#define ARES_VERSION_PATCH [0-9]+$/)) {
|
||||||
|
libcares_ver_patch = substr($3, 1, length($3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libcares_ver = libcares_ver_major "," libcares_ver_minor "," libcares_ver_patch;
|
||||||
|
print "LIBCARES_VERSION = " libcares_ver "";
|
||||||
|
print "LIBCARES_VERSION_STR = " libcares_ver_str "";
|
||||||
|
print "LIBCARES_COPYRIGHT_STR = " libcares_copyright_str "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/* Copyright (C) 2005 by Daniel Stenberg
|
||||||
|
*
|
||||||
* Permission to use, copy, modify, and distribute this
|
* Permission to use, copy, modify, and distribute this
|
||||||
* software and its documentation for any purpose and without
|
* software and its documentation for any purpose and without
|
||||||
* fee is hereby granted, provided that the above copyright
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/* Copyright (C) 2005 by Dominick Meglio
|
||||||
|
*
|
||||||
* Permission to use, copy, modify, and distribute this
|
* Permission to use, copy, modify, and distribute this
|
||||||
* software and its documentation for any purpose and without
|
* software and its documentation for any purpose and without
|
||||||
* fee is hereby granted, provided that the above copyright
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ includedir=@includedir@
|
|||||||
|
|
||||||
Name: c-ares
|
Name: c-ares
|
||||||
URL: http://daniel.haxx.se/projects/c-ares/
|
URL: http://daniel.haxx.se/projects/c-ares/
|
||||||
Description: asyncronous DNS lookup library
|
Description: asynchronous DNS lookup library
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
Requires:
|
Requires:
|
||||||
Requires.private:
|
Requires.private:
|
||||||
|
|||||||
@@ -7,9 +7,6 @@
|
|||||||
port build */
|
port build */
|
||||||
|
|
||||||
#ifndef NETWARE
|
#ifndef NETWARE
|
||||||
#ifndef __CYGWIN__
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
#include <process.h> /* for the _getpid() proto */
|
#include <process.h> /* for the _getpid() proto */
|
||||||
#endif /* !NETWARE */
|
#endif /* !NETWARE */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -149,6 +146,11 @@ typedef enum __ns_opcode {
|
|||||||
|
|
||||||
#define T_CNAME ns_t_cname
|
#define T_CNAME ns_t_cname
|
||||||
|
|
||||||
|
#define NS_MAXDNAME 256 /* maximum domain name */
|
||||||
|
#define MAXDNAME NS_MAXDNAME
|
||||||
|
|
||||||
|
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
|
||||||
|
#define MAXCDNAME NS_MAXCDNAME
|
||||||
|
|
||||||
#define NS_PACKETSZ 512 /* maximum packet size */
|
#define NS_PACKETSZ 512 /* maximum packet size */
|
||||||
#define PACKETSZ NS_PACKETSZ
|
#define PACKETSZ NS_PACKETSZ
|
||||||
|
|||||||
14
ares/setup.h
14
ares/setup.h
@@ -16,13 +16,11 @@
|
|||||||
* without express or implied warranty.
|
* without express or implied warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(WIN32) && defined(__WIN32__)
|
/*
|
||||||
/* Borland fix */
|
* Define WIN32 when build target is Win32 API
|
||||||
#define WIN32
|
*/
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(WIN32) && defined(_WIN32)
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||||
/* VS2005 on x64 fix */
|
|
||||||
#define WIN32
|
#define WIN32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -97,10 +95,6 @@
|
|||||||
#define ssize_t int
|
#define ssize_t int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_WS2TCPIP_H
|
|
||||||
#define socklen_t int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -91,6 +91,31 @@ struct timeval {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows build targets have socklen_t definition in
|
||||||
|
* ws2tcpip.h but some versions of ws2tcpip.h do not
|
||||||
|
* have the definition. It seems that when the socklen_t
|
||||||
|
* definition is missing from ws2tcpip.h the definition
|
||||||
|
* for INET_ADDRSTRLEN is also missing, and that when one
|
||||||
|
* definition is present the other one also is available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(HAVE_SOCKLEN_T)
|
||||||
|
# if ( defined(_MSC_VER) && !defined(INET_ADDRSTRLEN) ) || \
|
||||||
|
(!defined(_MSC_VER) && !defined(HAVE_WS2TCPIP_H) )
|
||||||
|
# define socklen_t int
|
||||||
|
# define HAVE_SOCKLEN_T
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__minix)
|
||||||
|
/* Minix doesn't support recv on TCP sockets */
|
||||||
|
#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
|
||||||
|
(RECV_TYPE_ARG2)(y), \
|
||||||
|
(RECV_TYPE_ARG3)(z))
|
||||||
|
|
||||||
|
#elif defined(HAVE_RECV)
|
||||||
/*
|
/*
|
||||||
* The definitions for the return type and arguments types
|
* The definitions for the return type and arguments types
|
||||||
* of functions recv() and send() belong and come from the
|
* of functions recv() and send() belong and come from the
|
||||||
@@ -113,7 +138,6 @@ struct timeval {
|
|||||||
* SEND_TYPE_RETV must also be defined.
|
* SEND_TYPE_RETV must also be defined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_RECV
|
|
||||||
#if !defined(RECV_TYPE_ARG1) || \
|
#if !defined(RECV_TYPE_ARG1) || \
|
||||||
!defined(RECV_TYPE_ARG2) || \
|
!defined(RECV_TYPE_ARG2) || \
|
||||||
!defined(RECV_TYPE_ARG3) || \
|
!defined(RECV_TYPE_ARG3) || \
|
||||||
@@ -136,7 +160,14 @@ struct timeval {
|
|||||||
#endif
|
#endif
|
||||||
#endif /* HAVE_RECV */
|
#endif /* HAVE_RECV */
|
||||||
|
|
||||||
#ifdef HAVE_SEND
|
|
||||||
|
#if defined(__minix)
|
||||||
|
/* Minix doesn't support send on TCP sockets */
|
||||||
|
#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
|
||||||
|
(SEND_TYPE_ARG2)(y), \
|
||||||
|
(SEND_TYPE_ARG3)(z))
|
||||||
|
|
||||||
|
#elif defined(HAVE_SEND)
|
||||||
#if !defined(SEND_TYPE_ARG1) || \
|
#if !defined(SEND_TYPE_ARG1) || \
|
||||||
!defined(SEND_QUAL_ARG2) || \
|
!defined(SEND_QUAL_ARG2) || \
|
||||||
!defined(SEND_TYPE_ARG2) || \
|
!defined(SEND_TYPE_ARG2) || \
|
||||||
@@ -358,5 +389,96 @@ typedef int sig_atomic_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use this ZERO_NULL to avoid picky compiler warnings,
|
||||||
|
* when assigning a NULL pointer to a function pointer var.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ZERO_NULL 0
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__LP64__) && defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
|
||||||
|
#include <sys/socket.h>
|
||||||
|
/* HP-UX has this oddity where it features a few functions that don't work
|
||||||
|
with socklen_t so we need to convert to ints
|
||||||
|
|
||||||
|
This is due to socklen_t being a 64bit int under 64bit ABI, but the
|
||||||
|
pre-xopen (default) interfaces require an int, which is 32bits.
|
||||||
|
|
||||||
|
Therefore, Anytime socklen_t is passed by pointer, the libc function
|
||||||
|
truncates the 64bit socklen_t value by treating it as a 32bit value.
|
||||||
|
|
||||||
|
|
||||||
|
Note that some socket calls are allowed to have a NULL pointer for
|
||||||
|
the socklen arg.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline static int Curl_hp_getsockname(int s, struct sockaddr *name,
|
||||||
|
socklen_t *namelen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
if(namelen) {
|
||||||
|
int len = *namelen;
|
||||||
|
rc = getsockname(s, name, &len);
|
||||||
|
*namelen = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = getsockname(s, name, 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static int Curl_hp_getsockopt(int s, int level, int optname,
|
||||||
|
void *optval, socklen_t *optlen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
if(optlen) {
|
||||||
|
int len = *optlen;
|
||||||
|
rc = getsockopt(s, level, optname, optval, &len);
|
||||||
|
*optlen = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = getsockopt(s, level, optname, optval, 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static int Curl_hp_accept(int sockfd, struct sockaddr *addr,
|
||||||
|
socklen_t *addrlen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
if(addrlen) {
|
||||||
|
int len = *addrlen;
|
||||||
|
rc = accept(sockfd, addr, &len);
|
||||||
|
*addrlen = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = accept(sockfd, addr, 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline static ssize_t Curl_hp_recvfrom(int s, void *buf, size_t len, int flags,
|
||||||
|
struct sockaddr *from,
|
||||||
|
socklen_t *fromlen)
|
||||||
|
{
|
||||||
|
ssize_t rc;
|
||||||
|
if(fromlen) {
|
||||||
|
int fromlen32 = *fromlen;
|
||||||
|
rc = recvfrom(s, buf, len, flags, from, &fromlen32);
|
||||||
|
*fromlen = fromlen32;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = recvfrom(s, buf, len, flags, from, 0);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define getsockname(a,b,c) Curl_hp_getsockname((a),(b),(c))
|
||||||
|
#define getsockopt(a,b,c,d,e) Curl_hp_getsockopt((a),(b),(c),(d),(e))
|
||||||
|
#define accept(a,b,c) Curl_hp_accept((a),(b),(c))
|
||||||
|
#define recvfrom(a,b,c,d,e,f) Curl_hp_recvfrom((a),(b),(c),(d),(e),(f))
|
||||||
|
|
||||||
|
#endif /* HPUX work-around */
|
||||||
|
|
||||||
|
|
||||||
#endif /* __SETUP_ONCE_H */
|
#endif /* __SETUP_ONCE_H */
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ BSC32=bscmake.exe
|
|||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
# ADD BASE LINK32 ws2_32.lib advapi32.lib /nologo /subsystem:console /machine:I386
|
||||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release"
|
# ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "adig - Win32 Debug"
|
!ELSEIF "$(CFG)" == "adig - Win32 Debug"
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@ BSC32=bscmake.exe
|
|||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 ws2_32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug"
|
# ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug"
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ RSC=rc.exe
|
|||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release"
|
# PROP Output_Dir "Release"
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
@@ -48,8 +49,8 @@ BSC32=bscmake.exe
|
|||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
# ADD BASE LINK32 ws2_32.lib advapi32.lib /nologo /subsystem:console /machine:I386
|
||||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release"
|
# ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "ahost - Win32 Debug"
|
!ELSEIF "$(CFG)" == "ahost - Win32 Debug"
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ LINK32=link.exe
|
|||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug"
|
# PROP Output_Dir "Debug"
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
||||||
@@ -71,8 +73,8 @@ BSC32=bscmake.exe
|
|||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 ws2_32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug"
|
# ADD LINK32 ws2_32.lib advapi32.lib areslib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug"
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ SOURCE=..\..\ares_init.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\ares_llist.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\ares_mkquery.c
|
SOURCE=..\..\ares_mkquery.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -213,6 +217,10 @@ SOURCE=..\..\ares_ipv6.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\ares_llist.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\ares_private.h
|
SOURCE=..\..\ares_private.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
213
configure.ac
213
configure.ac
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -24,11 +24,11 @@ dnl Process this file with autoconf to produce a configure script.
|
|||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
|
|
||||||
dnl We don't know the version number "staticly" so we use a dash here
|
dnl We don't know the version number "statically" so we use a dash here
|
||||||
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
||||||
|
|
||||||
dnl configure script copyright
|
dnl configure script copyright
|
||||||
AC_COPYRIGHT([Copyright (c) 1998 - 2006 Daniel Stenberg, <daniel@haxx.se>
|
AC_COPYRIGHT([Copyright (c) 1998 - 2008 Daniel Stenberg, <daniel@haxx.se>
|
||||||
This configure script may be copied, distributed and modified under the
|
This configure script may be copied, distributed and modified under the
|
||||||
terms of the curl license; see COPYING for more details])
|
terms of the curl license; see COPYING for more details])
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ AC_SUBST(AR)
|
|||||||
if test "x$AR" = "xar-was-not-found-by-configure"; then
|
if test "x$AR" = "xar-was-not-found-by-configure"; then
|
||||||
AC_MSG_WARN([ar was not found, this may ruin your chances to build fine])
|
AC_MSG_WARN([ar was not found, this may ruin your chances to build fine])
|
||||||
fi
|
fi
|
||||||
|
AC_SUBST(libext)
|
||||||
|
|
||||||
dnl figure out the libcurl version
|
dnl figure out the libcurl version
|
||||||
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
||||||
@@ -173,6 +174,7 @@ case $host in
|
|||||||
esac
|
esac
|
||||||
AC_MSG_RESULT($mimpure)
|
AC_MSG_RESULT($mimpure)
|
||||||
AM_CONDITIONAL(MIMPURE, test x$mimpure = xyes)
|
AM_CONDITIONAL(MIMPURE, test x$mimpure = xyes)
|
||||||
|
AM_CONDITIONAL(STATICLIB, false)
|
||||||
|
|
||||||
AC_MSG_CHECKING([if we need BUILDING_LIBCURL])
|
AC_MSG_CHECKING([if we need BUILDING_LIBCURL])
|
||||||
case $host in
|
case $host in
|
||||||
@@ -184,6 +186,7 @@ case $host in
|
|||||||
then
|
then
|
||||||
AC_DEFINE(CURL_STATICLIB, 1, [when not building a shared library])
|
AC_DEFINE(CURL_STATICLIB, 1, [when not building a shared library])
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AM_CONDITIONAL(STATICLIB, true)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
@@ -221,6 +224,45 @@ CURL_CHECK_HEADER_WINSOCK
|
|||||||
CURL_CHECK_HEADER_WINSOCK2
|
CURL_CHECK_HEADER_WINSOCK2
|
||||||
CURL_CHECK_HEADER_WS2TCPIP
|
CURL_CHECK_HEADER_WS2TCPIP
|
||||||
|
|
||||||
|
CURL_CHECK_HEADER_WINLDAP
|
||||||
|
CURL_CHECK_HEADER_WINBER
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl platform/compiler/architecture specific checks/flags
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
case $host in
|
||||||
|
#
|
||||||
|
x86_64*linux*)
|
||||||
|
#
|
||||||
|
dnl find out if icc is being used
|
||||||
|
if test "z$ICC" = "z"; then
|
||||||
|
CURL_DETECT_ICC
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$ICC" = "yes"; then
|
||||||
|
dnl figure out icc version
|
||||||
|
AC_MSG_CHECKING([icc version])
|
||||||
|
iccver=`$CC -dumpversion`
|
||||||
|
iccnhi=`echo $iccver | cut -d . -f1`
|
||||||
|
iccnlo=`echo $iccver | cut -d . -f2`
|
||||||
|
iccnum=`(expr $iccnhi "*" 100 + $iccnlo) 2>/dev/null`
|
||||||
|
AC_MSG_RESULT($iccver)
|
||||||
|
#
|
||||||
|
if test "$iccnum" -ge "900" && test "$iccnum" -lt "1000"; then
|
||||||
|
dnl icc 9.X specific
|
||||||
|
CFLAGS="$CFLAGS -i-dynamic"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$iccnum" -ge "1000"; then
|
||||||
|
dnl icc 10.X or later
|
||||||
|
CFLAGS="$CFLAGS -shared-intel"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
#
|
||||||
|
esac
|
||||||
|
|
||||||
dnl ************************************************************
|
dnl ************************************************************
|
||||||
dnl switch off particular protocols
|
dnl switch off particular protocols
|
||||||
@@ -281,10 +323,29 @@ AC_HELP_STRING([--disable-ldap],[Disable LDAP support]),
|
|||||||
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
AC_SUBST(CURL_DISABLE_LDAP, [1])
|
AC_SUBST(CURL_DISABLE_LDAP, [1])
|
||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*)
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin*)
|
||||||
|
# Force no ldap. config/build process is broken for cygwin
|
||||||
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
|
AC_SUBST(CURL_DISABLE_LDAP, [1])
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
;;
|
;;
|
||||||
esac ],
|
*)
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac ],[
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin*)
|
||||||
|
# Force no ldap. config/build process is broken for cygwin
|
||||||
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
|
AC_SUBST(CURL_DISABLE_LDAP, [1])
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
esac ]
|
||||||
)
|
)
|
||||||
AC_MSG_CHECKING([whether to support ldaps])
|
AC_MSG_CHECKING([whether to support ldaps])
|
||||||
AC_ARG_ENABLE(ldaps,
|
AC_ARG_ENABLE(ldaps,
|
||||||
@@ -544,6 +605,11 @@ AC_HELP_STRING([--with-lber-lib=libname],[Specify name of lber lib file]),
|
|||||||
|
|
||||||
if test x$CURL_DISABLE_LDAP != x1 ; then
|
if test x$CURL_DISABLE_LDAP != x1 ; then
|
||||||
|
|
||||||
|
CURL_CHECK_HEADER_LBER
|
||||||
|
CURL_CHECK_HEADER_LDAP
|
||||||
|
CURL_CHECK_HEADER_LDAPSSL
|
||||||
|
CURL_CHECK_HEADER_LDAP_SSL
|
||||||
|
|
||||||
if test -z "$LDAPLIBNAME" ; then
|
if test -z "$LDAPLIBNAME" ; then
|
||||||
case $host in
|
case $host in
|
||||||
*-*-cygwin* | *-*-mingw* | *-*-pw32*)
|
*-*-cygwin* | *-*-mingw* | *-*-pw32*)
|
||||||
@@ -559,12 +625,20 @@ if test x$CURL_DISABLE_LDAP != x1 ; then
|
|||||||
AC_MSG_WARN(["$LDAPLIBNAME" is not an LDAP library: LDAP disabled])
|
AC_MSG_WARN(["$LDAPLIBNAME" is not an LDAP library: LDAP disabled])
|
||||||
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
||||||
|
AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS])
|
||||||
|
AC_SUBST(CURL_DISABLE_LDAPS, [1])
|
||||||
else
|
else
|
||||||
dnl Try to find the right ldap library name for this system
|
dnl Try to find the right ldap libraries for this system
|
||||||
AC_SEARCH_LIBS(ldap_init, [ldap],, [
|
CURL_CHECK_LIBS_LDAP
|
||||||
AC_MSG_WARN([Cannot find LDAP library: LDAP disabled])
|
case X-"$curl_cv_ldap_LIBS" in
|
||||||
|
X-unknown)
|
||||||
|
AC_MSG_WARN([Cannot find libraries for LDAP support: LDAP disabled])
|
||||||
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
AC_SUBST(CURL_DISABLE_LDAP, [1])
|
||||||
|
AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS])
|
||||||
|
AC_SUBST(CURL_DISABLE_LDAPS, [1])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -578,13 +652,9 @@ if test x$CURL_DISABLE_LDAP != x1 ; then
|
|||||||
AC_MSG_WARN(["$LBERLIBNAME" is not an LBER library: LDAP disabled])
|
AC_MSG_WARN(["$LBERLIBNAME" is not an LBER library: LDAP disabled])
|
||||||
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
||||||
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
||||||
|
AC_DEFINE(CURL_DISABLE_LDAPS, 1, [to disable LDAPS])
|
||||||
|
AC_SUBST(CURL_DISABLE_LDAPS, [1])
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
dnl Try to find the right lber library name for this system
|
|
||||||
AC_SEARCH_LIBS(ber_free, [lber],, [
|
|
||||||
AC_MSG_WARN([Cannot find a library defining ber_free(): LDAP disabled])
|
|
||||||
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
|
|
||||||
AC_SUBST(CURL_DISABLE_LDAP, [1])])
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -858,6 +928,9 @@ dnl **********************************************************************
|
|||||||
dnl Check for GSS-API libraries
|
dnl Check for GSS-API libraries
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
dnl check for gss stuff in the /usr as default
|
||||||
|
|
||||||
|
GSSAPI_ROOT="/usr"
|
||||||
AC_ARG_WITH(gssapi-includes,
|
AC_ARG_WITH(gssapi-includes,
|
||||||
AC_HELP_STRING([--with-gssapi-includes=DIR],
|
AC_HELP_STRING([--with-gssapi-includes=DIR],
|
||||||
[Specify location of GSSAPI header]),
|
[Specify location of GSSAPI header]),
|
||||||
@@ -878,6 +951,10 @@ AC_ARG_WITH(gssapi,
|
|||||||
GSSAPI_ROOT="$withval"
|
GSSAPI_ROOT="$withval"
|
||||||
if test x"$GSSAPI_ROOT" != xno; then
|
if test x"$GSSAPI_ROOT" != xno; then
|
||||||
want_gss="yes"
|
want_gss="yes"
|
||||||
|
if test x"$GSSAPI_ROOT" = xyes; then
|
||||||
|
dnl if yes, then use default root
|
||||||
|
GSSAPI_ROOT="/usr"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -889,11 +966,15 @@ if test x"$want_gss" = xyes; then
|
|||||||
if test -z "$GSSAPI_INCS"; then
|
if test -z "$GSSAPI_INCS"; then
|
||||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||||
GSSAPI_INCS=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
|
GSSAPI_INCS=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
|
||||||
|
GSSAPI_LIBS=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||||
elif test "$GSSAPI_ROOT" != "yes"; then
|
elif test "$GSSAPI_ROOT" != "yes"; then
|
||||||
GSSAPI_INCS="-I$GSSAPI_ROOT/include"
|
GSSAPI_INCS="-I$GSSAPI_ROOT/include"
|
||||||
|
GSSAPI_LIBS="-lgssapi"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
|
CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
|
||||||
|
LIBS="$LIBS $GSSAPI_LIBS"
|
||||||
|
|
||||||
AC_CHECK_HEADER(gss.h,
|
AC_CHECK_HEADER(gss.h,
|
||||||
[
|
[
|
||||||
@@ -902,19 +983,19 @@ if test x"$want_gss" = xyes; then
|
|||||||
gnu_gss=yes
|
gnu_gss=yes
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
dnl not found, check Heimdal
|
dnl not found, check MIT
|
||||||
AC_CHECK_HEADER(gssapi.h,
|
|
||||||
[
|
|
||||||
dnl found in the given dirs
|
|
||||||
AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have the Heimdal gssapi libraries])
|
|
||||||
],
|
|
||||||
[
|
|
||||||
dnl not found, check in gssapi/ subdir
|
|
||||||
AC_CHECK_HEADER(gssapi/gssapi.h,
|
AC_CHECK_HEADER(gssapi/gssapi.h,
|
||||||
[
|
[
|
||||||
dnl found
|
dnl found in the given dirs
|
||||||
AC_DEFINE(HAVE_GSSMIT, 1, [if you have the MIT gssapi libraries])
|
AC_DEFINE(HAVE_GSSMIT, 1, [if you have the MIT gssapi libraries])
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
dnl not found, check for Heimdal
|
||||||
|
AC_CHECK_HEADER(gssapi.h,
|
||||||
|
[
|
||||||
|
dnl found
|
||||||
|
AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have the Heimdal gssapi libraries])
|
||||||
|
],
|
||||||
[
|
[
|
||||||
dnl no header found, disabling GSS
|
dnl no header found, disabling GSS
|
||||||
want_gss=no
|
want_gss=no
|
||||||
@@ -935,18 +1016,23 @@ if test x"$want_gss" = xyes; then
|
|||||||
|
|
||||||
if test -n "$gnu_gss"; then
|
if test -n "$gnu_gss"; then
|
||||||
curl_gss_msg="enabled (GNU GSS)"
|
curl_gss_msg="enabled (GNU GSS)"
|
||||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR -lgss"
|
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||||
|
LIBS="$LIBS -lgss"
|
||||||
elif test -z "$GSSAPI_LIB_DIR"; then
|
elif test -z "$GSSAPI_LIB_DIR"; then
|
||||||
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
|
||||||
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
dnl krb5-config doesn't have --libs-only-L or similar, put everything
|
||||||
LDFLAGS="$LDFLAGS $gss_ldflags"
|
dnl into LIBS
|
||||||
|
gss_libs=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||||
|
LIBS="$LIBS $gss_libs"
|
||||||
elif test "$GSSAPI_ROOT" != "yes"; then
|
elif test "$GSSAPI_ROOT" != "yes"; then
|
||||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff -lgssapi"
|
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
|
||||||
|
LIBS="$LIBS -lgssapi"
|
||||||
else
|
else
|
||||||
LDFLAGS="$LDFLAGS -lgssapi"
|
LIBS="$LIBS -lgssapi"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR -lgssapi"
|
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||||
|
LIBS="$LIBS -lgssapi"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
CPPFLAGS="$save_CPPFLAGS"
|
CPPFLAGS="$save_CPPFLAGS"
|
||||||
@@ -1249,6 +1335,7 @@ else
|
|||||||
if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1"
|
if test "$HAVE_LIBZ" = "1" && test "$HAVE_ZLIB_H" != "1"
|
||||||
then
|
then
|
||||||
AC_MSG_WARN([configure found only the libz lib, not the header file!])
|
AC_MSG_WARN([configure found only the libz lib, not the header file!])
|
||||||
|
HAVE_LIBZ=""
|
||||||
elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1"
|
elif test "$HAVE_LIBZ" != "1" && test "$HAVE_ZLIB_H" = "1"
|
||||||
then
|
then
|
||||||
AC_MSG_WARN([configure found only the libz header file, not the lib!])
|
AC_MSG_WARN([configure found only the libz header file, not the lib!])
|
||||||
@@ -1293,7 +1380,7 @@ if test X"$OPT_LIBSSH2" != Xno; then
|
|||||||
yes)
|
yes)
|
||||||
dnl --with-libssh2 (without path) used
|
dnl --with-libssh2 (without path) used
|
||||||
PREFIX_LIBSSH2=/usr/local/lib
|
PREFIX_LIBSSH2=/usr/local/lib
|
||||||
LIB_LIBSSH2="$PREFIX_LIBSSH2/lib$libsuff"
|
LIB_LIBSSH2="$PREFIX_LIBSSH2$libsuff"
|
||||||
;;
|
;;
|
||||||
off)
|
off)
|
||||||
dnl no --with-libssh2 option given, just check default places
|
dnl no --with-libssh2 option given, just check default places
|
||||||
@@ -1313,7 +1400,9 @@ if test X"$OPT_LIBSSH2" != Xno; then
|
|||||||
AC_CHECK_HEADERS(libssh2.h,
|
AC_CHECK_HEADERS(libssh2.h,
|
||||||
curl_ssh_msg="enabled (libSSH2)"
|
curl_ssh_msg="enabled (libSSH2)"
|
||||||
LIBSSH2_ENABLED=1
|
LIBSSH2_ENABLED=1
|
||||||
AC_DEFINE(USE_LIBSSH2, 1, [if libSSH2 is in use]))
|
AC_DEFINE(USE_LIBSSH2, 1, [if libSSH2 is in use])
|
||||||
|
AC_SUBST(USE_LIBSSH2, [1])
|
||||||
|
)
|
||||||
|
|
||||||
if test X"$OPT_LIBSSH2" != Xoff &&
|
if test X"$OPT_LIBSSH2" != Xoff &&
|
||||||
test "$LIBSSH2_ENABLED" != "1"; then
|
test "$LIBSSH2_ENABLED" != "1"; then
|
||||||
@@ -1469,6 +1558,14 @@ if test "$OPENSSL_ENABLED" != "1" -a "$GNUTLS_ENABLED" != "1"; then
|
|||||||
version="unknown"
|
version="unknown"
|
||||||
gtlsprefix=$OPT_GNUTLS
|
gtlsprefix=$OPT_GNUTLS
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Check for functionPK11_CreateGenericObject
|
||||||
|
dnl this is needed for using the PEM PKCS#11 module
|
||||||
|
AC_CHECK_LIB(nss3, PK11_CreateGenericObject,
|
||||||
|
[
|
||||||
|
AC_DEFINE(HAVE_PK11_CREATEGENERICOBJECT, 1, [if you have the function PK11_CreateGenericObject])
|
||||||
|
AC_SUBST(HAVE_PK11_CREATEGENERICOBJECT, [1])
|
||||||
|
])
|
||||||
if test -n "$addlib"; then
|
if test -n "$addlib"; then
|
||||||
|
|
||||||
CLEANLIBS="$LIBS"
|
CLEANLIBS="$LIBS"
|
||||||
@@ -1514,36 +1611,20 @@ fi dnl OPENSSL != 1 -a GNUTLS_ENABLED != 1
|
|||||||
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED" = "x"; then
|
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED" = "x"; then
|
||||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
||||||
AC_MSG_WARN([Use --with-ssl, --with-gnutls or --with-nss to address this.])
|
AC_MSG_WARN([Use --with-ssl, --with-gnutls or --with-nss to address this.])
|
||||||
|
else
|
||||||
|
# SSL is enabled, genericly
|
||||||
|
AC_SUBST(SSL_ENABLED)
|
||||||
|
SSL_ENABLED="1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Check for the CA bundle
|
dnl Check for the CA bundle
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
if test X"$USE_GNUTLS$OPENSSL_ENABLED" != "X"; then
|
CURL_CHECK_CA_BUNDLE
|
||||||
|
|
||||||
AC_MSG_CHECKING([CA cert bundle install path])
|
|
||||||
|
|
||||||
AC_ARG_WITH(ca-bundle,
|
|
||||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
|
||||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
|
||||||
[ ca="$withval" ],
|
|
||||||
[
|
|
||||||
if test "x$prefix" != xNONE; then
|
|
||||||
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
|
||||||
else
|
|
||||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
|
||||||
fi
|
|
||||||
] )
|
|
||||||
|
|
||||||
if test "x$ca" != "xno"; then
|
|
||||||
CURL_CA_BUNDLE='"'$ca'"'
|
|
||||||
AC_SUBST(CURL_CA_BUNDLE)
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$ca])
|
|
||||||
fi dnl only done if some kind of SSL was enabled
|
|
||||||
|
|
||||||
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||||
|
AM_CONDITIONAL(CAPATH, test x$capath != xno)
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Check for the presence of IDN libraries and headers
|
dnl Check for the presence of IDN libraries and headers
|
||||||
@@ -1681,6 +1762,9 @@ if test "x$RECENTAIX" = "xyes"; then
|
|||||||
dnl the optimizer assumes that pointers can only point to
|
dnl the optimizer assumes that pointers can only point to
|
||||||
dnl an object of the same type.
|
dnl an object of the same type.
|
||||||
CFLAGS="$CFLAGS -qnoansialias"
|
CFLAGS="$CFLAGS -qnoansialias"
|
||||||
|
dnl Force AIX xlc to stop after the compilation phase, and not
|
||||||
|
dnl generate object code, when the source compiles with errors.
|
||||||
|
CFLAGS="$CFLAGS -qhalt=e"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1730,7 +1814,7 @@ if test x$cross_compiling != xyes; then
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
dnl and for crosscompilings
|
dnl and for crosscompiling
|
||||||
AC_CHECK_FUNCS(gmtime_r)
|
AC_CHECK_FUNCS(gmtime_r)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1755,7 +1839,6 @@ AC_CHECK_HEADERS(
|
|||||||
assert.h \
|
assert.h \
|
||||||
unistd.h \
|
unistd.h \
|
||||||
stdlib.h \
|
stdlib.h \
|
||||||
ldap_ssl.h \
|
|
||||||
limits.h \
|
limits.h \
|
||||||
arpa/inet.h \
|
arpa/inet.h \
|
||||||
net/if.h \
|
net/if.h \
|
||||||
@@ -1776,6 +1859,7 @@ AC_CHECK_HEADERS(
|
|||||||
utime.h \
|
utime.h \
|
||||||
sys/utime.h \
|
sys/utime.h \
|
||||||
sys/poll.h \
|
sys/poll.h \
|
||||||
|
poll.h \
|
||||||
sys/resource.h \
|
sys/resource.h \
|
||||||
libgen.h \
|
libgen.h \
|
||||||
locale.h \
|
locale.h \
|
||||||
@@ -1823,6 +1907,7 @@ AC_CHECK_SIZEOF(curl_off_t, ,[
|
|||||||
AC_CHECK_SIZEOF(size_t)
|
AC_CHECK_SIZEOF(size_t)
|
||||||
AC_CHECK_SIZEOF(long)
|
AC_CHECK_SIZEOF(long)
|
||||||
AC_CHECK_SIZEOF(time_t)
|
AC_CHECK_SIZEOF(time_t)
|
||||||
|
AC_CHECK_SIZEOF(off_t)
|
||||||
|
|
||||||
AC_CHECK_TYPE(long long,
|
AC_CHECK_TYPE(long long,
|
||||||
[AC_DEFINE(HAVE_LONGLONG, 1, [if your compiler supports long long])]
|
[AC_DEFINE(HAVE_LONGLONG, 1, [if your compiler supports long long])]
|
||||||
@@ -1891,6 +1976,7 @@ AC_CHECK_FUNCS( strtoll \
|
|||||||
select \
|
select \
|
||||||
strdup \
|
strdup \
|
||||||
strstr \
|
strstr \
|
||||||
|
strcasestr \
|
||||||
strtok_r \
|
strtok_r \
|
||||||
uname \
|
uname \
|
||||||
strcasecmp \
|
strcasecmp \
|
||||||
@@ -1910,6 +1996,7 @@ AC_CHECK_FUNCS( strtoll \
|
|||||||
strlcat \
|
strlcat \
|
||||||
getpwuid \
|
getpwuid \
|
||||||
geteuid \
|
geteuid \
|
||||||
|
getppid \
|
||||||
utime \
|
utime \
|
||||||
sigsetjmp \
|
sigsetjmp \
|
||||||
basename \
|
basename \
|
||||||
@@ -2036,6 +2123,8 @@ if test "$disable_poll" = "no"; then
|
|||||||
AC_RUN_IFELSE([
|
AC_RUN_IFELSE([
|
||||||
#ifdef HAVE_SYS_POLL_H
|
#ifdef HAVE_SYS_POLL_H
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#elif defined(HAVE_POLL_H)
|
||||||
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
@@ -2189,7 +2278,6 @@ AC_HELP_STRING([--disable-verbose],[Disable verbose strings]),
|
|||||||
no)
|
no)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_DEFINE(CURL_DISABLE_VERBOSE_STRINGS, 1, [to disable verbose strings])
|
AC_DEFINE(CURL_DISABLE_VERBOSE_STRINGS, 1, [to disable verbose strings])
|
||||||
AC_SUBST(CURL_DISABLE_VERBOSE_STRINGS)
|
|
||||||
curl_verbose_msg="no"
|
curl_verbose_msg="no"
|
||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
@@ -2212,7 +2300,7 @@ AC_HELP_STRING([--disable-sspi],[Disable SSPI]),
|
|||||||
if test "$ac_cv_native_windows" = "yes"; then
|
if test "$ac_cv_native_windows" = "yes"; then
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
|
AC_DEFINE(USE_WINDOWS_SSPI, 1, [to enable SSPI support])
|
||||||
AC_SUBST(USE_WINDOWS_SSPI)
|
AC_SUBST(USE_WINDOWS_SSPI, [1])
|
||||||
curl_sspi_msg="yes"
|
curl_sspi_msg="yes"
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@@ -2262,7 +2350,6 @@ AC_HELP_STRING([--disable-crypto-auth],[Disable cryptographic authentication]),
|
|||||||
no)
|
no)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_DEFINE(CURL_DISABLE_CRYPTO_AUTH, 1, [to disable cryptographic authentication])
|
AC_DEFINE(CURL_DISABLE_CRYPTO_AUTH, 1, [to disable cryptographic authentication])
|
||||||
AC_SUBST(CURL_DISABLE_CRYPTO_AUTH)
|
|
||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
;;
|
;;
|
||||||
@@ -2281,7 +2368,6 @@ AC_HELP_STRING([--disable-cookies],[Disable cookies support]),
|
|||||||
no)
|
no)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_DEFINE(CURL_DISABLE_COOKIES, 1, [to disable cookies support])
|
AC_DEFINE(CURL_DISABLE_COOKIES, 1, [to disable cookies support])
|
||||||
AC_SUBST(CURL_DISABLE_COOKIES)
|
|
||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
;;
|
;;
|
||||||
@@ -2308,9 +2394,7 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
|
|||||||
if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
|
if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols])
|
AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols])
|
||||||
AC_SUBST(CURL_HIDDEN_SYMBOLS)
|
|
||||||
AC_DEFINE(CURL_EXTERN_SYMBOL, [__attribute__ ((visibility ("default")))], [to make a symbol visible])
|
AC_DEFINE(CURL_EXTERN_SYMBOL, [__attribute__ ((visibility ("default")))], [to make a symbol visible])
|
||||||
AC_SUBST(CURL_EXTERN_SYMBOL)
|
|
||||||
CFLAGS="$CFLAGS -fvisibility=hidden"
|
CFLAGS="$CFLAGS -fvisibility=hidden"
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@@ -2321,9 +2405,7 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
|
|||||||
if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then
|
if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols])
|
AC_DEFINE(CURL_HIDDEN_SYMBOLS, 1, [to enable hidden symbols])
|
||||||
AC_SUBST(CURL_HIDDEN_SYMBOLS)
|
|
||||||
AC_DEFINE(CURL_EXTERN_SYMBOL, [__global], [to make a symbol visible])
|
AC_DEFINE(CURL_EXTERN_SYMBOL, [__global], [to make a symbol visible])
|
||||||
AC_SUBST(CURL_EXTERN_SYMBOL)
|
|
||||||
CFLAGS="$CFLAGS -xldscope=hidden"
|
CFLAGS="$CFLAGS -xldscope=hidden"
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@@ -2413,7 +2495,8 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
|||||||
Built-in manual: ${curl_manual_msg}
|
Built-in manual: ${curl_manual_msg}
|
||||||
Verbose errors: ${curl_verbose_msg}
|
Verbose errors: ${curl_verbose_msg}
|
||||||
SSPI support: ${curl_sspi_msg}
|
SSPI support: ${curl_sspi_msg}
|
||||||
ca cert path: ${ca}
|
ca cert bundle: ${ca}
|
||||||
|
ca cert path: ${capath}
|
||||||
LDAP support: ${curl_ldap_msg}
|
LDAP support: ${curl_ldap_msg}
|
||||||
LDAPS support: ${curl_ldaps_msg}
|
LDAPS support: ${curl_ldaps_msg}
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2001 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 2001 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the file COPYING, which
|
# This software is licensed as described in the file COPYING, which
|
||||||
# you should have received as part of this distribution. The terms
|
# you should have received as part of this distribution. The terms
|
||||||
@@ -41,10 +41,11 @@ Available values for OPTION include:
|
|||||||
--cflags pre-processor and compiler flags
|
--cflags pre-processor and compiler flags
|
||||||
--checkfor [version] check for (lib)curl of the specified version
|
--checkfor [version] check for (lib)curl of the specified version
|
||||||
--features newline separated list of enabled features
|
--features newline separated list of enabled features
|
||||||
--protocols newline separated list of enabled protocols
|
|
||||||
--help display this help and exit
|
--help display this help and exit
|
||||||
--libs library linking information
|
--libs library linking information
|
||||||
--prefix curl install prefix
|
--prefix curl install prefix
|
||||||
|
--protocols newline separated list of enabled protocols
|
||||||
|
--static-libs static libcurl library linking information
|
||||||
--version output version information
|
--version output version information
|
||||||
--vernum output the version information as a number (hexadecimal)
|
--vernum output the version information as a number (hexadecimal)
|
||||||
EOF
|
EOF
|
||||||
@@ -82,7 +83,7 @@ while test $# -gt 0; do
|
|||||||
if test "@USE_SSLEAY@" = "1"; then
|
if test "@USE_SSLEAY@" = "1"; then
|
||||||
echo "SSL"
|
echo "SSL"
|
||||||
NTLM=1 # OpenSSL implies NTLM
|
NTLM=1 # OpenSSL implies NTLM
|
||||||
elif test -n "@USE_GNUTLS@"; then
|
elif test -n "@SSL_ENABLED@"; then
|
||||||
echo "SSL"
|
echo "SSL"
|
||||||
fi
|
fi
|
||||||
if test "@KRB4_ENABLED@" = "1"; then
|
if test "@KRB4_ENABLED@" = "1"; then
|
||||||
@@ -112,13 +113,13 @@ while test $# -gt 0; do
|
|||||||
--protocols)
|
--protocols)
|
||||||
if test "@CURL_DISABLE_HTTP@" != "1"; then
|
if test "@CURL_DISABLE_HTTP@" != "1"; then
|
||||||
echo "HTTP"
|
echo "HTTP"
|
||||||
if test "@USE_SSLEAY@" = "1"; then
|
if test "@SSL_ENABLED@" = "1"; then
|
||||||
echo "HTTPS"
|
echo "HTTPS"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test "@CURL_DISABLE_FTP@" != "1"; then
|
if test "@CURL_DISABLE_FTP@" != "1"; then
|
||||||
echo "FTP"
|
echo "FTP"
|
||||||
if test "@USE_SSLEAY@" = "1"; then
|
if test "@SSL_ENABLED@" = "1"; then
|
||||||
echo "FTPS"
|
echo "FTPS"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -131,12 +132,19 @@ while test $# -gt 0; do
|
|||||||
if test "@CURL_DISABLE_LDAP@" != "1"; then
|
if test "@CURL_DISABLE_LDAP@" != "1"; then
|
||||||
echo "LDAP"
|
echo "LDAP"
|
||||||
fi
|
fi
|
||||||
|
if test "@CURL_DISABLE_LDAPS@" != "1"; then
|
||||||
|
echo "LDAPS"
|
||||||
|
fi
|
||||||
if test "@CURL_DISABLE_DICT@" != "1"; then
|
if test "@CURL_DISABLE_DICT@" != "1"; then
|
||||||
echo "DICT"
|
echo "DICT"
|
||||||
fi
|
fi
|
||||||
if test "@CURL_DISABLE_TFTP@" != "1"; then
|
if test "@CURL_DISABLE_TFTP@" != "1"; then
|
||||||
echo "TFTP"
|
echo "TFTP"
|
||||||
fi
|
fi
|
||||||
|
if test "@USE_LIBSSH2@" = "1"; then
|
||||||
|
echo "SCP"
|
||||||
|
echo "SFTP"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
--version)
|
--version)
|
||||||
echo libcurl @VERSION@
|
echo libcurl @VERSION@
|
||||||
@@ -181,7 +189,7 @@ while test $# -gt 0; do
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
--libs)
|
--libs)
|
||||||
if test "X@libdir@" != "X/usr/lib"; then
|
if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
|
||||||
CURLLIBDIR="-L@libdir@ "
|
CURLLIBDIR="-L@libdir@ "
|
||||||
else
|
else
|
||||||
CURLLIBDIR=""
|
CURLLIBDIR=""
|
||||||
@@ -193,6 +201,10 @@ while test $# -gt 0; do
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--static-libs)
|
||||||
|
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@ @LIBS@
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "unknown option: $1"
|
echo "unknown option: $1"
|
||||||
usage 1
|
usage 1
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ C
|
|||||||
C++
|
C++
|
||||||
|
|
||||||
Written by Jean-Philippe Barrette-LaPierre
|
Written by Jean-Philippe Barrette-LaPierre
|
||||||
http://rrette.com/curlpp.html
|
http://rrette.com/textpattern/index.php?s=cURLpp
|
||||||
|
|
||||||
Ch
|
Ch
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ glib/GTK+
|
|||||||
|
|
||||||
Java
|
Java
|
||||||
|
|
||||||
Maintained by Vic Hanson
|
Maintained by [blank]
|
||||||
http://curl.haxx.se/libcurl/java/
|
http://curl.haxx.se/libcurl/java/
|
||||||
|
|
||||||
Lisp
|
Lisp
|
||||||
@@ -82,9 +82,12 @@ Lisp
|
|||||||
|
|
||||||
Lua
|
Lua
|
||||||
|
|
||||||
LuaCURL Written by Alexander Marinov
|
luacurl by Alexander Marinov
|
||||||
http://luacurl.luaforge.net/
|
http://luacurl.luaforge.net/
|
||||||
|
|
||||||
|
Lua-cURL by J<>rgen H<>tzel
|
||||||
|
http://luaforge.net/projects/lua-curl/
|
||||||
|
|
||||||
Mono
|
Mono
|
||||||
|
|
||||||
Written by Jeffrey Phillips
|
Written by Jeffrey Phillips
|
||||||
@@ -92,7 +95,7 @@ Mono
|
|||||||
|
|
||||||
.NET
|
.NET
|
||||||
|
|
||||||
libcurl-net Written by Jeffrey Phillips
|
libcurl-net by Jeffrey Phillips
|
||||||
http://sourceforge.net/projects/libcurl-net/
|
http://sourceforge.net/projects/libcurl-net/
|
||||||
|
|
||||||
Object-Pascal
|
Object-Pascal
|
||||||
@@ -127,12 +130,12 @@ PostgreSQL
|
|||||||
|
|
||||||
Python
|
Python
|
||||||
|
|
||||||
PycURL is written by Kjetil Jacobsen
|
PycURL by Kjetil Jacobsen
|
||||||
http://pycurl.sourceforge.net/
|
http://pycurl.sourceforge.net/
|
||||||
|
|
||||||
R
|
R
|
||||||
|
|
||||||
RCurl is written by Duncan Temple Lang
|
RCurl by Duncan Temple Lang
|
||||||
http://www.omegahat.org/RCurl/
|
http://www.omegahat.org/RCurl/
|
||||||
|
|
||||||
Rexx
|
Rexx
|
||||||
@@ -140,24 +143,33 @@ Rexx
|
|||||||
Written Mark Hessling
|
Written Mark Hessling
|
||||||
http://rexxcurl.sourceforge.net/
|
http://rexxcurl.sourceforge.net/
|
||||||
|
|
||||||
|
RPG
|
||||||
|
|
||||||
|
Support for ILE/RPG on OS/400 is included in source distribution
|
||||||
|
http://curl.haxx.se/libcurl/
|
||||||
|
See packages/OS400/README.OS400 and packages/OS400/curl.inc.in
|
||||||
|
|
||||||
Ruby
|
Ruby
|
||||||
|
|
||||||
Written by Ross Bamford
|
curb - written by Ross Bamford
|
||||||
http://curb.rubyforge.org/
|
http://curb.rubyforge.org/
|
||||||
|
|
||||||
|
ruby-curl-multi - written by Kristjan Petursson and Keith Rarick
|
||||||
|
http://curl-multi.rubyforge.org/
|
||||||
|
|
||||||
Scheme
|
Scheme
|
||||||
|
|
||||||
Bigloo binding written by Kirill Lisovsky
|
Bigloo binding by Kirill Lisovsky
|
||||||
http://curl.haxx.se/libcurl/scheme/
|
http://curl.haxx.se/libcurl/scheme/
|
||||||
|
|
||||||
S-Lang
|
S-Lang
|
||||||
|
|
||||||
S-Lang binding written by John E Davis
|
S-Lang binding by John E Davis
|
||||||
http://www.jedsoft.org/slang/modules/curl.html
|
http://www.jedsoft.org/slang/modules/curl.html
|
||||||
|
|
||||||
Smalltalk
|
Smalltalk
|
||||||
|
|
||||||
Smalltalk binding written by Danil Osipchuk
|
Smalltalk binding by Danil Osipchuk
|
||||||
http://www.squeaksource.com/CurlPlugin/
|
http://www.squeaksource.com/CurlPlugin/
|
||||||
|
|
||||||
SP-Forth
|
SP-Forth
|
||||||
@@ -166,17 +178,17 @@ SP-Forth
|
|||||||
|
|
||||||
SPL
|
SPL
|
||||||
|
|
||||||
SPL binding written by Clifford Wolf
|
SPL binding by Clifford Wolf
|
||||||
http://www.clifford.at/spl/
|
http://www.clifford.at/spl/
|
||||||
|
|
||||||
Tcl
|
Tcl
|
||||||
|
|
||||||
Tclcurl is written by Andr<64>s Garc<72>a
|
Tclcurl by Andr<64>s Garc<72>a
|
||||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html
|
http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html
|
||||||
|
|
||||||
Visual Basic
|
Visual Basic
|
||||||
|
|
||||||
libcurl-vb is written by Jeffrey Phillips
|
libcurl-vb by Jeffrey Phillips
|
||||||
http://sourceforge.net/projects/libcurl-vb/
|
http://sourceforge.net/projects/libcurl-vb/
|
||||||
|
|
||||||
Q
|
Q
|
||||||
|
|||||||
@@ -10,16 +10,46 @@
|
|||||||
mind when you decide to contribute to the project. This concerns new features
|
mind when you decide to contribute to the project. This concerns new features
|
||||||
as well as corrections to existing flaws or bugs.
|
as well as corrections to existing flaws or bugs.
|
||||||
|
|
||||||
Join the Community
|
1. Learning cURL
|
||||||
|
1.1 Join the Community
|
||||||
|
1.2 License
|
||||||
|
1.3 What To Read
|
||||||
|
|
||||||
|
2. cURL Coding Standards
|
||||||
|
2.1 Naming
|
||||||
|
2.2 Indenting
|
||||||
|
2.3 Commenting
|
||||||
|
2.4 Line Lengths
|
||||||
|
2.5 General Style
|
||||||
|
2.6 Non-clobbering All Over
|
||||||
|
2.7 Platform Dependent Code
|
||||||
|
2.8 Write Separate Patches
|
||||||
|
2.9 Patch Against Recent Sources
|
||||||
|
2.10 Document
|
||||||
|
2.11 Test Cases
|
||||||
|
|
||||||
|
3. Pushing Out Your Changes
|
||||||
|
3.1 Write Access to CVS Repository
|
||||||
|
3.2 How To Make a Patch
|
||||||
|
3.3 How to get your changes into the main sources
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
1. Learning cURL
|
||||||
|
|
||||||
|
1.1 Join the Community
|
||||||
|
|
||||||
Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
|
Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
|
||||||
list(s). Read up on details before you post questions. Read this file before
|
list(s). Read up on details before you post questions. Read this file before
|
||||||
you start sending patches! We prefer patches and discussions being held on
|
you start sending patches! We prefer patches and discussions being held on
|
||||||
the mailing list(s), not sent to individuals.
|
the mailing list(s), not sent to individuals.
|
||||||
|
|
||||||
|
Before posting to one of the curl mailing lists, please read up on the mailing
|
||||||
|
list etiquette: http://curl.haxx.se/mail/etiquette.html
|
||||||
|
|
||||||
We also hang out on IRC in #curl on irc.freenode.net
|
We also hang out on IRC in #curl on irc.freenode.net
|
||||||
|
|
||||||
License
|
1.2. License
|
||||||
|
|
||||||
When contributing with code, you agree to put your changes and new code under
|
When contributing with code, you agree to put your changes and new code under
|
||||||
the same license curl and libcurl is already using unless stated and agreed
|
the same license curl and libcurl is already using unless stated and agreed
|
||||||
@@ -43,14 +73,16 @@ License
|
|||||||
give credit but also to keep a trace back to who made what changes. Please
|
give credit but also to keep a trace back to who made what changes. Please
|
||||||
always provide us with your full real name when contributing!
|
always provide us with your full real name when contributing!
|
||||||
|
|
||||||
What To Read
|
1.3 What To Read
|
||||||
|
|
||||||
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
|
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
|
||||||
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
|
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
|
||||||
you a lot of insights on what's going on right now. Asking there is a good
|
you a lot of insights on what's going on right now. Asking there is a good
|
||||||
idea too.
|
idea too.
|
||||||
|
|
||||||
Naming
|
2. cURL Coding Standards
|
||||||
|
|
||||||
|
2.1 Naming
|
||||||
|
|
||||||
Try using a non-confusing naming scheme for your new functions and variable
|
Try using a non-confusing naming scheme for your new functions and variable
|
||||||
names. It doesn't necessarily have to mean that you should use the same as in
|
names. It doesn't necessarily have to mean that you should use the same as in
|
||||||
@@ -61,7 +93,7 @@ Naming
|
|||||||
See the INTERNALS document on how we name non-exported library-global
|
See the INTERNALS document on how we name non-exported library-global
|
||||||
symbols.
|
symbols.
|
||||||
|
|
||||||
Indenting
|
2.2 Indenting
|
||||||
|
|
||||||
Please try using the same indenting levels and bracing method as all the
|
Please try using the same indenting levels and bracing method as all the
|
||||||
other code already does. It makes the source code a lot easier to follow if
|
other code already does. It makes the source code a lot easier to follow if
|
||||||
@@ -70,7 +102,9 @@ Indenting
|
|||||||
using spaces only (no tabs) and having the opening brace ({) on the same line
|
using spaces only (no tabs) and having the opening brace ({) on the same line
|
||||||
as the if() or while().
|
as the if() or while().
|
||||||
|
|
||||||
Commenting
|
Also note that we use if() and while() with no space before the parenthesis.
|
||||||
|
|
||||||
|
2.3 Commenting
|
||||||
|
|
||||||
Comment your source code extensively using C comments (/* comment */), DO NOT
|
Comment your source code extensively using C comments (/* comment */), DO NOT
|
||||||
use C++ comments (// this style). Commented code is quality code and enables
|
use C++ comments (// this style). Commented code is quality code and enables
|
||||||
@@ -78,12 +112,16 @@ Commenting
|
|||||||
replaced when someone wants to extend things, since other persons' source
|
replaced when someone wants to extend things, since other persons' source
|
||||||
code can get quite hard to read.
|
code can get quite hard to read.
|
||||||
|
|
||||||
General Style
|
2.4 Line Lengths
|
||||||
|
|
||||||
|
We try to keep source lines shorter than 80 columns.
|
||||||
|
|
||||||
|
2.5 General Style
|
||||||
|
|
||||||
Keep your functions small. If they're small you avoid a lot of mistakes and
|
Keep your functions small. If they're small you avoid a lot of mistakes and
|
||||||
you don't accidentally mix up variables etc.
|
you don't accidentally mix up variables etc.
|
||||||
|
|
||||||
Non-clobbering All Over
|
2.6 Non-clobbering All Over
|
||||||
|
|
||||||
When you write new functionality or fix bugs, it is important that you don't
|
When you write new functionality or fix bugs, it is important that you don't
|
||||||
fiddle all over the source files and functions. Remember that it is likely
|
fiddle all over the source files and functions. Remember that it is likely
|
||||||
@@ -92,14 +130,14 @@ Non-clobbering All Over
|
|||||||
functionality, try writing it in a new source file. If you fix bugs, try to
|
functionality, try writing it in a new source file. If you fix bugs, try to
|
||||||
fix one bug at a time and send them as separate patches.
|
fix one bug at a time and send them as separate patches.
|
||||||
|
|
||||||
Platform Dependent Code
|
2.7 Platform Dependent Code
|
||||||
|
|
||||||
Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for
|
Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for
|
||||||
particular operating systems or hardware in the #ifdef lines. The
|
particular operating systems or hardware in the #ifdef lines. The
|
||||||
HAVE_FEATURE shall be generated by the configure script for unix-like systems
|
HAVE_FEATURE shall be generated by the configure script for unix-like systems
|
||||||
and they are hard-coded in the config-[system].h files for the others.
|
and they are hard-coded in the config-[system].h files for the others.
|
||||||
|
|
||||||
Separate Patches
|
2.8 Write Separate Patches
|
||||||
|
|
||||||
It is annoying when you get a huge patch from someone that is said to fix 511
|
It is annoying when you get a huge patch from someone that is said to fix 511
|
||||||
odd problems, but discussions and opinions don't agree with 510 of them - or
|
odd problems, but discussions and opinions don't agree with 510 of them - or
|
||||||
@@ -110,14 +148,14 @@ Separate Patches
|
|||||||
description exactly what they correct so that all patches can be selectively
|
description exactly what they correct so that all patches can be selectively
|
||||||
applied by the maintainer or other interested parties.
|
applied by the maintainer or other interested parties.
|
||||||
|
|
||||||
Patch Against Recent Sources
|
2.9 Patch Against Recent Sources
|
||||||
|
|
||||||
Please try to get the latest available sources to make your patches
|
Please try to get the latest available sources to make your patches
|
||||||
against. It makes the life of the developers so much easier. The very best is
|
against. It makes the life of the developers so much easier. The very best is
|
||||||
if you get the most up-to-date sources from the CVS repository, but the
|
if you get the most up-to-date sources from the CVS repository, but the
|
||||||
latest release archive is quite OK as well!
|
latest release archive is quite OK as well!
|
||||||
|
|
||||||
Document
|
2.10 Document
|
||||||
|
|
||||||
Writing docs is dead boring and one of the big problems with many open source
|
Writing docs is dead boring and one of the big problems with many open source
|
||||||
projects. Someone's gotta do it. It makes it a lot easier if you submit a
|
projects. Someone's gotta do it. It makes it a lot easier if you submit a
|
||||||
@@ -128,16 +166,7 @@ Document
|
|||||||
ASCII files. All HTML files on the web site and in the release archives are
|
ASCII files. All HTML files on the web site and in the release archives are
|
||||||
generated from the nroff/ASCII versions.
|
generated from the nroff/ASCII versions.
|
||||||
|
|
||||||
Write Access to CVS Repository
|
2.11 Test Cases
|
||||||
|
|
||||||
If you are a frequent contributor, or have another good reason, you can of
|
|
||||||
course get write access to the CVS repository and then you'll be able to
|
|
||||||
check-in all your changes straight into the CVS tree instead of sending all
|
|
||||||
changes by mail as patches. Just ask if this is what you'd want. You will be
|
|
||||||
required to have posted a few quality patches first, before you can be
|
|
||||||
granted write access.
|
|
||||||
|
|
||||||
Test Cases
|
|
||||||
|
|
||||||
Since the introduction of the test suite, we can quickly verify that the main
|
Since the introduction of the test suite, we can quickly verify that the main
|
||||||
features are working as they're supposed to. To maintain this situation and
|
features are working as they're supposed to. To maintain this situation and
|
||||||
@@ -146,7 +175,18 @@ Test Cases
|
|||||||
test case that verifies that it works as documented. If every submitter also
|
test case that verifies that it works as documented. If every submitter also
|
||||||
posts a few test cases, it won't end up as a heavy burden on a single person!
|
posts a few test cases, it won't end up as a heavy burden on a single person!
|
||||||
|
|
||||||
How To Make a Patch
|
3. Pushing Out Your Changes
|
||||||
|
|
||||||
|
3.1 Write Access to CVS Repository
|
||||||
|
|
||||||
|
If you are a frequent contributor, or have another good reason, you can of
|
||||||
|
course get write access to the CVS repository and then you'll be able to
|
||||||
|
check-in all your changes straight into the CVS tree instead of sending all
|
||||||
|
changes by mail as patches. Just ask if this is what you'd want. You will be
|
||||||
|
required to have posted a few quality patches first, before you can be
|
||||||
|
granted write access.
|
||||||
|
|
||||||
|
3.2 How To Make a Patch
|
||||||
|
|
||||||
Keep a copy of the unmodified curl sources. Make your changes in a separate
|
Keep a copy of the unmodified curl sources. Make your changes in a separate
|
||||||
source tree. When you think you have something that you want to offer the
|
source tree. When you think you have something that you want to offer the
|
||||||
@@ -166,7 +206,7 @@ How To Make a Patch
|
|||||||
|
|
||||||
For unix-like operating systems:
|
For unix-like operating systems:
|
||||||
|
|
||||||
http://www.fsf.org/software/patch/patch.html
|
http://www.gnu.org/software/patch/patch.html
|
||||||
http://www.gnu.org/directory/diffutils.html
|
http://www.gnu.org/directory/diffutils.html
|
||||||
|
|
||||||
For Windows:
|
For Windows:
|
||||||
@@ -174,7 +214,7 @@ How To Make a Patch
|
|||||||
http://gnuwin32.sourceforge.net/packages/patch.htm
|
http://gnuwin32.sourceforge.net/packages/patch.htm
|
||||||
http://gnuwin32.sourceforge.net/packages/diffutils.htm
|
http://gnuwin32.sourceforge.net/packages/diffutils.htm
|
||||||
|
|
||||||
How to get your patches into the libcurl sources
|
3.3 How to get your changes into the main sources
|
||||||
|
|
||||||
1. Submit your patch to the curl-library mailing list
|
1. Submit your patch to the curl-library mailing list
|
||||||
|
|
||||||
@@ -189,5 +229,5 @@ How to get your patches into the libcurl sources
|
|||||||
simply drop such patches from my TODO list.
|
simply drop such patches from my TODO list.
|
||||||
|
|
||||||
5. If you've followed the above mentioned paragraphs and your patch still
|
5. If you've followed the above mentioned paragraphs and your patch still
|
||||||
hasn't been incorporated after some weeks, consider resubmitting them to
|
hasn't been incorporated after some weeks, consider resubmitting it to the
|
||||||
the list.
|
list.
|
||||||
|
|||||||
44
docs/FAQ
44
docs/FAQ
@@ -1,4 +1,4 @@
|
|||||||
Updated: July 30, 2007 (http://curl.haxx.se/docs/faq.html)
|
Updated: Feb 18, 2008 (http://curl.haxx.se/docs/faq.html)
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -18,6 +18,7 @@ FAQ
|
|||||||
1.8 I have a problem who do I mail?
|
1.8 I have a problem who do I mail?
|
||||||
1.9 Where do I buy commercial support for curl?
|
1.9 Where do I buy commercial support for curl?
|
||||||
1.10 How many are using curl?
|
1.10 How many are using curl?
|
||||||
|
1.11 Why don't you update ca-bundle.crt
|
||||||
|
|
||||||
2. Install Related Problems
|
2. Install Related Problems
|
||||||
2.1 configure doesn't find OpenSSL even when it is installed
|
2.1 configure doesn't find OpenSSL even when it is installed
|
||||||
@@ -83,6 +84,7 @@ FAQ
|
|||||||
5.10 How do I prevent libcurl from writing the response to stdout?
|
5.10 How do I prevent libcurl from writing the response to stdout?
|
||||||
5.11 How do I make libcurl not receive the whole HTTP response?
|
5.11 How do I make libcurl not receive the whole HTTP response?
|
||||||
5.12 Can I make libcurl fake or hide my real IP address?
|
5.12 Can I make libcurl fake or hide my real IP address?
|
||||||
|
5.13 How do I stop an ongoing transfer?
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
6.1 I have a GPL program, can I use the libcurl library?
|
6.1 I have a GPL program, can I use the libcurl library?
|
||||||
@@ -214,8 +216,7 @@ FAQ
|
|||||||
improvements and have them inserted in the main sources (of course on the
|
improvements and have them inserted in the main sources (of course on the
|
||||||
condition that developers agree on that the fixes are good).
|
condition that developers agree on that the fixes are good).
|
||||||
|
|
||||||
The full list of the more than 530 contributors is found in the docs/THANKS
|
The full list of all contributors is found in the docs/THANKS file.
|
||||||
file.
|
|
||||||
|
|
||||||
curl is developed by a community, with Daniel at the wheel.
|
curl is developed by a community, with Daniel at the wheel.
|
||||||
|
|
||||||
@@ -296,7 +297,7 @@ FAQ
|
|||||||
as used by numerous applications that include libcurl binaries in their
|
as used by numerous applications that include libcurl binaries in their
|
||||||
distribution packages (like Adobe Acrobat Reader and Google Earth).
|
distribution packages (like Adobe Acrobat Reader and Google Earth).
|
||||||
|
|
||||||
More than 70 known named companies use curl in commercial environments and
|
More than 80 known named companies use curl in commercial environments and
|
||||||
products. More than 100 known named open source projects depend on
|
products. More than 100 known named open source projects depend on
|
||||||
(lib)curl.
|
(lib)curl.
|
||||||
|
|
||||||
@@ -317,6 +318,29 @@ FAQ
|
|||||||
http://counter.li.org/estimates.php
|
http://counter.li.org/estimates.php
|
||||||
http://news.netcraft.com/archives/2005/03/14/fedora_makes_rapid_progress.html
|
http://news.netcraft.com/archives/2005/03/14/fedora_makes_rapid_progress.html
|
||||||
|
|
||||||
|
1.11 Why don't you update ca-bundle.crt
|
||||||
|
|
||||||
|
The ca-bundle.crt file that used to be bundled with curl was very outdated
|
||||||
|
(it being last modified year 2000 should tell) and must be replaced with a
|
||||||
|
much more modern and up-to-date version by anyone who wants to verify peers
|
||||||
|
anyway. It is no longer provided, the last curl release that shipped it was
|
||||||
|
curl 7.18.0.
|
||||||
|
|
||||||
|
In the cURL project we've decided not to attempt to keep this file updated
|
||||||
|
(or even present anymore) since deciding what to add to a ca cert bundle is
|
||||||
|
an undertaking we've not been ready to accept, and the one we can get from
|
||||||
|
Mozilla is perfectly fine so there's no need to duplicate that work.
|
||||||
|
|
||||||
|
Today, with many services performed over HTTPS, every operating system
|
||||||
|
should come with a default ca cert bundle that can be deemed somewhat
|
||||||
|
trustworthy and that collection (if reasonably updated) should be deemed to
|
||||||
|
be a lot better than a private curl version.
|
||||||
|
|
||||||
|
If you want the most recent collection of ca certs that Mozilla Firefox
|
||||||
|
uses, we recommend that you extract the collection yourself from Mozilla
|
||||||
|
Firefox (by running 'make ca-bundle), or by using our online service setup
|
||||||
|
for this purpose: http://curl.haxx.se/docs/caextract.html
|
||||||
|
|
||||||
|
|
||||||
2. Install Related Problems
|
2. Install Related Problems
|
||||||
|
|
||||||
@@ -1033,6 +1057,18 @@ FAQ
|
|||||||
that makes you see and use a different IP address locally than what the
|
that makes you see and use a different IP address locally than what the
|
||||||
remote server will see you coming from.
|
remote server will see you coming from.
|
||||||
|
|
||||||
|
5.13 How do I stop an ongoing transfer?
|
||||||
|
|
||||||
|
There are several ways, but none of them are instant. There is no function
|
||||||
|
you can call from another thread or similar that will stop it immediately.
|
||||||
|
Instead you need to make sure that one of the callbacks you use return an
|
||||||
|
appropriate value that will stop the transfer.
|
||||||
|
|
||||||
|
Suitable callbacks that you can do this with include the progress callback,
|
||||||
|
the read callback and the write callback.
|
||||||
|
|
||||||
|
If you're using the multi interface, you also stop a transfer by removing
|
||||||
|
the particular easy handle from the multi stack.
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
|
|
||||||
|
|||||||
17
docs/INSTALL
17
docs/INSTALL
@@ -188,7 +188,7 @@ Win32
|
|||||||
environment variables, for example:
|
environment variables, for example:
|
||||||
|
|
||||||
set ZLIB_PATH=c:\zlib-1.2.3
|
set ZLIB_PATH=c:\zlib-1.2.3
|
||||||
set OPENSSL_PATH=c:\openssl-0.9.8e
|
set OPENSSL_PATH=c:\openssl-0.9.8g
|
||||||
set LIBSSH2_PATH=c:\libssh2-0.17
|
set LIBSSH2_PATH=c:\libssh2-0.17
|
||||||
|
|
||||||
ATTENTION: if you want to build with libssh2 support you have to use latest
|
ATTENTION: if you want to build with libssh2 support you have to use latest
|
||||||
@@ -257,7 +257,7 @@ Win32
|
|||||||
Before running nmake define the OPENSSL_PATH environment variable with
|
Before running nmake define the OPENSSL_PATH environment variable with
|
||||||
the root/base directory of OpenSSL, for example:
|
the root/base directory of OpenSSL, for example:
|
||||||
|
|
||||||
set OPENSSL_PATH=c:\openssl-0.9.8e
|
set OPENSSL_PATH=c:\openssl-0.9.8g
|
||||||
|
|
||||||
Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
|
Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
|
||||||
directory. 'nmake vc-ssl' will create a libcurl static and dynamic
|
directory. 'nmake vc-ssl' will create a libcurl static and dynamic
|
||||||
@@ -521,7 +521,7 @@ NetWare
|
|||||||
http://www.gknw.net/development/ossl/netware/
|
http://www.gknw.net/development/ossl/netware/
|
||||||
for CLIB-based builds OpenSSL needs to be patched to build with BSD
|
for CLIB-based builds OpenSSL needs to be patched to build with BSD
|
||||||
sockets (currently only a winsock-based CLIB build is supported):
|
sockets (currently only a winsock-based CLIB build is supported):
|
||||||
http://www.gknw.net/development/ossl/netware/patches/v_0.9.8e/openssl-0.9.8e.diff
|
http://www.gknw.net/development/ossl/netware/patches/v_0.9.8g/openssl-0.9.8g.diff
|
||||||
- optional SSH2 sources (version 0.17 or later);
|
- optional SSH2 sources (version 0.17 or later);
|
||||||
|
|
||||||
Set a search path to your compiler, linker and tools; on Linux make
|
Set a search path to your compiler, linker and tools; on Linux make
|
||||||
@@ -714,6 +714,9 @@ REDUCING SIZE
|
|||||||
|
|
||||||
./configure CFLAGS='-Os' ...
|
./configure CFLAGS='-Os' ...
|
||||||
|
|
||||||
|
Note that newer compilers often produce smaller code than older versions
|
||||||
|
due to better optimization.
|
||||||
|
|
||||||
Be sure to specify as many --disable- and --without- flags on the configure
|
Be sure to specify as many --disable- and --without- flags on the configure
|
||||||
command-line as you can to disable all the libcurl features that you
|
command-line as you can to disable all the libcurl features that you
|
||||||
know your application is not going to need. Besides specifying the
|
know your application is not going to need. Besides specifying the
|
||||||
@@ -740,9 +743,9 @@ REDUCING SIZE
|
|||||||
sections of the shared library using the -R option to objcopy (e.g. the
|
sections of the shared library using the -R option to objcopy (e.g. the
|
||||||
.comment section).
|
.comment section).
|
||||||
|
|
||||||
Using these techniques it is possible to create an HTTP-only shared
|
Using these techniques it is possible to create an HTTP-only shared libcurl
|
||||||
libcurl library for i386 Linux platforms that is less than 90 KB in
|
library for i386 Linux platforms that is only 96 KiB in size (as of libcurl
|
||||||
size (as of version 7.15.4).
|
version 7.17.1, using gcc 4.2.2).
|
||||||
|
|
||||||
You may find that statically linking libcurl to your application will
|
You may find that statically linking libcurl to your application will
|
||||||
result in a lower total size.
|
result in a lower total size.
|
||||||
@@ -805,10 +808,12 @@ PORTS
|
|||||||
- ia64 Linux 2.3.99
|
- ia64 Linux 2.3.99
|
||||||
- m68k AmigaOS 3
|
- m68k AmigaOS 3
|
||||||
- m68k Linux
|
- m68k Linux
|
||||||
|
- m68k uClinux
|
||||||
- m68k OpenBSD
|
- m68k OpenBSD
|
||||||
- m88k dg-dgux5.4R3.00
|
- m88k dg-dgux5.4R3.00
|
||||||
- s390 Linux
|
- s390 Linux
|
||||||
- XScale/PXA250 Linux 2.4
|
- XScale/PXA250 Linux 2.4
|
||||||
|
- Nios II uClinux
|
||||||
|
|
||||||
Useful URLs
|
Useful URLs
|
||||||
===========
|
===========
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
Updated for curl 7.9.1 on November 2, 2001
|
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -37,8 +36,8 @@ Windows vs Unix
|
|||||||
|
|
||||||
2. Windows requires a couple of init calls for the socket stuff.
|
2. Windows requires a couple of init calls for the socket stuff.
|
||||||
|
|
||||||
Those must be made by the application that uses libcurl, in curl that means
|
That's taken care of by the curl_global_init() call, but if other libs also
|
||||||
src/main.c has some code #ifdef'ed to do just that.
|
do it etc there might be reasons for applications to alter that behaviour.
|
||||||
|
|
||||||
3. The file descriptors for network communication and file operations are
|
3. The file descriptors for network communication and file operations are
|
||||||
not easily interchangable as in unix.
|
not easily interchangable as in unix.
|
||||||
@@ -98,7 +97,9 @@ Library
|
|||||||
|
|
||||||
... analyzes the URL, it separates the different components and connects to
|
... analyzes the URL, it separates the different components and connects to
|
||||||
the remote host. This may involve using a proxy and/or using SSL. The
|
the remote host. This may involve using a proxy and/or using SSL. The
|
||||||
Curl_gethost() function in lib/hostip.c is used for looking up host names.
|
Curl_resolv() function in lib/hostip.c is used for looking up host names
|
||||||
|
(it does then use the proper underlying method, which may vary between
|
||||||
|
platforms and builds).
|
||||||
|
|
||||||
When Curl_connect is done, we are connected to the remote site. Then it is
|
When Curl_connect is done, we are connected to the remote site. Then it is
|
||||||
time to tell the server to get a document/file. Curl_do() arranges this.
|
time to tell the server to get a document/file. Curl_do() arranges this.
|
||||||
@@ -123,17 +124,20 @@ Library
|
|||||||
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
|
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
|
||||||
returns.
|
returns.
|
||||||
|
|
||||||
Starting in 7.9.1, if this DO function fails and the connection is being
|
If this DO function fails and the connection is being re-used, libcurl will
|
||||||
re-used, libcurl will then close this connection, setup a new connection
|
then close this connection, setup a new connection and re-issue the DO
|
||||||
and re-issue the DO request on that. This is because there is no way to be
|
request on that. This is because there is no way to be perfectly sure that
|
||||||
perfectly sure that we have discovered a dead connection before the DO
|
we have discovered a dead connection before the DO function and thus we
|
||||||
function and thus we might wrongly be re-using a connection that was closed
|
might wrongly be re-using a connection that was closed by the remote peer.
|
||||||
by the remote peer.
|
|
||||||
|
Some time during the DO function, the Curl_setup_transfer() function must
|
||||||
|
be called with some basic info about the upcoming transfer: what socket(s)
|
||||||
|
to read/write and the expected file tranfer sizes (if known).
|
||||||
|
|
||||||
o Transfer()
|
o Transfer()
|
||||||
|
|
||||||
Curl_perform() then calls Transfer() in lib/transfer.c that performs
|
Curl_perform() then calls Transfer() in lib/transfer.c that performs the
|
||||||
the entire file transfer.
|
entire file transfer.
|
||||||
|
|
||||||
During transfer, the progress functions in lib/progress.c are called at a
|
During transfer, the progress functions in lib/progress.c are called at a
|
||||||
frequent interval (or at the user's choice, a specified callback might get
|
frequent interval (or at the user's choice, a specified callback might get
|
||||||
@@ -237,9 +241,8 @@ Library
|
|||||||
URL encoding and decoding, called escaping and unescaping in the source code,
|
URL encoding and decoding, called escaping and unescaping in the source code,
|
||||||
is found in lib/escape.c.
|
is found in lib/escape.c.
|
||||||
|
|
||||||
While transfering data in Transfer() a few functions might get
|
While transfering data in Transfer() a few functions might get used.
|
||||||
used. curl_getdate() in lib/getdate.c is for HTTP date comparisons (and
|
curl_getdate() in lib/parsedate.c is for HTTP date comparisons (and more).
|
||||||
more).
|
|
||||||
|
|
||||||
lib/getenv.c offers curl_getenv() which is for reading environment variables
|
lib/getenv.c offers curl_getenv() which is for reading environment variables
|
||||||
in a neat platform independent way. That's used in the client, but also in
|
in a neat platform independent way. That's used in the client, but also in
|
||||||
@@ -255,10 +258,6 @@ Library
|
|||||||
A function named curl_version() that returns the full curl version string is
|
A function named curl_version() that returns the full curl version string is
|
||||||
found in lib/version.c.
|
found in lib/version.c.
|
||||||
|
|
||||||
If authentication is requested but no password is given, a getpass_r() clone
|
|
||||||
exists in lib/getpass.c. libcurl offers a custom callback that can be used
|
|
||||||
instead of this, but it doesn't change much to us.
|
|
||||||
|
|
||||||
Persistent Connections
|
Persistent Connections
|
||||||
======================
|
======================
|
||||||
|
|
||||||
@@ -270,9 +269,11 @@ Persistent Connections
|
|||||||
all the options etc that the library-user may choose.
|
all the options etc that the library-user may choose.
|
||||||
o The 'SessionHandle' struct holds the "connection cache" (an array of
|
o The 'SessionHandle' struct holds the "connection cache" (an array of
|
||||||
pointers to 'connectdata' structs). There's one connectdata struct
|
pointers to 'connectdata' structs). There's one connectdata struct
|
||||||
allocated for each connection that libcurl knows about.
|
allocated for each connection that libcurl knows about. Note that when you
|
||||||
o This also enables the 'curl handle' to be reused on subsequent transfers,
|
use the multi interface, the multi handle will hold the connection cache
|
||||||
something that was illegal before libcurl 7.7.
|
and not the particular easy handle. This of course to allow all easy handles
|
||||||
|
in a multi stack to be able to share and re-use connections.
|
||||||
|
o This enables the 'curl handle' to be reused on subsequent transfers.
|
||||||
o When we are about to perform a transfer with curl_easy_perform(), we first
|
o When we are about to perform a transfer with curl_easy_perform(), we first
|
||||||
check for an already existing connection in the cache that we can use,
|
check for an already existing connection in the cache that we can use,
|
||||||
otherwise we create a new one and add to the cache. If the cache is full
|
otherwise we create a new one and add to the cache. If the cache is full
|
||||||
@@ -282,11 +283,46 @@ Persistent Connections
|
|||||||
o When the transfer operation is complete, we try to leave the connection
|
o When the transfer operation is complete, we try to leave the connection
|
||||||
open. Particular options may tell us not to, and protocols may signal
|
open. Particular options may tell us not to, and protocols may signal
|
||||||
closure on connections and then we don't keep it open of course.
|
closure on connections and then we don't keep it open of course.
|
||||||
o When curl_easy_cleanup() is called, we close all still opened connections.
|
o When curl_easy_cleanup() is called, we close all still opened connections,
|
||||||
|
unless of course the multi interface "owns" the connections.
|
||||||
|
|
||||||
You do realize that the curl handle must be re-used in order for the
|
You do realize that the curl handle must be re-used in order for the
|
||||||
persistent connections to work.
|
persistent connections to work.
|
||||||
|
|
||||||
|
multi interface/non-blocking
|
||||||
|
============================
|
||||||
|
|
||||||
|
We make an effort to provide a non-blocking interface to the library, the
|
||||||
|
multi interface. To make that interface work as good as possible, no
|
||||||
|
low-level functions within libcurl must be written to work in a blocking
|
||||||
|
manner.
|
||||||
|
|
||||||
|
One of the primary reasons we introduced c-ares support was to allow the name
|
||||||
|
resolve phase to be perfectly non-blocking as well.
|
||||||
|
|
||||||
|
The ultimate goal is to provide the easy interface simply by wrapping the
|
||||||
|
multi interface functions and thus treat everything internally as the multi
|
||||||
|
interface is the single interface we have.
|
||||||
|
|
||||||
|
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
|
||||||
|
and adjust the code to allow non-blocking operations even on multi-stage
|
||||||
|
protocols. The DICT, TELNET and TFTP are crappy examples and they are subject
|
||||||
|
for rewrite in the future to better fit the libcurl protocol family.
|
||||||
|
|
||||||
|
SSL libraries
|
||||||
|
=============
|
||||||
|
|
||||||
|
Originally libcurl supported SSLeay for SSL/TLS transports, but that was then
|
||||||
|
extended to its successor OpenSSL but has since also been extended to several
|
||||||
|
other SSL/TLS libraries and we expect and hope to further extend the support
|
||||||
|
in future libcurl versions.
|
||||||
|
|
||||||
|
To deal with this internally in the best way possible, we have a generic SSL
|
||||||
|
function API as provided by the sslgen.[ch] system, and they are the only SSL
|
||||||
|
functions we must use from within libcurl. sslgen is then crafted to use the
|
||||||
|
appropriate lower-level function calls to whatever SSL library that is in
|
||||||
|
use.
|
||||||
|
|
||||||
Library Symbols
|
Library Symbols
|
||||||
===============
|
===============
|
||||||
|
|
||||||
@@ -310,6 +346,13 @@ Return Codes and Informationals
|
|||||||
them. They are best used when revealing information that isn't otherwise
|
them. They are best used when revealing information that isn't otherwise
|
||||||
obvious.
|
obvious.
|
||||||
|
|
||||||
|
API/ABI
|
||||||
|
=======
|
||||||
|
|
||||||
|
We make an effort to not export or show internals or how internals work, as
|
||||||
|
that makes it easier to keep a solid API/ABI over time. See docs/libcurl/ABI
|
||||||
|
for our promise to users.
|
||||||
|
|
||||||
Client
|
Client
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,21 @@ join in and help us correct one or more of these! Also be sure to check the
|
|||||||
changelog of the current development status, as one or more of these problems
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
47. If a CONNECT response is larger than BUFSIZE when the connection is meant
|
52. Gautam Kachroo's issue that identifies a problem with the multi interface
|
||||||
to be kept alive, the function will return prematurely and will confuse the
|
where a connection can be re-used without actually being properly
|
||||||
rest of the HTTP protocol code.
|
SSL-negoatiated:
|
||||||
|
http://curl.haxx.se/mail/lib-2008-01/0277.html
|
||||||
|
|
||||||
46. If a CONNECT response is chunked-encoded, the function may return
|
49. If using --retry and the transfer timeouts (possibly due to using -m or
|
||||||
prematurely and will confuse the rest of the HTTP protocol code.
|
-y/-Y) the next attempt doesn't resume the transfer properly from what was
|
||||||
|
downloaded in the previous attempt but will truncate and restart at the
|
||||||
|
original position where it was at before the previous failed attempt. See
|
||||||
|
http://curl.haxx.se/mail/lib-2008-01/0080.html
|
||||||
|
|
||||||
|
48. If a CONNECT response-headers are larger than BUFSIZE (16KB) when the
|
||||||
|
connection is meant to be kept alive (like for NTLM proxy auth), the
|
||||||
|
function will return prematurely and will confuse the rest of the HTTP
|
||||||
|
protocol code. This should be very rare.
|
||||||
|
|
||||||
45. libcurl built to support ipv6 uses getaddrinfo() to resolve host names.
|
45. libcurl built to support ipv6 uses getaddrinfo() to resolve host names.
|
||||||
getaddrinfo() sorts the response list which effectively kills how libcurl
|
getaddrinfo() sorts the response list which effectively kills how libcurl
|
||||||
@@ -17,9 +26,6 @@ may have been fixed since this was written!
|
|||||||
initial suggested function to use for randomizing the response:
|
initial suggested function to use for randomizing the response:
|
||||||
http://curl.haxx.se/mail/lib-2007-07/0178.html
|
http://curl.haxx.se/mail/lib-2007-07/0178.html
|
||||||
|
|
||||||
44. --ftp-method nocwd does not handle URLs ending with a slash properly (it
|
|
||||||
should list the contents of that directory). See test case 351.
|
|
||||||
|
|
||||||
43. There seems to be a problem when connecting to the Microsoft telnet server.
|
43. There seems to be a problem when connecting to the Microsoft telnet server.
|
||||||
http://curl.haxx.se/bug/view.cgi?id=1720605
|
http://curl.haxx.se/bug/view.cgi?id=1720605
|
||||||
|
|
||||||
@@ -48,23 +54,9 @@ may have been fixed since this was written!
|
|||||||
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
|
||||||
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
|
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
|
||||||
|
|
||||||
33. Doing multi-pass HTTP authentication on a non-default port does not work.
|
|
||||||
This happens because the multi-pass code abuses the redirect following code
|
|
||||||
for doing multiple requests, and when we following redirects to an absolute
|
|
||||||
URL we must use the newly specified port and not the one specified in the
|
|
||||||
original URL. A proper fix to this would need to separate the negotiation
|
|
||||||
"redirect" from an actual redirect.
|
|
||||||
|
|
||||||
32. (At least on Windows) If libcurl is built with c-ares and there's no DNS
|
|
||||||
server configured in the system, the ares_init() call fails and thus
|
|
||||||
curl_easy_init() fails as well. This causes weird effects for people who use
|
|
||||||
numerical IP addresses only.
|
|
||||||
|
|
||||||
31. "curl-config --libs" will include details set in LDFLAGS when configure is
|
31. "curl-config --libs" will include details set in LDFLAGS when configure is
|
||||||
run that might be needed only for building libcurl. Similarly, it might
|
run that might be needed only for building libcurl. Further, curl-config
|
||||||
include options that perhaps aren't suitable both for static and dynamic
|
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
|
||||||
linking. Further, curl-config --cflags suffers from the same effects with
|
|
||||||
CFLAGS/CPPFLAGS.
|
|
||||||
|
|
||||||
30. You need to use -g to the command line tool in order to use RFC2732-style
|
30. You need to use -g to the command line tool in order to use RFC2732-style
|
||||||
IPv6 numerical addresses in URLs.
|
IPv6 numerical addresses in URLs.
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
Peer SSL Certificate Verification
|
Peer SSL Certificate Verification
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
libcurl performs peer SSL certificate verification by default. This is done by
|
libcurl performs peer SSL certificate verification by default. This is done
|
||||||
installing a default CA cert bundle on 'make install' (or similar), that CA
|
by using CA cert bundle that the SSL library can use to make sure the peer's
|
||||||
bundle package is used by default on operations against SSL servers.
|
server certificate is valid.
|
||||||
|
|
||||||
If you communicate with HTTPS or FTPS servers using certificates that are
|
If you communicate with HTTPS or FTPS servers using certificates that are
|
||||||
signed by CAs present in the bundle, you can be sure that the remote server
|
signed by CAs present in the bundle, you can be sure that the remote server
|
||||||
really is the one it claims to be.
|
really is the one it claims to be.
|
||||||
|
|
||||||
If the remote server uses a self-signed certificate, if you don't install
|
Until 7.18.0, curl bundled a severely outdated ca bundle file that was
|
||||||
curl's CA cert bundle, if the server uses a certificate signed by a CA that
|
installed by default. These days, the curl archives include no ca certs at
|
||||||
isn't included in the bundle or if the remote host is an impostor
|
all. You need to get them elsewhere. See below for example.
|
||||||
|
|
||||||
|
If the remote server uses a self-signed certificate, if you don't install a CA
|
||||||
|
cert bundle, if the server uses a certificate signed by a CA that isn't
|
||||||
|
included in the bundle you use or if the remote host is an impostor
|
||||||
impersonating your favorite site, and you want to transfer files from this
|
impersonating your favorite site, and you want to transfer files from this
|
||||||
server, do one of the following:
|
server, do one of the following:
|
||||||
|
|
||||||
1. Tell libcurl to *not* verify the peer. With libcurl you disable with with
|
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||||
|
|
||||||
With the curl command line tool, you disable this with -k/--insecure.
|
With the curl command line tool, you disable this with -k/--insecure.
|
||||||
@@ -27,10 +31,8 @@ server, do one of the following:
|
|||||||
With the curl command line tool: --cacert [file]
|
With the curl command line tool: --cacert [file]
|
||||||
|
|
||||||
3. Add the CA cert for your server to the existing default CA cert bundle.
|
3. Add the CA cert for your server to the existing default CA cert bundle.
|
||||||
The default path of the CA bundle installed with the curl package is:
|
The default path of the CA bundle used can be changed by running configure
|
||||||
/usr/local/share/curl/curl-ca-bundle.crt, which can be changed by running
|
with the --with-ca-bundle option pointing out the path of your choice.
|
||||||
configure with the --with-ca-bundle option pointing out the path of your
|
|
||||||
choice.
|
|
||||||
|
|
||||||
To do this, you need to get the CA cert for your server in PEM format and
|
To do this, you need to get the CA cert for your server in PEM format and
|
||||||
then append that to your CA cert bundle.
|
then append that to your CA cert bundle.
|
||||||
@@ -48,8 +50,6 @@ server, do one of the following:
|
|||||||
o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
||||||
as described below.
|
as described below.
|
||||||
|
|
||||||
(Thanks to Frankie V for this description)
|
|
||||||
|
|
||||||
If you use the 'openssl' tool, this is one way to get extract the CA cert
|
If you use the 'openssl' tool, this is one way to get extract the CA cert
|
||||||
for a particular server:
|
for a particular server:
|
||||||
|
|
||||||
@@ -64,8 +64,6 @@ server, do one of the following:
|
|||||||
cert_bundle or use it stand-alone as described. Just remember that the
|
cert_bundle or use it stand-alone as described. Just remember that the
|
||||||
security is no better than the way you obtained the certificate.
|
security is no better than the way you obtained the certificate.
|
||||||
|
|
||||||
(Thanks to Doug Kaufman for this description)
|
|
||||||
|
|
||||||
4. If you're using the curl command line tool, you can specify your own CA
|
4. If you're using the curl command line tool, you can specify your own CA
|
||||||
cert path by setting the environment variable CURL_CA_BUNDLE to the path
|
cert path by setting the environment variable CURL_CA_BUNDLE to the path
|
||||||
of your choice.
|
of your choice.
|
||||||
@@ -80,8 +78,9 @@ server, do one of the following:
|
|||||||
5. all directories along %PATH%
|
5. all directories along %PATH%
|
||||||
|
|
||||||
5. Get a better/different/newer CA cert bundle! One option is to extract the
|
5. Get a better/different/newer CA cert bundle! One option is to extract the
|
||||||
one a recent Mozilla browser uses, by following the instruction found
|
one a recent Mozilla browser uses by running 'make ca-bundle' in the curl
|
||||||
here:
|
build tree root, or possibly download a version that was generated this
|
||||||
|
way for you:
|
||||||
|
|
||||||
http://curl.haxx.se/docs/caextract.html
|
http://curl.haxx.se/docs/caextract.html
|
||||||
|
|
||||||
|
|||||||
47
docs/THANKS
47
docs/THANKS
@@ -12,6 +12,8 @@ Albert Chin-A-Young
|
|||||||
Albert Choy
|
Albert Choy
|
||||||
Ale Vesely
|
Ale Vesely
|
||||||
Aleksandar Milivojevic
|
Aleksandar Milivojevic
|
||||||
|
Alessandro Vesely
|
||||||
|
Alex Fishman
|
||||||
Alex Neblett
|
Alex Neblett
|
||||||
Alex Suykov
|
Alex Suykov
|
||||||
Alex aka WindEagle
|
Alex aka WindEagle
|
||||||
@@ -19,8 +21,10 @@ Alexander Kourakos
|
|||||||
Alexander Krasnostavsky
|
Alexander Krasnostavsky
|
||||||
Alexander Lazic
|
Alexander Lazic
|
||||||
Alexander Zhuravlev
|
Alexander Zhuravlev
|
||||||
|
Alexey Pesternikov
|
||||||
Alexey Simak
|
Alexey Simak
|
||||||
Alexis Carvalho
|
Alexis Carvalho
|
||||||
|
Allen Pulsifer
|
||||||
Amol Pattekar
|
Amol Pattekar
|
||||||
Anders Gustafsson
|
Anders Gustafsson
|
||||||
Andi Jahja
|
Andi Jahja
|
||||||
@@ -35,6 +39,8 @@ Andrew Biggs
|
|||||||
Andrew Bushnell
|
Andrew Bushnell
|
||||||
Andrew Francis
|
Andrew Francis
|
||||||
Andrew Fuller
|
Andrew Fuller
|
||||||
|
Andrew Moise
|
||||||
|
Andrew Wansink
|
||||||
Andr<EFBFBD>s Garc<72>a
|
Andr<EFBFBD>s Garc<72>a
|
||||||
Andy Cedilnik
|
Andy Cedilnik
|
||||||
Andy Serpa
|
Andy Serpa
|
||||||
@@ -71,10 +77,12 @@ Casey O'Donnell
|
|||||||
Chih-Chung Chang
|
Chih-Chung Chang
|
||||||
Chris "Bob Bob"
|
Chris "Bob Bob"
|
||||||
Chris Combes
|
Chris Combes
|
||||||
|
Chris Flerackers
|
||||||
Chris Gaukroger
|
Chris Gaukroger
|
||||||
Chris Maltby
|
Chris Maltby
|
||||||
Christian Kurz
|
Christian Kurz
|
||||||
Christian Robottom Reis
|
Christian Robottom Reis
|
||||||
|
Christian Vogt
|
||||||
Christophe Demory
|
Christophe Demory
|
||||||
Christophe Legry
|
Christophe Legry
|
||||||
Christopher R. Palmer
|
Christopher R. Palmer
|
||||||
@@ -82,6 +90,7 @@ Ciprian Badescu
|
|||||||
Clarence Gardner
|
Clarence Gardner
|
||||||
Clifford Wolf
|
Clifford Wolf
|
||||||
Cody Jones
|
Cody Jones
|
||||||
|
Colin Hogben
|
||||||
Colin Watson
|
Colin Watson
|
||||||
Colm Buckley
|
Colm Buckley
|
||||||
Cory Nelson
|
Cory Nelson
|
||||||
@@ -97,6 +106,8 @@ Dan Nelson
|
|||||||
Dan Torop
|
Dan Torop
|
||||||
Dan Zitter
|
Dan Zitter
|
||||||
Daniel Black
|
Daniel Black
|
||||||
|
Daniel Cater
|
||||||
|
Daniel Egger
|
||||||
Daniel Johnson
|
Daniel Johnson
|
||||||
Daniel Stenberg
|
Daniel Stenberg
|
||||||
Daniel at touchtunes
|
Daniel at touchtunes
|
||||||
@@ -122,6 +133,7 @@ David Phillips
|
|||||||
David Shaw
|
David Shaw
|
||||||
David Tarendash
|
David Tarendash
|
||||||
David Thiel
|
David Thiel
|
||||||
|
David Wright
|
||||||
David Yan
|
David Yan
|
||||||
Detlef Schmier
|
Detlef Schmier
|
||||||
Diego Casorran
|
Diego Casorran
|
||||||
@@ -132,6 +144,7 @@ Dirk Eddelbuettel
|
|||||||
Dirk Manske
|
Dirk Manske
|
||||||
Dmitriy Sergeyev
|
Dmitriy Sergeyev
|
||||||
Dmitry Bartsevich
|
Dmitry Bartsevich
|
||||||
|
Dmitry Kurochkin
|
||||||
Dmitry Rechkin
|
Dmitry Rechkin
|
||||||
Dolbneff A.V
|
Dolbneff A.V
|
||||||
Domenico Andreoli
|
Domenico Andreoli
|
||||||
@@ -149,10 +162,12 @@ Dylan Salisbury
|
|||||||
Early Ehlinger
|
Early Ehlinger
|
||||||
Edin Kadribasic
|
Edin Kadribasic
|
||||||
Ellis Pritchard
|
Ellis Pritchard
|
||||||
|
Emil Romanus
|
||||||
Emiliano Ida
|
Emiliano Ida
|
||||||
Enrico Scholz
|
Enrico Scholz
|
||||||
Enrik Berkhan
|
Enrik Berkhan
|
||||||
Eric Cooper
|
Eric Cooper
|
||||||
|
Eric Landes
|
||||||
Eric Lavigne
|
Eric Lavigne
|
||||||
Eric Melville
|
Eric Melville
|
||||||
Eric Rautman
|
Eric Rautman
|
||||||
@@ -177,25 +192,31 @@ Frank Ticheler
|
|||||||
Fred New
|
Fred New
|
||||||
Fred Noz
|
Fred Noz
|
||||||
Frederic Lepied
|
Frederic Lepied
|
||||||
|
Gary Maxwell
|
||||||
Gautam Mani
|
Gautam Mani
|
||||||
Gavrie Philipson
|
Gavrie Philipson
|
||||||
Gaz Iqbal
|
Gaz Iqbal
|
||||||
Georg Horn
|
Georg Horn
|
||||||
Georg Huettenegger
|
Georg Huettenegger
|
||||||
|
Georg Lippitsch
|
||||||
Georg Wicherski
|
Georg Wicherski
|
||||||
Gerd v. Egidy
|
Gerd v. Egidy
|
||||||
Gerhard Herre
|
Gerhard Herre
|
||||||
Gerrit Bruchh<68>user
|
Gerrit Bruchh<68>user
|
||||||
|
Giancarlo Formicuccia
|
||||||
Giaslas Georgios
|
Giaslas Georgios
|
||||||
Gilad
|
Gilad
|
||||||
Gilbert Ramirez Jr.
|
Gilbert Ramirez Jr.
|
||||||
|
Gilles Blanc
|
||||||
Gisle Vanem
|
Gisle Vanem
|
||||||
Giuseppe Attardi
|
Giuseppe Attardi
|
||||||
Giuseppe D'Ambrosio
|
Giuseppe D'Ambrosio
|
||||||
Glen Nakamura
|
Glen Nakamura
|
||||||
Glen Scott
|
Glen Scott
|
||||||
Greg Hewgill
|
Greg Hewgill
|
||||||
|
Greg Morse
|
||||||
Greg Onufer
|
Greg Onufer
|
||||||
|
Greg Zavertnik
|
||||||
Grigory Entin
|
Grigory Entin
|
||||||
Guenole Bescon
|
Guenole Bescon
|
||||||
Guillaume Arluison
|
Guillaume Arluison
|
||||||
@@ -217,9 +238,11 @@ Ian Gulliver
|
|||||||
Ian Turner
|
Ian Turner
|
||||||
Ian Wilkes
|
Ian Wilkes
|
||||||
Ignacio Vazquez-Abrams
|
Ignacio Vazquez-Abrams
|
||||||
|
Igor Franchuk
|
||||||
Igor Polyakov
|
Igor Polyakov
|
||||||
Ilguiz Latypov
|
Ilguiz Latypov
|
||||||
Ilja van Sprundel
|
Ilja van Sprundel
|
||||||
|
Immanuel Gregoire
|
||||||
Ingmar Runge
|
Ingmar Runge
|
||||||
Ingo Ralf Blum
|
Ingo Ralf Blum
|
||||||
Ingo Wilken
|
Ingo Wilken
|
||||||
@@ -240,12 +263,14 @@ Jared Lundell
|
|||||||
Jari Sundell
|
Jari Sundell
|
||||||
Jason S. Priebe
|
Jason S. Priebe
|
||||||
Jay Austin
|
Jay Austin
|
||||||
|
Jayesh A Shah
|
||||||
Jaz Fresh
|
Jaz Fresh
|
||||||
Jean Jacques Drouin
|
Jean Jacques Drouin
|
||||||
Jean-Claude Chauve
|
Jean-Claude Chauve
|
||||||
Jean-Louis Lemaire
|
Jean-Louis Lemaire
|
||||||
Jean-Marc Ranger
|
Jean-Marc Ranger
|
||||||
Jean-Philippe Barrette-LaPierre
|
Jean-Philippe Barrette-LaPierre
|
||||||
|
Jeff Johnson
|
||||||
Jeff Lawson
|
Jeff Lawson
|
||||||
Jeff Phillips
|
Jeff Phillips
|
||||||
Jeff Pohlmeyer
|
Jeff Pohlmeyer
|
||||||
@@ -255,7 +280,9 @@ Jesper Jensen
|
|||||||
Jesse Noller
|
Jesse Noller
|
||||||
Jim Drash
|
Jim Drash
|
||||||
Joe Halpin
|
Joe Halpin
|
||||||
|
Joe Malicki
|
||||||
Joel Chen
|
Joel Chen
|
||||||
|
Jofell Gallardo
|
||||||
Johan Anderson
|
Johan Anderson
|
||||||
Johan Nilsson
|
Johan Nilsson
|
||||||
John Crow
|
John Crow
|
||||||
@@ -263,6 +290,7 @@ John Janssen
|
|||||||
John Kelly
|
John Kelly
|
||||||
John Lask
|
John Lask
|
||||||
John McGowan
|
John McGowan
|
||||||
|
Johnny Luong
|
||||||
Jon Grubbs
|
Jon Grubbs
|
||||||
Jon Travis
|
Jon Travis
|
||||||
Jon Turner
|
Jon Turner
|
||||||
@@ -274,6 +302,7 @@ Jose Kahan
|
|||||||
Josh Kapell
|
Josh Kapell
|
||||||
Juan F. Codagnone
|
Juan F. Codagnone
|
||||||
Juan Ignacio Herv<72>s
|
Juan Ignacio Herv<72>s
|
||||||
|
Judson Bishop
|
||||||
Juergen Wilke
|
Juergen Wilke
|
||||||
Jukka Pihl
|
Jukka Pihl
|
||||||
Julian Noble
|
Julian Noble
|
||||||
@@ -296,7 +325,9 @@ Ken Rastatter
|
|||||||
Kent Boortz
|
Kent Boortz
|
||||||
Kevin Fisk
|
Kevin Fisk
|
||||||
Kevin Lussier
|
Kevin Lussier
|
||||||
|
Kevin Reed
|
||||||
Kevin Roth
|
Kevin Roth
|
||||||
|
Kim Rinnewitz
|
||||||
Kimmo Kinnunen
|
Kimmo Kinnunen
|
||||||
Kjell Ericson
|
Kjell Ericson
|
||||||
Kjetil Jacobsen
|
Kjetil Jacobsen
|
||||||
@@ -313,6 +344,7 @@ Lars Gustafsson
|
|||||||
Lars J. Aas
|
Lars J. Aas
|
||||||
Lars Nilsson
|
Lars Nilsson
|
||||||
Lars Torben Wilson
|
Lars Torben Wilson
|
||||||
|
Lau Hang Kin
|
||||||
Legoff Vincent
|
Legoff Vincent
|
||||||
Lehel Bernadt
|
Lehel Bernadt
|
||||||
Len Krause
|
Len Krause
|
||||||
@@ -337,6 +369,7 @@ Marco G. Salvagno
|
|||||||
Marcus Webster
|
Marcus Webster
|
||||||
Mario Schroeder
|
Mario Schroeder
|
||||||
Mark Butler
|
Mark Butler
|
||||||
|
Mark Davies
|
||||||
Mark Eichin
|
Mark Eichin
|
||||||
Mark Lentczner
|
Mark Lentczner
|
||||||
Markus Koetter
|
Markus Koetter
|
||||||
@@ -349,6 +382,7 @@ Martin Skinner
|
|||||||
Marty Kuhrt
|
Marty Kuhrt
|
||||||
Maruko
|
Maruko
|
||||||
Massimiliano Ziccardi
|
Massimiliano Ziccardi
|
||||||
|
Mateusz Loskot
|
||||||
Mathias Axelsson
|
Mathias Axelsson
|
||||||
Mats Lidell
|
Mats Lidell
|
||||||
Matt Kraai
|
Matt Kraai
|
||||||
@@ -357,6 +391,8 @@ Matt Witherspoon
|
|||||||
Matthew Blain
|
Matthew Blain
|
||||||
Matthew Clarke
|
Matthew Clarke
|
||||||
Maurice Barnum
|
Maurice Barnum
|
||||||
|
Max Katsev
|
||||||
|
Maxim Perenesenko
|
||||||
Mekonikum
|
Mekonikum
|
||||||
Mettgut Jamalla
|
Mettgut Jamalla
|
||||||
Michael Benedict
|
Michael Benedict
|
||||||
@@ -378,6 +414,7 @@ Mitz Wark
|
|||||||
Mohamed Lrhazi
|
Mohamed Lrhazi
|
||||||
Mohun Biswas
|
Mohun Biswas
|
||||||
Moonesamy
|
Moonesamy
|
||||||
|
Nathan Coulter
|
||||||
Nathan O'Sullivan
|
Nathan O'Sullivan
|
||||||
Nathanael Nerode
|
Nathanael Nerode
|
||||||
Naveen Noel
|
Naveen Noel
|
||||||
@@ -393,6 +430,7 @@ Nicolas Croiset
|
|||||||
Nicolas Fran<61>ois
|
Nicolas Fran<61>ois
|
||||||
Niels van Tongeren
|
Niels van Tongeren
|
||||||
Nikita Schmidt
|
Nikita Schmidt
|
||||||
|
Nikitinskit Dmitriy
|
||||||
Nir Soffer
|
Nir Soffer
|
||||||
Nis Jorgensen
|
Nis Jorgensen
|
||||||
Nodak Sodak
|
Nodak Sodak
|
||||||
@@ -403,6 +441,7 @@ Olaf St
|
|||||||
Oren Tirosh
|
Oren Tirosh
|
||||||
P R Schaffner
|
P R Schaffner
|
||||||
Patrick Bihan-Faou
|
Patrick Bihan-Faou
|
||||||
|
Patrick Monnerat
|
||||||
Patrick Smith
|
Patrick Smith
|
||||||
Paul Harrington
|
Paul Harrington
|
||||||
Paul Marquis
|
Paul Marquis
|
||||||
@@ -428,6 +467,7 @@ Peter Wullinger
|
|||||||
Peteris Krumins
|
Peteris Krumins
|
||||||
Phil Karn
|
Phil Karn
|
||||||
Philip Gladstone
|
Philip Gladstone
|
||||||
|
Philip Langdale
|
||||||
Philippe Hameau
|
Philippe Hameau
|
||||||
Philippe Raoult
|
Philippe Raoult
|
||||||
Philippe Vaucher
|
Philippe Vaucher
|
||||||
@@ -435,11 +475,13 @@ Pierre
|
|||||||
Puneet Pawaia
|
Puneet Pawaia
|
||||||
Quagmire
|
Quagmire
|
||||||
Rafael Sagula
|
Rafael Sagula
|
||||||
|
Ralf S. Engelschall
|
||||||
Ralph Beckmann
|
Ralph Beckmann
|
||||||
Ralph Mitchell
|
Ralph Mitchell
|
||||||
Ramana Mokkapati
|
Ramana Mokkapati
|
||||||
Randy McMurchy
|
Randy McMurchy
|
||||||
Ravi Pratap
|
Ravi Pratap
|
||||||
|
Ray Pekowski
|
||||||
Reinout van Schouwen
|
Reinout van Schouwen
|
||||||
Renaud Chaillat
|
Renaud Chaillat
|
||||||
Renaud Duhaut
|
Renaud Duhaut
|
||||||
@@ -466,6 +508,7 @@ Robert Foreman
|
|||||||
Robert Iakobashvili
|
Robert Iakobashvili
|
||||||
Robert Olson
|
Robert Olson
|
||||||
Robert Weaver
|
Robert Weaver
|
||||||
|
Robin Johnson
|
||||||
Robin Kay
|
Robin Kay
|
||||||
Robson Braga Araujo
|
Robson Braga Araujo
|
||||||
Rodney Simmons
|
Rodney Simmons
|
||||||
@@ -486,6 +529,7 @@ Samuel D
|
|||||||
Samuel Listopad
|
Samuel Listopad
|
||||||
Sander Gates
|
Sander Gates
|
||||||
Saul good
|
Saul good
|
||||||
|
Scott Cantor
|
||||||
Scott Davis
|
Scott Davis
|
||||||
Sebastien Willemijns
|
Sebastien Willemijns
|
||||||
Sergio Ballestrero
|
Sergio Ballestrero
|
||||||
@@ -500,6 +544,7 @@ Simon Josefsson
|
|||||||
Simon Liu
|
Simon Liu
|
||||||
Song Ma
|
Song Ma
|
||||||
Sonia Subramanian
|
Sonia Subramanian
|
||||||
|
Spacen Jasset
|
||||||
Spiridonoff A.V
|
Spiridonoff A.V
|
||||||
Stadler Stephan
|
Stadler Stephan
|
||||||
Stefan Esser
|
Stefan Esser
|
||||||
@@ -557,10 +602,12 @@ Ulf H
|
|||||||
Ulrich Zadow
|
Ulrich Zadow
|
||||||
Venkat Akella
|
Venkat Akella
|
||||||
Victor Snezhko
|
Victor Snezhko
|
||||||
|
Vikram Saxena
|
||||||
Vilmos Nebehaj
|
Vilmos Nebehaj
|
||||||
Vincent Bronner
|
Vincent Bronner
|
||||||
Vincent Penquerc'h
|
Vincent Penquerc'h
|
||||||
Vincent Sanders
|
Vincent Sanders
|
||||||
|
Vladimir Lazarenko
|
||||||
Vojtech Janota
|
Vojtech Janota
|
||||||
Vojtech Minarik
|
Vojtech Minarik
|
||||||
Walter J. Mack
|
Walter J. Mack
|
||||||
|
|||||||
529
docs/TODO
529
docs/TODO
@@ -4,257 +4,445 @@
|
|||||||
| (__| |_| | _ <| |___
|
| (__| |_| | _ <| |___
|
||||||
\___|\___/|_| \_\_____|
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
TODO
|
Things that could be nice to do in the future
|
||||||
|
|
||||||
Things to do in project cURL. Please tell us what you think, contribute and
|
Things to do in project cURL. Please tell us what you think, contribute and
|
||||||
send us patches that improve things! Also check the http://curl.haxx.se/dev
|
send us patches that improve things!
|
||||||
web section for various technical development notes.
|
|
||||||
|
|
||||||
All bugs documented in the KNOWN_BUGS document are subject for fixing!
|
All bugs documented in the KNOWN_BUGS document are subject for fixing!
|
||||||
|
|
||||||
LIBCURL
|
1. libcurl
|
||||||
|
1.1 Zero-copy interface
|
||||||
|
1.2 More data sharing
|
||||||
|
1.3 struct lifreq
|
||||||
|
1.4 Get IP address
|
||||||
|
1.5 c-ares ipv6
|
||||||
|
1.6 configure-based info in public headers
|
||||||
|
|
||||||
* Introduce another callback interface for upload/download that makes one
|
2. libcurl - multi interface
|
||||||
less copy of data and thus a faster operation.
|
2.1 More non-blocking
|
||||||
|
2.2 Pause transfers
|
||||||
|
2.3 Remove easy interface internally
|
||||||
|
2.4 Avoid having to remove/readd handles
|
||||||
|
|
||||||
|
3. Documentation
|
||||||
|
3.1 More and better
|
||||||
|
|
||||||
|
4. FTP
|
||||||
|
4.1 PRET
|
||||||
|
4.2 Alter passive/active on failure and retry
|
||||||
|
4.3 Earlier bad letter detection
|
||||||
|
4.4 REST for large files
|
||||||
|
4.5 FTP proxy support
|
||||||
|
4.6 PORT port range
|
||||||
|
4.7 ASCII support
|
||||||
|
|
||||||
|
5. HTTP
|
||||||
|
5.1 Other HTTP versions with CONNECT
|
||||||
|
5.2 Better persistancy for HTTP 1.0
|
||||||
|
5.3 support FF3 sqlite cookie files
|
||||||
|
|
||||||
|
6. TELNET
|
||||||
|
6.1 ditch stdin
|
||||||
|
6.2 ditch telnet-specific select
|
||||||
|
|
||||||
|
7. SSL
|
||||||
|
7.1 Disable specific versions
|
||||||
|
7.2 Provide mytex locking API
|
||||||
|
7.3 dumpcert
|
||||||
|
7.4 Evaluate SSL patches
|
||||||
|
7.5 Cache OpenSSL contexts
|
||||||
|
7.6 Export session ids
|
||||||
|
7.7 Provide callback for cert verfication
|
||||||
|
7.8 Support other SSL libraries
|
||||||
|
7.9 Support SRP on the TLS layer
|
||||||
|
7.10 improve configure --with-ssl
|
||||||
|
|
||||||
|
8. GnuTLS
|
||||||
|
8.1 Make NTLM work without OpenSSL functions
|
||||||
|
8.2 SSl engine stuff
|
||||||
|
8.3 SRP
|
||||||
|
8.4 non-blocking
|
||||||
|
8.5 check connection
|
||||||
|
|
||||||
|
9. LDAP
|
||||||
|
9.1 ditch ldap-specific select
|
||||||
|
|
||||||
|
10. New protocols
|
||||||
|
10.1 RTSP
|
||||||
|
10.2 RSYNC
|
||||||
|
10.3 RTMP
|
||||||
|
|
||||||
|
11. Client
|
||||||
|
11.1 Content-Disposition
|
||||||
|
11.2 sync
|
||||||
|
11.3 glob posts
|
||||||
|
11.4 prevent file overwriting
|
||||||
|
11.5 ftp wildcard download
|
||||||
|
11.6 simultaneous parallel transfers
|
||||||
|
11.7 provide formpost headers
|
||||||
|
11.8 url-specific options
|
||||||
|
|
||||||
|
12. Build
|
||||||
|
12.1 roffit
|
||||||
|
|
||||||
|
13. Test suite
|
||||||
|
13.1 SSL tunnel
|
||||||
|
13.2 nicer lacking perl message
|
||||||
|
13.3 more protocols supported
|
||||||
|
13.4 more platforms supported
|
||||||
|
|
||||||
|
14. Next SONAME bump
|
||||||
|
14.1 http-style HEAD output for ftp
|
||||||
|
14.2 combine error codes
|
||||||
|
14.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||||
|
|
||||||
|
15. Next major release
|
||||||
|
15.1 cleanup return codes
|
||||||
|
15.2 remove obsolete defines
|
||||||
|
15.3 size_t
|
||||||
|
15.4 remove several functions
|
||||||
|
15.5 remove CURLOPT_FAILONERROR
|
||||||
|
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
1. libcurl
|
||||||
|
|
||||||
|
1.1 Zero-copy interface
|
||||||
|
|
||||||
|
Introdue another callback interface for upload/download that makes one less
|
||||||
|
copy of data and thus a faster operation.
|
||||||
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
||||||
|
|
||||||
* More data sharing. curl_share_* functions already exist and work, and they
|
1.2 More data sharing
|
||||||
can be extended to share more. For example, enable sharing of the ares
|
|
||||||
channel and the connection cache.
|
|
||||||
|
|
||||||
* Introduce a new error code indicating authentication problems (for proxy
|
curl_share_* functions already exist and work, and they can be extended to
|
||||||
CONNECT error 407 for example). This cannot be an error code, we must not
|
share more. For example, enable sharing of the ares channel and the
|
||||||
return informational stuff as errors, consider a new info returned by
|
connection cache.
|
||||||
curl_easy_getinfo() http://curl.haxx.se/bug/view.cgi?id=845941
|
|
||||||
|
|
||||||
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
1.3 struct lifreq
|
||||||
|
|
||||||
|
Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||||
To support ipv6 interface addresses properly.
|
To support ipv6 interface addresses for network interfaces properly.
|
||||||
|
|
||||||
* Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
1.4 Get IP address
|
||||||
GET_FTP_DATA_IP. Return a string with the used IP. Suggested by Alan.
|
|
||||||
|
|
||||||
* Add option that changes the interval in which the progress callback is
|
Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
||||||
called at most.
|
GET_FTP_DATA_IP. Return a string with the used IP.
|
||||||
|
|
||||||
* Make libcurl built with c-ares use c-ares' IPv6 abilities. They weren't
|
1.5 c-ares ipv6
|
||||||
|
|
||||||
|
Make libcurl built with c-ares use c-ares' IPv6 abilities. They weren't
|
||||||
present when we first added c-ares support but they have been added since!
|
present when we first added c-ares support but they have been added since!
|
||||||
When this is done and works, we can actually start considering making c-ares
|
When this is done and works, we can actually start considering making c-ares
|
||||||
powered libcurl the default build (which of course would require that we'd
|
powered libcurl the default build (which of course would require that we'd
|
||||||
bundle the c-ares source code in the libcurl source code releases).
|
bundle the c-ares source code in the libcurl source code releases).
|
||||||
|
|
||||||
* Make the curl/*.h headers include the proper system includes based on what
|
1.6 configure-based info in public headers
|
||||||
was present at the time when configure was run. Currently, the sys/select.h
|
|
||||||
header is for example included by curl/multi.h only on specific platforms
|
|
||||||
we know MUST have it. This is error-prone. We therefore want the header
|
|
||||||
files to adapt to configure results. Those results must be stored in a new
|
|
||||||
header and they must use a curl name space, i.e not be HAVE_* prefix (as
|
|
||||||
that would risk collide with other apps that use libcurl and that runs
|
|
||||||
configure).
|
|
||||||
|
|
||||||
Work on this has been started but hasn't been finished, and the initial
|
Make the public headers include the proper system includes based on what was
|
||||||
patch and some details are found here:
|
present at the time when configure was run. Currently, the sys/select.h
|
||||||
|
header is for example included by curl/multi.h only on specific platforms we
|
||||||
|
know MUST have it. This is error-prone. We therefore want the header files to
|
||||||
|
adapt to configure results. Those results must be stored in a new header and
|
||||||
|
they must use a curl name space, i.e not be HAVE_* prefix (as that would risk
|
||||||
|
collide with other apps that use libcurl and that runs configure).
|
||||||
|
|
||||||
|
Work on this has been started but hasn't been finished, and the initial patch
|
||||||
|
and some details are found here:
|
||||||
http://curl.haxx.se/mail/lib-2006-12/0084.html
|
http://curl.haxx.se/mail/lib-2006-12/0084.html
|
||||||
|
|
||||||
LIBCURL - multi interface
|
The remaining problems to solve involve the platforms that can't run
|
||||||
|
configure.
|
||||||
|
|
||||||
* Make sure we don't ever loop because of non-blocking sockets return
|
2. libcurl - multi interface
|
||||||
|
|
||||||
|
2.1 More non-blocking
|
||||||
|
|
||||||
|
Make sure we don't ever loop because of non-blocking sockets return
|
||||||
EWOULDBLOCK or similar. The GnuTLS connection etc.
|
EWOULDBLOCK or similar. The GnuTLS connection etc.
|
||||||
|
|
||||||
* Make transfers treated more carefully. We need a way to tell libcurl we
|
2.2 Pause transfers
|
||||||
have data to write, as the current system expects us to upload data each
|
|
||||||
time the socket is writable and there is no way to say that we want to
|
|
||||||
upload data soon just not right now, without that aborting the upload. The
|
|
||||||
opposite situation should be possible as well, that we tell libcurl we're
|
|
||||||
ready to accept read data. Today libcurl feeds the data as soon as it is
|
|
||||||
available for reading, no matter what.
|
|
||||||
|
|
||||||
* Make curl_easy_perform() a wrapper-function that simply creates a multi
|
Make transfers treated more carefully. We need a way to tell libcurl we have
|
||||||
|
data to write, as the current system expects us to upload data each time the
|
||||||
|
socket is writable and there is no way to say that we want to upload data
|
||||||
|
soon just not right now, without that aborting the upload. The opposite
|
||||||
|
situation should be possible as well, that we tell libcurl we're ready to
|
||||||
|
accept read data. Today libcurl feeds the data as soon as it is available for
|
||||||
|
reading, no matter what.
|
||||||
|
|
||||||
|
2.3 Remove easy interface internally
|
||||||
|
|
||||||
|
Make curl_easy_perform() a wrapper-function that simply creates a multi
|
||||||
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
||||||
transfer is done, then detach the easy handle, destroy the multi handle and
|
transfer is done, then detach the easy handle, destroy the multi handle and
|
||||||
return the easy handle's return code. This will thus make everything
|
return the easy handle's return code. This will thus make everything
|
||||||
internally use and assume the multi interface. The select()-loop should use
|
internally use and assume the multi interface. The select()-loop should use
|
||||||
curl_multi_socket().
|
curl_multi_socket().
|
||||||
|
|
||||||
* curl_multi_handle_control() - this can control the easy handle (while)
|
2.4 Avoid having to remove/readd handles
|
||||||
added to a multi handle in various ways:
|
|
||||||
|
curl_multi_handle_control() - this can control the easy handle (while) added
|
||||||
|
to a multi handle in various ways:
|
||||||
|
|
||||||
o RESTART, unconditionally restart this easy handle's transfer from the
|
o RESTART, unconditionally restart this easy handle's transfer from the
|
||||||
start, re-init the state
|
start, re-init the state
|
||||||
|
|
||||||
o RESTART_COMPLETED, restart this easy handle's transfer but only if the
|
o RESTART_COMPLETED, restart this easy handle's transfer but only if the
|
||||||
existing transfer has already completed and it is in a "finished state".
|
existing transfer has already completed and it is in a "finished state".
|
||||||
|
|
||||||
o STOP, just stop this transfer and consider it completed
|
o STOP, just stop this transfer and consider it completed
|
||||||
|
|
||||||
o PAUSE?
|
o PAUSE?
|
||||||
|
|
||||||
o RESUME?
|
o RESUME?
|
||||||
|
|
||||||
DOCUMENTATION
|
3. Documentation
|
||||||
|
|
||||||
* More and better
|
3.1 More and better
|
||||||
|
|
||||||
FTP
|
Exactly
|
||||||
|
|
||||||
* PRET is a command that primarily "drftpd" supports, which could be useful
|
4. FTP
|
||||||
|
|
||||||
|
4.1 PRET
|
||||||
|
|
||||||
|
PRET is a command that primarily "drftpd" supports, which could be useful
|
||||||
when using libcurl against such a server. It is a non-standard and a rather
|
when using libcurl against such a server. It is a non-standard and a rather
|
||||||
oddly designed command, but...
|
oddly designed command, but...
|
||||||
http://curl.haxx.se/bug/feature.cgi?id=1729967
|
http://curl.haxx.se/bug/feature.cgi?id=1729967
|
||||||
|
|
||||||
* When trying to connect passively to a server which only supports active
|
4.2 Alter passive/active on failure and retry
|
||||||
|
|
||||||
|
When trying to connect passively to a server which only supports active
|
||||||
connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
|
connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
|
||||||
connection. There could be a way to fallback to an active connection (and
|
connection. There could be a way to fallback to an active connection (and
|
||||||
vice versa). http://curl.haxx.se/bug/feature.cgi?id=1754793
|
vice versa). http://curl.haxx.se/bug/feature.cgi?id=1754793
|
||||||
|
|
||||||
* Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in
|
4.3 Earlier bad letter detection
|
||||||
the process to avoid doing a resolve and connect in vain.
|
|
||||||
|
|
||||||
* REST fix for servers not behaving well on >2GB requests. This should fail
|
Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in the
|
||||||
if the server doesn't set the pointer to the requested index. The tricky
|
process to avoid doing a resolve and connect in vain.
|
||||||
(impossible?) part is to figure out if the server did the right thing or
|
|
||||||
not.
|
|
||||||
|
|
||||||
* Support the most common FTP proxies, Philip Newton provided a list
|
4.4 REST for large files
|
||||||
allegedly from ncftp:
|
|
||||||
http://curl.haxx.se/mail/archive-2003-04/0126.html
|
|
||||||
|
|
||||||
* Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
REST fix for servers not behaving well on >2GB requests. This should fail if
|
||||||
|
the server doesn't set the pointer to the requested index. The tricky
|
||||||
|
(impossible?) part is to figure out if the server did the right thing or not.
|
||||||
|
|
||||||
|
4.5 FTP proxy support
|
||||||
|
|
||||||
|
Support the most common FTP proxies, Philip Newton provided a list allegedly
|
||||||
|
from ncftp. This is not a subject without debate, and is probably not really
|
||||||
|
suitable for libcurl. http://curl.haxx.se/mail/archive-2003-04/0126.html
|
||||||
|
|
||||||
|
4.6 PORT port range
|
||||||
|
|
||||||
|
Make CURLOPT_FTPPORT support an additional port number on the IP/if/name,
|
||||||
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
like "blabla:[port]" or possibly even "blabla:[portfirst]-[portsecond]".
|
||||||
http://curl.haxx.se/bug/feature.cgi?id=1505166
|
http://curl.haxx.se/bug/feature.cgi?id=1505166
|
||||||
|
|
||||||
* FTP ASCII transfers do not follow RFC959. They don't convert the data
|
4.7 ASCII support
|
||||||
|
|
||||||
|
FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||||
accordingly.
|
accordingly.
|
||||||
|
|
||||||
* Since USERPWD always override the user and password specified in URLs, we
|
5. HTTP
|
||||||
might need another way to specify user+password for anonymous ftp logins.
|
|
||||||
|
|
||||||
* The FTP code should get a way of returning errors that is known to still
|
5.1 Other HTTP versions with CONNECT
|
||||||
have the control connection alive and sound. Currently, a returned error
|
|
||||||
from within ftp-functions does not tell if the control connection is still
|
|
||||||
OK to use or not. This causes libcurl to fail to re-use connections
|
|
||||||
slightly too often.
|
|
||||||
|
|
||||||
HTTP
|
When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
|
||||||
|
never been reported as causing trouble to anyone, but should be considered to
|
||||||
|
use the HTTP version the user has chosen.
|
||||||
|
|
||||||
* When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
|
5.2 Better persistancy for HTTP 1.0
|
||||||
never been reported as causing trouble to anyone, but should be considered
|
|
||||||
to use the HTTP version the user has chosen.
|
|
||||||
|
|
||||||
* "Better" support for persistent connections over HTTP 1.0
|
"Better" support for persistent connections over HTTP 1.0
|
||||||
http://curl.haxx.se/bug/feature.cgi?id=1089001
|
http://curl.haxx.se/bug/feature.cgi?id=1089001
|
||||||
|
|
||||||
TELNET
|
5.3 support FF3 sqlite cookie files
|
||||||
|
|
||||||
* Reading input (to send to the remote server) on stdin is a crappy solution
|
Firefox 3 is changing from its former format to a a sqlite database instead.
|
||||||
for library purposes. We need to invent a good way for the application to
|
We should consider how (lib)curl can/should support this.
|
||||||
be able to provide the data to send.
|
http://curl.haxx.se/bug/feature.cgi?id=1871388
|
||||||
|
|
||||||
* Move the telnet support's network select() loop go away and merge the code
|
6. TELNET
|
||||||
|
|
||||||
|
6.1 ditch stdin
|
||||||
|
|
||||||
|
Reading input (to send to the remote server) on stdin is a crappy solution for
|
||||||
|
library purposes. We need to invent a good way for the application to be able
|
||||||
|
to provide the data to send.
|
||||||
|
|
||||||
|
6.2 ditch telnet-specific select
|
||||||
|
|
||||||
|
Move the telnet support's network select() loop go away and merge the code
|
||||||
into the main transfer loop. Until this is done, the multi interface won't
|
into the main transfer loop. Until this is done, the multi interface won't
|
||||||
work for telnet.
|
work for telnet.
|
||||||
|
|
||||||
SSL
|
7. SSL
|
||||||
|
|
||||||
* Provide an option that allows for disabling specific SSL versions, such as
|
7.1 Disable specific versions
|
||||||
|
|
||||||
|
Provide an option that allows for disabling specific SSL versions, such as
|
||||||
SSLv2 http://curl.haxx.se/bug/feature.cgi?id=1767276
|
SSLv2 http://curl.haxx.se/bug/feature.cgi?id=1767276
|
||||||
|
|
||||||
* Provide a libcurl API for setting mutex callbacks in the underlying SSL
|
7.2 Provide mytex locking API
|
||||||
|
|
||||||
|
Provide a libcurl API for setting mutex callbacks in the underlying SSL
|
||||||
library, so that the same application code can use mutex-locking
|
library, so that the same application code can use mutex-locking
|
||||||
independently of OpenSSL or GnutTLS being used.
|
independently of OpenSSL or GnutTLS being used.
|
||||||
|
|
||||||
* Anton Fedorov's "dumpcert" patch:
|
7.3 dumpcert
|
||||||
|
|
||||||
|
Anton Fedorov's "dumpcert" patch:
|
||||||
http://curl.haxx.se/mail/lib-2004-03/0088.html
|
http://curl.haxx.se/mail/lib-2004-03/0088.html
|
||||||
|
|
||||||
* Evaluate/apply Gertjan van Wingerde's SSL patches:
|
7.4 Evaluate SSL patches
|
||||||
|
|
||||||
|
Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||||
|
|
||||||
* "Look at SSL cafile - quick traces look to me like these are done on every
|
7.5 Cache OpenSSL contexts
|
||||||
request as well, when they should only be necessary once per ssl context
|
|
||||||
(or once per handle)". The major improvement we can rather easily do is to
|
|
||||||
make sure we don't create and kill a new SSL "context" for every request,
|
|
||||||
but instead make one for every connection and re-use that SSL context in
|
|
||||||
the same style connections are re-used. It will make us use slightly more
|
|
||||||
memory but it will libcurl do less creations and deletions of SSL contexts.
|
|
||||||
|
|
||||||
* Add an interface to libcurl that enables "session IDs" to get
|
"Look at SSL cafile - quick traces look to me like these are done on every
|
||||||
|
request as well, when they should only be necessary once per ssl context (or
|
||||||
|
once per handle)". The major improvement we can rather easily do is to make
|
||||||
|
sure we don't create and kill a new SSL "context" for every request, but
|
||||||
|
instead make one for every connection and re-use that SSL context in the same
|
||||||
|
style connections are re-used. It will make us use slightly more memory but
|
||||||
|
it will libcurl do less creations and deletions of SSL contexts.
|
||||||
|
|
||||||
|
7.6 Export session ids
|
||||||
|
|
||||||
|
Add an interface to libcurl that enables "session IDs" to get
|
||||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||||
serialise the current SSL state to a buffer of your choice, and
|
serialise the current SSL state to a buffer of your choice, and recover/reset
|
||||||
recover/reset the state from such a buffer at a later date - this is used
|
the state from such a buffer at a later date - this is used by mod_ssl for
|
||||||
by mod_ssl for apache to implement and SSL session ID cache".
|
apache to implement and SSL session ID cache".
|
||||||
|
|
||||||
* OpenSSL supports a callback for customised verification of the peer
|
7.7 Provide callback for cert verfication
|
||||||
|
|
||||||
|
OpenSSL supports a callback for customised verification of the peer
|
||||||
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
|
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
|
||||||
it be? There's so much that could be done if it were! (brought by Chris
|
it be? There's so much that could be done if it were!
|
||||||
Clark)
|
|
||||||
|
|
||||||
* Make curl's SSL layer capable of using other free SSL libraries. Such as
|
7.8 Support other SSL libraries
|
||||||
|
|
||||||
|
Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||||
MatrixSSL (http://www.matrixssl.org/).
|
MatrixSSL (http://www.matrixssl.org/).
|
||||||
|
|
||||||
* Peter Sylvester's patch for SRP on the TLS layer.
|
7.9 Support SRP on the TLS layer
|
||||||
Awaits OpenSSL support for this, no need to support this in libcurl before
|
|
||||||
there's an OpenSSL release that does it.
|
|
||||||
|
|
||||||
* make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
Peter Sylvester's patch for SRP on the TLS layer. Awaits OpenSSL support for
|
||||||
|
this, no need to support this in libcurl before there's an OpenSSL release
|
||||||
|
that does it.
|
||||||
|
|
||||||
|
7.10 improve configure --with-ssl
|
||||||
|
|
||||||
|
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||||
then NSS...
|
then NSS...
|
||||||
|
|
||||||
GnuTLS
|
8. GnuTLS
|
||||||
|
|
||||||
* Get NTLM working using the functions provided by libgcrypt, since GnuTLS
|
8.1 Make NTLM work without OpenSSL functions
|
||||||
|
|
||||||
|
Get NTLM working using the functions provided by libgcrypt, since GnuTLS
|
||||||
already depends on that to function. Not strictly SSL/TLS related, but
|
already depends on that to function. Not strictly SSL/TLS related, but
|
||||||
hey... Another option is to get available DES and MD4 source code from the
|
hey... Another option is to get available DES and MD4 source code from the
|
||||||
cryptopp library. They are fine license-wise, but are C++.
|
cryptopp library. They are fine license-wise, but are C++.
|
||||||
|
|
||||||
* SSL engine stuff?
|
8.2 SSl engine stuff
|
||||||
|
|
||||||
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
Is this even possible?
|
||||||
on the TLS to provide name and password
|
|
||||||
|
|
||||||
* Fix the connection phase to be non-blocking when multi interface is used
|
8.3 SRP
|
||||||
|
|
||||||
* Add a way to check if the connection seems to be alive, to correspond to
|
Work out a common method with Peter Sylvester's OpenSSL-patch for SRP on the
|
||||||
the SSL_peak() way we use with OpenSSL.
|
TLS to provide name and password. GnuTLS already supports it...
|
||||||
|
|
||||||
LDAP
|
8.4 non-blocking
|
||||||
|
|
||||||
|
Fix the connection phase to be non-blocking when multi interface is used
|
||||||
|
|
||||||
|
8.5 check connection
|
||||||
|
|
||||||
|
Add a way to check if the connection seems to be alive, to correspond to the
|
||||||
|
SSL_peak() way we use with OpenSSL.
|
||||||
|
|
||||||
|
9. LDAP
|
||||||
|
|
||||||
|
9.1 ditch ldap-specific select
|
||||||
|
|
||||||
* Look over the implementation. The looping will have to "go away" from the
|
* Look over the implementation. The looping will have to "go away" from the
|
||||||
lib/ldap.c source file and get moved to the main network code so that the
|
lib/ldap.c source file and get moved to the main network code so that the
|
||||||
multi interface and friends will work for LDAP as well.
|
multi interface and friends will work for LDAP as well.
|
||||||
|
|
||||||
NEW PROTOCOLS
|
10. New protocols
|
||||||
|
|
||||||
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
10.1 RTSP
|
||||||
|
|
||||||
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
|
RFC2326 (protocol - very HTTP-like, also contains URL description)
|
||||||
|
|
||||||
|
10.2 RSYNC
|
||||||
|
|
||||||
|
There's no RFC for protocol nor URI/URL format. An implementation should
|
||||||
most probably use an existing rsync library, such as librsync.
|
most probably use an existing rsync library, such as librsync.
|
||||||
|
|
||||||
CLIENT
|
10.3 RTMP
|
||||||
|
|
||||||
* Add option that is similar to -O but that takes the output file name from
|
There exists a patch that claims to introduce this protocol:
|
||||||
the Content-Disposition: header, and/or uses the local file name used in
|
http://osdir.com/ml/gnu.gnash.devel2/2006-11/msg00278.html, further details
|
||||||
|
in the feature-request: http://curl.haxx.se/bug/feature.cgi?id=1843469
|
||||||
|
|
||||||
|
11. Client
|
||||||
|
|
||||||
|
11.1 Content-Disposition
|
||||||
|
|
||||||
|
Add option that is similar to -O but that takes the output file name from the
|
||||||
|
Content-Disposition: header, and/or uses the local file name used in
|
||||||
redirections for the cases the server bounces the request further to a
|
redirections for the cases the server bounces the request further to a
|
||||||
different file (name): http://curl.haxx.se/bug/feature.cgi?id=1364676
|
different file (name): http://curl.haxx.se/bug/feature.cgi?id=1364676
|
||||||
|
|
||||||
* "curl --sync http://example.com/feed[1-100].rss" or
|
11.2 sync
|
||||||
|
|
||||||
|
"curl --sync http://example.com/feed[1-100].rss" or
|
||||||
"curl --sync http://example.net/{index,calendar,history}.html"
|
"curl --sync http://example.net/{index,calendar,history}.html"
|
||||||
|
|
||||||
Downloads a range or set of URLs using the remote name, but only if the
|
Downloads a range or set of URLs using the remote name, but only if the
|
||||||
remote file is newer than the local file. A Last-Modified HTTP date header
|
remote file is newer than the local file. A Last-Modified HTTP date header
|
||||||
should also be used to set the mod date on the downloaded file.
|
should also be used to set the mod date on the downloaded file.
|
||||||
(idea from "Brianiac")
|
|
||||||
|
|
||||||
* Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
11.3 glob posts
|
||||||
Requested by Dane Jensen and others. This is easily scripted though.
|
|
||||||
|
|
||||||
* Add an option that prevents cURL from overwriting existing local files. When
|
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
||||||
|
This is easily scripted though.
|
||||||
|
|
||||||
|
11.4 prevent file overwriting
|
||||||
|
|
||||||
|
Add an option that prevents cURL from overwriting existing local files. When
|
||||||
used, and there already is an existing file with the target file name
|
used, and there already is an existing file with the target file name
|
||||||
(either -O or -o), a number should be appended (and increased if already
|
(either -O or -o), a number should be appended (and increased if already
|
||||||
existing). So that index.html becomes first index.html.1 and then
|
existing). So that index.html becomes first index.html.1 and then
|
||||||
index.html.2 etc. Jeff Pohlmeyer suggested.
|
index.html.2 etc.
|
||||||
|
|
||||||
* "curl ftp://site.com/*.txt"
|
11.5 ftp wildcard download
|
||||||
|
|
||||||
* The client could be told to use maximum N simultaneous parallel transfers
|
"curl ftp://site.com/*.txt"
|
||||||
and then just make sure that happens. It should of course not make more
|
|
||||||
than one connection to the same remote host. This would require the client
|
|
||||||
to use the multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
|
|
||||||
|
|
||||||
* Extending the capabilities of the multipart formposting. How about leaving
|
11.6 simultaneous parallel transfers
|
||||||
|
|
||||||
|
The client could be told to use maximum N simultaneous parallel transfers and
|
||||||
|
then just make sure that happens. It should of course not make more than one
|
||||||
|
connection to the same remote host. This would require the client to use the
|
||||||
|
multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
|
||||||
|
|
||||||
|
11.7 provide formpost headers
|
||||||
|
|
||||||
|
Extending the capabilities of the multipart formposting. How about leaving
|
||||||
the ';type=foo' syntax as it is and adding an extra tag (headers) which
|
the ';type=foo' syntax as it is and adding an extra tag (headers) which
|
||||||
works like this: curl -F "coolfiles=@fil1.txt;headers=@fil1.hdr" where
|
works like this: curl -F "coolfiles=@fil1.txt;headers=@fil1.hdr" where
|
||||||
fil1.hdr contains extra headers like
|
fil1.hdr contains extra headers like
|
||||||
@@ -264,17 +452,11 @@ TODO
|
|||||||
X-User-Comment: Please don't use browser specific HTML code
|
X-User-Comment: Please don't use browser specific HTML code
|
||||||
|
|
||||||
which should overwrite the program reasonable defaults (plain/text,
|
which should overwrite the program reasonable defaults (plain/text,
|
||||||
8bit...) (Idea brough to us by kromJx)
|
8bit...)
|
||||||
|
|
||||||
* ability to specify the classic computing suffixes on the range
|
11.8 url-specific options
|
||||||
specifications. For example, to download the first 500 Kilobytes of a file,
|
|
||||||
be able to specify the following for the -r option: "-r 0-500K" or for the
|
|
||||||
first 2 Megabytes of a file: "-r 0-2M". (Mark Smith suggested)
|
|
||||||
|
|
||||||
* --data-encode that URL encodes the data before posting
|
Provide a way to make options bound to a specific URL among several on the
|
||||||
http://curl.haxx.se/mail/archive-2003-11/0091.html (Kevin Roth suggested)
|
|
||||||
|
|
||||||
* Provide a way to make options bound to a specific URL among several on the
|
|
||||||
command line. Possibly by letting ':' separate options between URLs,
|
command line. Possibly by letting ':' separate options between URLs,
|
||||||
similar to this:
|
similar to this:
|
||||||
|
|
||||||
@@ -286,32 +468,46 @@ TODO
|
|||||||
|
|
||||||
The example would do a POST-GET-POST combination on a single command line.
|
The example would do a POST-GET-POST combination on a single command line.
|
||||||
|
|
||||||
BUILD
|
12. Build
|
||||||
|
|
||||||
* Consider extending 'roffit' to produce decent ASCII output, and use that
|
12.1 roffit
|
||||||
|
|
||||||
|
Consider extending 'roffit' to produce decent ASCII output, and use that
|
||||||
instead of (g)nroff when building src/hugehelp.c
|
instead of (g)nroff when building src/hugehelp.c
|
||||||
|
|
||||||
TEST SUITE
|
13. Test suite
|
||||||
|
|
||||||
* Make our own version of stunnel for simple port forwarding to enable HTTPS
|
13.1 SSL tunnel
|
||||||
|
|
||||||
|
Make our own version of stunnel for simple port forwarding to enable HTTPS
|
||||||
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
||||||
provide test tools built with either OpenSSL or GnuTLS
|
provide test tools built with either OpenSSL or GnuTLS
|
||||||
|
|
||||||
* If perl wasn't found by the configure script, don't attempt to run the
|
13.2 nicer lacking perl message
|
||||||
tests but explain something nice why it doesn't.
|
|
||||||
|
|
||||||
* Extend the test suite to include more protocols. The telnet could just do
|
If perl wasn't found by the configure script, don't attempt to run the tests
|
||||||
ftp or http operations (for which we have test servers).
|
but explain something nice why it doesn't.
|
||||||
|
|
||||||
* Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
|
13.3 more protocols supported
|
||||||
|
|
||||||
|
Extend the test suite to include more protocols. The telnet could just do ftp
|
||||||
|
or http operations (for which we have test servers).
|
||||||
|
|
||||||
|
13.4 more platforms supported
|
||||||
|
|
||||||
|
Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
|
||||||
fork()s and it should become even more portable.
|
fork()s and it should become even more portable.
|
||||||
|
|
||||||
NEXT soname bump
|
14. Next SONAME bump
|
||||||
|
|
||||||
* #undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
|
14.1 http-style HEAD output for ftp
|
||||||
|
|
||||||
|
#undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
|
||||||
from being output in NOBODY requests over ftp
|
from being output in NOBODY requests over ftp
|
||||||
|
|
||||||
* Combine some of the error codes to remove duplicates. The original
|
14.2 combine error codes
|
||||||
|
|
||||||
|
Combine some of the error codes to remove duplicates. The original
|
||||||
numbering should not be changed, and the old identifiers would be
|
numbering should not be changed, and the old identifiers would be
|
||||||
macroed to the new ones in an CURL_NO_OLDIES section to help with
|
macroed to the new ones in an CURL_NO_OLDIES section to help with
|
||||||
backward compatibility.
|
backward compatibility.
|
||||||
@@ -327,23 +523,50 @@ TODO
|
|||||||
CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND
|
CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND
|
||||||
CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
|
CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
|
||||||
|
|
||||||
NEXT MAJOR RELEASE
|
14.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||||
|
|
||||||
* curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
The current prototype only provides 'purpose' that tells what the
|
||||||
|
connection/socket is for, but not any protocol or similar. It makes it hard
|
||||||
|
for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
|
||||||
|
similar.
|
||||||
|
|
||||||
|
15. Next major release
|
||||||
|
|
||||||
|
15.1 cleanup return codes
|
||||||
|
|
||||||
|
curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
||||||
CURLMcode. These should be changed to be the same.
|
CURLMcode. These should be changed to be the same.
|
||||||
|
|
||||||
* remove obsolete defines from curl/curl.h
|
15.2 remove obsolete defines
|
||||||
|
|
||||||
* make several functions use size_t instead of int in their APIs
|
remove obsolete defines from curl/curl.h
|
||||||
|
|
||||||
|
15.3 size_t
|
||||||
|
|
||||||
|
make several functions use size_t instead of int in their APIs
|
||||||
|
|
||||||
|
15.4 remove several functions
|
||||||
|
|
||||||
|
remove the following functions from the public API:
|
||||||
|
|
||||||
* remove the following functions from the public API:
|
|
||||||
curl_getenv
|
curl_getenv
|
||||||
|
|
||||||
curl_mprintf (and variations)
|
curl_mprintf (and variations)
|
||||||
|
|
||||||
curl_strequal
|
curl_strequal
|
||||||
|
|
||||||
curl_strnequal
|
curl_strnequal
|
||||||
|
|
||||||
They will instead become curlx_ - alternatives. That makes the curl app
|
They will instead become curlx_ - alternatives. That makes the curl app
|
||||||
still capable of building with them from source.
|
still capable of building with them from source.
|
||||||
|
|
||||||
* Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
|
15.5 remove CURLOPT_FAILONERROR
|
||||||
|
|
||||||
|
Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
|
||||||
internally. Let the app judge success or not for itself.
|
internally. Let the app judge success or not for itself.
|
||||||
|
|
||||||
|
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||||
|
|
||||||
|
Remove support for a global DNS cache. Anything global is silly, and we
|
||||||
|
already offer the share interface for the same functionality but done
|
||||||
|
"right".
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl-config 1 "25 Jan 2004" "Curl 7.15.4" "curl-config manual"
|
.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl-config \- Get information about a libcurl installation
|
curl-config \- Get information about a libcurl installation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -62,6 +62,9 @@ the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
|
|||||||
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
|
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
|
||||||
be listed using uppercase and are separated by newlines. There may be none,
|
be listed using uppercase and are separated by newlines. There may be none,
|
||||||
one or several protocols in the list. (Added in 7.13.0)
|
one or several protocols in the list. (Added in 7.13.0)
|
||||||
|
.IP "--static-libs"
|
||||||
|
Shows the complete set of libs and other linker options you will need in order
|
||||||
|
to link your application with libcurl statically. (Added in 7.17.1)
|
||||||
.IP "--version"
|
.IP "--version"
|
||||||
Outputs version information about the installed libcurl.
|
Outputs version information about the installed libcurl.
|
||||||
.IP "--vernum"
|
.IP "--vernum"
|
||||||
|
|||||||
241
docs/curl.1
241
docs/curl.1
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "28 Feb 2007" "Curl 7.16.2" "Curl Manual"
|
.TH curl 1 "5 Jan 2008" "Curl 7.18.0" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -35,7 +35,7 @@ FILE). The command is designed to work without user interaction.
|
|||||||
|
|
||||||
curl offers a busload of useful tricks like proxy support, user
|
curl offers a busload of useful tricks like proxy support, user
|
||||||
authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer
|
authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer
|
||||||
resume and more. As you will see below, the amount of features will make your
|
resume and more. As you will see below, the number of features will make your
|
||||||
head spin!
|
head spin!
|
||||||
|
|
||||||
curl is powered by libcurl for all transfer-related features. See
|
curl is powered by libcurl for all transfer-related features. See
|
||||||
@@ -82,7 +82,7 @@ specified on a single command line and cannot be used between separate curl
|
|||||||
invokes.
|
invokes.
|
||||||
.SH "PROGRESS METER"
|
.SH "PROGRESS METER"
|
||||||
curl normally displays a progress meter during operations, indicating amount
|
curl normally displays a progress meter during operations, indicating amount
|
||||||
of transfered data, transfer speeds and estimated time left etc.
|
of transferred data, transfer speeds and estimated time left etc.
|
||||||
|
|
||||||
However, since curl displays data to the terminal by default, if you invoke
|
However, since curl displays data to the terminal by default, if you invoke
|
||||||
curl to do an operation and it is about to write data to the terminal, it
|
curl to do an operation and it is about to write data to the terminal, it
|
||||||
@@ -106,8 +106,8 @@ file instead of overwriting it. If the file doesn't exist, it will be created.
|
|||||||
If this option is used twice, the second one will disable append mode again.
|
If this option is used twice, the second one will disable append mode again.
|
||||||
.IP "-A/--user-agent <agent string>"
|
.IP "-A/--user-agent <agent string>"
|
||||||
(HTTP) Specify the User-Agent string to send to the HTTP server. Some badly
|
(HTTP) Specify the User-Agent string to send to the HTTP server. Some badly
|
||||||
done CGIs fail if its not set to "Mozilla/4.0". To encode blanks in the
|
done CGIs fail if this field isn't set to "Mozilla/4.0". To encode blanks in
|
||||||
string, surround the string with single quote marks. This can also be set
|
the string, surround the string with single quote marks. This can also be set
|
||||||
with the \fI-H/--header\fP option of course.
|
with the \fI-H/--header\fP option of course.
|
||||||
|
|
||||||
If this option is set more than once, the last one will be the one that's
|
If this option is set more than once, the last one will be the one that's
|
||||||
@@ -115,10 +115,10 @@ used.
|
|||||||
.IP "--anyauth"
|
.IP "--anyauth"
|
||||||
(HTTP) Tells curl to figure out authentication method by itself, and use the
|
(HTTP) Tells curl to figure out authentication method by itself, and use the
|
||||||
most secure one the remote site claims it supports. This is done by first
|
most secure one the remote site claims it supports. This is done by first
|
||||||
doing a request and checking the response-headers, thus inducing an extra
|
doing a request and checking the response-headers, thus possibly inducing an
|
||||||
network round-trip. This is used instead of setting a specific authentication
|
extra network round-trip. This is used instead of setting a specific
|
||||||
method, which you can do with \fI--basic\fP, \fI--digest\fP, \fI--ntlm\fP, and
|
authentication method, which you can do with \fI--basic\fP, \fI--digest\fP,
|
||||||
\fI--negotiate\fP.
|
\fI--ntlm\fP, and \fI--negotiate\fP.
|
||||||
|
|
||||||
Note that using --anyauth is not recommended if you do uploads from stdin,
|
Note that using --anyauth is not recommended if you do uploads from stdin,
|
||||||
since it may require data to be sent twice and then the client must be able to
|
since it may require data to be sent twice and then the client must be able to
|
||||||
@@ -224,43 +224,63 @@ To create remote directories when using FTP or SFTP, try
|
|||||||
If this option is used several times, the following occurrences make no
|
If this option is used several times, the following occurrences make no
|
||||||
difference.
|
difference.
|
||||||
.IP "-d/--data <data>"
|
.IP "-d/--data <data>"
|
||||||
(HTTP) Sends the specified data in a POST request to the HTTP server, in a way
|
(HTTP) Sends the specified data in a POST request to the HTTP server, in the
|
||||||
that can emulate as if a user has filled in a HTML form and pressed the submit
|
same way that a browser does when a user has filled in an HTML form and
|
||||||
button. Note that the data is sent exactly as specified with no extra
|
presses the submit button. This will cause curl to pass the data to the server
|
||||||
processing (with all newlines cut off). The data is expected to be
|
using the content-type application/x-www-form-urlencoded. Compare to
|
||||||
\&"url-encoded". This will cause curl to pass the data to the server using the
|
\fI-F/--form\fP.
|
||||||
content-type application/x-www-form-urlencoded. Compare to \fI-F/--form\fP. If
|
|
||||||
this option is used more than once on the same command line, the data pieces
|
\fI-d/--data\fP is the same as \fI--data-ascii\fP. To post data purely binary,
|
||||||
specified will be merged together with a separating &-letter. Thus, using '-d
|
you should instead use the \fI--data-binary\fP option. To URL encode the value
|
||||||
name=daniel -d skill=lousy' would generate a post chunk that looks like
|
of a form field you may use \fI--data-urlencode\fP.
|
||||||
\&'name=daniel&skill=lousy'.
|
|
||||||
|
If any of these options is used more than once on the same command line, the
|
||||||
|
data pieces specified will be merged together with a separating
|
||||||
|
&-letter. Thus, using '-d name=daniel -d skill=lousy' would generate a post
|
||||||
|
chunk that looks like \&'name=daniel&skill=lousy'.
|
||||||
|
|
||||||
If you start the data with the letter @, the rest should be a file name to
|
If you start the data with the letter @, the rest should be a file name to
|
||||||
read the data from, or - if you want curl to read the data from stdin. The
|
read the data from, or - if you want curl to read the data from stdin. The
|
||||||
contents of the file must already be url-encoded. Multiple files can also be
|
contents of the file must already be url-encoded. Multiple files can also be
|
||||||
specified. Posting data from a file named 'foobar' would thus be done with
|
specified. Posting data from a file named 'foobar' would thus be done with
|
||||||
\fI--data\fP @foobar".
|
\fI--data @foobar\fP.
|
||||||
|
|
||||||
To post data purely binary, you should instead use the \fI--data-binary\fP
|
|
||||||
option.
|
|
||||||
|
|
||||||
\fI-d/--data\fP is the same as \fI--data-ascii\fP.
|
|
||||||
|
|
||||||
If this option is used several times, the ones following the first will
|
|
||||||
append data.
|
|
||||||
.IP "--data-ascii <data>"
|
|
||||||
(HTTP) This is an alias for the \fI-d/--data\fP option.
|
|
||||||
|
|
||||||
If this option is used several times, the ones following the first will
|
|
||||||
append data.
|
|
||||||
.IP "--data-binary <data>"
|
.IP "--data-binary <data>"
|
||||||
(HTTP) This posts data in a similar manner as \fI--data-ascii\fP does,
|
(HTTP) This posts data exactly as specified with no extra processing
|
||||||
although when using this option the entire context of the posted data is kept
|
whatsoever.
|
||||||
as-is. If you want to post a binary file without the strip-newlines feature of
|
|
||||||
the \fI--data-ascii\fP option, this is for you.
|
|
||||||
|
|
||||||
If this option is used several times, the ones following the first will
|
If you start the data with the letter @, the rest should be a filename. Data
|
||||||
append data.
|
is posted in a similar manner as \fI--data-ascii\fP does, except that newlines
|
||||||
|
are preserved and conversions are never done.
|
||||||
|
|
||||||
|
If this option is used several times, the ones following the first will append
|
||||||
|
data. As described in \fI-d/--data\fP.
|
||||||
|
.IP "--data-urlencode <data>"
|
||||||
|
(HTTP) This posts data, similar to the other --data options with the exception
|
||||||
|
that this performs URL encoding. (Added in 7.18.0)
|
||||||
|
|
||||||
|
To be CGI compliant, the <data> part should begin with a \fIname\fP followed
|
||||||
|
by a separator and a content specification. The <data> part can be passed to
|
||||||
|
curl using one of the following syntaxes:
|
||||||
|
.RS
|
||||||
|
.IP "content"
|
||||||
|
This will make curl URL encode the content and pass that on. Just be careful
|
||||||
|
so that the content doesn't contain any = or @ letters, as that will then make
|
||||||
|
the syntax match one of the other cases below!
|
||||||
|
.IP "=content"
|
||||||
|
This will make curl URL encode the content and pass that on. The preceding =
|
||||||
|
letter is not included in the data.
|
||||||
|
.IP "name=content"
|
||||||
|
This will make curl URL encode the content part and pass that on. Note that
|
||||||
|
the name part is expected to be URL encoded already.
|
||||||
|
.IP "@filename"
|
||||||
|
This will make curl load data from the given file (including any newlines),
|
||||||
|
URL encode that data and pass it on in the POST.
|
||||||
|
.IP "name@filename"
|
||||||
|
This will make curl load data from the given file (including any newlines),
|
||||||
|
URL encode that data and pass it on in the POST. The name part gets an equal
|
||||||
|
sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the
|
||||||
|
name is expected to be URL encoded already.
|
||||||
|
.RE
|
||||||
.IP "--digest"
|
.IP "--digest"
|
||||||
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
||||||
prevents the password from being sent over the wire in clear text. Use this in
|
prevents the password from being sent over the wire in clear text. Use this in
|
||||||
@@ -330,7 +350,9 @@ them independently.
|
|||||||
|
|
||||||
If curl is built against the NSS SSL library then this option tells
|
If curl is built against the NSS SSL library then this option tells
|
||||||
curl the nickname of the certificate to use within the NSS database defined
|
curl the nickname of the certificate to use within the NSS database defined
|
||||||
by --cacert.
|
by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
|
||||||
|
NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
|
||||||
|
loaded.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--cert-type <type>"
|
.IP "--cert-type <type>"
|
||||||
@@ -339,9 +361,10 @@ DER and ENG are recognized types. If not specified, PEM is assumed.
|
|||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--cacert <CA certificate>"
|
.IP "--cacert <CA certificate>"
|
||||||
(SSL) Tells curl to use the specified certificate file to verify the
|
(SSL) Tells curl to use the specified certificate file to verify the peer. The
|
||||||
peer. The file may contain multiple CA certificates. The certificate(s) must
|
file may contain multiple CA certificates. The certificate(s) must be in PEM
|
||||||
be in PEM format.
|
format. Normally curl is built to use a default file for this, so this option
|
||||||
|
is typically used to alter that default file.
|
||||||
|
|
||||||
curl recognizes the environment variable named 'CURL_CA_BUNDLE' if that is
|
curl recognizes the environment variable named 'CURL_CA_BUNDLE' if that is
|
||||||
set, and uses the given path as a path to a CA cert bundle. This option
|
set, and uses the given path as a path to a CA cert bundle. This option
|
||||||
@@ -352,7 +375,10 @@ The windows version of curl will automatically look for a CA certs file named
|
|||||||
Current Working Directory, or in any folder along your PATH.
|
Current Working Directory, or in any folder along your PATH.
|
||||||
|
|
||||||
If curl is built against the NSS SSL library then this option tells
|
If curl is built against the NSS SSL library then this option tells
|
||||||
curl the directory that the NSS certificate database resides in.
|
curl the nickname of the CA certificate to use within the NSS database
|
||||||
|
defined by the environment variable SSL_DIR (or by default /etc/pki/nssdb).
|
||||||
|
If the NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files
|
||||||
|
may be loaded.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--capath <CA certificate directory>"
|
.IP "--capath <CA certificate directory>"
|
||||||
@@ -383,9 +409,10 @@ has been provided, this data is sent off using the ACCT command. (Added in
|
|||||||
|
|
||||||
If this option is used twice, the second will override the previous use.
|
If this option is used twice, the second will override the previous use.
|
||||||
.IP "--ftp-create-dirs"
|
.IP "--ftp-create-dirs"
|
||||||
(FTP) When an FTP or SFTP URL/operation uses a path that doesn't currently exist on
|
(FTP/SFTP) When an FTP or SFTP URL/operation uses a path that doesn't
|
||||||
the server, the standard behavior of curl is to fail. Using this option, curl
|
currently exist on the server, the standard behavior of curl is to
|
||||||
will instead attempt to create missing directories.
|
fail. Using this option, curl will instead attempt to create missing
|
||||||
|
directories.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable directory creation.
|
If this option is used twice, the second will again disable directory creation.
|
||||||
.IP "--ftp-method [method]"
|
.IP "--ftp-method [method]"
|
||||||
@@ -539,6 +566,11 @@ for you.
|
|||||||
See also the \fI-A/--user-agent\fP and \fI-e/--referer\fP options.
|
See also the \fI-A/--user-agent\fP and \fI-e/--referer\fP options.
|
||||||
|
|
||||||
This option can be used multiple times to add/replace/remove multiple headers.
|
This option can be used multiple times to add/replace/remove multiple headers.
|
||||||
|
.IP "--hostpubmd5"
|
||||||
|
Pass a string containing 32 hexadecimal digits. The string should be the 128
|
||||||
|
bit MD5 checksum of the remote host's public key, curl will refuse the
|
||||||
|
connection with the host unless the md5sums match. This option is only for SCP
|
||||||
|
and SFTP transfers. (Added in 7.17.1)
|
||||||
.IP "--ignore-content-length"
|
.IP "--ignore-content-length"
|
||||||
(HTTP)
|
(HTTP)
|
||||||
Ignore the Content-Length header. This is particularly useful for servers
|
Ignore the Content-Length header. This is particularly useful for servers
|
||||||
@@ -582,6 +614,14 @@ See this online resource for further details:
|
|||||||
\fBhttp://curl.haxx.se/docs/sslcerts.html\fP
|
\fBhttp://curl.haxx.se/docs/sslcerts.html\fP
|
||||||
|
|
||||||
If this option is used twice, the second time will again disable it.
|
If this option is used twice, the second time will again disable it.
|
||||||
|
.IP "--keepalive-time <seconds>"
|
||||||
|
This option sets the time a connection needs to remain idle before sending
|
||||||
|
keepalive probes and the time between individual keepalive probes. It is
|
||||||
|
currently effective on operating systems offering the TCP_KEEPIDLE and
|
||||||
|
TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This
|
||||||
|
option has no effect if \fI--no-keepalive\fP is used. (Added in 7.18.0)
|
||||||
|
|
||||||
|
If this option is used multiple times, the last occurrence sets the amount.
|
||||||
.IP "--key <key>"
|
.IP "--key <key>"
|
||||||
(SSL/SSH) Private key file name. Allows you to provide your private key in this
|
(SSL/SSH) Private key file name. Allows you to provide your private key in this
|
||||||
separate file.
|
separate file.
|
||||||
@@ -607,8 +647,12 @@ If this option is used several times, the last one will be used.
|
|||||||
Specify which config file to read curl arguments from. The config file is a
|
Specify which config file to read curl arguments from. The config file is a
|
||||||
text file in which command line arguments can be written which then will be
|
text file in which command line arguments can be written which then will be
|
||||||
used as if they were written on the actual command line. Options and their
|
used as if they were written on the actual command line. Options and their
|
||||||
parameters must be specified on the same config file line. If the parameter is
|
parameters must be specified on the same config file line, separated by
|
||||||
to contain white spaces, the parameter must be enclosed within quotes. If the
|
white space, colon, the equals sign or any combination thereof (however,
|
||||||
|
the preferred separator is the equals sign). If the parameter is to contain
|
||||||
|
white spaces, the parameter must be enclosed within quotes. Within double
|
||||||
|
quotes, the following escape sequences are available: \\\\, \\", \\t, \\n,
|
||||||
|
\\r and \\v. A backlash preceding any other letter is ignored. If the
|
||||||
first column of a config line is a '#' character, the rest of the line will be
|
first column of a config line is a '#' character, the rest of the line will be
|
||||||
treated as a comment. Only write one option per physical line in the config
|
treated as a comment. Only write one option per physical line in the config
|
||||||
file.
|
file.
|
||||||
@@ -663,7 +707,8 @@ NOTE: this does not properly support -F and the sending of multipart
|
|||||||
formposts, so in those cases the output program will be missing necessary
|
formposts, so in those cases the output program will be missing necessary
|
||||||
calls to \fIcurl_formadd(3)\fP, and possibly more.
|
calls to \fIcurl_formadd(3)\fP, and possibly more.
|
||||||
|
|
||||||
If this option is used several times, the last given file name will be used.
|
If this option is used several times, the last given file name will be
|
||||||
|
used. (Added in 7.16.1)
|
||||||
.IP "--limit-rate <speed>"
|
.IP "--limit-rate <speed>"
|
||||||
Specify the maximum transfer rate you want curl to use. This feature is useful
|
Specify the maximum transfer rate you want curl to use. This feature is useful
|
||||||
if you have a limited pipe and you'd like your transfer not use your entire
|
if you have a limited pipe and you'd like your transfer not use your entire
|
||||||
@@ -769,6 +814,9 @@ meant as a support for Kerberos5 authentication but may be also used along
|
|||||||
with another authentication methods. For more information see IETF draft
|
with another authentication methods. For more information see IETF draft
|
||||||
draft-brezak-spnego-http-04.txt.
|
draft-brezak-spnego-http-04.txt.
|
||||||
|
|
||||||
|
If you want to enable Negotiate for your proxy authentication, then use
|
||||||
|
\fI--proxy-negotiate\fP.
|
||||||
|
|
||||||
This option requires that the library was built with GSSAPI support. This is
|
This option requires that the library was built with GSSAPI support. This is
|
||||||
not very common. Use \fI-V/--version\fP to see if your version supports
|
not very common. Use \fI-V/--version\fP to see if your version supports
|
||||||
GSS-Negotiate.
|
GSS-Negotiate.
|
||||||
@@ -786,6 +834,11 @@ will output the data in chunks, not necessarily exactly when the data arrives.
|
|||||||
Using this option will disable that buffering.
|
Using this option will disable that buffering.
|
||||||
|
|
||||||
If this option is used twice, the second will again switch on buffering.
|
If this option is used twice, the second will again switch on buffering.
|
||||||
|
.IP "--no-keepalive"
|
||||||
|
Disables the use of keepalive messages on the TCP connection, as by default
|
||||||
|
curl enables them.
|
||||||
|
|
||||||
|
If this option is used twice, the second will again enable keepalive.
|
||||||
.IP "--no-sessionid"
|
.IP "--no-sessionid"
|
||||||
(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
|
(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
|
||||||
are done using the cache. Note that while nothing ever should get hurt by
|
are done using the cache. Note that while nothing ever should get hurt by
|
||||||
@@ -839,9 +892,16 @@ You may use this option as many times as you have number of URLs.
|
|||||||
(SSL/SSH) Pass phrase for the private key
|
(SSL/SSH) Pass phrase for the private key
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
|
.IP "--post301"
|
||||||
|
Tells curl to respect RFC 2616/10.3.2 and not convert POST requests into GET
|
||||||
|
requests when following a 301 redirection. The non-RFC behaviour is ubiquitous
|
||||||
|
in web browsers, so curl does the conversion by default to maintain
|
||||||
|
consistency. However, a server may requires a POST to remain a POST after such
|
||||||
|
a redirection. This option is meaningful only when using \fI-L/--location\fP
|
||||||
|
(Added in 7.17.1)
|
||||||
.IP "--proxy-anyauth"
|
.IP "--proxy-anyauth"
|
||||||
Tells curl to pick a suitable authentication method when communicating with
|
Tells curl to pick a suitable authentication method when communicating with
|
||||||
the given proxy. This will cause an extra request/response round-trip. (Added
|
the given proxy. This might cause an extra request/response round-trip. (Added
|
||||||
in 7.13.2)
|
in 7.13.2)
|
||||||
|
|
||||||
If this option is used twice, the second will again disable the proxy use-any
|
If this option is used twice, the second will again disable the proxy use-any
|
||||||
@@ -858,6 +918,13 @@ Tells curl to use HTTP Digest authentication when communicating with the given
|
|||||||
proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
|
proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable proxy HTTP Digest.
|
If this option is used twice, the second will again disable proxy HTTP Digest.
|
||||||
|
.IP "--proxy-negotiate"
|
||||||
|
Tells curl to use HTTP Negotiate authentication when communicating
|
||||||
|
with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate
|
||||||
|
with a remote host.
|
||||||
|
|
||||||
|
If this option is used twice, the second will again disable proxy HTTP
|
||||||
|
Negotiate. (Added in 7.17.1)
|
||||||
.IP "--proxy-ntlm"
|
.IP "--proxy-ntlm"
|
||||||
Tells curl to use HTTP NTLM authentication when communicating with the given
|
Tells curl to use HTTP NTLM authentication when communicating with the given
|
||||||
proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host.
|
proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host.
|
||||||
@@ -921,9 +988,9 @@ This option can be used multiple times.
|
|||||||
random data. The data is used to seed the random engine for SSL connections.
|
random data. The data is used to seed the random engine for SSL connections.
|
||||||
See also the \fI--egd-file\fP option.
|
See also the \fI--egd-file\fP option.
|
||||||
.IP "-r/--range <range>"
|
.IP "-r/--range <range>"
|
||||||
(HTTP/FTP)
|
(HTTP/FTP/FILE) Retrieve a byte range (i.e a partial document) from a
|
||||||
Retrieve a byte range (i.e a partial document) from a HTTP/1.1 or FTP
|
HTTP/1.1, FTP server or a local FILE. Ranges can be specified in a number of
|
||||||
server. Ranges can be specified in a number of ways.
|
ways.
|
||||||
.RS
|
.RS
|
||||||
.TP 10
|
.TP 10
|
||||||
.B 0-499
|
.B 0-499
|
||||||
@@ -1022,9 +1089,28 @@ This option overrides any previous use of \fI-x/--proxy\fP, as they are
|
|||||||
mutually exclusive.
|
mutually exclusive.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
|
.IP "--socks4a <host[:port]>"
|
||||||
|
Use the specified SOCKS4a proxy. If the port number is not specified, it is
|
||||||
|
assumed at port 1080. (Added in 7.18.0)
|
||||||
|
|
||||||
|
This option overrides any previous use of \fI-x/--proxy\fP, as they are
|
||||||
|
mutually exclusive.
|
||||||
|
|
||||||
|
If this option is used several times, the last one will be used.
|
||||||
|
.IP "--socks5-hostname <host[:port]>"
|
||||||
|
Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If
|
||||||
|
the port number is not specified, it is assumed at port 1080. (Added in
|
||||||
|
7.18.0)
|
||||||
|
|
||||||
|
This option overrides any previous use of \fI-x/--proxy\fP, as they are
|
||||||
|
mutually exclusive.
|
||||||
|
|
||||||
|
If this option is used several times, the last one will be used. (This option
|
||||||
|
was previously wrongly documented and used as --socks without the number
|
||||||
|
appended.)
|
||||||
.IP "--socks5 <host[:port]>"
|
.IP "--socks5 <host[:port]>"
|
||||||
Use the specified SOCKS5 proxy. If the port number is not specified, it is
|
Use the specified SOCKS5 proxy - but resolve the host name locally. If the
|
||||||
assumed at port 1080. (Added in 7.11.1)
|
port number is not specified, it is assumed at port 1080.
|
||||||
|
|
||||||
This option overrides any previous use of \fI-x/--proxy\fP, as they are
|
This option overrides any previous use of \fI-x/--proxy\fP, as they are
|
||||||
mutually exclusive.
|
mutually exclusive.
|
||||||
@@ -1101,6 +1187,9 @@ If this option is used several times, each occurrence will toggle it on/off.
|
|||||||
Specify user and password to use for server authentication. Overrides
|
Specify user and password to use for server authentication. Overrides
|
||||||
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
|
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
|
||||||
|
|
||||||
|
If you just give the user name (without entering a colon) curl will prompt for
|
||||||
|
a password.
|
||||||
|
|
||||||
If you use an SSPI-enabled curl binary and do NTLM authentication, you can
|
If you use an SSPI-enabled curl binary and do NTLM authentication, you can
|
||||||
force curl to pick up the user name and password from your environment by
|
force curl to pick up the user name and password from your environment by
|
||||||
simply specifying a single colon with this option: "-u :".
|
simply specifying a single colon with this option: "-u :".
|
||||||
@@ -1381,8 +1470,6 @@ Unsupported protocol. This build of curl has no support for this protocol.
|
|||||||
Failed to initialize.
|
Failed to initialize.
|
||||||
.IP 3
|
.IP 3
|
||||||
URL malformat. The syntax was not correct.
|
URL malformat. The syntax was not correct.
|
||||||
.IP 4
|
|
||||||
URL user malformatted. The user-part of the URL syntax was not correct.
|
|
||||||
.IP 5
|
.IP 5
|
||||||
Couldn't resolve proxy. The given proxy host could not be resolved.
|
Couldn't resolve proxy. The given proxy host could not be resolved.
|
||||||
.IP 6
|
.IP 6
|
||||||
@@ -1395,21 +1482,14 @@ FTP weird server reply. The server sent data curl couldn't parse.
|
|||||||
FTP access denied. The server denied login or denied access to the particular
|
FTP access denied. The server denied login or denied access to the particular
|
||||||
resource or directory you wanted to reach. Most often you tried to change to a
|
resource or directory you wanted to reach. Most often you tried to change to a
|
||||||
directory that doesn't exist on the server.
|
directory that doesn't exist on the server.
|
||||||
.IP 10
|
|
||||||
FTP user/password incorrect. Either one or both were not accepted by the
|
|
||||||
server.
|
|
||||||
.IP 11
|
.IP 11
|
||||||
FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request.
|
FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request.
|
||||||
.IP 12
|
|
||||||
FTP weird USER reply. Curl couldn't parse the reply sent to the USER request.
|
|
||||||
.IP 13
|
.IP 13
|
||||||
FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request.
|
FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request.
|
||||||
.IP 14
|
.IP 14
|
||||||
FTP weird 227 format. Curl couldn't parse the 227-line the server sent.
|
FTP weird 227 format. Curl couldn't parse the 227-line the server sent.
|
||||||
.IP 15
|
.IP 15
|
||||||
FTP can't get host. Couldn't resolve the host IP we got in the 227-line.
|
FTP can't get host. Couldn't resolve the host IP we got in the 227-line.
|
||||||
.IP 16
|
|
||||||
FTP can't reconnect. Couldn't connect to the host we got in the 227-line.
|
|
||||||
.IP 17
|
.IP 17
|
||||||
FTP couldn't set binary. Couldn't change transfer method to binary.
|
FTP couldn't set binary. Couldn't change transfer method to binary.
|
||||||
.IP 18
|
.IP 18
|
||||||
@@ -1417,8 +1497,6 @@ Partial file. Only a part of the file was transferred.
|
|||||||
.IP 19
|
.IP 19
|
||||||
FTP couldn't download/access the given file, the RETR (or similar) command
|
FTP couldn't download/access the given file, the RETR (or similar) command
|
||||||
failed.
|
failed.
|
||||||
.IP 20
|
|
||||||
FTP write error. The transfer was reported bad by the server.
|
|
||||||
.IP 21
|
.IP 21
|
||||||
FTP quote error. A quote command returned error from the server.
|
FTP quote error. A quote command returned error from the server.
|
||||||
.IP 22
|
.IP 22
|
||||||
@@ -1427,8 +1505,6 @@ error with the HTTP error code being 400 or above. This return code only
|
|||||||
appears if \fI-f/--fail\fP is used.
|
appears if \fI-f/--fail\fP is used.
|
||||||
.IP 23
|
.IP 23
|
||||||
Write error. Curl couldn't write data to a local filesystem or similar.
|
Write error. Curl couldn't write data to a local filesystem or similar.
|
||||||
.IP 24
|
|
||||||
Malformed user. User name badly specified.
|
|
||||||
.IP 25
|
.IP 25
|
||||||
FTP couldn't STOR file. The server denied the STOR operation, used for FTP
|
FTP couldn't STOR file. The server denied the STOR operation, used for FTP
|
||||||
uploading.
|
uploading.
|
||||||
@@ -1439,17 +1515,12 @@ Out of memory. A memory allocation request failed.
|
|||||||
.IP 28
|
.IP 28
|
||||||
Operation timeout. The specified time-out period was reached according to the
|
Operation timeout. The specified time-out period was reached according to the
|
||||||
conditions.
|
conditions.
|
||||||
.IP 29
|
|
||||||
FTP couldn't set ASCII. The server returned an unknown reply.
|
|
||||||
.IP 30
|
.IP 30
|
||||||
FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT
|
FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT
|
||||||
command, try doing a transfer using PASV instead!
|
command, try doing a transfer using PASV instead!
|
||||||
.IP 31
|
.IP 31
|
||||||
FTP couldn't use REST. The REST command failed. This command is used for
|
FTP couldn't use REST. The REST command failed. This command is used for
|
||||||
resumed FTP transfers.
|
resumed FTP transfers.
|
||||||
.IP 32
|
|
||||||
FTP couldn't use SIZE. The SIZE command failed. The command is an extension
|
|
||||||
to the original FTP spec RFC 959.
|
|
||||||
.IP 33
|
.IP 33
|
||||||
HTTP range error. The range "command" didn't work.
|
HTTP range error. The range "command" didn't work.
|
||||||
.IP 34
|
.IP 34
|
||||||
@@ -1464,20 +1535,14 @@ FILE couldn't read file. Failed to open the file. Permissions?
|
|||||||
LDAP cannot bind. LDAP bind operation failed.
|
LDAP cannot bind. LDAP bind operation failed.
|
||||||
.IP 39
|
.IP 39
|
||||||
LDAP search failed.
|
LDAP search failed.
|
||||||
.IP 40
|
|
||||||
Library not found. The LDAP library was not found.
|
|
||||||
.IP 41
|
.IP 41
|
||||||
Function not found. A required LDAP function was not found.
|
Function not found. A required LDAP function was not found.
|
||||||
.IP 42
|
.IP 42
|
||||||
Aborted by callback. An application told curl to abort the operation.
|
Aborted by callback. An application told curl to abort the operation.
|
||||||
.IP 43
|
.IP 43
|
||||||
Internal error. A function was called with a bad parameter.
|
Internal error. A function was called with a bad parameter.
|
||||||
.IP 44
|
|
||||||
Internal error. A function was called in a bad order.
|
|
||||||
.IP 45
|
.IP 45
|
||||||
Interface error. A specified outgoing interface could not be used.
|
Interface error. A specified outgoing interface could not be used.
|
||||||
.IP 46
|
|
||||||
Bad password entered. An error was signalled when the password was entered.
|
|
||||||
.IP 47
|
.IP 47
|
||||||
Too many redirects. When following redirects, curl hit the maximum amount.
|
Too many redirects. When following redirects, curl hit the maximum amount.
|
||||||
.IP 48
|
.IP 48
|
||||||
@@ -1485,7 +1550,7 @@ Unknown TELNET option specified.
|
|||||||
.IP 49
|
.IP 49
|
||||||
Malformed telnet option.
|
Malformed telnet option.
|
||||||
.IP 51
|
.IP 51
|
||||||
The remote peer's SSL certificate wasn't ok
|
The peer's SSL certificate or SSH MD5 fingerprint was not ok
|
||||||
.IP 52
|
.IP 52
|
||||||
The server didn't reply anything, which here is considered an error.
|
The server didn't reply anything, which here is considered an error.
|
||||||
.IP 53
|
.IP 53
|
||||||
@@ -1496,14 +1561,12 @@ Cannot set SSL crypto engine as default
|
|||||||
Failed sending network data
|
Failed sending network data
|
||||||
.IP 56
|
.IP 56
|
||||||
Failure in receiving network data
|
Failure in receiving network data
|
||||||
.IP 57
|
|
||||||
Share is in use (internal error)
|
|
||||||
.IP 58
|
.IP 58
|
||||||
Problem with the local certificate
|
Problem with the local certificate
|
||||||
.IP 59
|
.IP 59
|
||||||
Couldn't use specified SSL cipher
|
Couldn't use specified SSL cipher
|
||||||
.IP 60
|
.IP 60
|
||||||
Problem with the CA cert (path? permission?)
|
Peer certificate cannot be authenticated with known CA certificates
|
||||||
.IP 61
|
.IP 61
|
||||||
Unrecognized transfer encoding
|
Unrecognized transfer encoding
|
||||||
.IP 62
|
.IP 62
|
||||||
@@ -1536,6 +1599,14 @@ No such user (TFTP)
|
|||||||
Character conversion failed
|
Character conversion failed
|
||||||
.IP 76
|
.IP 76
|
||||||
Character conversion functions required
|
Character conversion functions required
|
||||||
|
.IP 77
|
||||||
|
Problem with reading the SSL CA cert (path? access rights?)
|
||||||
|
.IP 78
|
||||||
|
The resource referenced in the URL does not exist
|
||||||
|
.IP 79
|
||||||
|
An unspecified error occurred during the SSH session
|
||||||
|
.IP 80
|
||||||
|
Failed to shut down the SSL connection
|
||||||
.IP XX
|
.IP XX
|
||||||
There will appear more error codes here in future releases. The existing ones
|
There will appear more error codes here in future releases. The existing ones
|
||||||
are meant to never change.
|
are meant to never change.
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <curl/multi.h>
|
#include <curl/multi.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *urls[] = {
|
static const char *urls[] = {
|
||||||
"http://www.microsoft.com",
|
"http://www.microsoft.com",
|
||||||
@@ -74,7 +77,7 @@ static const char *urls[] = {
|
|||||||
#define MAX 10 /* number of simultaneous transfers */
|
#define MAX 10 /* number of simultaneous transfers */
|
||||||
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
|
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
|
||||||
|
|
||||||
static int cb(char *d, size_t n, size_t l, void *p)
|
static size_t cb(char *d, size_t n, size_t l, void *p)
|
||||||
{
|
{
|
||||||
/* take care of the data here, ignored in this example */
|
/* take care of the data here, ignored in this example */
|
||||||
(void)d;
|
(void)d;
|
||||||
@@ -138,7 +141,11 @@ int main(void)
|
|||||||
L = 100;
|
L = 100;
|
||||||
|
|
||||||
if (M == -1) {
|
if (M == -1) {
|
||||||
|
#ifdef WIN32
|
||||||
|
Sleep(L);
|
||||||
|
#else
|
||||||
sleep(L / 1000);
|
sleep(L / 1000);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
T.tv_sec = L/1000;
|
T.tv_sec = L/1000;
|
||||||
T.tv_usec = (L%1000)*1000;
|
T.tv_usec = (L%1000)*1000;
|
||||||
|
|||||||
@@ -4,27 +4,24 @@
|
|||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||||
|
|
||||||
EXTRA_DIST = README Makefile.example makefile.dj $(COMPLICATED_EXAMPLES)
|
EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
|
||||||
|
makefile.dj $(COMPLICATED_EXAMPLES)
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)/include
|
INCLUDES = -I$(top_srcdir)/include
|
||||||
|
|
||||||
LIBDIR = $(top_builddir)/lib
|
LIBDIR = $(top_builddir)/lib
|
||||||
|
|
||||||
|
if STATICLIB
|
||||||
|
# we need this define when building with a static lib on Windows
|
||||||
|
STATICCPPFLAGS = -DCURL_STATICLIB
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPFLAGS = -DCURL_NO_OLDIES $(STATICCPPFLAGS)
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
LDADD = $(LIBDIR)/libcurl.la
|
LDADD = $(LIBDIR)/libcurl.la
|
||||||
|
|
||||||
# These are all libcurl example programs to be test compiled
|
# Makefile.inc provides the noinst_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||||
noinst_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
|
include Makefile.inc
|
||||||
debug fileupload fopen ftpget ftpgetresp ftpupload \
|
|
||||||
getinfo getinmemory http-post httpput \
|
|
||||||
https multi-app multi-debugcallback multi-double \
|
|
||||||
multi-post multi-single persistant post-callback \
|
|
||||||
postit2 sepheaders simple simplepost simplessl
|
|
||||||
|
|
||||||
# These examples require external dependencies that may not be commonly
|
|
||||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
|
||||||
COMPLICATED_EXAMPLES = \
|
|
||||||
curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \
|
|
||||||
ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
|
||||||
opensslthreadlock.c sampleconv.c synctime.c
|
|
||||||
|
|
||||||
|
|||||||
16
docs/examples/Makefile.inc
Normal file
16
docs/examples/Makefile.inc
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# These are all libcurl example programs to be test compiled
|
||||||
|
noinst_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
|
||||||
|
debug fileupload fopen ftpget ftpgetresp ftpupload \
|
||||||
|
getinfo getinmemory http-post httpput \
|
||||||
|
https multi-app multi-debugcallback multi-double \
|
||||||
|
multi-post multi-single persistant post-callback \
|
||||||
|
postit2 sepheaders simple simplepost simplessl
|
||||||
|
|
||||||
|
# These examples require external dependencies that may not be commonly
|
||||||
|
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||||
|
COMPLICATED_EXAMPLES = \
|
||||||
|
curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \
|
||||||
|
ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||||
|
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c
|
||||||
|
|
||||||
|
|
||||||
135
docs/examples/Makefile.m32
Normal file
135
docs/examples/Makefile.m32
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
#########################################################################
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
## Makefile for building curl examples with MingW32
|
||||||
|
## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3)
|
||||||
|
##
|
||||||
|
## Usage:
|
||||||
|
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1]
|
||||||
|
##
|
||||||
|
## Hint: you can also set environment vars to control the build, f.e.:
|
||||||
|
## set ZLIB_PATH=c:/zlib-1.2.3
|
||||||
|
## set ZLIB=1
|
||||||
|
##
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
|
ifndef ZLIB_PATH
|
||||||
|
ZLIB_PATH = ../../zlib-1.2.3
|
||||||
|
endif
|
||||||
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
|
ifndef OPENSSL_PATH
|
||||||
|
OPENSSL_PATH = ../../openssl-0.9.8g
|
||||||
|
endif
|
||||||
|
# Edit the path below to point to the base of your LibSSH2 package.
|
||||||
|
ifndef LIBSSH2_PATH
|
||||||
|
LIBSSH2_PATH = ../../libssh2-0.18
|
||||||
|
endif
|
||||||
|
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||||
|
ifndef LDAP_SDK
|
||||||
|
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||||
|
endif
|
||||||
|
|
||||||
|
PROOT = ../..
|
||||||
|
ARES_LIB = $(PROOT)/ares
|
||||||
|
|
||||||
|
SSL = 1
|
||||||
|
ZLIB = 1
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -g -O2 -Wall
|
||||||
|
# comment LDFLAGS below to keep debug info
|
||||||
|
LDFLAGS = -s
|
||||||
|
RC = windres
|
||||||
|
RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
|
||||||
|
RM = del /q /f > NUL 2>&1
|
||||||
|
CP = copy
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
## Nothing more to do below this line!
|
||||||
|
|
||||||
|
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
|
||||||
|
LINK = $(CC) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
curl_PROGRAMS = curl.exe
|
||||||
|
ifdef DYN
|
||||||
|
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||||
|
curl_LDADD = -L$(PROOT)/lib -lcurldll
|
||||||
|
else
|
||||||
|
curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
|
||||||
|
curl_LDADD = -L$(PROOT)/lib -lcurl
|
||||||
|
CFLAGS += -DCURL_STATICLIB
|
||||||
|
endif
|
||||||
|
ifdef ARES
|
||||||
|
ifndef DYN
|
||||||
|
curl_DEPENDENCIES += $(ARES_LIB)/libcares.a
|
||||||
|
endif
|
||||||
|
CFLAGS += -DUSE_ARES
|
||||||
|
curl_LDADD += -L$(ARES_LIB) -lcares
|
||||||
|
endif
|
||||||
|
ifdef SSH2
|
||||||
|
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||||
|
curl_LDADD += -L$(LIBSSH2_PATH)/win32 -lssh2
|
||||||
|
endif
|
||||||
|
ifdef SSL
|
||||||
|
INCLUDES += -I"$(OPENSSL_PATH)/outinc"
|
||||||
|
CFLAGS += -DUSE_SSLEAY -DHAVE_OPENSSL_ENGINE_H
|
||||||
|
ifdef DYN
|
||||||
|
curl_LDADD += -L$(OPENSSL_PATH)/out -leay32 -lssl32
|
||||||
|
else
|
||||||
|
curl_LDADD += -L$(OPENSSL_PATH)/out -lssl -lcrypto -lgdi32
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifdef ZLIB
|
||||||
|
INCLUDES += -I"$(ZLIB_PATH)"
|
||||||
|
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||||
|
curl_LDADD += -L$(ZLIB_PATH) -lz
|
||||||
|
endif
|
||||||
|
ifdef SSPI
|
||||||
|
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||||
|
endif
|
||||||
|
ifdef IPV6
|
||||||
|
CFLAGS += -DENABLE_IPV6
|
||||||
|
endif
|
||||||
|
ifdef LDAPS
|
||||||
|
CFLAGS += -DHAVE_LDAP_SSL
|
||||||
|
endif
|
||||||
|
ifdef USE_LDAP_NOVELL
|
||||||
|
CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
|
||||||
|
curl_LDADD += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
|
||||||
|
endif
|
||||||
|
ifdef USE_LDAP_OPENLDAP
|
||||||
|
CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
|
||||||
|
curl_LDADD += -L"$(LDAP_SDK)/lib" -lldap -llber
|
||||||
|
endif
|
||||||
|
ifndef USE_LDAP_NOVELL
|
||||||
|
ifndef USE_LDAP_OPENLDAP
|
||||||
|
curl_LDADD += -lwldap32
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
curl_LDADD += -lws2_32 -lwinmm
|
||||||
|
COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
|
||||||
|
|
||||||
|
# Makefile.inc provides the noinst_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||||
|
include Makefile.inc
|
||||||
|
|
||||||
|
example_PROGRAMS := $(patsubst %,%.exe,$(strip $(noinst_PROGRAMS)))
|
||||||
|
|
||||||
|
.SUFFIXES: .rc .res .o .exe
|
||||||
|
|
||||||
|
|
||||||
|
all: $(example_PROGRAMS)
|
||||||
|
|
||||||
|
.o.exe: $(curl_DEPENDENCIES)
|
||||||
|
$(LINK) $< $(curl_LDADD)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
.rc.res:
|
||||||
|
$(RC) $(RCFLAGS) $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(example_PROGRAMS)
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +40,6 @@ curlx.c - getting file info from the remote cert data
|
|||||||
debug.c - showing how to use the debug callback
|
debug.c - showing how to use the debug callback
|
||||||
fileupload.c - uploading to a file:// URL
|
fileupload.c - uploading to a file:// URL
|
||||||
fopen.c - fopen() layer that supports opening URLs and files
|
fopen.c - fopen() layer that supports opening URLs and files
|
||||||
ftp3rdparty.c - FTP 3rd party transfer
|
|
||||||
ftpget.c - simple getting a file from FTP
|
ftpget.c - simple getting a file from FTP
|
||||||
ftpgetresp.c - get the response strings from the FTP server
|
ftpgetresp.c - get the response strings from the FTP server
|
||||||
ftpupload.c - upload a file to an FTP server
|
ftpupload.c - upload a file to an FTP server
|
||||||
@@ -50,6 +49,7 @@ getinmemory.c - download a file to memory only
|
|||||||
ghiper.c - curl_multi_socket() using code with glib-2
|
ghiper.c - curl_multi_socket() using code with glib-2
|
||||||
hiperfifo.c - downloads all URLs written to the fifo, using
|
hiperfifo.c - downloads all URLs written to the fifo, using
|
||||||
curl_multi_socket() and libevent
|
curl_multi_socket() and libevent
|
||||||
|
htmltidy.c - download a document and use libtidy to parse the HTML
|
||||||
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
||||||
page using libxml
|
page using libxml
|
||||||
http-post.c - HTTP POST
|
http-post.c - HTTP POST
|
||||||
@@ -60,9 +60,9 @@ multi-debugcallback.c - a multi-interface app using the debug callback
|
|||||||
multi-double.c - a multi-interface app doing two simultaneous transfers
|
multi-double.c - a multi-interface app doing two simultaneous transfers
|
||||||
multi-post.c - a multi-interface app doing a multipart formpost
|
multi-post.c - a multi-interface app doing a multipart formpost
|
||||||
multi-single.c - a multi-interface app getting a single file
|
multi-single.c - a multi-interface app getting a single file
|
||||||
multithread.c - an example using multi-treading transfering multiple files
|
multithread.c - an example using multi-treading transferring multiple files
|
||||||
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
||||||
persistant.c - request two URLs with a persistant connection
|
persistant.c - request two URLs with a persistent connection
|
||||||
post-callback.c - send a HTTP POST using a callback
|
post-callback.c - send a HTTP POST using a callback
|
||||||
postit2.c - send a HTTP multipart formpost
|
postit2.c - send a HTTP multipart formpost
|
||||||
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
||||||
@@ -72,5 +72,5 @@ sepheaders.c - download headers to a separate file
|
|||||||
simple.c - the most simple download a URL source
|
simple.c - the most simple download a URL source
|
||||||
simplepost.c - HTTP POST
|
simplepost.c - HTTP POST
|
||||||
simplessl.c - HTTPS example with certificates many options set
|
simplessl.c - HTTPS example with certificates many options set
|
||||||
synctime.c - Sync local time by extracing date from remote HTTP servers
|
synctime.c - Sync local time by extracting date from remote HTTP servers
|
||||||
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
/* ioctl callback function */
|
/* ioctl callback function */
|
||||||
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
|
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
|
||||||
{
|
{
|
||||||
int fd = (int)userp;
|
intptr_t fd = (intptr_t)userp;
|
||||||
|
|
||||||
(void)handle; /* not used in here */
|
(void)handle; /* not used in here */
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
|||||||
{
|
{
|
||||||
size_t retcode;
|
size_t retcode;
|
||||||
|
|
||||||
int fd = (int)stream;
|
intptr_t fd = (intptr_t)stream;
|
||||||
|
|
||||||
retcode = read(fd, ptr, size * nmemb);
|
retcode = read(fd, ptr, size * nmemb);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
int hd ;
|
intptr_t hd ;
|
||||||
struct stat file_info;
|
struct stat file_info;
|
||||||
|
|
||||||
char *file;
|
char *file;
|
||||||
@@ -100,13 +100,13 @@ int main(int argc, char **argv)
|
|||||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||||
|
|
||||||
/* which file to upload */
|
/* which file to upload */
|
||||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd);
|
curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
|
||||||
|
|
||||||
/* set the ioctl function */
|
/* set the ioctl function */
|
||||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
|
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
|
||||||
|
|
||||||
/* pass the file descriptor to the ioctl callback as well */
|
/* pass the file descriptor to the ioctl callback as well */
|
||||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, hd);
|
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
|
||||||
|
|
||||||
/* enable "uploading" (which means PUT when doing HTTP) */
|
/* enable "uploading" (which means PUT when doing HTTP) */
|
||||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ void dump(const char *text,
|
|||||||
|
|
||||||
static
|
static
|
||||||
int my_trace(CURL *handle, curl_infotype type,
|
int my_trace(CURL *handle, curl_infotype type,
|
||||||
unsigned char *data, size_t size,
|
char *data, size_t size,
|
||||||
void *userp)
|
void *userp)
|
||||||
{
|
{
|
||||||
struct data *config = (struct data *)userp;
|
struct data *config = (struct data *)userp;
|
||||||
@@ -98,7 +98,7 @@ int my_trace(CURL *handle, curl_infotype type,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dump(text, stderr, data, size, config->trace_ascii);
|
dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct FtpFile {
|
|||||||
FILE *stream;
|
FILE *stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||||
{
|
{
|
||||||
struct FtpFile *out=(struct FtpFile *)stream;
|
struct FtpFile *out=(struct FtpFile *)stream;
|
||||||
if(out && !out->stream) {
|
if(out && !out->stream) {
|
||||||
|
|||||||
@@ -14,7 +14,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This example shows an FTP upload, with a rename of the file just after
|
* This example shows an FTP upload, with a rename of the file just after
|
||||||
@@ -28,12 +33,26 @@
|
|||||||
#define REMOTE_URL "ftp://localhost/" UPLOAD_FILE_AS
|
#define REMOTE_URL "ftp://localhost/" UPLOAD_FILE_AS
|
||||||
#define RENAME_FILE_TO "renamed-and-fine.txt"
|
#define RENAME_FILE_TO "renamed-and-fine.txt"
|
||||||
|
|
||||||
|
/* NOTE: if you want this example to work on Windows with libcurl as a
|
||||||
|
DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
|
||||||
|
Failing to do so will give you a crash since a DLL may not use the
|
||||||
|
variable's memory when passed in to it from an app like this. */
|
||||||
|
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
/* in real-world cases, this would probably get this data differently
|
||||||
|
as this fread() stuff is exactly what the library already would do
|
||||||
|
by default internally */
|
||||||
|
size_t retcode = fread(ptr, size, nmemb, stream);
|
||||||
|
|
||||||
|
fprintf(stderr, "*** We read %d bytes from file\n", retcode);
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
FILE * hd_src ;
|
FILE *hd_src;
|
||||||
int hd ;
|
|
||||||
struct stat file_info;
|
struct stat file_info;
|
||||||
|
|
||||||
struct curl_slist *headerlist=NULL;
|
struct curl_slist *headerlist=NULL;
|
||||||
@@ -41,13 +60,13 @@ int main(int argc, char **argv)
|
|||||||
static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
|
static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
|
||||||
|
|
||||||
/* get the file size of the local file */
|
/* get the file size of the local file */
|
||||||
hd = open(LOCAL_FILE, O_RDONLY) ;
|
if(stat(LOCAL_FILE, &file_info)) {
|
||||||
fstat(hd, &file_info);
|
printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
|
||||||
close(hd) ;
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Local file size: %ld bytes.\n", file_info.st_size);
|
||||||
|
|
||||||
/* get a FILE * of the same file, could also be made with
|
/* get a FILE * of the same file */
|
||||||
fdopen() from the previous descriptor, but hey this is just
|
|
||||||
an example! */
|
|
||||||
hd_src = fopen(LOCAL_FILE, "rb");
|
hd_src = fopen(LOCAL_FILE, "rb");
|
||||||
|
|
||||||
/* In windows, this will init the winsock stuff */
|
/* In windows, this will init the winsock stuff */
|
||||||
@@ -60,6 +79,9 @@ int main(int argc, char **argv)
|
|||||||
headerlist = curl_slist_append(headerlist, buf_1);
|
headerlist = curl_slist_append(headerlist, buf_1);
|
||||||
headerlist = curl_slist_append(headerlist, buf_2);
|
headerlist = curl_slist_append(headerlist, buf_2);
|
||||||
|
|
||||||
|
/* we want to use our own read function */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||||
|
|
||||||
/* enable uploading */
|
/* enable uploading */
|
||||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1) ;
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1) ;
|
||||||
|
|
||||||
@@ -72,12 +94,6 @@ int main(int argc, char **argv)
|
|||||||
/* now specify which file to upload */
|
/* now specify which file to upload */
|
||||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
||||||
|
|
||||||
/* NOTE: if you want this example to work on Windows with libcurl as a
|
|
||||||
DLL, you MUST also provide a read callback with
|
|
||||||
CURLOPT_READFUNCTION. Failing to do so will give you a crash since a
|
|
||||||
DLL may not use the variable's memory when passed in to it from an app
|
|
||||||
like this. */
|
|
||||||
|
|
||||||
/* Set the size of the file to upload (optional). If you give a *_LARGE
|
/* Set the size of the file to upload (optional). If you give a *_LARGE
|
||||||
option you MUST make sure that the type of the passed-in argument is a
|
option you MUST make sure that the type of the passed-in argument is a
|
||||||
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
|
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
|
||||||
|
|||||||
@@ -98,5 +98,8 @@ int main(int argc, char **argv)
|
|||||||
if(chunk.memory)
|
if(chunk.memory)
|
||||||
free(chunk.memory);
|
free(chunk.memory);
|
||||||
|
|
||||||
|
/* we're done with libcurl, so clean it up */
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ CSOURCES = fopen.c ftpget.c ftpgetresp.c ftpupload.c getinmemory.c \
|
|||||||
multi-post.c multi-single.c persistant.c post-callback.c \
|
multi-post.c multi-single.c persistant.c post-callback.c \
|
||||||
postit2.c sepheaders.c simple.c simplepost.c simplessl.c \
|
postit2.c sepheaders.c simple.c simplepost.c simplessl.c \
|
||||||
multi-debugcallback.c fileupload.c getinfo.c anyauthput.c \
|
multi-debugcallback.c fileupload.c getinfo.c anyauthput.c \
|
||||||
10-at-a-time.c # ftpuploadresume.c ftp3rdparty.c cookie_interface.c
|
10-at-a-time.c # ftpuploadresume.c cookie_interface.c
|
||||||
|
|
||||||
PROGRAMS = $(CSOURCES:.c=.exe)
|
PROGRAMS = $(CSOURCES:.c=.exe)
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void dump(const char *text,
|
|||||||
|
|
||||||
static
|
static
|
||||||
int my_trace(CURL *handle, curl_infotype type,
|
int my_trace(CURL *handle, curl_infotype type,
|
||||||
unsigned char *data, size_t size,
|
char *data, size_t size,
|
||||||
void *userp)
|
void *userp)
|
||||||
{
|
{
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ int main(void)
|
|||||||
*/
|
*/
|
||||||
#ifdef USE_CHUNKED
|
#ifdef USE_CHUNKED
|
||||||
{
|
{
|
||||||
curl_slist *chunk = NULL;
|
struct curl_slist *chunk = NULL;
|
||||||
|
|
||||||
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
|
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
|
||||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||||
@@ -98,7 +98,7 @@ int main(void)
|
|||||||
/* A less good option would be to enforce HTTP 1.0, but that might also
|
/* A less good option would be to enforce HTTP 1.0, but that might also
|
||||||
have other implications. */
|
have other implications. */
|
||||||
{
|
{
|
||||||
curl_slist *chunk = NULL;
|
struct curl_slist *chunk = NULL;
|
||||||
|
|
||||||
chunk = curl_slist_append(chunk, "Expect:");
|
chunk = curl_slist_append(chunk, "Expect:");
|
||||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||||
|
|||||||
217
docs/examples/smooth-gtk-thread.c
Normal file
217
docs/examples/smooth-gtk-thread.c
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This is a multi threaded application that uses a progress bar to show
|
||||||
|
* status. It uses Gtk+ to make a smooth pulse.
|
||||||
|
*
|
||||||
|
* Written by Jud Bishop after studying the other examples provided with
|
||||||
|
* libcurl.
|
||||||
|
*
|
||||||
|
* To compile (on a single line):
|
||||||
|
* gcc -ggdb `pkg-config --cflags --libs gtk+-2.0` -lcurl -lssl -lcrypto
|
||||||
|
* -lgthread-2.0 -dl smooth-gtk-thread.c -o smooth-gtk-thread
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <curl/types.h> /* new for v7 */
|
||||||
|
#include <curl/easy.h> /* new for v7 */
|
||||||
|
|
||||||
|
#define NUMT 4
|
||||||
|
|
||||||
|
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
int j = 0;
|
||||||
|
gint num_urls = 9; /* Just make sure this is less than urls[]*/
|
||||||
|
char *urls[]= {
|
||||||
|
"90022",
|
||||||
|
"90023",
|
||||||
|
"90024",
|
||||||
|
"90025",
|
||||||
|
"90026",
|
||||||
|
"90027",
|
||||||
|
"90028",
|
||||||
|
"90029",
|
||||||
|
"90030"
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t write_file(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
|
{
|
||||||
|
/* printf("write_file\n"); */
|
||||||
|
return fwrite(ptr, size, nmemb, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://xoap.weather.com/weather/local/46214?cc=*&dayf=5&unit=i */
|
||||||
|
void *pull_one_url(void *NaN)
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
gchar *http;
|
||||||
|
FILE *outfile;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* Stop threads from entering unless j is incremented */
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
while ( j < num_urls )
|
||||||
|
{
|
||||||
|
printf("j = %d\n", j);
|
||||||
|
|
||||||
|
http =
|
||||||
|
g_strdup_printf("xoap.weather.com/weather/local/%s?cc=*&dayf=5&unit=i\n",
|
||||||
|
urls[j]);
|
||||||
|
|
||||||
|
printf( "http %s", http );
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl)
|
||||||
|
{
|
||||||
|
|
||||||
|
outfile = fopen(urls[j], "w");
|
||||||
|
/* printf("fopen\n"); */
|
||||||
|
|
||||||
|
/* Set the URL and transfer type */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, http);
|
||||||
|
|
||||||
|
/* Write to the file */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file);
|
||||||
|
|
||||||
|
j++; /* critical line */
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
fclose(outfile);
|
||||||
|
printf("fclose\n");
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
g_free (http);
|
||||||
|
|
||||||
|
/* Adds more latency, testing the mutex.*/
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
} /* end while */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean pulse_bar(gpointer data)
|
||||||
|
{
|
||||||
|
gdk_threads_enter();
|
||||||
|
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));
|
||||||
|
gdk_threads_leave();
|
||||||
|
|
||||||
|
/* Return true so the function will be called again;
|
||||||
|
* returning false removes this timeout function.
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *create_thread(void *progress_bar)
|
||||||
|
{
|
||||||
|
pthread_t tid[NUMT];
|
||||||
|
int i;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/* Make sure I don't create more threads than urls. */
|
||||||
|
for(i=0; i < NUMT && i < num_urls ; i++) {
|
||||||
|
error = pthread_create(&tid[i],
|
||||||
|
NULL, /* default attributes please */
|
||||||
|
pull_one_url,
|
||||||
|
NULL);
|
||||||
|
if(0 != error)
|
||||||
|
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for all threads to terminate. */
|
||||||
|
for(i=0; i < NUMT && i < num_urls; i++) {
|
||||||
|
error = pthread_join(tid[i], NULL);
|
||||||
|
fprintf(stderr, "Thread %d terminated\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This stops the pulsing if you have it turned on in the progress bar
|
||||||
|
section */
|
||||||
|
g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(progress_bar),
|
||||||
|
"pulse_id")));
|
||||||
|
|
||||||
|
/* This destroys the progress bar */
|
||||||
|
gtk_widget_destroy(progress_bar);
|
||||||
|
|
||||||
|
/* [Un]Comment this out to kill the program rather than pushing close. */
|
||||||
|
/* gtk_main_quit(); */
|
||||||
|
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean cb_delete(GtkWidget *window, gpointer data)
|
||||||
|
{
|
||||||
|
gtk_main_quit();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
GtkWidget *top_window, *outside_frame, *inside_frame, *progress_bar;
|
||||||
|
GtkAdjustment *adj;
|
||||||
|
|
||||||
|
/* Init thread */
|
||||||
|
g_thread_init(NULL);
|
||||||
|
gdk_threads_init ();
|
||||||
|
gdk_threads_enter ();
|
||||||
|
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
|
||||||
|
/* Base window */
|
||||||
|
top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
|
||||||
|
/* Frame */
|
||||||
|
outside_frame = gtk_frame_new(NULL);
|
||||||
|
gtk_frame_set_shadow_type(GTK_FRAME(outside_frame), GTK_SHADOW_OUT);
|
||||||
|
gtk_container_add(GTK_CONTAINER(top_window), outside_frame);
|
||||||
|
|
||||||
|
/* Frame */
|
||||||
|
inside_frame = gtk_frame_new(NULL);
|
||||||
|
gtk_frame_set_shadow_type(GTK_FRAME(inside_frame), GTK_SHADOW_IN);
|
||||||
|
gtk_container_set_border_width(GTK_CONTAINER(inside_frame), 5);
|
||||||
|
gtk_container_add(GTK_CONTAINER(outside_frame), inside_frame);
|
||||||
|
|
||||||
|
/* Progress bar */
|
||||||
|
progress_bar = gtk_progress_bar_new();
|
||||||
|
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progress_bar));
|
||||||
|
/* Make uniform pulsing */
|
||||||
|
gint pulse_ref = g_timeout_add (300, pulse_bar, progress_bar);
|
||||||
|
g_object_set_data(G_OBJECT(progress_bar), "pulse_id",
|
||||||
|
GINT_TO_POINTER(pulse_ref));
|
||||||
|
gtk_container_add(GTK_CONTAINER(inside_frame), progress_bar);
|
||||||
|
|
||||||
|
gtk_widget_show_all(top_window);
|
||||||
|
printf("gtk_widget_show_all\n");
|
||||||
|
|
||||||
|
g_signal_connect(G_OBJECT (top_window), "delete-event",
|
||||||
|
G_CALLBACK(cb_delete), NULL);
|
||||||
|
|
||||||
|
if (!g_thread_create(&create_thread, progress_bar, FALSE, NULL) != 0)
|
||||||
|
g_warning("can't create the thread");
|
||||||
|
|
||||||
|
gtk_main();
|
||||||
|
gdk_threads_leave();
|
||||||
|
printf("gdk_threads_leave\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
145
docs/examples/threaded-ssl.c
Normal file
145
docs/examples/threaded-ssl.c
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* A multi-threaded example that uses pthreads and fetches 4 remote files at
|
||||||
|
* once over HTTPS. The lock callbacks and stuff assume OpenSSL or GnuTLS
|
||||||
|
* (libgcrypt) so far.
|
||||||
|
*
|
||||||
|
* OpenSSL docs for this:
|
||||||
|
* http://www.openssl.org/docs/crypto/threads.html
|
||||||
|
* gcrypt docs for this:
|
||||||
|
* http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_OPENSSL /* or USE_GNUTLS accordingly */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
/* we have this global to let the callback get easy access to it */
|
||||||
|
static pthread_mutex_t *lockarray;
|
||||||
|
|
||||||
|
#ifdef USE_OPENSSL
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
static void lock_callback(int mode, int type, char *file, int line)
|
||||||
|
{
|
||||||
|
(void)file;
|
||||||
|
(void)line;
|
||||||
|
if (mode & CRYPTO_LOCK) {
|
||||||
|
pthread_mutex_lock(&(lockarray[type]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pthread_mutex_unlock(&(lockarray[type]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long thread_id(void)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
|
||||||
|
ret=(unsigned long)pthread_self();
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_locks(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
|
||||||
|
sizeof(pthread_mutex_t));
|
||||||
|
for (i=0; i<CRYPTO_num_locks(); i++) {
|
||||||
|
pthread_mutex_init(&(lockarray[i]),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CRYPTO_set_id_callback((unsigned long (*)())thread_id);
|
||||||
|
CRYPTO_set_locking_callback((void (*)())lock_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kill_locks(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CRYPTO_set_locking_callback(NULL);
|
||||||
|
for (i=0; i<CRYPTO_num_locks(); i++)
|
||||||
|
pthread_mutex_destroy(&(lockarray[i]));
|
||||||
|
|
||||||
|
OPENSSL_free(lockarray);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||||
|
|
||||||
|
void init_locks(void)
|
||||||
|
{
|
||||||
|
gcry_control(GCRYCTL_SET_THREAD_CBS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kill_locks()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* List of URLs to fetch.*/
|
||||||
|
const char *urls[]= {
|
||||||
|
"https://www.sf.net/",
|
||||||
|
"https://www.openssl.org/",
|
||||||
|
"https://www.sf.net/",
|
||||||
|
"https://www.openssl.org/",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *pull_one_url(void *url)
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
|
/* this example doesn't verify the server's certificate, which means we
|
||||||
|
might be downloading stuff from an impostor */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
|
curl_easy_perform(curl); /* ignores error */
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
pthread_t tid[4];
|
||||||
|
int i;
|
||||||
|
int error;
|
||||||
|
(void)argc; /* we don't use any arguments in this example */
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
init_locks();
|
||||||
|
|
||||||
|
for(i=0; i< 4; i++) {
|
||||||
|
error = pthread_create(&tid[i],
|
||||||
|
NULL, /* default attributes please */
|
||||||
|
pull_one_url,
|
||||||
|
(void *)urls[i]);
|
||||||
|
if(0 != error)
|
||||||
|
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now wait for all threads to terminate */
|
||||||
|
for(i=0; i< 4; i++) {
|
||||||
|
error = pthread_join(tid[i], NULL);
|
||||||
|
fprintf(stderr, "Thread %d terminated\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_locks();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
54
docs/libcurl/ABI
Normal file
54
docs/libcurl/ABI
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
_ _ ____ _
|
||||||
|
___| | | | _ \| |
|
||||||
|
/ __| | | | |_) | |
|
||||||
|
| (__| |_| | _ <| |___
|
||||||
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
|
libcurl's binary interface
|
||||||
|
|
||||||
|
ABI - Application Binary Interface
|
||||||
|
|
||||||
|
First, allow me to define the word for this context: ABI describes the
|
||||||
|
low-level interface between an application program a library. Calling
|
||||||
|
conventions, function arguments, return values, struct sizes/defines and
|
||||||
|
more.
|
||||||
|
|
||||||
|
For a longer descricption, see
|
||||||
|
http://en.wikipedia.org/wiki/Application_binary_interface
|
||||||
|
|
||||||
|
Upgrades
|
||||||
|
|
||||||
|
In the vast majority of all cases, a typical libcurl upgrade does not break
|
||||||
|
the ABI at all. Your application can remain using libcurl just as before,
|
||||||
|
only with less bugs and possibly with added new features. You need to read
|
||||||
|
the release notes, and if they mention an ABI break/soname bump, you may
|
||||||
|
have to verify that your application still builds fine and uses libcurl as
|
||||||
|
it now is defined to work.
|
||||||
|
|
||||||
|
Version Numbers
|
||||||
|
|
||||||
|
In libcurl land, you really can't tell by the libcurl version number if that
|
||||||
|
libcurl is binary compatible or not with another libcurl version.
|
||||||
|
|
||||||
|
Soname Bumps
|
||||||
|
|
||||||
|
Whenever there are changes done to the library that will cause an ABI
|
||||||
|
breakage, that may require your application to get attention or possibly be
|
||||||
|
changed to adhere to new things, we will bump the soname. Then the library
|
||||||
|
will get a different output name and thus can in fact be installed in
|
||||||
|
parallell with an older installed lib (on most systems). Thus, old
|
||||||
|
applications built against the previous ABI version will remain working and
|
||||||
|
using the older lib, while newer applications build and use the newer one.
|
||||||
|
|
||||||
|
During the first seven years of libcurl releases, there have only been four
|
||||||
|
ABI breakages.
|
||||||
|
|
||||||
|
Downgrades
|
||||||
|
|
||||||
|
Going to an older libcurl version from one you're currently using can be a
|
||||||
|
tricky thing. Mostly we add features and options to newer libcurls as that
|
||||||
|
won't break ABI or hamper existing applications. This has the implication
|
||||||
|
that going backwards may get you in a situation where you pick a libcurl
|
||||||
|
that doesn't support the options your application needs. Or possibly you
|
||||||
|
even downgrade so far so you cross an ABI break border and thus a different
|
||||||
|
soname, and then your application may need to adapt to the modified ABI.
|
||||||
@@ -18,7 +18,8 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
|||||||
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
|
||||||
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||||
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||||
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3
|
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
|
||||||
|
curl_easy_pause.3
|
||||||
|
|
||||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||||
@@ -36,7 +37,7 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
|||||||
curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \
|
curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \
|
||||||
curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.html \
|
curl_easy_reset.html curl_easy_escape.html curl_easy_unescape.html \
|
||||||
curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html \
|
curl_multi_setopt.html curl_multi_socket.html curl_multi_timeout.html \
|
||||||
curl_formget.html curl_multi_assign.html
|
curl_formget.html curl_multi_assign.html curl_easy_pause.html
|
||||||
|
|
||||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \
|
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \
|
||||||
curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf \
|
curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf \
|
||||||
@@ -53,11 +54,11 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \
|
|||||||
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
curl_share_strerror.pdf curl_global_init_mem.pdf libcurl-tutorial.pdf \
|
||||||
curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \
|
curl_easy_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \
|
||||||
curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf \
|
curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf \
|
||||||
curl_formget.pdf curl_multi_assign.pdf
|
curl_formget.pdf curl_multi_assign.pdf curl_easy_pause.pdf
|
||||||
|
|
||||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4
|
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI
|
||||||
|
|
||||||
MAN2HTML= roffit --mandir=. < $< >$@
|
MAN2HTML= roffit --mandir=. < $< >$@
|
||||||
|
|
||||||
|
|||||||
63
docs/libcurl/curl_easy_pause.3
Normal file
63
docs/libcurl/curl_easy_pause.3
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.TH curl_easy_pause 3 "17 Dec 2007" "libcurl 7.18.0" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_easy_pause - pause and unpause a connection
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #include <curl/curl.h>
|
||||||
|
|
||||||
|
.BI "CURLcode curl_easy_pause(CURL *"handle ", int "bitmask " );"
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Using this function, you can explicitly mark a running connection to get
|
||||||
|
paused, and you can unpause a connection that was previously paused.
|
||||||
|
|
||||||
|
A connection can made to pause by using this function or by letting the read
|
||||||
|
or the write callbacks return the proper magic return code
|
||||||
|
(\fICURL_READFUNC_PAUSE\fP and \fICURL_WRITEFUNC_PAUSE\fP).
|
||||||
|
|
||||||
|
NOTE: while it may feel tempting, take care and notice that you cannot call
|
||||||
|
this function from another thread.
|
||||||
|
|
||||||
|
When this function is called to unpause reading, the chance is high that you
|
||||||
|
will get your write callback called before this function returns.
|
||||||
|
|
||||||
|
The \fBhandle\fP argument is of course identifying the handle that operates on
|
||||||
|
the connection you want to pause or unpause.
|
||||||
|
|
||||||
|
The \fBbitmask\fP argument is a set of bits that sets the new state of the
|
||||||
|
connection. The following bits can be used:
|
||||||
|
.IP CURLPAUSE_RECV
|
||||||
|
Pause receiving data. There will be no data received on this conneciton until
|
||||||
|
this function is called again without this bit set. Thus, the write callback
|
||||||
|
(\fICURLOPT_WRITEFUNCTION\fP) won't be called.
|
||||||
|
.IP CURLPAUSE_SEND
|
||||||
|
Pause sending data. There will be no data sent on this connection until this
|
||||||
|
function is called again without this bit set. Thus, the read callback
|
||||||
|
(\fICURLOPT_READFUNCTION\fP) won't be called.
|
||||||
|
.IP CURLPAUSE_ALL
|
||||||
|
Convenience define that pauses both directions.
|
||||||
|
.IP CURLPAUSE_CONT
|
||||||
|
Convenience define that unpauses both directions
|
||||||
|
.SH RETURN VALUE
|
||||||
|
CURLE_OK (zero) means that the option was set properly, and a non-zero return
|
||||||
|
code means something wrong occurred after the new state was set. See the
|
||||||
|
\fIlibcurl-errors(3)\fP man page for the full list with descriptions.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
This function was added in libcurl 7.18.0. Before this version, there was no
|
||||||
|
explicit support for pausing transfers.
|
||||||
|
.SH "MEMORY USE"
|
||||||
|
When pausing a read by returning the magic return code from a write callback,
|
||||||
|
the read data is already in libcurl's internal buffers so it'll have to keep
|
||||||
|
it in an allocated buffer until the reading is again unpaused using this
|
||||||
|
function.
|
||||||
|
|
||||||
|
If the downloaded data is compressed and is asked to get uncompressed
|
||||||
|
automatially on download, libcurl will continue to uncompress the entire
|
||||||
|
downloaded chunk and it will cache the data uncompressed. This has the side-
|
||||||
|
effect that if you download something that is compressed a lot, it can result
|
||||||
|
in a very large data amount needing to be allocated to save the data during
|
||||||
|
the pause. This said, you should probably consider not using paused reading if
|
||||||
|
you allow libcurl to uncompress data automatically.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_easy_cleanup "(3), " curl_easy_reset "(3)"
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "30 Aug 2007" "libcurl 7.17.0" "libcurl Manual"
|
.TH curl_easy_setopt 3 "5 Jan 2008" "libcurl 7.18.0" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_setopt \- set options for a curl easy handle
|
curl_easy_setopt \- set options for a curl easy handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -95,6 +95,10 @@ of bytes actually taken care of. If that amount differs from the amount passed
|
|||||||
to your function, it'll signal an error to the library and it will abort the
|
to your function, it'll signal an error to the library and it will abort the
|
||||||
transfer and return \fICURLE_WRITE_ERROR\fP.
|
transfer and return \fICURLE_WRITE_ERROR\fP.
|
||||||
|
|
||||||
|
From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will
|
||||||
|
cause writing to this connection to become paused. See
|
||||||
|
\fIcurl_easy_pause(3)\fP for further details.
|
||||||
|
|
||||||
This function may be called with zero bytes data if the transfered file is
|
This function may be called with zero bytes data if the transfered file is
|
||||||
empty.
|
empty.
|
||||||
|
|
||||||
@@ -142,6 +146,10 @@ The read callback may return \fICURL_READFUNC_ABORT\fP to stop the current
|
|||||||
operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error
|
operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error
|
||||||
code from the transfer (Added in 7.12.1)
|
code from the transfer (Added in 7.12.1)
|
||||||
|
|
||||||
|
From 7.18.0, the function can return CURL_READFUNC_PAUSE which then will cause
|
||||||
|
reading from this connection to become paused. See \fIcurl_easy_pause(3)\fP
|
||||||
|
for further details.
|
||||||
|
|
||||||
If you set the callback pointer to NULL, or doesn't set it at all, the default
|
If you set the callback pointer to NULL, or doesn't set it at all, the default
|
||||||
internal read function will be used. It is simply doing an fread() on the FILE
|
internal read function will be used. It is simply doing an fread() on the FILE
|
||||||
* stream set with \fICURLOPT_READDATA\fP.
|
* stream set with \fICURLOPT_READDATA\fP.
|
||||||
@@ -163,11 +171,32 @@ something special I/O-related needs to be done that the library can't do by
|
|||||||
itself. For now, rewinding the read data stream is the only action it can
|
itself. For now, rewinding the read data stream is the only action it can
|
||||||
request. The rewinding of the read data stream may be necessary when doing a
|
request. The rewinding of the read data stream may be necessary when doing a
|
||||||
HTTP PUT or POST with a multi-pass authentication method. (Option added in
|
HTTP PUT or POST with a multi-pass authentication method. (Option added in
|
||||||
7.12.3)
|
7.12.3).
|
||||||
|
|
||||||
|
Use \fICURLOPT_SEEKFUNCTION\fP instead to provide seeking!
|
||||||
.IP CURLOPT_IOCTLDATA
|
.IP CURLOPT_IOCTLDATA
|
||||||
Pass a pointer that will be untouched by libcurl and passed as the 3rd
|
Pass a pointer that will be untouched by libcurl and passed as the 3rd
|
||||||
argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option
|
argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option
|
||||||
added in 7.12.3)
|
added in 7.12.3)
|
||||||
|
.IP CURLOPT_SEEKFUNCTION
|
||||||
|
Function pointer that should match the following prototype: \fIint
|
||||||
|
function(void *instream, curl_off_t offset, int origin);\fP This function gets
|
||||||
|
called by libcurl to seek to a certain position in the input stream and can be
|
||||||
|
used to fast forward a file in a resumed upload (instead of reading all
|
||||||
|
uploaded bytes with the normal read function/callback). It is also called to
|
||||||
|
rewind a stream when doing a HTTP PUT or POST with a multi-pass authentication
|
||||||
|
method. The function shall work like "fseek" or "lseek" and accepted SEEK_SET,
|
||||||
|
SEEK_CUR and SEEK_END as argument for origin, although (in 7.18.0) libcurl
|
||||||
|
only passes SEEK_SET. The callback must return 0 on success as returning
|
||||||
|
non-zero will cause the upload operation to fail.
|
||||||
|
|
||||||
|
If you forward the input arguments directly to "fseek" or "lseek", note that
|
||||||
|
the data type for \fIoffset\fP is not the same as defined for curl_off_t on
|
||||||
|
many systems! (Option added in 7.18.0)
|
||||||
|
.IP CURLOPT_SEEKDATA
|
||||||
|
Data pointer to pass to the file read function. If you use the
|
||||||
|
\fICURLOPT_SEEKFUNCTION\fP option, this is the pointer you'll get as input. If
|
||||||
|
you don't specify a seek callback, NULL is passed. (Option added in 7.18.0)
|
||||||
.IP CURLOPT_SOCKOPTFUNCTION
|
.IP CURLOPT_SOCKOPTFUNCTION
|
||||||
Function pointer that should match the \fIcurl_sockopt_callback\fP prototype
|
Function pointer that should match the \fIcurl_sockopt_callback\fP prototype
|
||||||
found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the
|
found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the
|
||||||
@@ -184,6 +213,30 @@ unrecoverable error to the library and it will close the socket and return
|
|||||||
Pass a pointer that will be untouched by libcurl and passed as the first
|
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||||
argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
|
argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
|
||||||
(Option added in 7.15.6.)
|
(Option added in 7.15.6.)
|
||||||
|
.IP CURLOPT_OPENSOCKETFUNCTION
|
||||||
|
Function pointer that should match the \fIcurl_opensocket_callback\fP
|
||||||
|
prototype found in \fI<curl/curl.h>\fP. This function gets called by libcurl
|
||||||
|
instead of the \fIsocket(2)\fP call. The callback's \fIpurpose\fP argument
|
||||||
|
identifies the exact purpose for this particular socket, and currently only
|
||||||
|
one value is supported: \fICURLSOCKTYPE_IPCXN\fP for the primary connection
|
||||||
|
(meaning the control connection in the FTP case). Future versions of libcurl
|
||||||
|
may support more purposes. It passes the resolved peer address as a
|
||||||
|
\fIaddress\fP argument so the callback can modify the address or refuse to
|
||||||
|
connect at all. The callback function should return the socket or
|
||||||
|
\fICURL_SOCKET_BAD\fP in case no connection should be established or any error
|
||||||
|
detected. Any additional \fIsetsockopt(2)\fP calls can be done on the socket
|
||||||
|
at the user's discretion. \fICURL_SOCKET_BAD\fP return value from the
|
||||||
|
callback function will signal an unrecoverable error to the library and it
|
||||||
|
will return \fICURLE_COULDNT_CONNECT\fP. This return code can be used for IP
|
||||||
|
address blacklisting. The default behavior is:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
return socket(addr->family, addr->socktype, addr->protocol);
|
||||||
|
.Ed
|
||||||
|
(Option added in 7.17.1.)
|
||||||
|
.IP CURLOPT_OPENSOCKETDATA
|
||||||
|
Pass a pointer that will be untouched by libcurl and passed as the first
|
||||||
|
argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP.
|
||||||
|
(Option added in 7.17.1.)
|
||||||
.IP CURLOPT_PROGRESSFUNCTION
|
.IP CURLOPT_PROGRESSFUNCTION
|
||||||
Function pointer that should match the \fIcurl_progress_callback\fP prototype
|
Function pointer that should match the \fIcurl_progress_callback\fP prototype
|
||||||
found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of
|
found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of
|
||||||
@@ -257,6 +310,9 @@ Pass a pointer to whatever you want passed in to your
|
|||||||
\fICURLOPT_DEBUGFUNCTION\fP in the last void * argument. This pointer is not
|
\fICURLOPT_DEBUGFUNCTION\fP in the last void * argument. This pointer is not
|
||||||
used by libcurl, it is only passed to the callback.
|
used by libcurl, it is only passed to the callback.
|
||||||
.IP CURLOPT_SSL_CTX_FUNCTION
|
.IP CURLOPT_SSL_CTX_FUNCTION
|
||||||
|
This option does only function for libcurl powered by OpenSSL. If libcurl was
|
||||||
|
built against another SSL library, this functionality is absent.
|
||||||
|
|
||||||
Function pointer that should match the following prototype: \fBCURLcode
|
Function pointer that should match the following prototype: \fBCURLcode
|
||||||
sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called
|
sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called
|
||||||
by libcurl just before the initialization of an SSL connection after having
|
by libcurl just before the initialization of an SSL connection after having
|
||||||
@@ -362,8 +418,7 @@ POST/PUT and a 401 or 407 is received immediately afterwards.
|
|||||||
.SH NETWORK OPTIONS
|
.SH NETWORK OPTIONS
|
||||||
.IP CURLOPT_URL
|
.IP CURLOPT_URL
|
||||||
The actual URL to deal with. The parameter should be a char * to a zero
|
The actual URL to deal with. The parameter should be a char * to a zero
|
||||||
terminated string. The string must remain present until curl no longer needs
|
terminated string.
|
||||||
it, as it doesn't copy the string.
|
|
||||||
|
|
||||||
If the given URL lacks the protocol part ("http://" or "ftp://" etc), it will
|
If the given URL lacks the protocol part ("http://" or "ftp://" etc), it will
|
||||||
attempt to guess which protocol to use based on the given host name. If the
|
attempt to guess which protocol to use based on the given host name. If the
|
||||||
@@ -407,13 +462,21 @@ Pass a long with this option to set the proxy port to connect to unless it is
|
|||||||
specified in the proxy string \fICURLOPT_PROXY\fP.
|
specified in the proxy string \fICURLOPT_PROXY\fP.
|
||||||
.IP CURLOPT_PROXYTYPE
|
.IP CURLOPT_PROXYTYPE
|
||||||
Pass a long with this option to set type of the proxy. Available options for
|
Pass a long with this option to set type of the proxy. Available options for
|
||||||
this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_SOCKS4\fP (added in 7.15.2)
|
this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_SOCKS4\fP (added in 7.15.2),
|
||||||
\fICURLPROXY_SOCKS5\fP. The HTTP type is default. (Added in 7.10)
|
\fICURLPROXY_SOCKS5\fP, \fICURLPROXY_SOCKS4A\fP (added in 7.18.0) and
|
||||||
|
\fICURLPROXY_SOCKS5_HOSTNAME\fP (added in 7.18.0). The HTTP type is
|
||||||
|
default. (Added in 7.10)
|
||||||
.IP CURLOPT_HTTPPROXYTUNNEL
|
.IP CURLOPT_HTTPPROXYTUNNEL
|
||||||
Set the parameter to non-zero to get the library to tunnel all operations
|
Set the parameter to non-zero to get the library to tunnel all operations
|
||||||
through a given HTTP proxy. There is a big difference between using a proxy
|
through a given HTTP proxy. There is a big difference between using a proxy
|
||||||
and to tunnel through it. If you don't know what this means, you probably
|
and to tunnel through it. If you don't know what this means, you probably
|
||||||
don't want this tunneling option.
|
don't want this tunneling option.
|
||||||
|
.IP CURLOPT_SOCKS5_RESOLVE_LOCAL
|
||||||
|
Set the parameter to 1 to get the library to resolve the host name locally
|
||||||
|
instead of passing it to the proxy to resolve, when using a SOCKS5 proxy.
|
||||||
|
|
||||||
|
Note that libcurl before 7.18.0 always resolved the host name locally even
|
||||||
|
when SOCKS5 was used. (Added in 7.18.0)
|
||||||
.IP CURLOPT_INTERFACE
|
.IP CURLOPT_INTERFACE
|
||||||
Pass a char * as parameter. This set the interface name to use as outgoing
|
Pass a char * as parameter. This set the interface name to use as outgoing
|
||||||
network interface. The name can be an interface name, an IP address or a host
|
network interface. The name can be an interface name, an IP address or a host
|
||||||
@@ -619,6 +682,13 @@ redirections have been followed, the next redirect will cause an error
|
|||||||
\fICURLOPT_FOLLOWLOCATION\fP is used at the same time. Added in 7.15.1:
|
\fICURLOPT_FOLLOWLOCATION\fP is used at the same time. Added in 7.15.1:
|
||||||
Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for
|
Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for
|
||||||
an infinite number of redirects (which is the default)
|
an infinite number of redirects (which is the default)
|
||||||
|
.IP CURLOPT_POST301
|
||||||
|
A non-zero parameter tells the library to respect RFC 2616/10.3.2 and not
|
||||||
|
convert POST requests into GET requests when following a 301 redirection. The
|
||||||
|
non-RFC behaviour is ubiquitous in web browsers, so the library does the
|
||||||
|
conversion by default to maintain consistency. However, a server may requires
|
||||||
|
a POST to remain a POST after such a redirection. This option is meaningful
|
||||||
|
only when setting \fICURLOPT_FOLLOWLOCATION\fP. (Added in 7.17.1)
|
||||||
.IP CURLOPT_PUT
|
.IP CURLOPT_PUT
|
||||||
A non-zero parameter tells the library to use HTTP PUT to transfer data. The
|
A non-zero parameter tells the library to use HTTP PUT to transfer data. The
|
||||||
data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
|
data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
|
||||||
@@ -631,14 +701,18 @@ also make the library use the a "Content-Type:
|
|||||||
application/x-www-form-urlencoded" header. (This is by far the most commonly
|
application/x-www-form-urlencoded" header. (This is by far the most commonly
|
||||||
used POST method).
|
used POST method).
|
||||||
|
|
||||||
Use the \fICURLOPT_POSTFIELDS\fP option to specify what data to post and
|
Use one of \fICURLOPT_POSTFIELDS\fP or \fICURLOPT_COPYPOSTFIELDS\fP options to
|
||||||
\fICURLOPT_POSTFIELDSIZE\fP to set the data size.
|
specify what data to post and \fICURLOPT_POSTFIELDSIZE\fP or
|
||||||
|
\fICURLOPT_POSTFIELDSIZE_LARGE\fP to set the data size.
|
||||||
|
|
||||||
Optionally, you can provide data to POST using the \fICURLOPT_READFUNCTION\fP
|
Optionally, you can provide data to POST using the \fICURLOPT_READFUNCTION\fP
|
||||||
and \fICURLOPT_READDATA\fP options but then you must make sure to not set
|
and \fICURLOPT_READDATA\fP options but then you must make sure to not set
|
||||||
\fICURLOPT_POSTFIELDS\fP to anything but NULL. When providing data with a
|
\fICURLOPT_POSTFIELDS\fP to anything but NULL. When providing data with a
|
||||||
callback, you must transmit it using chunked transfer-encoding or you must set
|
callback, you must transmit it using chunked transfer-encoding or you must set
|
||||||
the size of the data with the \fICURLOPT_POSTFIELDSIZE\fP option.
|
the size of the data with the \fICURLOPT_POSTFIELDSIZE\fP or
|
||||||
|
\fICURLOPT_POSTFIELDSIZE_LARGE\fP option. To enable chunked encoding, you
|
||||||
|
simply pass in the appropriate Transfer-Encoding header, see the
|
||||||
|
post-callback.c example.
|
||||||
|
|
||||||
You can override the default POST Content-Type: header by setting your own
|
You can override the default POST Content-Type: header by setting your own
|
||||||
with \fICURLOPT_HTTPHEADER\fP.
|
with \fICURLOPT_HTTPHEADER\fP.
|
||||||
@@ -659,11 +733,14 @@ If you issue a POST request and then want to make a HEAD or GET using the same
|
|||||||
re-used handle, you must explicitly set the new request type using
|
re-used handle, you must explicitly set the new request type using
|
||||||
\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar.
|
\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar.
|
||||||
.IP CURLOPT_POSTFIELDS
|
.IP CURLOPT_POSTFIELDS
|
||||||
Pass a char * as parameter, which should be the full data to post in an HTTP
|
Pass a void * as parameter, which should be the full data to post in an HTTP
|
||||||
POST operation. You must make sure that the data is formatted the way you want
|
POST operation. You must make sure that the data is formatted the way you want
|
||||||
the server to receive it. libcurl will not convert or encode it for you. Most
|
the server to receive it. libcurl will not convert or encode it for you. Most
|
||||||
web servers will assume this data to be url-encoded. Take note.
|
web servers will assume this data to be url-encoded. Take note.
|
||||||
|
|
||||||
|
The pointed data are NOT copied by the library: as a consequence, they must
|
||||||
|
be preserved by the calling application until the transfer finishes.
|
||||||
|
|
||||||
This POST is a normal application/x-www-form-urlencoded kind (and libcurl will
|
This POST is a normal application/x-www-form-urlencoded kind (and libcurl will
|
||||||
set that Content-Type by default when this option is used), which is the most
|
set that Content-Type by default when this option is used), which is the most
|
||||||
commonly used one by HTML forms. See also the \fICURLOPT_POST\fP. Using
|
commonly used one by HTML forms. See also the \fICURLOPT_POST\fP. Using
|
||||||
@@ -690,6 +767,22 @@ Pass a curl_off_t as parameter. Use this to set the size of the
|
|||||||
\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the
|
\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the
|
||||||
data to figure out the size. This is the large file version of the
|
data to figure out the size. This is the large file version of the
|
||||||
\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1)
|
\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1)
|
||||||
|
.IP CURLOPT_COPYPOSTFIELDS
|
||||||
|
Pass a char * as parameter, which should be the full data to post in an HTTP
|
||||||
|
POST operation. It behaves as the \fICURLOPT_POSTFIELDS\fP option, but the
|
||||||
|
original data are copied by the library, allowing the application to overwrite
|
||||||
|
the original data after setting this option.
|
||||||
|
|
||||||
|
Because data are copied, care must be taken when using this option in
|
||||||
|
conjunction with \fICURLOPT_POSTFIELDSIZE\fP or
|
||||||
|
\fICURLOPT_POSTFIELDSIZE_LARGE\fP: If the size has not been set prior to
|
||||||
|
\fICURLOPT_COPYPOSTFIELDS\fP, the data are assumed to be a NUL-terminated
|
||||||
|
string; else the stored size informs the library about the data byte count to
|
||||||
|
copy. In any case, the size must not be changed after
|
||||||
|
\fICURLOPT_COPYPOSTFIELDS\fP, unless another \fICURLOPT_POSTFIELDS\fP or
|
||||||
|
\fICURLOPT_COPYPOSTFIELDS\fP option is issued.
|
||||||
|
(Added in 7.17.1)
|
||||||
|
|
||||||
.IP CURLOPT_HTTPPOST
|
.IP CURLOPT_HTTPPOST
|
||||||
Tells libcurl you want a multipart/formdata HTTP POST to be made and you
|
Tells libcurl you want a multipart/formdata HTTP POST to be made and you
|
||||||
instruct what data to pass on to the server. Pass a pointer to a linked list
|
instruct what data to pass on to the server. Pass a pointer to a linked list
|
||||||
@@ -803,7 +896,9 @@ format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL
|
|||||||
cookie engine was not enabled it will enable its cookie engine. Passing a
|
cookie engine was not enabled it will enable its cookie engine. Passing a
|
||||||
magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1)
|
magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1)
|
||||||
Passing the special string \&"SESS" will only erase all session cookies known
|
Passing the special string \&"SESS" will only erase all session cookies known
|
||||||
by cURL. (Added in 7.15.4)
|
by cURL. (Added in 7.15.4) Passing the special string \&"FLUSH" will write
|
||||||
|
all cookies known by cURL to the file specified by \fICURLOPT_COOKIEJAR\fP.
|
||||||
|
(Added in 7.17.1)
|
||||||
.IP CURLOPT_HTTPGET
|
.IP CURLOPT_HTTPGET
|
||||||
Pass a long. If the long is non-zero, this forces the HTTP request to get back
|
Pass a long. If the long is non-zero, this forces the HTTP request to get back
|
||||||
to GET. usable if a POST, HEAD, PUT or a custom request have been used
|
to GET. usable if a POST, HEAD, PUT or a custom request have been used
|
||||||
@@ -1011,6 +1106,13 @@ or similar.
|
|||||||
libcurl does not do a complete ASCII conversion when doing ASCII transfers
|
libcurl does not do a complete ASCII conversion when doing ASCII transfers
|
||||||
over FTP. This is a known limitation/flaw that nobody has rectified. libcurl
|
over FTP. This is a known limitation/flaw that nobody has rectified. libcurl
|
||||||
simply sets the mode to ascii and performs a standard transfer.
|
simply sets the mode to ascii and performs a standard transfer.
|
||||||
|
.IP CURLOPT_PROXY_TRANSFER_MODE
|
||||||
|
Pass a long. If the value is set to 1 (one), it tells libcurl to set the
|
||||||
|
transfer mode (binary or ASCII) for FTP transfers done via an HTTP proxy, by
|
||||||
|
appending ;type=a or ;type=i to the URL. Without this setting, or it being
|
||||||
|
set to 0 (zero, the default), \fICURLOPT_TRANSFERTEXT\fP has no effect when
|
||||||
|
doing FTP via a proxy. Beware that not all proxies support this feature.
|
||||||
|
(Added in 7.18.0)
|
||||||
.IP CURLOPT_CRLF
|
.IP CURLOPT_CRLF
|
||||||
Convert Unix newlines to CRLF newlines on transfers.
|
Convert Unix newlines to CRLF newlines on transfers.
|
||||||
.IP CURLOPT_RANGE
|
.IP CURLOPT_RANGE
|
||||||
@@ -1020,6 +1122,8 @@ transfers also support several intervals, separated with commas as in
|
|||||||
\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP
|
\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP
|
||||||
server to send the response document in pieces (using standard MIME separation
|
server to send the response document in pieces (using standard MIME separation
|
||||||
techniques). Pass a NULL to this option to disable the use of ranges.
|
techniques). Pass a NULL to this option to disable the use of ranges.
|
||||||
|
|
||||||
|
Ranges work on HTTP, FTP and FILE (since 7.18.0) transfers only.
|
||||||
.IP CURLOPT_RESUME_FROM
|
.IP CURLOPT_RESUME_FROM
|
||||||
Pass a long as parameter. It contains the offset in number of bytes that you
|
Pass a long as parameter. It contains the offset in number of bytes that you
|
||||||
want the transfer to start from. Set this option to 0 to make the transfer
|
want the transfer to start from. Set this option to 0 to make the transfer
|
||||||
@@ -1030,12 +1134,19 @@ option to -1 to make the transfer start from the end of the target file
|
|||||||
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
||||||
you want the transfer to start from. (Added in 7.11.0)
|
you want the transfer to start from. (Added in 7.11.0)
|
||||||
.IP CURLOPT_CUSTOMREQUEST
|
.IP CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It will be user
|
Pass a pointer to a zero terminated string as parameter. It will be used
|
||||||
instead of GET or HEAD when doing an HTTP request, or instead of LIST or NLST
|
instead of GET or HEAD when doing an HTTP request, or instead of LIST or NLST
|
||||||
when doing an ftp directory listing. This is useful for doing DELETE or other
|
when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||||
more or less obscure HTTP requests. Don't do this at will, make sure your
|
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||||
server supports the command first.
|
server supports the command first.
|
||||||
|
|
||||||
|
Note that libcurl will still act and assume the keyword it would use if you
|
||||||
|
didn't set your custom one is the one in use and it will act according to
|
||||||
|
that. Thus, changing this to a HEAD when libcurl otherwise would do a GET
|
||||||
|
might cause libcurl to act funny, and similar. To switch to a proper HEAD, use
|
||||||
|
\fICURLOPT_NOBODY\fP, to switch to a proper POST, use \fICURLOPT_POST\fP or
|
||||||
|
\fICURLOPT_POSTFIELDS\fP and so on.
|
||||||
|
|
||||||
Restore to the internal default by setting this to NULL.
|
Restore to the internal default by setting this to NULL.
|
||||||
|
|
||||||
Many people have wrongly used this option to replace the entire request with
|
Many people have wrongly used this option to replace the entire request with
|
||||||
@@ -1266,15 +1377,19 @@ operations.
|
|||||||
|
|
||||||
If the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP is
|
If the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP is
|
||||||
returned.
|
returned.
|
||||||
|
|
||||||
|
Note that even though this option doesn't need any parameter, in some
|
||||||
|
configurations \fIcurl_easy_setopt\fP might be defined as a macro taking
|
||||||
|
exactly three arguments. Therefore, it's recommended to pass 1 as parameter to
|
||||||
|
this option.
|
||||||
.IP CURLOPT_SSLVERSION
|
.IP CURLOPT_SSLVERSION
|
||||||
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||||
The available options are:
|
The available options are:
|
||||||
.RS
|
.RS
|
||||||
.IP CURL_SSLVERSION_DEFAULT
|
.IP CURL_SSLVERSION_DEFAULT
|
||||||
The default action. When libcurl built with OpenSSL or NSS, this will attempt
|
The default action. This will attempt to figure out the remote SSL protocol
|
||||||
to figure out the remote SSL protocol version. Unfortunately there are a lot of
|
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
|
||||||
ancient and broken servers in use which cannot handle this technique and will
|
by default with 7.18.1).
|
||||||
fail to connect. When libcurl is built with GnuTLS, this will mean SSLv3.
|
|
||||||
.IP CURL_SSLVERSION_TLSv1
|
.IP CURL_SSLVERSION_TLSv1
|
||||||
Force TLSv1
|
Force TLSv1
|
||||||
.IP CURL_SSLVERSION_SSLv2
|
.IP CURL_SSLVERSION_SSLv2
|
||||||
@@ -1404,6 +1519,11 @@ Pass a long set to a bitmask consisting of one or more of
|
|||||||
CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
|
CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
|
||||||
CURLSSH_AUTH_KEYBOARD. Set CURLSSH_AUTH_ANY to let libcurl pick one.
|
CURLSSH_AUTH_KEYBOARD. Set CURLSSH_AUTH_ANY to let libcurl pick one.
|
||||||
(Added in 7.16.1)
|
(Added in 7.16.1)
|
||||||
|
.IP CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
|
||||||
|
Pass a char * pointing to a string containing 32 hexadecimal digits. The
|
||||||
|
string should be the 128 bit MD5 cheksum of the remote host's public key, and
|
||||||
|
libcurl will reject the connection to the host unless the md5sums match. This
|
||||||
|
option is only for SCP and SFTP transfers. (Added in 7.17.1)
|
||||||
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
.IP CURLOPT_SSH_PUBLIC_KEYFILE
|
||||||
Pass a char * pointing to a file name for your public key. If not used,
|
Pass a char * pointing to a file name for your public key. If not used,
|
||||||
libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
|
libcurl defaults to using \fB~/.ssh/id_dsa.pub\fP.
|
||||||
@@ -1426,6 +1546,14 @@ this curl handle use the data from the shared handle instead of keeping the
|
|||||||
data to itself. This enables several curl handles to share data. If the curl
|
data to itself. This enables several curl handles to share data. If the curl
|
||||||
handles are used simultaneously, you \fBMUST\fP use the locking methods in the
|
handles are used simultaneously, you \fBMUST\fP use the locking methods in the
|
||||||
share handle. See \fIcurl_share_setopt(3)\fP for details.
|
share handle. See \fIcurl_share_setopt(3)\fP for details.
|
||||||
|
|
||||||
|
If you add a share that is set to share cookies, your easy handle will use
|
||||||
|
that cookie cache and get the cookie engine enabled. If you unshare an object
|
||||||
|
that were using cookies (or change to another object that doesn't share
|
||||||
|
cookies), the easy handle will get its cookie engine disabled.
|
||||||
|
|
||||||
|
Data that the share object is not set to share will be dealt with the usual
|
||||||
|
way, as if no share was used.
|
||||||
.IP CURLOPT_NEW_FILE_PERMS
|
.IP CURLOPT_NEW_FILE_PERMS
|
||||||
Pass a long as a parameter, containing the value of the permissions that will
|
Pass a long as a parameter, containing the value of the permissions that will
|
||||||
be assigned to newly created files on the remote server. The default value is
|
be assigned to newly created files on the remote server. The default value is
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user