Compare commits
386 Commits
curl-7_15_
...
curl-7_15_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1d3969b215 | ||
![]() |
94116d9ebc | ||
![]() |
cc5174a89a | ||
![]() |
31552100c5 | ||
![]() |
8df5dcb193 | ||
![]() |
7929600798 | ||
![]() |
a05ea124b9 | ||
![]() |
6a03ab3ad4 | ||
![]() |
6a151c1312 | ||
![]() |
990e56fb13 | ||
![]() |
2bd3033f68 | ||
![]() |
fe105a07e3 | ||
![]() |
a5782defd3 | ||
![]() |
bcccd2fe74 | ||
![]() |
404e23734b | ||
![]() |
973d63f4f2 | ||
![]() |
405d98ee63 | ||
![]() |
f81724969d | ||
![]() |
edb5444fa3 | ||
![]() |
e877cb7bd7 | ||
![]() |
482b3ba702 | ||
![]() |
752acedc0b | ||
![]() |
fb88723afc | ||
![]() |
3718737091 | ||
![]() |
3d3f056f7e | ||
![]() |
c60621c367 | ||
![]() |
606562aa7e | ||
![]() |
f689d06ca9 | ||
![]() |
7cfd7f3fb1 | ||
![]() |
4a8dfb3461 | ||
![]() |
3752b3aead | ||
![]() |
b81d41df22 | ||
![]() |
dadf3f06ee | ||
![]() |
8ed0d5675f | ||
![]() |
d5e9041344 | ||
![]() |
d99c20f628 | ||
![]() |
973ed24dc8 | ||
![]() |
5d5f5e3be8 | ||
![]() |
d9e14408f0 | ||
![]() |
c9c5ce2365 | ||
![]() |
975534370f | ||
![]() |
28605f6bd3 | ||
![]() |
3c6d3b69c2 | ||
![]() |
00312e95fe | ||
![]() |
4223130bb0 | ||
![]() |
c811e1ce70 | ||
![]() |
77475f2ad0 | ||
![]() |
3680a2f6f5 | ||
![]() |
1946058e7b | ||
![]() |
73daf8ce33 | ||
![]() |
094ceeba14 | ||
![]() |
3b7359a27a | ||
![]() |
df9108e19b | ||
![]() |
6307e783d8 | ||
![]() |
b9cd73c76d | ||
![]() |
b62c230ca2 | ||
![]() |
800193da9b | ||
![]() |
577ba5783c | ||
![]() |
9bece2b313 | ||
![]() |
e85e30546c | ||
![]() |
758f6eed51 | ||
![]() |
80ee5d3bd8 | ||
![]() |
dd06c60ada | ||
![]() |
6ca627ae74 | ||
![]() |
80a0b81c2a | ||
![]() |
06a7b0561b | ||
![]() |
12db20be4e | ||
![]() |
3cbb1b2b64 | ||
![]() |
d75e587613 | ||
![]() |
414c57d138 | ||
![]() |
c14a84e6f2 | ||
![]() |
def0db30e7 | ||
![]() |
6ef7a81a3b | ||
![]() |
95152aec68 | ||
![]() |
8ed6762363 | ||
![]() |
87c5ed8bec | ||
![]() |
ecc6c1f501 | ||
![]() |
3d8338b0d4 | ||
![]() |
c91e25518f | ||
![]() |
a8dddeab61 | ||
![]() |
8f0a5ab660 | ||
![]() |
db03d4bdd0 | ||
![]() |
0ec96e4279 | ||
![]() |
6e520c4cdc | ||
![]() |
1e8683d72d | ||
![]() |
2df622fd14 | ||
![]() |
fede784fa2 | ||
![]() |
f191b143e9 | ||
![]() |
59212553b5 | ||
![]() |
e532b196cc | ||
![]() |
0f5232280c | ||
![]() |
38898ba4af | ||
![]() |
48f56d9600 | ||
![]() |
17bf5ac2fc | ||
![]() |
343b882d80 | ||
![]() |
db06d21339 | ||
![]() |
19240f08bb | ||
![]() |
d774730f83 | ||
![]() |
c2edf42567 | ||
![]() |
08f0e55b4f | ||
![]() |
deeb74b7e4 | ||
![]() |
0542002d7a | ||
![]() |
c1e307f585 | ||
![]() |
7b4ba43dcf | ||
![]() |
b0e4debaab | ||
![]() |
676597e961 | ||
![]() |
686d90745b | ||
![]() |
5dc02d53c3 | ||
![]() |
0598547b58 | ||
![]() |
67c7745f5d | ||
![]() |
a2c289646d | ||
![]() |
e6efecd054 | ||
![]() |
778b6a86c0 | ||
![]() |
e5babd086d | ||
![]() |
c212ebbdda | ||
![]() |
83b8de3d43 | ||
![]() |
e174d374f2 | ||
![]() |
4edb93508d | ||
![]() |
38c994b83b | ||
![]() |
1b8643d4c9 | ||
![]() |
d3c796f5b0 | ||
![]() |
83d8a6a450 | ||
![]() |
a21a77d230 | ||
![]() |
260b88c197 | ||
![]() |
655331a91b | ||
![]() |
09e569f83d | ||
![]() |
e4a4b562c4 | ||
![]() |
35b4a755f9 | ||
![]() |
5a4b43848a | ||
![]() |
d98869a088 | ||
![]() |
4d33cf739d | ||
![]() |
34e7daf989 | ||
![]() |
b0adcd6a46 | ||
![]() |
be285cde3f | ||
![]() |
0ff1faf7f2 | ||
![]() |
bcc62cc9e3 | ||
![]() |
97b466d409 | ||
![]() |
f17d9bba14 | ||
![]() |
d74725ce67 | ||
![]() |
3dad55d7a8 | ||
![]() |
598ffeea89 | ||
![]() |
83367f67de | ||
![]() |
15f2647d71 | ||
![]() |
6421d69bff | ||
![]() |
18081e30e1 | ||
![]() |
97181b5c0d | ||
![]() |
a63f9887b9 | ||
![]() |
1282aad4a5 | ||
![]() |
b8fad99f09 | ||
![]() |
c7e9e60b05 | ||
![]() |
47f2e1da73 | ||
![]() |
5975229919 | ||
![]() |
38295e8a75 | ||
![]() |
f9612b5eaf | ||
![]() |
5cf2ef2ef7 | ||
![]() |
938b5c886e | ||
![]() |
0618e68200 | ||
![]() |
bac52f3969 | ||
![]() |
d494d62953 | ||
![]() |
7206181385 | ||
![]() |
3f22901a43 | ||
![]() |
f70f11fc70 | ||
![]() |
cffebd7fd6 | ||
![]() |
b8c8e7349f | ||
![]() |
8bba99ae56 | ||
![]() |
b5c5f57613 | ||
![]() |
33df856925 | ||
![]() |
ce09cedd2e | ||
![]() |
7d68101f83 | ||
![]() |
aa50a00898 | ||
![]() |
26f112ba55 | ||
![]() |
159b9162f8 | ||
![]() |
d7999f9fcb | ||
![]() |
f13eba4c78 | ||
![]() |
050e82e088 | ||
![]() |
88377e5b61 | ||
![]() |
241af465fd | ||
![]() |
59510a554d | ||
![]() |
b10aa95d28 | ||
![]() |
097bee681a | ||
![]() |
8548c2fc61 | ||
![]() |
dc4fbd2e97 | ||
![]() |
60b029869f | ||
![]() |
f592ea6c30 | ||
![]() |
a39ac3d94a | ||
![]() |
4b23ddc002 | ||
![]() |
4486d336a6 | ||
![]() |
45e4b811b0 | ||
![]() |
0e6a1a4420 | ||
![]() |
b8bf708db9 | ||
![]() |
6fdbb01194 | ||
![]() |
d29147565c | ||
![]() |
75c9430559 | ||
![]() |
9ac99a80c3 | ||
![]() |
a15d107dde | ||
![]() |
09897b8146 | ||
![]() |
29e446e508 | ||
![]() |
10beb36b1c | ||
![]() |
a65a888866 | ||
![]() |
98180b5cc7 | ||
![]() |
92009181af | ||
![]() |
831bdb9f63 | ||
![]() |
50a4dbbb5e | ||
![]() |
ad6511c313 | ||
![]() |
7a37fa4aef | ||
![]() |
dcee24191f | ||
![]() |
87bcb6f377 | ||
![]() |
b0bc2f00d2 | ||
![]() |
3b19c7d0d9 | ||
![]() |
12f5c67bf5 | ||
![]() |
d7a83d8995 | ||
![]() |
7725729d90 | ||
![]() |
e96445bd02 | ||
![]() |
da2c124675 | ||
![]() |
8cb695a963 | ||
![]() |
54cbd7e154 | ||
![]() |
5994b62930 | ||
![]() |
2fbf94b0f3 | ||
![]() |
32bc30e210 | ||
![]() |
f3bc8e6ce1 | ||
![]() |
16f3a32bec | ||
![]() |
c44d2498e3 | ||
![]() |
2aed209efa | ||
![]() |
b55b780d7b | ||
![]() |
8d4eb2bc1f | ||
![]() |
67bf4f28ff | ||
![]() |
803582f8ac | ||
![]() |
03603f392a | ||
![]() |
fcfd6d9504 | ||
![]() |
c31451cf13 | ||
![]() |
5deff1a179 | ||
![]() |
e236a1c99b | ||
![]() |
a2f3094eb0 | ||
![]() |
65afc576ea | ||
![]() |
8971f656b4 | ||
![]() |
394ce9ee39 | ||
![]() |
67a83c1b34 | ||
![]() |
1e8d094274 | ||
![]() |
4c35a40858 | ||
![]() |
802b2aaf6a | ||
![]() |
0e79a8944b | ||
![]() |
bebf70667d | ||
![]() |
d9bd5de0b1 | ||
![]() |
31c7aa0ba4 | ||
![]() |
fc2388189f | ||
![]() |
4431338691 | ||
![]() |
bda1e9aeab | ||
![]() |
4969ca768d | ||
![]() |
2acd1c1642 | ||
![]() |
e1e753179a | ||
![]() |
f4cc8153ae | ||
![]() |
e4d8cb4ee0 | ||
![]() |
723a78ae3f | ||
![]() |
cd9d0d7dec | ||
![]() |
665d4f08c8 | ||
![]() |
00c7780fcb | ||
![]() |
15ab13dc42 | ||
![]() |
8a0ca3066e | ||
![]() |
ea01755bb4 | ||
![]() |
69c2084a18 | ||
![]() |
99c0a1a7d0 | ||
![]() |
5acf997e69 | ||
![]() |
dd87e4ed39 | ||
![]() |
2f8c26ba8a | ||
![]() |
81b9793807 | ||
![]() |
7278f17e8f | ||
![]() |
66c7427df0 | ||
![]() |
c1a06d858d | ||
![]() |
53b5fdbe9e | ||
![]() |
687cf0235e | ||
![]() |
b6e9229cf0 | ||
![]() |
089e4848d8 | ||
![]() |
58d2e7c6d1 | ||
![]() |
fa18d6fb76 | ||
![]() |
4dcb930247 | ||
![]() |
74a299fd08 | ||
![]() |
532a560d87 | ||
![]() |
0040a60559 | ||
![]() |
cc34342790 | ||
![]() |
bdbf6e9d19 | ||
![]() |
db86f765eb | ||
![]() |
b11dec5dd5 | ||
![]() |
86becc7591 | ||
![]() |
8922bc038b | ||
![]() |
009f5790a4 | ||
![]() |
0536b6c459 | ||
![]() |
0e3ebd9841 | ||
![]() |
598965a606 | ||
![]() |
d7a2938849 | ||
![]() |
a683658675 | ||
![]() |
25169f68b7 | ||
![]() |
e5247ae65d | ||
![]() |
a718cb05ff | ||
![]() |
b466ef2581 | ||
![]() |
c7a634641f | ||
![]() |
e4388643f1 | ||
![]() |
bc4208201c | ||
![]() |
a0d69d52a1 | ||
![]() |
c23a1be139 | ||
![]() |
9799f7afb0 | ||
![]() |
6358b24fac | ||
![]() |
b58634316f | ||
![]() |
e3657644d6 | ||
![]() |
7d1e3ebeed | ||
![]() |
9e61dfe85e | ||
![]() |
7b51aafa86 | ||
![]() |
5f487123df | ||
![]() |
f1f32477e3 | ||
![]() |
df2b1251a0 | ||
![]() |
02c7cf6fa5 | ||
![]() |
60006ff993 | ||
![]() |
f3af5d7b8e | ||
![]() |
d551412a32 | ||
![]() |
6de67a134e | ||
![]() |
8ec31398e0 | ||
![]() |
fd0d560b47 | ||
![]() |
cc542269a1 | ||
![]() |
7b488a3bef | ||
![]() |
f448168501 | ||
![]() |
80a8fb98db | ||
![]() |
898bb397b1 | ||
![]() |
74ed5b5ebd | ||
![]() |
178afd81a9 | ||
![]() |
d6eb1a7b98 | ||
![]() |
4ff56b15e9 | ||
![]() |
e6b98d3152 | ||
![]() |
5fd8dd2dce | ||
![]() |
0ad3e046a4 | ||
![]() |
d6c5d24af3 | ||
![]() |
8a3280a2de | ||
![]() |
450a0a647a | ||
![]() |
676c0cf123 | ||
![]() |
a731319321 | ||
![]() |
81b06a09b7 | ||
![]() |
23b34744d9 | ||
![]() |
bc8590aa12 | ||
![]() |
939d368d5f | ||
![]() |
336e3b8baf | ||
![]() |
47c06fa308 | ||
![]() |
b7f447f8d8 | ||
![]() |
03af76b631 | ||
![]() |
e105d5c28f | ||
![]() |
d6ffb4c177 | ||
![]() |
6dbfce1031 | ||
![]() |
fea5ddf585 | ||
![]() |
b9f39c2711 | ||
![]() |
5acac0309a | ||
![]() |
78febad718 | ||
![]() |
a6a5bba0a9 | ||
![]() |
51581c034d | ||
![]() |
8f25a95b47 | ||
![]() |
7f5d092223 | ||
![]() |
2e5cccd1b6 | ||
![]() |
2645782f89 | ||
![]() |
9533092511 | ||
![]() |
6005a461bb | ||
![]() |
e2df946eee | ||
![]() |
d14588120f | ||
![]() |
ab31cfa664 | ||
![]() |
af1c397969 | ||
![]() |
947f9deed5 | ||
![]() |
ce95eee903 | ||
![]() |
b15f3bb969 | ||
![]() |
998e8cba19 | ||
![]() |
e3f523ab2a | ||
![]() |
36485e56ed | ||
![]() |
b4113360f6 | ||
![]() |
2d71e22f08 | ||
![]() |
2ae67c431c | ||
![]() |
4b1a91b64f | ||
![]() |
4f69318e12 | ||
![]() |
1cc98ab50f | ||
![]() |
a6494602fd | ||
![]() |
50ec78b488 | ||
![]() |
7d044d14f9 | ||
![]() |
df03d5a8b2 | ||
![]() |
6a0ed81e67 | ||
![]() |
c94f3e8188 | ||
![]() |
1e5f6cc1dc | ||
![]() |
b1fece74e3 | ||
![]() |
fdbe0df6e7 | ||
![]() |
93d59520e4 | ||
![]() |
b68d3a073b | ||
![]() |
2100311f41 | ||
![]() |
e1269e3156 | ||
![]() |
c88d61b044 |
1183
CHANGES.2005
Normal file
1183
CHANGES.2005
Normal file
File diff suppressed because it is too large
Load Diff
2
COPYING
2
COPYING
@@ -1,6 +1,6 @@
|
|||||||
COPYRIGHT AND PERMISSION NOTICE
|
COPYRIGHT AND PERMISSION NOTICE
|
||||||
|
|
||||||
Copyright (c) 1996 - 2005, Daniel Stenberg, <daniel@haxx.se>.
|
Copyright (c) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>.
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
6
CVS-INFO
6
CVS-INFO
@@ -53,12 +53,6 @@ installed:
|
|||||||
give you an older version of the file that isn't up-to-date. That file was
|
give you an older version of the file that isn't up-to-date. That file was
|
||||||
checked in once and won't be updated very regularly.
|
checked in once and won't be updated very regularly.
|
||||||
|
|
||||||
o yacc/bison
|
|
||||||
|
|
||||||
If you don't have yacc or bison, you must rename the lib/getdate.c.cvs file
|
|
||||||
to lib/getdate.c to be able to build libcurl. yacc/bison is normally used
|
|
||||||
to generate the lib/getdate.c file from the lib/getdate.y source file.
|
|
||||||
|
|
||||||
MAC OS X
|
MAC OS X
|
||||||
|
|
||||||
With Mac OS X 10.2 and the associated Developer Tools, the installed versions
|
With Mac OS X 10.2 and the associated Developer Tools, the installed versions
|
||||||
|
27
README
27
README
@@ -33,32 +33,7 @@ WEB SITE
|
|||||||
Visit the curl web site or mirrors for the latest news and downloads:
|
Visit the curl web site or mirrors for the latest news and downloads:
|
||||||
|
|
||||||
Sweden http://curl.haxx.se/
|
Sweden http://curl.haxx.se/
|
||||||
Australia http://curl.planetmirror.com/
|
Mirrors http://curlm.haxx.se/
|
||||||
Austria http://curl.gds.tuwien.ac.at/
|
|
||||||
Denmark http://curl.cofman.dk/
|
|
||||||
France http://curl.fastmirror.net/
|
|
||||||
Germany http://curl.miscellaneousmirror.org/
|
|
||||||
Germany http://curl.mirror.at.stealer.net/
|
|
||||||
Germany http://curl.mirroring.de/
|
|
||||||
Germany http://curl.mons-new-media.de/
|
|
||||||
Germany http://curl.triplemind.com/
|
|
||||||
Germany http://curl.freemirror.de/
|
|
||||||
Netherlands http://curl.nedmirror.nl/
|
|
||||||
Russia http://curl.tsuren.net/
|
|
||||||
Taiwan http://curl.cs.pu.edu.tw/
|
|
||||||
Thailand http://curl.siamu.ac.th/
|
|
||||||
US (AZ) http://curl.islandofpoker.com/
|
|
||||||
US (CA) http://curl.mirror.redwire.net/
|
|
||||||
US (CA) http://curl.mirrormonster.com/
|
|
||||||
US (CA) http://curl.signal42.com/
|
|
||||||
US (CA) http://curl.tolix.org/
|
|
||||||
US (CA) http://curl.webhosting76.com/
|
|
||||||
US (CA) http://curl.meulie.net/
|
|
||||||
US (FL) http://curl.hoxt.com/
|
|
||||||
US (TX) http://curl.109k.com/
|
|
||||||
US (TX) http://curl.mirrors.cyberservers.net/
|
|
||||||
US (TX) http://curl.seekmeup.com/
|
|
||||||
US (TX) http://curl.hostingzero.com/
|
|
||||||
|
|
||||||
CVS
|
CVS
|
||||||
|
|
||||||
|
101
RELEASE-NOTES
101
RELEASE-NOTES
@@ -1,61 +1,72 @@
|
|||||||
Curl and libcurl 7.15.1
|
Curl and libcurl 7.15.4
|
||||||
|
|
||||||
Public curl release number: 91
|
Public curl release number: 94
|
||||||
Releases counted from the very beginning: 118
|
Releases counted from the very beginning: 121
|
||||||
Available command line options: 109
|
Available command line options: 112
|
||||||
Available curl_easy_setopt() options: 125
|
Available curl_easy_setopt() options: 132
|
||||||
Number of public functions in libcurl: 46
|
Number of public functions in libcurl: 49
|
||||||
Amount of public web site mirrors: 27
|
Amount of public web site mirrors: 33
|
||||||
Number of known libcurl bindings: 32
|
Number of known libcurl bindings: 32
|
||||||
Number of contributors: 459
|
Number of contributors: 492
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o the libcurl.pc pkgconfig file now gets installed on make install
|
o NTLM2 session response support
|
||||||
o URL globbing now offers "range steps": [1-100:10]
|
o CURLOPT_COOKIELIST set to "SESS" clears all session cookies
|
||||||
o LDAPv3 is now the preferred LDAP protocol version
|
o CURLINFO_LASTSOCKET returned sockets are now checked more before returned
|
||||||
o --max-redirs and CURLOPT_MAXREDIRS set to 0 limits redirects
|
o curl-config got a --checkfor option to compare version numbers
|
||||||
o improved MSVC makefile
|
o line end conversions for FTP ASCII transfers
|
||||||
|
o curl_multi_socket() API added (still mostly untested)
|
||||||
|
o conversion callback options for EBCDIC <=> ASCII conversions
|
||||||
|
o added CURLINFO_FTP_ENTRY_PATH
|
||||||
|
o less blocking for the multi interface during (Open)SSL connect negotiation
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o buffer overflow problem: http://curl.haxx.se/docs/adv_20051207.html
|
o builds fine on cygwin
|
||||||
o using file:// on non-existing files are properly handled
|
o md5-sess with Digest authentication
|
||||||
o builds fine on DJGPP
|
o dict with letters such as space in a word
|
||||||
o CURLOPT_ERRORBUFFER is now always filled in on errors
|
o dict with url-encoded words in the URL
|
||||||
o curl outputs error on bad --limit-rate units
|
o libcurl.m4 when default=yes but no libcurl was found
|
||||||
o fixed libcurl's use of poll() on cygwin
|
o numerous bugs fixed in the TFTP code
|
||||||
o the GnuTLS code didn't support client certificates
|
o possible memory leak when adding easy handles to multi stack
|
||||||
o TFTP over IPv6 works
|
o TFTP works in a more portable fashion (== on more platforms)
|
||||||
o no reverse lookups on IP addresses when ipv6-enabled
|
o WSAGetLastError() is now used (better) on Windows
|
||||||
o SSPI compatibility fix: using the proper DLLs
|
o GnuTLS non-block case that could cause data trashing
|
||||||
o binary LDAP properties are now shown base64 encoded
|
o deflate code survives lack of zlib header
|
||||||
o Windows uploads from stdin using curl can now contain ctrl-Z bytes
|
o CURLOPT_INTERFACE works with hostname
|
||||||
o -r [num] would produce an invalid HTTP Range: header
|
o configure runs fine with ICC
|
||||||
o multi interface with multi IP hosts could leak socket descriptors
|
o closed control connection with FTP when easy handle was removed from multi
|
||||||
o the GnuTLS code didn't handle rehandshakes
|
o curl --trace crash when built with VS2005
|
||||||
o re-use of a dead FTP connection
|
o SSL connect time-out
|
||||||
o name resolve error codes fixed for Windows builds
|
o improved NTLM functionality
|
||||||
o double WWW-Authenticate Digest headers are now handled
|
o following redirects with more than one question mark in source URL
|
||||||
o curl-config --vernum fixed
|
o fixed debug build crash with -d
|
||||||
|
o generates a fine AIX Toolbox RPM spec
|
||||||
|
o treat FTP AUTH failures properly
|
||||||
|
o TFTP transfers could trash data
|
||||||
|
o -d + -G combo crash
|
||||||
|
|
||||||
Other curl-related news since the previous public release:
|
Other curl-related news:
|
||||||
|
|
||||||
o FTP-SSL is now RFC4217
|
o tclcurl 0.15.3 was released:
|
||||||
o CurlPas 2005-11-05 was released: http://curlpas.sf.net/
|
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||||
o pycurl 7.15.0 was released http://pycurl.sf.net
|
|
||||||
o New web mirrors:
|
New curl mirrors:
|
||||||
http://curl.triplemind.com/ located in Mannheim, Germany
|
|
||||||
http://curl.nedmirror.nl located in Amsterdam, the Netherlands
|
o http://curl.webdesign-zdg.de/ in Frankfurt, Germany
|
||||||
http://curl.hoxt.com located in Florida, US
|
o http://curl.de-mirror.de/ in Aachen, Germany
|
||||||
|
o http://curl.osmirror.nl/ in Amsterdam, the Netherlands
|
||||||
|
o http://curl.usphp.com/ in Florida, US
|
||||||
|
o http://curl.oslevel.de/ in Karlsruhe, Germany
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
Dave Dribin, Bradford Bruce, Temprimus, Ofer, Dima Barsky, Amol Pattekar, Jaz
|
Dan Fandrich, Ilja van Sprundel, David McCreedy, Tor Arntsen, Xavier Bouchoux,
|
||||||
Fresh, tommink[at]post.pl, Gisle Vanem, Nis Jorgensen, Vilmos Nebehaj, Dmitry
|
David Byron, Michele Bini, Ates Goral, Katie Wang, Robson Braga Araujo,
|
||||||
Bartsevich, David Lang, Eugene Kotlyarov, Jan Kunder, Yang Tse, Quagmire,
|
Ale Vesely, Paul Querna, Gisle Vanem, Mark Eichin, Roland Blom, Andreas
|
||||||
Albert Chin, David Shaw, Doug Kaufman, Bryan Henderson, Jamie Newton, Stefan
|
Ntaflos, David Shaw, Michael Wallner, Olaf St<53>ben, Mikael Sennerholm,
|
||||||
Esser
|
Brian Dessent
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
To get fixed in 7.15.0 (planned release: November 2005)
|
To get fixed in 7.15.4 (planned release: June 2006)
|
||||||
======================
|
======================
|
||||||
|
|
||||||
60 - CONNECT 407 responses that kills the connection (not very likely though)
|
66 -
|
||||||
|
|
||||||
63 -
|
|
||||||
|
|
||||||
|
601
acinclude.m4
601
acinclude.m4
@@ -1,3 +1,393 @@
|
|||||||
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
#
|
||||||
|
# This software is licensed as described in the file COPYING, which
|
||||||
|
# you should have received as part of this distribution. The terms
|
||||||
|
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
#
|
||||||
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
# copies of the Software, and permit persons to whom the Software is
|
||||||
|
# furnished to do so, under the terms of the COPYING file.
|
||||||
|
#
|
||||||
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, either express or implied.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINDOWS
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid windows.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [
|
||||||
|
AC_CACHE_CHECK([for windows.h], [ac_cv_header_windows_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*WINVER;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_windows_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_windows_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_windows_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1,
|
||||||
|
[Define to 1 if you have the windows.h header file.])
|
||||||
|
AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1,
|
||||||
|
[Define to avoid automatic inclusion of winsock.h])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINSOCK
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winsock.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for winsock.h], [ac_cv_header_winsock_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
],[
|
||||||
|
int dummy=WSACleanup();
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_winsock_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1,
|
||||||
|
[Define to 1 if you have the winsock.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINSOCK2
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winsock2.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for winsock2.h], [ac_cv_header_winsock2_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*IPPROTO_ESP;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock2_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock2_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_winsock2_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1,
|
||||||
|
[Define to 1 if you have the winsock2.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WS2TCPIP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid ws2tcpip.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
|
||||||
|
AC_CACHE_CHECK([for ws2tcpip.h], [ac_cv_header_ws2tcpip_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*IP_PKTINFO;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_ws2tcpip_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_ws2tcpip_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_ws2tcpip_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1,
|
||||||
|
[Define to 1 if you have the ws2tcpip.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_TYPE_SOCKLEN_T
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for existing socklen_t type, and provide
|
||||||
|
dnl an equivalent type if socklen_t not available
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_TYPE_SOCKLEN_T], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl
|
||||||
|
AC_CHECK_TYPE([socklen_t], ,[
|
||||||
|
AC_CACHE_CHECK([for socklen_t equivalent],
|
||||||
|
[curl_cv_socklen_t_equiv], [
|
||||||
|
curl_cv_socklen_t_equiv="unknown"
|
||||||
|
for arg2 in "struct sockaddr" void; do
|
||||||
|
for t in int size_t unsigned long "unsigned long"; do
|
||||||
|
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>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
int getpeername (int, $arg2 *, $t *);
|
||||||
|
],[
|
||||||
|
$t len=0;
|
||||||
|
getpeername(0,0,&len);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_socklen_t_equiv="$t"
|
||||||
|
break 2
|
||||||
|
])
|
||||||
|
done
|
||||||
|
done
|
||||||
|
])
|
||||||
|
if test "$curl_cv_socklen_t_equiv" = "unknown"; then
|
||||||
|
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
|
||||||
|
[type to use in place of socklen_t if not defined])
|
||||||
|
fi
|
||||||
|
],[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_FUNC_GETNAMEINFO
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Test if the getnameinfo function is available,
|
||||||
|
dnl and check the types of five of its arguments.
|
||||||
|
dnl If the function succeeds HAVE_GETNAMEINFO will be
|
||||||
|
dnl defined, defining the types of the arguments in
|
||||||
|
dnl GETNAMEINFO_TYPE_ARG1, GETNAMEINFO_TYPE_ARG2,
|
||||||
|
dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7.
|
||||||
|
dnl This function is experimental and its results shall
|
||||||
|
dnl not be trusted while this notice is in place ------
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl
|
||||||
|
AC_REQUIRE([CURL_CHECK_TYPE_SOCKLEN_T])dnl
|
||||||
|
AC_CHECK_HEADERS(sys/types.h sys/socket.h netdb.h)
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for getnameinfo])
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
AC_LANG_FUNC_LINK_TRY([getnameinfo])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" != "yes"; then
|
||||||
|
AC_MSG_CHECKING([deeper for getnameinfo])
|
||||||
|
AC_TRY_LINK([
|
||||||
|
],[
|
||||||
|
getnameinfo();
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([but still no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" != "yes"; then
|
||||||
|
AC_MSG_CHECKING([deeper and deeper for getnameinfo])
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
getnameinfo(0, 0, 0, 0, 0, 0, 0);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([but still no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" = "yes"; then
|
||||||
|
AC_CACHE_CHECK([types of arguments for getnameinfo],
|
||||||
|
[curl_cv_func_getnameinfo_args], [
|
||||||
|
curl_cv_func_getnameinfo_args="unknown"
|
||||||
|
for gni_arg1 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do
|
||||||
|
for gni_arg2 in 'socklen_t' 'size_t' 'int'; do
|
||||||
|
for gni_arg46 in 'size_t' 'int' 'socklen_t' 'unsigned int' 'DWORD'; do
|
||||||
|
for gni_arg7 in 'int' 'unsigned int'; do
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#if (!defined(_WIN32_WINNT)) || (_WIN32_WINNT < 0x0501)
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define GNICALLCONV WSAAPI
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#define GNICALLCONV
|
||||||
|
#endif
|
||||||
|
extern int GNICALLCONV getnameinfo($gni_arg1, $gni_arg2,
|
||||||
|
char *, $gni_arg46,
|
||||||
|
char *, $gni_arg46,
|
||||||
|
$gni_arg7);
|
||||||
|
],[
|
||||||
|
$gni_arg2 salen=0;
|
||||||
|
$gni_arg46 hostlen=0;
|
||||||
|
$gni_arg46 servlen=0;
|
||||||
|
$gni_arg7 flags=0;
|
||||||
|
int res = getnameinfo(0, salen, 0, hostlen, 0, servlen, flags);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_func_getnameinfo_args="$gni_arg1,$gni_arg2,$gni_arg46,$gni_arg7"
|
||||||
|
break 4
|
||||||
|
])
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
]) # AC_CACHE_CHECK
|
||||||
|
if test "$curl_cv_func_getnameinfo_args" = "unknown"; then
|
||||||
|
AC_MSG_WARN([Cannot find proper types to use for getnameinfo args])
|
||||||
|
AC_MSG_WARN([HAVE_GETNAMEINFO will not be defined])
|
||||||
|
else
|
||||||
|
gni_prev_IFS=$IFS; IFS=','
|
||||||
|
set dummy `echo "$curl_cv_func_getnameinfo_args" | sed 's/\*/\*/g'`
|
||||||
|
IFS=$gni_prev_IFS
|
||||||
|
shift
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $[1],
|
||||||
|
[Define to the type of arg 1 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG2, $[2],
|
||||||
|
[Define to the type of arg 2 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG46, $[3],
|
||||||
|
[Define to the type of args 4 and 6 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG7, $[4],
|
||||||
|
[Define to the type of arg 7 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_GETNAMEINFO, 1,
|
||||||
|
[Define to 1 if you have the getnameinfo function.])
|
||||||
|
ac_cv_func_getnameinfo="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
]) # AC_DEFUN
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||||
|
dnl -------------------------------------------------
|
||||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||||
dnl four known different ways, with the one used almost everywhere being POSIX
|
dnl four known different ways, with the one used almost everywhere being POSIX
|
||||||
dnl and XPG3, while the other different ways for different systems (old BSD,
|
dnl and XPG3, while the other different ways for different systems (old BSD,
|
||||||
@@ -59,12 +449,27 @@ dnl FIONBIO test was also bad
|
|||||||
dnl the code was bad, try a different program now, test 3
|
dnl the code was bad, try a different program now, test 3
|
||||||
|
|
||||||
AC_TRY_COMPILE([
|
AC_TRY_COMPILE([
|
||||||
/* headers for ioctlsocket test (cygwin?) */
|
/* headers for ioctlsocket test (Windows) */
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
],[
|
],[
|
||||||
/* ioctlsocket source code */
|
/* ioctlsocket source code */
|
||||||
int socket;
|
SOCKET sd;
|
||||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
unsigned long flags = 0;
|
||||||
|
sd = socket(0, 0, 0);
|
||||||
|
ioctlsocket(sd, FIONBIO, &flags);
|
||||||
],[
|
],[
|
||||||
dnl ioctlsocket test was good
|
dnl ioctlsocket test was good
|
||||||
nonblock="ioctlsocket"
|
nonblock="ioctlsocket"
|
||||||
@@ -122,6 +527,9 @@ dnl end of non-blocking try-compile test
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl TYPE_SOCKADDR_STORAGE
|
||||||
|
dnl -------------------------------------------------
|
||||||
dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but
|
dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but
|
||||||
dnl AIX 4.3 is one known exception.
|
dnl AIX 4.3 is one known exception.
|
||||||
AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
||||||
@@ -130,6 +538,16 @@ AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
|||||||
AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1,
|
AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1,
|
||||||
[if struct sockaddr_storage is defined]), ,
|
[if struct sockaddr_storage is defined]), ,
|
||||||
[
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -142,58 +560,13 @@ AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
|||||||
#ifdef HAVE_ARPA_INET_H
|
#ifdef HAVE_ARPA_INET_H
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl Check for socklen_t: historically on BSD it is an int, and in
|
|
||||||
dnl POSIX 1g it is a type of its own, but some platforms use different
|
|
||||||
dnl types for the argument to getsockopt, getpeername, etc. So we
|
|
||||||
dnl have to test to find something that will work.
|
|
||||||
AC_DEFUN([TYPE_SOCKLEN_T],
|
|
||||||
[
|
|
||||||
AC_CHECK_TYPE([socklen_t], ,[
|
|
||||||
AC_MSG_CHECKING([for socklen_t equivalent])
|
|
||||||
AC_CACHE_VAL([curl_cv_socklen_t_equiv],
|
|
||||||
[
|
|
||||||
# Systems have either "struct sockaddr *" or
|
|
||||||
# "void *" as the second argument to getpeername
|
|
||||||
curl_cv_socklen_t_equiv=
|
|
||||||
for arg2 in "struct sockaddr" void; do
|
|
||||||
for t in int size_t unsigned long "unsigned long"; do
|
|
||||||
AC_TRY_COMPILE([
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int getpeername (int, $arg2 *, $t *);
|
|
||||||
],[
|
|
||||||
$t len;
|
|
||||||
getpeername(0,0,&len);
|
|
||||||
],[
|
|
||||||
curl_cv_socklen_t_equiv="$t"
|
|
||||||
break
|
|
||||||
])
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
if test "x$curl_cv_socklen_t_equiv" = x; then
|
|
||||||
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
AC_MSG_RESULT($curl_cv_socklen_t_equiv)
|
|
||||||
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
|
|
||||||
[type to use in place of socklen_t if not defined])],
|
|
||||||
[#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
dnl TYPE_IN_ADDR_T
|
||||||
|
dnl -------------------------------------------------
|
||||||
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||||
dnl and a few other things.
|
dnl and a few other things.
|
||||||
AC_DEFUN([TYPE_IN_ADDR_T],
|
AC_DEFUN([TYPE_IN_ADDR_T],
|
||||||
@@ -205,15 +578,33 @@ AC_DEFUN([TYPE_IN_ADDR_T],
|
|||||||
curl_cv_in_addr_t_equiv=
|
curl_cv_in_addr_t_equiv=
|
||||||
for t in "unsigned long" int size_t unsigned long; do
|
for t in "unsigned long" int size_t unsigned long; do
|
||||||
AC_TRY_COMPILE([
|
AC_TRY_COMPILE([
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#undef inline
|
||||||
#include <sys/types.h>
|
#ifdef HAVE_WINDOWS_H
|
||||||
#endif
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <sys/socket.h>
|
#endif
|
||||||
#endif
|
#include <windows.h>
|
||||||
#ifdef HAVE_ARPA_INET_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <arpa/inet.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
],[
|
],[
|
||||||
$t data = inet_addr ("1.2.3.4");
|
$t data = inet_addr ("1.2.3.4");
|
||||||
],[
|
],[
|
||||||
@@ -229,10 +620,36 @@ AC_DEFUN([TYPE_IN_ADDR_T],
|
|||||||
AC_MSG_RESULT($curl_cv_in_addr_t_equiv)
|
AC_MSG_RESULT($curl_cv_in_addr_t_equiv)
|
||||||
AC_DEFINE_UNQUOTED(in_addr_t, $curl_cv_in_addr_t_equiv,
|
AC_DEFINE_UNQUOTED(in_addr_t, $curl_cv_in_addr_t_equiv,
|
||||||
[type to use in place of in_addr_t if not defined])],
|
[type to use in place of in_addr_t if not defined])],
|
||||||
[#include <sys/types.h>
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>])
|
#endif
|
||||||
])
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
]) dnl AC_CHECK_TYPE
|
||||||
|
]) dnl AC_DEFUN
|
||||||
|
|
||||||
dnl ************************************************************
|
dnl ************************************************************
|
||||||
dnl check for "localhost", if it doesn't exist, we can't do the
|
dnl check for "localhost", if it doesn't exist, we can't do the
|
||||||
@@ -687,12 +1104,45 @@ if test "$ac_cv_func_gethostbyname_r" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl CURL_DETECT_ICC ([ACTION-IF-YES])
|
||||||
|
dnl
|
||||||
|
dnl check if this is the Intel ICC compiler, and if so run the ACTION-IF-YES
|
||||||
|
dnl sets the $ICC variable to "yes" or "no"
|
||||||
|
dnl **********************************************************************
|
||||||
|
AC_DEFUN([CURL_DETECT_ICC],
|
||||||
|
[
|
||||||
|
ICC="no"
|
||||||
|
AC_MSG_CHECKING([for icc in use])
|
||||||
|
if test "$GCC" = "yes"; then
|
||||||
|
dnl check if this is icc acting as gcc in disguise
|
||||||
|
AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
|
||||||
|
dnl action if the text is found, this it has not been replaced by the
|
||||||
|
dnl cpp
|
||||||
|
ICC="no",
|
||||||
|
dnl the text was not found, it was replaced by the cpp
|
||||||
|
ICC="yes"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
[$1]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if test "$ICC" = "no"; then
|
||||||
|
# this is not ICC
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
dnl We create a function for detecting which compiler we use and then set as
|
dnl We create a function for detecting which compiler we use and then set as
|
||||||
dnl pendantic compiler options as possible for that particular compiler. The
|
dnl pendantic compiler options as possible for that particular compiler. The
|
||||||
dnl options are only used for debug-builds.
|
dnl options are only used for debug-builds.
|
||||||
|
|
||||||
AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||||
[
|
[
|
||||||
|
if test "z$ICC" = "z"; then
|
||||||
|
CURL_DETECT_ICC
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$GCC" = "yes"; then
|
if test "$GCC" = "yes"; then
|
||||||
|
|
||||||
dnl figure out gcc version!
|
dnl figure out gcc version!
|
||||||
@@ -703,17 +1153,6 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
|||||||
gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
|
gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
|
||||||
AC_MSG_RESULT($gccver)
|
AC_MSG_RESULT($gccver)
|
||||||
|
|
||||||
AC_MSG_CHECKING([if this is icc in disguise])
|
|
||||||
AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
|
|
||||||
dnl action if the text is found, this it has not been replaced by the
|
|
||||||
dnl cpp
|
|
||||||
ICC="no"
|
|
||||||
AC_MSG_RESULT([no]),
|
|
||||||
dnl the text was not found, it was replaced by the cpp
|
|
||||||
ICC="yes"
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
)
|
|
||||||
|
|
||||||
if test "$ICC" = "yes"; then
|
if test "$ICC" = "yes"; then
|
||||||
dnl this is icc, not gcc.
|
dnl this is icc, not gcc.
|
||||||
|
|
||||||
@@ -884,3 +1323,19 @@ else
|
|||||||
AC_MSG_RESULT($DLFOUNDFILE)
|
AC_MSG_RESULT($DLFOUNDFILE)
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# This is only a temporary fix. This macro is here to replace the broken one
|
||||||
|
# delivered by the automake project (including the 1.9.6 release). As soon as
|
||||||
|
# they ship a working version we SHOULD remove this work-around.
|
||||||
|
|
||||||
|
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||||
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
test x"${MISSING+set}" = xset || MISSING="\${SHELL} \"$am_aux_dir/missing\""
|
||||||
|
# Use eval to expand $SHELL
|
||||||
|
if eval "$MISSING --run true"; then
|
||||||
|
am_missing_run="$MISSING --run "
|
||||||
|
else
|
||||||
|
am_missing_run=
|
||||||
|
AC_MSG_WARN([`missing' script is too old or missing])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
@@ -11,3 +11,6 @@ Dan Fandrich
|
|||||||
Gisle Vanem
|
Gisle Vanem
|
||||||
Gunter Knauf
|
Gunter Knauf
|
||||||
Henrik Stoerner
|
Henrik Stoerner
|
||||||
|
Yang Tse
|
||||||
|
Nick Mathewson
|
||||||
|
Alexander Lazic
|
||||||
|
37
ares/CHANGES
37
ares/CHANGES
@@ -1,5 +1,38 @@
|
|||||||
Changelog for the c-ares project
|
Changelog for the c-ares project
|
||||||
|
|
||||||
|
* May 10, 2006
|
||||||
|
|
||||||
|
- Bram Matthys brought my attention to a libtool peculiarity where detecting
|
||||||
|
things such as C++ compiler actually is a bad thing and since we don't need
|
||||||
|
that detection I added a work-around, much inspired by a previous patch by
|
||||||
|
Paolo Bonzini. This also shortens the configure script quite a lot.
|
||||||
|
|
||||||
|
* May 3, 2006
|
||||||
|
|
||||||
|
- Nick Mathewson added the ARES_OPT_SOCK_STATE_CB option that when set makes
|
||||||
|
c-ares call a callback on socket state changes. A better way than the
|
||||||
|
ares_getsock() to get full control over the socket state.
|
||||||
|
|
||||||
|
* January 9, 2006
|
||||||
|
|
||||||
|
- Alexander Lazic improved the getservbyport_r() configure check.
|
||||||
|
|
||||||
|
* January 6, 2006
|
||||||
|
|
||||||
|
- Alexander Lazic pointed out that the buildconf should use the ACLOCAL_FLAGS
|
||||||
|
variable for easier controlling what it does and how it runs.
|
||||||
|
|
||||||
|
* January 5, 2006
|
||||||
|
|
||||||
|
- James Bursa fixed c-ares to find the hosts file on RISC OS, and made it
|
||||||
|
build with newer gcc versions that no longer defines "riscos".
|
||||||
|
|
||||||
|
* December 22
|
||||||
|
|
||||||
|
- Daniel Stenberg added ares_getsock() that extracts the set of sockets to
|
||||||
|
wait for action on. Similar to ares_fds() but not restricted to using
|
||||||
|
select() for the waiting.
|
||||||
|
|
||||||
* November 25
|
* November 25
|
||||||
|
|
||||||
- Yang Tse fixed some send() / recv() compiler warnings
|
- Yang Tse fixed some send() / recv() compiler warnings
|
||||||
@@ -8,8 +41,8 @@
|
|||||||
|
|
||||||
- Added constants that will be used by ares_getaddrinfo
|
- Added constants that will be used by ares_getaddrinfo
|
||||||
|
|
||||||
- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it is
|
- Made ares_getnameinfo use the reentrant getservbyport (getservbyport_r) if it
|
||||||
available to ensure it works properly in a threaded environment.
|
is available to ensure it works properly in a threaded environment.
|
||||||
|
|
||||||
* September 10
|
* September 10
|
||||||
|
|
||||||
|
@@ -43,7 +43,13 @@ VER=-version-info 1:0:0
|
|||||||
# set age to 0. (c:r:a=0)
|
# set age to 0. (c:r:a=0)
|
||||||
#
|
#
|
||||||
|
|
||||||
libcares_la_LDFLAGS = $(VER)
|
if NO_UNDEFINED
|
||||||
|
# The -no-undefined flag is crucial for this to build fine on some platforms
|
||||||
|
UNDEF = -no-undefined
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
libcares_la_LDFLAGS = $(UNDEF) $(VER)
|
||||||
|
|
||||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
include Makefile.inc
|
include Makefile.inc
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \
|
CSOURCES = ares_fds.c ares_getsock.c ares_process.c ares_free_hostent.c \
|
||||||
ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \
|
ares_query.c ares__close_sockets.c ares_free_string.c ares_search.c \
|
||||||
ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \
|
ares__get_hostent.c ares_gethostbyaddr.c ares_send.c ares__read_line.c \
|
||||||
ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \
|
ares_gethostbyname.c ares_strerror.c ares_cancel.c ares_init.c \
|
||||||
ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \
|
ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c \
|
||||||
windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \
|
ares_expand_name.c ares_parse_a_reply.c windows_port.c \
|
||||||
ares_parse_aaaa_reply.c ares_getnameinfo.c inet_net_pton.c bitncmp.c \
|
ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c \
|
||||||
inet_ntop.c
|
ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.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
|
||||||
|
@@ -20,7 +20,7 @@ endif
|
|||||||
TARGETS = adig.nlm ahost.nlm
|
TARGETS = adig.nlm ahost.nlm
|
||||||
LTARGET = libcares.lib
|
LTARGET = libcares.lib
|
||||||
VERSION = $(LIBCARES_VERSION)
|
VERSION = $(LIBCARES_VERSION)
|
||||||
COPYR = Copyright (C) 1996 - 2005, Daniel Stenberg, <daniel@haxx.se>
|
COPYR = Copyright (C) 1996 - 2006, 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
|
||||||
@@ -88,7 +88,7 @@ LD = nlmconv
|
|||||||
LDFLAGS = -T
|
LDFLAGS = -T
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||||
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
|
CFLAGS += -Wall -Wno-format -Wno-uninitialized # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
@@ -256,8 +256,8 @@ config.h: Makefile.netware
|
|||||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||||
@echo $(DL)*/$(DL) >> $@
|
@echo $(DL)*/$(DL) >> $@
|
||||||
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
|
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
|
||||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
@echo $(DL)#define VERSION "$(LIBCARES_VERSION_STR)"$(DL) >> $@
|
||||||
@echo $(DL)#define PACKAGE_BUGREPORT "curl-bug@haxx.se"$(DL) >> $@
|
@echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"$(DL) >> $@
|
||||||
@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) >> $@
|
||||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||||
|
@@ -19,8 +19,8 @@ USE_WATT32 = 0
|
|||||||
|
|
||||||
CC = cl
|
CC = cl
|
||||||
|
|
||||||
CFLAGS = -nologo -$(CFG_MODEL)$(DEBUG_MODEL) -W2 -Yd -Zi
|
CFLAGS = -nologo -$(CFG_MODEL)$(DEBUG_MODEL) -W3 -Yd -Zi
|
||||||
LDFLAGS = -machine:i386 -map -warn:2
|
LDFLAGS = -machine:i386 -map
|
||||||
|
|
||||||
OBJ_DIR = VC6_obj
|
OBJ_DIR = VC6_obj
|
||||||
DEF_FILE = cares.def
|
DEF_FILE = cares.def
|
||||||
@@ -36,7 +36,7 @@ EX_LIBS = advapi32.lib ws2_32.lib
|
|||||||
|
|
||||||
!if "$(DEBUG_MODEL)" == "d"
|
!if "$(DEBUG_MODEL)" == "d"
|
||||||
CFLAGS = $(CFLAGS) -D_DEBUG -GZ
|
CFLAGS = $(CFLAGS) -D_DEBUG -GZ
|
||||||
LDFLAGS = $(LDFLAGS) -debug -debugtype:coff -fixed:no
|
LDFLAGS = $(LDFLAGS) -debug -fixed:no
|
||||||
|
|
||||||
!else
|
!else
|
||||||
CFLAGS = $(CFLAGS) -O2 -Og
|
CFLAGS = $(CFLAGS) -O2 -Og
|
||||||
@@ -52,6 +52,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj \
|
|||||||
$(OBJ_DIR)\ares_search.obj \
|
$(OBJ_DIR)\ares_search.obj \
|
||||||
$(OBJ_DIR)\ares__get_hostent.obj \
|
$(OBJ_DIR)\ares__get_hostent.obj \
|
||||||
$(OBJ_DIR)\ares_gethostbyaddr.obj \
|
$(OBJ_DIR)\ares_gethostbyaddr.obj \
|
||||||
|
$(OBJ_DIR)\ares_getsock.obj \
|
||||||
$(OBJ_DIR)\ares_send.obj \
|
$(OBJ_DIR)\ares_send.obj \
|
||||||
$(OBJ_DIR)\ares__read_line.obj \
|
$(OBJ_DIR)\ares__read_line.obj \
|
||||||
$(OBJ_DIR)\ares_gethostbyname.obj \
|
$(OBJ_DIR)\ares_gethostbyname.obj \
|
||||||
@@ -78,10 +79,10 @@ all: $(OBJ_DIR) cares.lib cares.dll cares_imp.lib ahost.exe adig.exe
|
|||||||
$(OBJ_DIR):
|
$(OBJ_DIR):
|
||||||
mkdir $(OBJ_DIR)
|
mkdir $(OBJ_DIR)
|
||||||
|
|
||||||
cares.lib: $(OBJECTS)
|
cares.lib: $(OBJ_DIR) $(OBJECTS)
|
||||||
lib -nologo -out:$@ $(OBJECTS)
|
lib -nologo -out:$@ $(OBJECTS)
|
||||||
|
|
||||||
cares_imp.lib cares.dll: $(DEF_FILE) $(OBJECTS)
|
cares_imp.lib cares.dll: $(OBJ_DIR) $(DEF_FILE) $(OBJECTS)
|
||||||
link $(LDFLAGS) -dll -implib:cares_imp.lib -out:cares.dll \
|
link $(LDFLAGS) -dll -implib:cares_imp.lib -out:cares.dll \
|
||||||
-def:$(DEF_FILE) $(OBJECTS) $(EX_LIBS)
|
-def:$(DEF_FILE) $(OBJECTS) $(EX_LIBS)
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
|
|||||||
@echo ares_free_string >> $@
|
@echo ares_free_string >> $@
|
||||||
@echo ares_gethostbyaddr >> $@
|
@echo ares_gethostbyaddr >> $@
|
||||||
@echo ares_gethostbyname >> $@
|
@echo ares_gethostbyname >> $@
|
||||||
|
@echo ares_getsock >> $@
|
||||||
@echo ares_init >> $@
|
@echo ares_init >> $@
|
||||||
@echo ares_init_options >> $@
|
@echo ares_init_options >> $@
|
||||||
@echo ares_mkquery >> $@
|
@echo ares_mkquery >> $@
|
||||||
@@ -119,10 +121,10 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
|
|||||||
@echo ares_gettimeofday >> $@
|
@echo ares_gettimeofday >> $@
|
||||||
@echo ares_parse_aaaa_reply >> $@
|
@echo ares_parse_aaaa_reply >> $@
|
||||||
|
|
||||||
ahost.exe: $(OBJ_DIR)\ahost.obj cares_imp.lib
|
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj cares_imp.lib
|
||||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj cares_imp.lib $(EX_LIBS)
|
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj cares_imp.lib $(EX_LIBS)
|
||||||
|
|
||||||
adig.exe: $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
|
adig.exe: $(OBJ_DIR) $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib
|
||||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)
|
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\adig.obj $(OBJ_DIR)\getopt.obj cares_imp.lib $(EX_LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@@ -1,3 +1,372 @@
|
|||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINDOWS
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid windows.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINDOWS], [
|
||||||
|
AC_CACHE_CHECK([for windows.h], [ac_cv_header_windows_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*WINVER;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_windows_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_windows_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_windows_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINDOWS_H, 1,
|
||||||
|
[Define to 1 if you have the windows.h header file.])
|
||||||
|
AC_DEFINE_UNQUOTED(WIN32_LEAN_AND_MEAN, 1,
|
||||||
|
[Define to avoid automatic inclusion of winsock.h])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINSOCK
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winsock.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINSOCK], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for winsock.h], [ac_cv_header_winsock_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
],[
|
||||||
|
int dummy=WSACleanup();
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_winsock_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1,
|
||||||
|
[Define to 1 if you have the winsock.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WINSOCK2
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid winsock2.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WINSOCK2], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINDOWS])dnl
|
||||||
|
AC_CACHE_CHECK([for winsock2.h], [ac_cv_header_winsock2_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*IPPROTO_ESP;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock2_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_winsock2_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_winsock2_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1,
|
||||||
|
[Define to 1 if you have the winsock2.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_HEADER_WS2TCPIP
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for compilable and valid ws2tcpip.h header
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_HEADER_WS2TCPIP], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
|
||||||
|
AC_CACHE_CHECK([for ws2tcpip.h], [ac_cv_header_ws2tcpip_h], [
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
],[
|
||||||
|
int dummy=2*IP_PKTINFO;
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
ac_cv_header_ws2tcpip_h="yes"
|
||||||
|
],[
|
||||||
|
ac_cv_header_ws2tcpip_h="no"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$ac_cv_header_ws2tcpip_h" = "xyes"; then
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_WS2TCPIP_H, 1,
|
||||||
|
[Define to 1 if you have the ws2tcpip.h header file.])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_TYPE_SOCKLEN_T
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for existing socklen_t type, and provide
|
||||||
|
dnl an equivalent type if socklen_t not available
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_TYPE_SOCKLEN_T], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl
|
||||||
|
AC_CHECK_TYPE([socklen_t], ,[
|
||||||
|
AC_CACHE_CHECK([for socklen_t equivalent],
|
||||||
|
[curl_cv_socklen_t_equiv], [
|
||||||
|
curl_cv_socklen_t_equiv="unknown"
|
||||||
|
for arg2 in "struct sockaddr" void; do
|
||||||
|
for t in int size_t unsigned long "unsigned long"; do
|
||||||
|
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>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
int getpeername (int, $arg2 *, $t *);
|
||||||
|
],[
|
||||||
|
$t len=0;
|
||||||
|
getpeername(0,0,&len);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_socklen_t_equiv="$t"
|
||||||
|
break 2
|
||||||
|
])
|
||||||
|
done
|
||||||
|
done
|
||||||
|
])
|
||||||
|
if test "$curl_cv_socklen_t_equiv" = "unknown"; then
|
||||||
|
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
|
||||||
|
[type to use in place of socklen_t if not defined])
|
||||||
|
fi
|
||||||
|
],[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_FUNC_GETNAMEINFO
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Test if the getnameinfo function is available,
|
||||||
|
dnl and check the types of five of its arguments.
|
||||||
|
dnl If the function succeeds HAVE_GETNAMEINFO will be
|
||||||
|
dnl defined, defining the types of the arguments in
|
||||||
|
dnl GETNAMEINFO_TYPE_ARG1, GETNAMEINFO_TYPE_ARG2,
|
||||||
|
dnl GETNAMEINFO_TYPE_ARG46 and GETNAMEINFO_TYPE_ARG7.
|
||||||
|
dnl This function is experimental and its results shall
|
||||||
|
dnl not be trusted while this notice is in place ------
|
||||||
|
|
||||||
|
AC_DEFUN([CURL_CHECK_FUNC_GETNAMEINFO], [
|
||||||
|
AC_REQUIRE([CURL_CHECK_HEADER_WS2TCPIP])dnl
|
||||||
|
AC_REQUIRE([CURL_CHECK_TYPE_SOCKLEN_T])dnl
|
||||||
|
AC_CHECK_HEADERS(sys/types.h sys/socket.h netdb.h)
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for getnameinfo])
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
AC_LANG_FUNC_LINK_TRY([getnameinfo])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" != "yes"; then
|
||||||
|
AC_MSG_CHECKING([deeper for getnameinfo])
|
||||||
|
AC_TRY_LINK([
|
||||||
|
],[
|
||||||
|
getnameinfo();
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([but still no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" != "yes"; then
|
||||||
|
AC_MSG_CHECKING([deeper and deeper for getnameinfo])
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
getnameinfo(0, 0, 0, 0, 0, 0, 0);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
curl_cv_getnameinfo="yes"
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([but still no])
|
||||||
|
curl_cv_getnameinfo="no"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
if test "$curl_cv_getnameinfo" = "yes"; then
|
||||||
|
AC_CACHE_CHECK([types of arguments for getnameinfo],
|
||||||
|
[curl_cv_func_getnameinfo_args], [
|
||||||
|
curl_cv_func_getnameinfo_args="unknown"
|
||||||
|
for gni_arg1 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do
|
||||||
|
for gni_arg2 in 'socklen_t' 'size_t' 'int'; do
|
||||||
|
for gni_arg46 in 'size_t' 'int' 'socklen_t' 'unsigned int' 'DWORD'; do
|
||||||
|
for gni_arg7 in 'int' 'unsigned int'; do
|
||||||
|
AC_COMPILE_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#if (!defined(_WIN32_WINNT)) || (_WIN32_WINNT < 0x0501)
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define GNICALLCONV WSAAPI
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#define GNICALLCONV
|
||||||
|
#endif
|
||||||
|
extern int GNICALLCONV getnameinfo($gni_arg1, $gni_arg2,
|
||||||
|
char *, $gni_arg46,
|
||||||
|
char *, $gni_arg46,
|
||||||
|
$gni_arg7);
|
||||||
|
],[
|
||||||
|
$gni_arg2 salen=0;
|
||||||
|
$gni_arg46 hostlen=0;
|
||||||
|
$gni_arg46 servlen=0;
|
||||||
|
$gni_arg7 flags=0;
|
||||||
|
int res = getnameinfo(0, salen, 0, hostlen, 0, servlen, flags);
|
||||||
|
])
|
||||||
|
],[
|
||||||
|
curl_cv_func_getnameinfo_args="$gni_arg1,$gni_arg2,$gni_arg46,$gni_arg7"
|
||||||
|
break 4
|
||||||
|
])
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
]) # AC_CACHE_CHECK
|
||||||
|
if test "$curl_cv_func_getnameinfo_args" = "unknown"; then
|
||||||
|
AC_MSG_WARN([Cannot find proper types to use for getnameinfo args])
|
||||||
|
AC_MSG_WARN([HAVE_GETNAMEINFO will not be defined])
|
||||||
|
else
|
||||||
|
gni_prev_IFS=$IFS; IFS=','
|
||||||
|
set dummy `echo "$curl_cv_func_getnameinfo_args" | sed 's/\*/\*/g'`
|
||||||
|
IFS=$gni_prev_IFS
|
||||||
|
shift
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG1, $[1],
|
||||||
|
[Define to the type of arg 1 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG2, $[2],
|
||||||
|
[Define to the type of arg 2 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG46, $[3],
|
||||||
|
[Define to the type of args 4 and 6 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(GETNAMEINFO_TYPE_ARG7, $[4],
|
||||||
|
[Define to the type of arg 7 for getnameinfo.])
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_GETNAMEINFO, 1,
|
||||||
|
[Define to 1 if you have the getnameinfo function.])
|
||||||
|
ac_cv_func_getnameinfo="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
]) # AC_DEFUN
|
||||||
|
|
||||||
|
|
||||||
|
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||||
|
dnl -------------------------------------------------
|
||||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||||
dnl four known different ways, with the one used almost everywhere being POSIX
|
dnl four known different ways, with the one used almost everywhere being POSIX
|
||||||
dnl and XPG3, while the other different ways for different systems (old BSD,
|
dnl and XPG3, while the other different ways for different systems (old BSD,
|
||||||
@@ -59,12 +428,27 @@ dnl FIONBIO test was also bad
|
|||||||
dnl the code was bad, try a different program now, test 3
|
dnl the code was bad, try a different program now, test 3
|
||||||
|
|
||||||
AC_TRY_COMPILE([
|
AC_TRY_COMPILE([
|
||||||
/* headers for ioctlsocket test (cygwin?) */
|
/* headers for ioctlsocket test (Windows) */
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
],[
|
],[
|
||||||
/* ioctlsocket source code */
|
/* ioctlsocket source code */
|
||||||
int socket;
|
SOCKET sd;
|
||||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
unsigned long flags = 0;
|
||||||
|
sd = socket(0, 0, 0);
|
||||||
|
ioctlsocket(sd, FIONBIO, &flags);
|
||||||
],[
|
],[
|
||||||
dnl ioctlsocket test was good
|
dnl ioctlsocket test was good
|
||||||
nonblock="ioctlsocket"
|
nonblock="ioctlsocket"
|
||||||
@@ -122,6 +506,132 @@ dnl end of non-blocking try-compile test
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl TYPE_SOCKADDR_STORAGE
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but
|
||||||
|
dnl AIX 4.3 is one known exception.
|
||||||
|
AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
||||||
|
[
|
||||||
|
AC_CHECK_TYPE([struct sockaddr_storage],
|
||||||
|
AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1,
|
||||||
|
[if struct sockaddr_storage is defined]), ,
|
||||||
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl TYPE_IN_ADDR_T
|
||||||
|
dnl -------------------------------------------------
|
||||||
|
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||||
|
dnl and a few other things.
|
||||||
|
AC_DEFUN([TYPE_IN_ADDR_T],
|
||||||
|
[
|
||||||
|
AC_CHECK_TYPE([in_addr_t], ,[
|
||||||
|
AC_MSG_CHECKING([for in_addr_t equivalent])
|
||||||
|
AC_CACHE_VAL([curl_cv_in_addr_t_equiv],
|
||||||
|
[
|
||||||
|
curl_cv_in_addr_t_equiv=
|
||||||
|
for t in "unsigned long" int size_t unsigned long; do
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
$t data = inet_addr ("1.2.3.4");
|
||||||
|
],[
|
||||||
|
curl_cv_in_addr_t_equiv="$t"
|
||||||
|
break
|
||||||
|
])
|
||||||
|
done
|
||||||
|
|
||||||
|
if test "x$curl_cv_in_addr_t_equiv" = x; then
|
||||||
|
AC_MSG_ERROR([Cannot find a type to use in place of in_addr_t])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($curl_cv_in_addr_t_equiv)
|
||||||
|
AC_DEFINE_UNQUOTED(in_addr_t, $curl_cv_in_addr_t_equiv,
|
||||||
|
[type to use in place of in_addr_t if not defined])],
|
||||||
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
]) dnl AC_CHECK_TYPE
|
||||||
|
]) dnl AC_DEFUN
|
||||||
|
|
||||||
|
|
||||||
dnl We create a function for detecting which compiler we use and then set as
|
dnl We create a function for detecting which compiler we use and then set as
|
||||||
dnl pendantic compiler options as possible for that particular compiler. The
|
dnl pendantic compiler options as possible for that particular compiler. The
|
||||||
dnl options are only used for debug-builds.
|
dnl options are only used for debug-builds.
|
||||||
@@ -272,7 +782,7 @@ AC_DEFUN([CARES_CHECK_CONSTANT], [
|
|||||||
dnl This macro determines how many parameters getservbyport_r takes
|
dnl This macro determines how many parameters getservbyport_r takes
|
||||||
AC_DEFUN([CARES_CHECK_GETSERVBYPORT_R], [
|
AC_DEFUN([CARES_CHECK_GETSERVBYPORT_R], [
|
||||||
AC_MSG_CHECKING([how many arguments getservbyport_r takes])
|
AC_MSG_CHECKING([how many arguments getservbyport_r takes])
|
||||||
AC_TRY_COMPILE(
|
AC_TRY_LINK(
|
||||||
[#include <netdb.h>],
|
[#include <netdb.h>],
|
||||||
[
|
[
|
||||||
int p1, p5;
|
int p1, p5;
|
||||||
@@ -280,7 +790,7 @@ AC_DEFUN([CARES_CHECK_GETSERVBYPORT_R], [
|
|||||||
struct servent *p3, *p6;
|
struct servent *p3, *p6;
|
||||||
getservbyport_r(p1, p2, p3, p4, p5, &p6);
|
getservbyport_r(p1, p2, p3, p4, p5, &p6);
|
||||||
], ac_func_getservbyport_r=6,
|
], ac_func_getservbyport_r=6,
|
||||||
[AC_TRY_COMPILE(
|
[AC_TRY_LINK(
|
||||||
[#include <netdb.h>],
|
[#include <netdb.h>],
|
||||||
[
|
[
|
||||||
int p1, p5;
|
int p1, p5;
|
||||||
@@ -288,7 +798,7 @@ AC_DEFUN([CARES_CHECK_GETSERVBYPORT_R], [
|
|||||||
struct servent *p3;
|
struct servent *p3;
|
||||||
getservbyport_r(p1, p2, p3, p4, p5);
|
getservbyport_r(p1, p2, p3, p4, p5);
|
||||||
], ac_func_getservbyport_r=5,
|
], ac_func_getservbyport_r=5,
|
||||||
[AC_TRY_COMPILE(
|
[AC_TRY_LINK(
|
||||||
[#include <netdb.h>],
|
[#include <netdb.h>],
|
||||||
[
|
[
|
||||||
int p1;
|
int p1;
|
||||||
@@ -316,3 +826,39 @@ else
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Prevent libtool for checking how to run C++ compiler and check for other
|
||||||
|
# tools we don't want to use. We do this by m4-defining the _LT_AC_TAGCONFIG
|
||||||
|
# variable to the code to run, as by default it uses a much more complicated
|
||||||
|
# approach. The code below that is actually added seems to be used for cases
|
||||||
|
# where configure has trouble figuring out what C compiler to use but where
|
||||||
|
# the installed libtool has an idea.
|
||||||
|
#
|
||||||
|
# This function is a re-implemented version of the Paolo Bonzini fix posted to
|
||||||
|
# the c-ares mailing list by Bram Matthys on May 6 2006. My version removes
|
||||||
|
# redundant code but also adds the LTCFLAGS check that wasn't in that patch.
|
||||||
|
#
|
||||||
|
# Some code in this function was extracted from the generated configure script.
|
||||||
|
#
|
||||||
|
# CARES_CLEAR_LIBTOOL_TAGS
|
||||||
|
AC_DEFUN([CARES_CLEAR_LIBTOOL_TAGS],
|
||||||
|
[m4_define([_LT_AC_TAGCONFIG], [
|
||||||
|
if test -f "$ltmain"; then
|
||||||
|
if test ! -f "${ofile}"; then
|
||||||
|
AC_MSG_WARN([output file `$ofile' does not exist])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$LTCC"; then
|
||||||
|
eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
|
||||||
|
if test -z "$LTCC"; then
|
||||||
|
AC_MSG_WARN([output file `$ofile' does not look like a libtool
|
||||||
|
script])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test -z "$LTCFLAGS"; then
|
||||||
|
eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])]
|
||||||
|
)
|
||||||
|
@@ -227,7 +227,7 @@ int main(int argc, char **argv)
|
|||||||
/* Set the TCP port number. */
|
/* Set the TCP port number. */
|
||||||
if (!isdigit((unsigned char)*optarg))
|
if (!isdigit((unsigned char)*optarg))
|
||||||
usage();
|
usage();
|
||||||
options.tcp_port = strtol(optarg, NULL, 0);
|
options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
|
||||||
optmask |= ARES_OPT_TCP_PORT;
|
optmask |= ARES_OPT_TCP_PORT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ int main(int argc, char **argv)
|
|||||||
/* Set the UDP port number. */
|
/* Set the UDP port number. */
|
||||||
if (!isdigit((unsigned char)*optarg))
|
if (!isdigit((unsigned char)*optarg))
|
||||||
usage();
|
usage();
|
||||||
options.udp_port = strtol(optarg, NULL, 0);
|
options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
|
||||||
optmask |= ARES_OPT_UDP_PORT;
|
optmask |= ARES_OPT_UDP_PORT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
24
ares/ares.h
24
ares/ares.h
@@ -93,6 +93,7 @@ extern "C" {
|
|||||||
#define ARES_OPT_SERVERS (1 << 6)
|
#define ARES_OPT_SERVERS (1 << 6)
|
||||||
#define ARES_OPT_DOMAINS (1 << 7)
|
#define ARES_OPT_DOMAINS (1 << 7)
|
||||||
#define ARES_OPT_LOOKUPS (1 << 8)
|
#define ARES_OPT_LOOKUPS (1 << 8)
|
||||||
|
#define ARES_OPT_SOCK_STATE_CB (1 << 9)
|
||||||
|
|
||||||
/* Nameinfo flag values */
|
/* Nameinfo flag values */
|
||||||
#define ARES_NI_NOFQDN (1 << 0)
|
#define ARES_NI_NOFQDN (1 << 0)
|
||||||
@@ -129,6 +130,23 @@ extern "C" {
|
|||||||
#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
|
#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
|
||||||
ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
|
ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
|
||||||
ARES_AI_ADDRCONFIG)
|
ARES_AI_ADDRCONFIG)
|
||||||
|
#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
|
||||||
|
many sockets */
|
||||||
|
#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
|
||||||
|
#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
|
||||||
|
ARES_GETSOCK_MAXNUM)))
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef void (*ares_sock_state_cb)(void *data,
|
||||||
|
SOCKET socket,
|
||||||
|
int readable,
|
||||||
|
int writable);
|
||||||
|
#else
|
||||||
|
typedef void (*ares_sock_state_cb)(void *data,
|
||||||
|
int socket,
|
||||||
|
int readable,
|
||||||
|
int writable);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ares_options {
|
struct ares_options {
|
||||||
int flags;
|
int flags;
|
||||||
@@ -142,6 +160,8 @@ struct ares_options {
|
|||||||
char **domains;
|
char **domains;
|
||||||
int ndomains;
|
int ndomains;
|
||||||
char *lookups;
|
char *lookups;
|
||||||
|
ares_sock_state_cb sock_state_cb;
|
||||||
|
void *sock_state_cb_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hostent;
|
struct hostent;
|
||||||
@@ -172,9 +192,11 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
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);
|
||||||
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
|
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
|
||||||
socklen_t salen, int flags, ares_nameinfo_callback callback,
|
socklen_t salen, int flags,
|
||||||
|
ares_nameinfo_callback callback,
|
||||||
void *arg);
|
void *arg);
|
||||||
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
|
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
|
||||||
|
int ares_getsock(ares_channel channel, int *socks, int numsocks);
|
||||||
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
|
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
|
||||||
struct timeval *tv);
|
struct timeval *tv);
|
||||||
void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
|
void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
void ares__close_sockets(struct server_state *server)
|
void ares__close_sockets(ares_channel channel, struct server_state *server)
|
||||||
{
|
{
|
||||||
struct send_request *sendreq;
|
struct send_request *sendreq;
|
||||||
|
|
||||||
@@ -46,11 +46,13 @@ void ares__close_sockets(struct server_state *server)
|
|||||||
/* 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);
|
||||||
closesocket(server->tcp_socket);
|
closesocket(server->tcp_socket);
|
||||||
server->tcp_socket = ARES_SOCKET_BAD;
|
server->tcp_socket = ARES_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
if (server->udp_socket != ARES_SOCKET_BAD)
|
if (server->udp_socket != ARES_SOCKET_BAD)
|
||||||
{
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0);
|
||||||
closesocket(server->udp_socket);
|
closesocket(server->udp_socket);
|
||||||
server->udp_socket = ARES_SOCKET_BAD;
|
server->udp_socket = ARES_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,7 @@ int ares__read_line(FILE *fp, char **buf, int *bufsize)
|
|||||||
if ((*buf)[len - 1] == '\n')
|
if ((*buf)[len - 1] == '\n')
|
||||||
{
|
{
|
||||||
(*buf)[len - 1] = 0;
|
(*buf)[len - 1] = 0;
|
||||||
return ARES_SUCCESS;
|
break;
|
||||||
}
|
}
|
||||||
offset = len;
|
offset = len;
|
||||||
|
|
||||||
@@ -61,4 +61,5 @@ int ares__read_line(FILE *fp, char **buf, int *bufsize)
|
|||||||
*buf = newbuf;
|
*buf = newbuf;
|
||||||
*bufsize *= 2;
|
*bufsize *= 2;
|
||||||
}
|
}
|
||||||
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,6 @@ might have been stored in their arguments.
|
|||||||
.BR ares_init (3)
|
.BR ares_init (3)
|
||||||
.BR ares_destroy (3)
|
.BR ares_destroy (3)
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
This function is not compatible with ares.
|
This function was added in c-ares 1.2.0
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Dirk Manske
|
Dirk Manske
|
||||||
|
@@ -38,6 +38,6 @@ void ares_cancel(ares_channel channel)
|
|||||||
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
{
|
{
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ void ares_destroy(ares_channel channel)
|
|||||||
struct query *query;
|
struct query *query;
|
||||||
|
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
free(channel->servers);
|
free(channel->servers);
|
||||||
for (i = 0; i < channel->ndomains; i++)
|
for (i = 0; i < channel->ndomains; i++)
|
||||||
free(channel->domains[i]);
|
free(channel->domains[i]);
|
||||||
|
@@ -70,7 +70,8 @@ struct nameinfo_query {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void nameinfo_callback(void *arg, int status, struct hostent *host);
|
static void nameinfo_callback(void *arg, int status, struct hostent *host);
|
||||||
static char *lookup_service(unsigned short port, int flags, char *buf);
|
static char *lookup_service(unsigned short port, int flags,
|
||||||
|
char *buf, size_t buflen);
|
||||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||||
static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
|
static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid,
|
||||||
char *buf, size_t buflen);
|
char *buf, size_t buflen);
|
||||||
@@ -109,7 +110,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
port = addr->sin_port;
|
port = addr->sin_port;
|
||||||
else
|
else
|
||||||
port = addr6->sin6_port;
|
port = addr6->sin6_port;
|
||||||
service = lookup_service(port, flags, buf);
|
service = lookup_service(port, flags, buf, sizeof(buf));
|
||||||
callback(arg, ARES_SUCCESS, NULL, service);
|
callback(arg, ARES_SUCCESS, NULL, service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -122,7 +123,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
{
|
{
|
||||||
unsigned int port = 0;
|
unsigned int port = 0;
|
||||||
char ipbuf[IPBUFSIZ];
|
char ipbuf[IPBUFSIZ];
|
||||||
char srvbuf[32];
|
char srvbuf[33];
|
||||||
char *service = NULL;
|
char *service = NULL;
|
||||||
ipbuf[0] = 0;
|
ipbuf[0] = 0;
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t
|
|||||||
}
|
}
|
||||||
/* They also want a service */
|
/* They also want a service */
|
||||||
if (flags & ARES_NI_LOOKUPSERVICE)
|
if (flags & ARES_NI_LOOKUPSERVICE)
|
||||||
service = lookup_service(port, flags, srvbuf);
|
service = lookup_service(port, flags, srvbuf, sizeof(srvbuf));
|
||||||
callback(arg, ARES_SUCCESS, ipbuf, service);
|
callback(arg, ARES_SUCCESS, ipbuf, service);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -198,10 +199,10 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
|||||||
{
|
{
|
||||||
if (niquery->family == AF_INET)
|
if (niquery->family == AF_INET)
|
||||||
service = lookup_service(niquery->addr.addr4.sin_port,
|
service = lookup_service(niquery->addr.addr4.sin_port,
|
||||||
niquery->flags, srvbuf);
|
niquery->flags, srvbuf, sizeof(srvbuf));
|
||||||
else
|
else
|
||||||
service = lookup_service(niquery->addr.addr6.sin6_port,
|
service = lookup_service(niquery->addr.addr6.sin6_port,
|
||||||
niquery->flags, srvbuf);
|
niquery->flags, srvbuf, sizeof(srvbuf));
|
||||||
}
|
}
|
||||||
/* NOFQDN means we have to strip off the domain name portion.
|
/* NOFQDN means we have to strip off the domain name portion.
|
||||||
We do this by determining our own domain name, then searching the string
|
We do this by determining our own domain name, then searching the string
|
||||||
@@ -240,10 +241,10 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
|||||||
{
|
{
|
||||||
if (niquery->family == AF_INET)
|
if (niquery->family == AF_INET)
|
||||||
service = lookup_service(niquery->addr.addr4.sin_port,
|
service = lookup_service(niquery->addr.addr4.sin_port,
|
||||||
niquery->flags, srvbuf);
|
niquery->flags, srvbuf, sizeof(srvbuf));
|
||||||
else
|
else
|
||||||
service = lookup_service(niquery->addr.addr6.sin6_port,
|
service = lookup_service(niquery->addr.addr6.sin6_port,
|
||||||
niquery->flags, srvbuf);
|
niquery->flags, srvbuf, sizeof(srvbuf));
|
||||||
}
|
}
|
||||||
niquery->callback(niquery->arg, ARES_SUCCESS, ipbuf, service);
|
niquery->callback(niquery->arg, ARES_SUCCESS, ipbuf, service);
|
||||||
return;
|
return;
|
||||||
@@ -253,30 +254,21 @@ static void nameinfo_callback(void *arg, int status, struct hostent *host)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *lookup_service(unsigned short port, int flags,
|
static char *lookup_service(unsigned short port, int flags,
|
||||||
char *buf) /* 33 bytes buffer */
|
char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
|
const char *proto;
|
||||||
|
struct servent *sep;
|
||||||
|
#ifdef HAVE_GETSERVBYPORT_R
|
||||||
|
struct servent se;
|
||||||
|
#endif
|
||||||
|
char tmpbuf[4096];
|
||||||
|
|
||||||
if (port)
|
if (port)
|
||||||
{
|
{
|
||||||
/* Just return the port as a string */
|
|
||||||
if (flags & ARES_NI_NUMERICSERV)
|
if (flags & ARES_NI_NUMERICSERV)
|
||||||
sprintf(buf, "%u", ntohs(port));
|
sep = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct servent *se;
|
|
||||||
const char *proto;
|
|
||||||
#ifdef HAVE_GETSERVBYPORT_R
|
|
||||||
#if GETSERVBYPORT_R_ARGS == 6
|
|
||||||
struct servent ret;
|
|
||||||
char buf[4096];
|
|
||||||
int len = 4096;
|
|
||||||
#elif GETSERVBYPORT_R_ARGS == 5
|
|
||||||
char buf[4096];
|
|
||||||
int len = 4096;
|
|
||||||
#elif GETSERVBYPORT_R_ARGS == 4
|
|
||||||
struct servent ret;
|
|
||||||
struct servent_data sed;
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_GETSERVBYPORT_R */
|
|
||||||
if (flags & ARES_NI_UDP)
|
if (flags & ARES_NI_UDP)
|
||||||
proto = "udp";
|
proto = "udp";
|
||||||
else if (flags & ARES_NI_SCTP)
|
else if (flags & ARES_NI_SCTP)
|
||||||
@@ -286,38 +278,40 @@ static char *lookup_service(unsigned short port, int flags,
|
|||||||
else
|
else
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
#ifdef HAVE_GETSERVBYPORT_R
|
#ifdef HAVE_GETSERVBYPORT_R
|
||||||
|
sep = &se;
|
||||||
|
memset(tmpbuf, 0, sizeof(tmpbuf));
|
||||||
#if GETSERVBYPORT_R_ARGS == 6
|
#if GETSERVBYPORT_R_ARGS == 6
|
||||||
se = &ret;
|
if (getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), &sep) != 0)
|
||||||
if (getservbyport_r(port, proto, se, buf, len, &ret))
|
sep = NULL;
|
||||||
se = NULL;
|
|
||||||
#elif GETSERVBYPORT_R_ARGS == 5
|
#elif GETSERVBYPORT_R_ARGS == 5
|
||||||
se = getservbyport_r(port, proto, se, buf, len);
|
sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf));
|
||||||
#elif GETSERVBYPORT_R_ARGS == 4
|
#elif GETSERVBYPORT_R_ARGS == 4
|
||||||
se = &ret;
|
if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
|
||||||
if (getservbyport_r(port, proto, se, &sed) == -1)
|
sep = NULL;
|
||||||
se = NULL;
|
|
||||||
#else
|
#else
|
||||||
/* Lets just hope the OS uses TLS! */
|
/* Lets just hope the OS uses TLS! */
|
||||||
se = getservbyport(port, proto);
|
sep = getservbyport(port, proto);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/* Lets just hope the OS uses TLS! */
|
/* Lets just hope the OS uses TLS! */
|
||||||
se = getservbyport(port, proto);
|
sep = getservbyport(port, proto);
|
||||||
#endif
|
#endif
|
||||||
if (se && se->s_name) {
|
|
||||||
size_t len = strlen(se->s_name);
|
|
||||||
if(len < 33) {
|
|
||||||
strcpy(buf, se->s_name);
|
|
||||||
}
|
}
|
||||||
|
if (sep && sep->s_name)
|
||||||
|
/* get service name */
|
||||||
|
strcpy(tmpbuf, sep->s_name);
|
||||||
else
|
else
|
||||||
/* too big name to fit the buffer */
|
/* get port as a string */
|
||||||
buf[0]=0;
|
sprintf(tmpbuf, "%u", ntohs(port));
|
||||||
}
|
if (strlen(tmpbuf) < buflen)
|
||||||
|
/* return it if buffer big enough */
|
||||||
|
strcpy(buf, tmpbuf);
|
||||||
else
|
else
|
||||||
sprintf(buf, "%u", ntohs(port));
|
/* avoid reusing previous one */
|
||||||
}
|
buf[0] = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
buf[0] = '\0';
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
58
ares/ares_getsock.3
Normal file
58
ares/ares_getsock.3
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.\" Copyright 1998 by Daniel Stenberg
|
||||||
|
.\"
|
||||||
|
.\" 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.
|
||||||
|
.\"
|
||||||
|
.TH ARES_GETSOCK 3 "22 December 2005"
|
||||||
|
.SH NAME
|
||||||
|
ares_getsock \- get file descriptors to wait on
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
.B #include <ares.h>
|
||||||
|
.PP
|
||||||
|
.B int ares_getsock(ares_channel \fIchannel\fP, int *\fIsocks\fP,
|
||||||
|
.B int \fInumsocks\fP);
|
||||||
|
.fi
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B ares_getsock
|
||||||
|
function retrieves the set of file descriptors which the calling
|
||||||
|
application should wait on for reading and/or writing for the
|
||||||
|
processing of name service queries pending on the name service channel
|
||||||
|
identified by
|
||||||
|
.IR channel .
|
||||||
|
File descriptors will be set in the integer array pointed to by
|
||||||
|
\fIsocks\fP.
|
||||||
|
\fInumsocks\fP is the size of the given array in number of ints.
|
||||||
|
|
||||||
|
This function can only return information about up to 16 sockets. If more are
|
||||||
|
in use (however unlikely that is), they are simply not reported back.
|
||||||
|
.SH RETURN VALUES
|
||||||
|
\fBares_getsock\fP returns a bitmask for what actions to wait for on the
|
||||||
|
different sockets. The ares.h header file provides these convenience macros to
|
||||||
|
extract the information appropriately:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about
|
||||||
|
this many sockets */
|
||||||
|
#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
|
||||||
|
#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
|
||||||
|
ARES_GETSOCK_MAXNUM)))
|
||||||
|
.fi
|
||||||
|
.SH NOTES
|
||||||
|
This function was added in c-ares 1.3.1
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR ares_timeout (3),
|
||||||
|
.BR ares_fds (3),
|
||||||
|
.BR ares_process (3)
|
71
ares/ares_getsock.c
Normal file
71
ares/ares_getsock.c
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/* Copyright 2005 by Daniel Stenberg.
|
||||||
|
*
|
||||||
|
* 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 <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ares.h"
|
||||||
|
#include "ares_private.h"
|
||||||
|
|
||||||
|
int ares_getsock(ares_channel channel,
|
||||||
|
int *s,
|
||||||
|
int numsocks) /* size of the 'socks' array */
|
||||||
|
{
|
||||||
|
struct server_state *server;
|
||||||
|
ares_socket_t nfds;
|
||||||
|
int i;
|
||||||
|
int sockindex=0;
|
||||||
|
int bitmap = 0;
|
||||||
|
unsigned int setbits = 0xffffffff;
|
||||||
|
|
||||||
|
ares_socket_t *socks = (ares_socket_t *)s;
|
||||||
|
|
||||||
|
/* No queries, no file descriptors. */
|
||||||
|
if (!channel->queries)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nfds = 0;
|
||||||
|
for (i = 0; i < channel->nservers; i++)
|
||||||
|
{
|
||||||
|
server = &channel->servers[i];
|
||||||
|
if (server->udp_socket != ARES_SOCKET_BAD)
|
||||||
|
{
|
||||||
|
if(sockindex >= numsocks)
|
||||||
|
break;
|
||||||
|
socks[sockindex] = server->udp_socket;
|
||||||
|
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
||||||
|
sockindex++;
|
||||||
|
}
|
||||||
|
if (server->tcp_socket != ARES_SOCKET_BAD)
|
||||||
|
{
|
||||||
|
if(sockindex >= numsocks)
|
||||||
|
break;
|
||||||
|
socks[sockindex] = server->tcp_socket;
|
||||||
|
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
|
||||||
|
sockindex++;
|
||||||
|
|
||||||
|
if (server->qhead) {
|
||||||
|
/* then the tcp socket is also writable! */
|
||||||
|
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (int)nfds;
|
||||||
|
}
|
@@ -98,6 +98,24 @@ The lookups to perform for host queries.
|
|||||||
.I lookups
|
.I lookups
|
||||||
should be set to a string of the characters "b" or "f", where "b"
|
should be set to a string of the characters "b" or "f", where "b"
|
||||||
indicates a DNS lookup and "f" indicates a lookup in the hosts file.
|
indicates a DNS lookup and "f" indicates a lookup in the hosts file.
|
||||||
|
.TP 18
|
||||||
|
.B ARES_OPT_SOCK_STATE_CB
|
||||||
|
.B void (*\fIsock_state_cb\fP)(void *data, int s, int read, int write);
|
||||||
|
.br
|
||||||
|
.B void *\fIsock_state_cb_data\fP;
|
||||||
|
.br
|
||||||
|
A callback function to be invoked when a socket changes state.
|
||||||
|
.I s
|
||||||
|
will be passed the socket whose state has changed;
|
||||||
|
.I read
|
||||||
|
will be set to true if the socket should listen for read events, and
|
||||||
|
.I write
|
||||||
|
will be set to true if the socket should listen for write events.
|
||||||
|
The value of
|
||||||
|
.I sock_state_cb_data
|
||||||
|
will be passed as the
|
||||||
|
.I data
|
||||||
|
argument.
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.I flags
|
.I flags
|
||||||
|
@@ -113,6 +113,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
|||||||
channel->queries = NULL;
|
channel->queries = NULL;
|
||||||
channel->domains = NULL;
|
channel->domains = NULL;
|
||||||
channel->sortlist = NULL;
|
channel->sortlist = NULL;
|
||||||
|
channel->sock_state_cb = NULL;
|
||||||
|
|
||||||
/* 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.
|
||||||
@@ -192,6 +193,11 @@ static int init_by_options(ares_channel channel, struct ares_options *options,
|
|||||||
channel->udp_port = options->udp_port;
|
channel->udp_port = options->udp_port;
|
||||||
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
|
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
|
||||||
channel->tcp_port = options->tcp_port;
|
channel->tcp_port = options->tcp_port;
|
||||||
|
if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
|
||||||
|
{
|
||||||
|
channel->sock_state_cb = options->sock_state_cb;
|
||||||
|
channel->sock_state_cb_data = options->sock_state_cb_data;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
@@ -504,7 +510,7 @@ DhcpNameServer
|
|||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
status = ARES_EOF;
|
status = ARES_EOF;
|
||||||
|
|
||||||
#elif defined(riscos)
|
#elif defined(__riscos__)
|
||||||
|
|
||||||
/* Under RISC OS, name servers are listed in the
|
/* Under RISC OS, name servers are listed in the
|
||||||
system variable Inet$Resolvers, space separated. */
|
system variable Inet$Resolvers, space separated. */
|
||||||
|
@@ -62,6 +62,10 @@
|
|||||||
#define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
|
#define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
|
||||||
#define PATH_HOSTS "sys:/etc/hosts"
|
#define PATH_HOSTS "sys:/etc/hosts"
|
||||||
|
|
||||||
|
#elif defined(__riscos__)
|
||||||
|
|
||||||
|
#define PATH_HOSTS "InetDBase:Hosts"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define PATH_RESOLV_CONF "/etc/resolv.conf"
|
#define PATH_RESOLV_CONF "/etc/resolv.conf"
|
||||||
@@ -172,13 +176,22 @@ struct ares_channeldata {
|
|||||||
|
|
||||||
/* Active queries */
|
/* Active queries */
|
||||||
struct query *queries;
|
struct query *queries;
|
||||||
|
|
||||||
|
ares_sock_state_cb sock_state_cb;
|
||||||
|
void *sock_state_cb_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
void ares__close_sockets(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);
|
||||||
|
|
||||||
|
#define SOCK_STATE_CALLBACK(c, s, r, w) \
|
||||||
|
do { \
|
||||||
|
if ((c)->sock_state_cb) \
|
||||||
|
(c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
#ifdef CURLDEBUG
|
||||||
/* This is low-level hard-hacking memory leak tracking and similar. Using the
|
/* This is low-level hard-hacking memory leak tracking and similar. Using the
|
||||||
libcurl lowlevel code from within library is ugly and only works when
|
libcurl lowlevel code from within library is ugly and only works when
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
#include <arpa/nameser_compat.h>
|
#include <arpa/nameser_compat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* WIN32 && !WATT32 */
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -39,7 +41,6 @@
|
|||||||
#ifdef NETWARE
|
#ifdef NETWARE
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -103,7 +104,7 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
|||||||
struct iovec *vec;
|
struct iovec *vec;
|
||||||
int i;
|
int i;
|
||||||
ssize_t scount;
|
ssize_t scount;
|
||||||
int wcount;
|
ssize_t wcount;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
@@ -148,7 +149,10 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
|||||||
wcount -= sendreq->len;
|
wcount -= 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);
|
||||||
server->qtail = NULL;
|
server->qtail = NULL;
|
||||||
|
}
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -178,7 +182,10 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
|
|||||||
{
|
{
|
||||||
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);
|
||||||
server->qtail = NULL;
|
server->qtail = NULL;
|
||||||
|
}
|
||||||
free(sendreq);
|
free(sendreq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -379,7 +386,7 @@ static void handle_error(ares_channel channel, int whichserver, time_t now)
|
|||||||
struct query *query, *next;
|
struct query *query, *next;
|
||||||
|
|
||||||
/* Reset communications with this server. */
|
/* Reset communications with this server. */
|
||||||
ares__close_sockets(&channel->servers[whichserver]);
|
ares__close_sockets(channel, &channel->servers[whichserver]);
|
||||||
|
|
||||||
/* Tell all queries talking to this server to move on and not try
|
/* Tell all queries talking to this server to move on and not try
|
||||||
* this server again.
|
* this server again.
|
||||||
@@ -451,7 +458,10 @@ void ares__send_query(ares_channel channel, struct query *query, time_t now)
|
|||||||
if (server->qtail)
|
if (server->qtail)
|
||||||
server->qtail->next = sendreq;
|
server->qtail->next = sendreq;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
|
||||||
server->qhead = sendreq;
|
server->qhead = sendreq;
|
||||||
|
}
|
||||||
server->qtail = sendreq;
|
server->qtail = sendreq;
|
||||||
query->timeout = 0;
|
query->timeout = 0;
|
||||||
}
|
}
|
||||||
@@ -574,6 +584,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -603,6 +614,8 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOCK_STATE_CALLBACK(channel, s, 1, 0);
|
||||||
|
|
||||||
server->udp_socket = s;
|
server->udp_socket = s;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -713,7 +726,7 @@ static struct query *end_query (ares_channel channel, struct query *query, int s
|
|||||||
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))
|
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
{
|
{
|
||||||
for (i = 0; i < channel->nservers; i++)
|
for (i = 0; i < channel->nservers; i++)
|
||||||
ares__close_sockets(&channel->servers[i]);
|
ares__close_sockets(channel, &channel->servers[i]);
|
||||||
}
|
}
|
||||||
return (next);
|
return (next);
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,11 @@
|
|||||||
|
|
||||||
#define ARES_VERSION_MAJOR 1
|
#define ARES_VERSION_MAJOR 1
|
||||||
#define ARES_VERSION_MINOR 3
|
#define ARES_VERSION_MINOR 3
|
||||||
#define ARES_VERSION_PATCH 0
|
#define ARES_VERSION_PATCH 1
|
||||||
#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.3.0"
|
#define ARES_VERSION_STR "1.3.1"
|
||||||
|
|
||||||
const char *ares_version(int *version);
|
const char *ares_version(int *version);
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force
|
${LIBTOOLIZE:-libtoolize} --copy --automake --force
|
||||||
${ACLOCAL:-aclocal}
|
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS
|
||||||
${AUTOHEADER:-autoheader}
|
${AUTOHEADER:-autoheader}
|
||||||
${AUTOCONF:-autoconf}
|
${AUTOCONF:-autoconf}
|
||||||
${AUTOMAKE:-automake} --add-missing
|
${AUTOMAKE:-automake} --add-missing
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef __ARES_CONFIG_WIN32_H
|
||||||
|
#define __ARES_CONFIG_WIN32_H
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
|
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
|
||||||
@@ -13,23 +16,72 @@
|
|||||||
* without express or implied warranty.
|
* without express or implied warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_WIN32_H
|
/* ================================================================ */
|
||||||
#define __CONFIG_WIN32_H
|
/* ares/config-win32.h - Hand crafted config file for windows */
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* HEADER FILES */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Define if you have the <getopt.h> header file. */
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
#define HAVE_GETOPT_H
|
#define HAVE_GETOPT_H 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__WATCOMC__)
|
/* Define if you have the <unistd.h> header file. */
|
||||||
#define HAVE_UNISTD_H
|
#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
|
||||||
|
defined(__POCC__)
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HAVE_AF_INET6
|
/* Define if you have the <windows.h> header file. */
|
||||||
#define HAVE_PF_INET6
|
#define HAVE_WINDOWS_H 1
|
||||||
#define HAVE_IOCTLSOCKET
|
|
||||||
#define HAVE_STRUCT_IN6_ADDR
|
|
||||||
#define HAVE_STRUCT_SOCKADDR_IN6
|
|
||||||
#define HAVE_STRUCT_ADDRINFO
|
|
||||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
|
||||||
|
|
||||||
#endif /* __CONFIG_WIN32_H */
|
/* Define if you have the <winsock.h> header file. */
|
||||||
|
#define HAVE_WINSOCK_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <winsock2.h> header file. */
|
||||||
|
#define HAVE_WINSOCK2_H 1
|
||||||
|
|
||||||
|
/* Define if you have the <ws2tcpip.h> header file. */
|
||||||
|
#define HAVE_WS2TCPIP_H 1
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* FUNCTIONS */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Define if you have the ioctlsocket function. */
|
||||||
|
#define HAVE_IOCTLSOCKET 1
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* STRUCT RELATED */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Define this if you have struct addrinfo */
|
||||||
|
#define HAVE_STRUCT_ADDRINFO 1
|
||||||
|
|
||||||
|
/* Define this if you have struct sockaddr_storage */
|
||||||
|
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
/* IPV6 COMPATIBILITY */
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Define this if you have address family AF_INET6 */
|
||||||
|
#define HAVE_AF_INET6 1
|
||||||
|
|
||||||
|
/* Define this if you have protocol family PF_INET6 */
|
||||||
|
#define HAVE_PF_INET6 1
|
||||||
|
|
||||||
|
/* Define this if you have struct in6_addr */
|
||||||
|
#define HAVE_STRUCT_IN6_ADDR 1
|
||||||
|
|
||||||
|
/* Define this if you have struct sockaddr_in6 */
|
||||||
|
#define HAVE_STRUCT_SOCKADDR_IN6 1
|
||||||
|
|
||||||
|
/* Define this if you have sockaddr_in6 with scopeid */
|
||||||
|
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ARES_CONFIG_WIN32_H */
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
|
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
AC_PREREQ(2.57)
|
||||||
AC_INIT(ares_init.c)
|
AC_INIT(ares_init.c)
|
||||||
|
AC_CONFIG_SRCDIR([ares_ipv6.h])
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
AM_INIT_AUTOMAKE(c-ares, CVS)
|
AM_INIT_AUTOMAKE(c-ares, CVS)
|
||||||
@@ -13,13 +16,12 @@ solaris*)
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# check for ssize_t
|
|
||||||
AC_CHECK_TYPE(ssize_t, ,
|
|
||||||
AC_DEFINE(ssize_t, int, [the signed version of size_t]))
|
|
||||||
|
|
||||||
AC_SEARCH_LIBS(gethostbyname, nsl)
|
AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||||
AC_SEARCH_LIBS(socket, socket)
|
AC_SEARCH_LIBS(socket, socket)
|
||||||
|
|
||||||
|
dnl check for cygwin stuff
|
||||||
|
AC_LIBTOOL_WIN32_DLL
|
||||||
|
|
||||||
dnl ************************************************************
|
dnl ************************************************************
|
||||||
dnl Option to switch on debug options. This makes an assumption that
|
dnl Option to switch on debug options. This makes an assumption that
|
||||||
dnl this is built as an 'ares' subdir in the curl source tree. Subject for
|
dnl this is built as an 'ares' subdir in the curl source tree. Subject for
|
||||||
@@ -38,9 +40,6 @@ 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
|
||||||
|
|
||||||
dnl Checks for standard header files, to make memdebug.h inclusions bettter
|
|
||||||
AC_HEADER_STDC
|
|
||||||
|
|
||||||
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])
|
||||||
@@ -48,6 +47,15 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include"
|
CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include"
|
||||||
CFLAGS="$CFLAGS -g"
|
CFLAGS="$CFLAGS -g"
|
||||||
|
|
||||||
|
dnl check for how to do large files, needed to get the curl_off_t check
|
||||||
|
dnl done right
|
||||||
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(curl_off_t, ,[
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "$srcdir/../include/curl/curl.h"
|
||||||
|
])
|
||||||
|
|
||||||
dnl set compiler "debug" options to become more picky, and remove
|
dnl set compiler "debug" options to become more picky, and remove
|
||||||
dnl optimize options from CFLAGS
|
dnl optimize options from CFLAGS
|
||||||
CURL_CC_DEBUG_OPTS
|
CURL_CC_DEBUG_OPTS
|
||||||
@@ -57,8 +65,37 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dnl libtool setup
|
||||||
|
CARES_CLEAR_LIBTOOL_TAGS
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if we need -no-undefined])
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin | *-*-mingw* | *-*-pw32*)
|
||||||
|
need_no_undefined=yes
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
need_no_undefined=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT($need_no_undefined)
|
||||||
|
AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
|
||||||
|
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl Make sure that our checks for headers windows.h winsock.h winsock2.h
|
||||||
|
dnl and ws2tcpip.h take precedence over any other further checks which
|
||||||
|
dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for
|
||||||
|
dnl this specific header files. And do them before its results are used.
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
CURL_CHECK_HEADER_WINDOWS
|
||||||
|
CURL_CHECK_HEADER_WINSOCK
|
||||||
|
CURL_CHECK_HEADER_WINSOCK2
|
||||||
|
CURL_CHECK_HEADER_WS2TCPIP
|
||||||
|
|
||||||
dnl check for a few basic system headers we need
|
dnl check for a few basic system headers we need
|
||||||
AC_CHECK_HEADERS(
|
AC_CHECK_HEADERS(
|
||||||
sys/types.h \
|
sys/types.h \
|
||||||
@@ -67,17 +104,23 @@ AC_CHECK_HEADERS(
|
|||||||
sys/socket.h \
|
sys/socket.h \
|
||||||
sys/ioctl.h \
|
sys/ioctl.h \
|
||||||
netdb.h \
|
netdb.h \
|
||||||
winsock2.h \
|
|
||||||
ws2tcpip.h \
|
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
net/if.h \
|
net/if.h \
|
||||||
arpa/nameser.h \
|
arpa/nameser.h \
|
||||||
arpa/nameser_compat.h \
|
arpa/nameser_compat.h \
|
||||||
arpa/inet.h, , ,
|
arpa/inet.h,
|
||||||
|
dnl to do if not found
|
||||||
|
[],
|
||||||
|
dnl to do if found
|
||||||
|
[],
|
||||||
|
dnl default includes
|
||||||
[
|
[
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
dnl We do this default-include simply to make sure that the nameser_compat.h
|
dnl We do this default-include simply to make sure that the nameser_compat.h
|
||||||
dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1
|
dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1
|
||||||
dnl (and others?) is not designed to allow this.
|
dnl (and others?) is not designed to allow this.
|
||||||
@@ -89,39 +132,68 @@ dnl *Sigh* these are needed in order for net/if.h to get properly detected.
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <winsock2.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(size_t)
|
||||||
|
AC_CHECK_SIZEOF(long)
|
||||||
|
AC_CHECK_SIZEOF(time_t)
|
||||||
|
|
||||||
|
AC_CHECK_TYPE(long long,
|
||||||
|
[AC_DEFINE(HAVE_LONGLONG, 1, [if your compiler supports long long])]
|
||||||
|
longlong="yes"
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "xyes" = "x$longlong"; then
|
||||||
|
AC_MSG_CHECKING([if numberLL works])
|
||||||
|
AC_COMPILE_IFELSE([long long val = 1000LL;],
|
||||||
|
[AC_DEFINE(HAVE_LL, 1, [if your compiler supports LL])]
|
||||||
|
AC_MSG_RESULT(yes),
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# check for ssize_t
|
||||||
|
AC_CHECK_TYPE(ssize_t, ,
|
||||||
|
AC_DEFINE(ssize_t, int, [the signed version of size_t]))
|
||||||
|
|
||||||
|
# Check for socklen_t or equivalent
|
||||||
|
CURL_CHECK_TYPE_SOCKLEN_T
|
||||||
|
|
||||||
|
TYPE_IN_ADDR_T
|
||||||
|
|
||||||
|
TYPE_SOCKADDR_STORAGE
|
||||||
|
|
||||||
AC_CHECK_TYPE(socklen_t, ,
|
|
||||||
AC_DEFINE(socklen_t, int, [the length of a socket address]),
|
|
||||||
[
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl check for AF_INET6
|
dnl check for AF_INET6
|
||||||
CARES_CHECK_CONSTANT(
|
CARES_CHECK_CONSTANT(
|
||||||
[
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
], [PF_INET6],
|
], [PF_INET6],
|
||||||
AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.])
|
AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.])
|
||||||
)
|
)
|
||||||
@@ -129,16 +201,23 @@ CARES_CHECK_CONSTANT(
|
|||||||
dnl check for PF_INET6
|
dnl check for PF_INET6
|
||||||
CARES_CHECK_CONSTANT(
|
CARES_CHECK_CONSTANT(
|
||||||
[
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
], [AF_INET6],
|
], [AF_INET6],
|
||||||
AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.])
|
AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.])
|
||||||
)
|
)
|
||||||
@@ -147,17 +226,25 @@ CARES_CHECK_CONSTANT(
|
|||||||
dnl check for the in6_addr structure
|
dnl check for the in6_addr structure
|
||||||
CARES_CHECK_STRUCT(
|
CARES_CHECK_STRUCT(
|
||||||
[
|
[
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#undef inline
|
||||||
#include <sys/types.h>
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
], [in6_addr],
|
], [in6_addr],
|
||||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
|
AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
|
||||||
@@ -166,17 +253,25 @@ CARES_CHECK_STRUCT(
|
|||||||
dnl check for the sockaddr_in6 structure
|
dnl check for the sockaddr_in6 structure
|
||||||
CARES_CHECK_STRUCT(
|
CARES_CHECK_STRUCT(
|
||||||
[
|
[
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#undef inline
|
||||||
#include <sys/types.h>
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
], [sockaddr_in6],
|
], [sockaddr_in6],
|
||||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1,
|
AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1,
|
||||||
@@ -188,17 +283,25 @@ AC_CHECK_MEMBER(struct sockaddr_in6.sin6_scope_id,
|
|||||||
[Define to 1 if your struct sockaddr_in6 has sin6_scope_id.])
|
[Define to 1 if your struct sockaddr_in6 has sin6_scope_id.])
|
||||||
, ,
|
, ,
|
||||||
[
|
[
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#undef inline
|
||||||
#include <sys/types.h>
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -207,15 +310,22 @@ AC_CHECK_MEMBER(struct addrinfo.ai_flags,
|
|||||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_ADDRINFO,1,
|
AC_DEFINE_UNQUOTED(HAVE_STRUCT_ADDRINFO,1,
|
||||||
[Define to 1 if you have struct addrinfo.]),,
|
[Define to 1 if you have struct addrinfo.]),,
|
||||||
[
|
[
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#undef inline
|
||||||
#include <sys/types.h>
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCaK2_H
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -224,10 +334,30 @@ AC_CHECK_MEMBER(struct addrinfo.ai_flags,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS( bitncmp \
|
||||||
|
if_indextoname,
|
||||||
|
dnl if found
|
||||||
|
[],
|
||||||
|
dnl if not found, $ac_func is the name we check for
|
||||||
|
func="$ac_func"
|
||||||
|
AC_MSG_CHECKING([deeper for $func])
|
||||||
|
AC_TRY_LINK( [],
|
||||||
|
[ $func ();],
|
||||||
|
AC_MSG_RESULT(yes!)
|
||||||
|
eval "ac_cv_func_$func=yes"
|
||||||
|
def=`echo "HAVE_$func" | tr 'a-z' 'A-Z'`
|
||||||
|
AC_DEFINE_UNQUOTED($def, 1, [If you have $func]),
|
||||||
|
AC_MSG_RESULT(but still no)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
dnl check for inet_pton
|
dnl check for inet_pton
|
||||||
AC_CHECK_FUNCS(inet_pton)
|
AC_CHECK_FUNCS(inet_pton)
|
||||||
dnl Some systems have it, but not IPv6
|
dnl Some systems have it, but not IPv6
|
||||||
@@ -241,9 +371,6 @@ AC_TRY_RUN(
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK_H
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -273,9 +400,6 @@ AC_TRY_RUN(
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK_H
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -307,9 +431,6 @@ AC_TRY_RUN(
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK_H
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -325,52 +446,82 @@ int main()
|
|||||||
}
|
}
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.])
|
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,
|
||||||
|
[Define to 1 if inet_ntop supports IPv6.])
|
||||||
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(struct in6_addr, ,
|
AC_CHECK_SIZEOF(struct in6_addr, ,
|
||||||
[
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK_H
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(struct in_addr, ,
|
AC_CHECK_SIZEOF(struct in_addr, ,
|
||||||
[
|
[
|
||||||
|
#undef inline
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSOCK_H
|
|
||||||
#include <winsock.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
AC_CHECK_FUNCS([bitncmp if_indextoname])
|
|
||||||
|
|
||||||
dnl God bless non-standardized functions! We need to see which getservbyport_r variant is available
|
dnl Check if the getnameinfo function is available
|
||||||
|
dnl and get the types of five of its arguments.
|
||||||
|
CURL_CHECK_FUNC_GETNAMEINFO
|
||||||
|
|
||||||
|
|
||||||
|
dnl God bless non-standardized functions! We need to see which getservbyport_r
|
||||||
|
dnl variant is available
|
||||||
CARES_CHECK_GETSERVBYPORT_R
|
CARES_CHECK_GETSERVBYPORT_R
|
||||||
|
|
||||||
CURL_CHECK_NONBLOCKING_SOCKET
|
CURL_CHECK_NONBLOCKING_SOCKET
|
||||||
|
|
||||||
AC_C_BIGENDIAN(
|
AC_C_BIGENDIAN(
|
||||||
[AC_DEFINE(ARES_BIG_ENDIAN, 1, [define this if ares is built for a big endian system])],
|
[AC_DEFINE(ARES_BIG_ENDIAN, 1,
|
||||||
|
[define this if ares is built for a big endian system])],
|
||||||
,
|
,
|
||||||
[AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])]
|
[AC_MSG_WARN([couldn't figure out endianess, assuming little endian!])]
|
||||||
)
|
)
|
||||||
|
90
ares/setup.h
90
ares/setup.h
@@ -1,5 +1,5 @@
|
|||||||
#ifndef ARES_SETUP_H
|
#ifndef __ARES_SETUP_H
|
||||||
#define ARES_SETUP_H
|
#define __ARES_SETUP_H
|
||||||
|
|
||||||
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
|
/* Copyright (C) 2004 - 2005 by Daniel Stenberg et al
|
||||||
*
|
*
|
||||||
@@ -14,6 +14,21 @@
|
|||||||
* without express or implied warranty.
|
* without express or implied warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(WIN32) && defined(__WIN32__)
|
||||||
|
/* Borland fix */
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WIN32) && defined(_WIN32)
|
||||||
|
/* VS2005 on x64 fix */
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include configuration script results or hand-crafted
|
||||||
|
* configuration file for platforms which lack config tool.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#else
|
#else
|
||||||
@@ -22,18 +37,56 @@
|
|||||||
#include "config-win32.h"
|
#include "config-win32.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* simple work-around for now, for systems without configure support */
|
|
||||||
#ifndef __DJGPP__
|
|
||||||
#define ssize_t int
|
|
||||||
#endif
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#define socklen_t int
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
/* Recent autoconf versions define these symbols in config.h. We don't want
|
/*
|
||||||
them (since they collide with the libcurl ones when we build
|
* Include header files for windows builds before redefining anything.
|
||||||
--enable-debug) so we undef them again here. */
|
* Use this preproessor block only to include or exclude windows.h,
|
||||||
|
* winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
|
||||||
|
* to any other further and independant block.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
# ifdef HAVE_WS2TCPIP_H
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# ifdef HAVE_WINSOCK_H
|
||||||
|
# include <winsock.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work-arounds for systems without configure support
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#if defined(__DJGPP__) || (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
|
||||||
|
defined(__POCC__)
|
||||||
|
#else
|
||||||
|
#define ssize_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_WS2TCPIP_H
|
||||||
|
#define socklen_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recent autoconf versions define these symbols in config.h. We don't
|
||||||
|
* want them (since they collide with the libcurl ones when we build
|
||||||
|
* --enable-debug) so we undef them again here.
|
||||||
|
*/
|
||||||
|
|
||||||
#undef PACKAGE_STRING
|
#undef PACKAGE_STRING
|
||||||
#undef PACKAGE_TARNAME
|
#undef PACKAGE_TARNAME
|
||||||
#undef PACKAGE_VERSION
|
#undef PACKAGE_VERSION
|
||||||
@@ -42,10 +95,11 @@
|
|||||||
#undef VERSION
|
#undef VERSION
|
||||||
#undef PACKAGE
|
#undef PACKAGE
|
||||||
|
|
||||||
/* now typedef our socket type */
|
/*
|
||||||
|
* Typedef our socket type
|
||||||
|
*/
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(WATT32)
|
#if defined(WIN32) && !defined(WATT32)
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
typedef SOCKET ares_socket_t;
|
typedef SOCKET ares_socket_t;
|
||||||
#define ARES_SOCKET_BAD INVALID_SOCKET
|
#define ARES_SOCKET_BAD INVALID_SOCKET
|
||||||
#else
|
#else
|
||||||
@@ -53,8 +107,10 @@ typedef int ares_socket_t;
|
|||||||
#define ARES_SOCKET_BAD -1
|
#define ARES_SOCKET_BAD -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Assume a few thing unless they're set by configure
|
/*
|
||||||
|
* Assume a few thing unless they're set by configure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER)
|
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER)
|
||||||
#define HAVE_SYS_TIME_H
|
#define HAVE_SYS_TIME_H
|
||||||
#endif
|
#endif
|
||||||
@@ -89,4 +145,4 @@ int ares_strcasecmp(const char *s1, const char *s2);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ARES_SETUP_H */
|
#endif /* __ARES_SETUP_H */
|
||||||
|
51
buildconf
51
buildconf
@@ -1,4 +1,26 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
#
|
||||||
|
# This software is licensed as described in the file COPYING, which
|
||||||
|
# you should have received as part of this distribution. The terms
|
||||||
|
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
#
|
||||||
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
# copies of the Software, and permit persons to whom the Software is
|
||||||
|
# furnished to do so, under the terms of the COPYING file.
|
||||||
|
#
|
||||||
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, either express or implied.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
die(){
|
die(){
|
||||||
echo "$@"
|
echo "$@"
|
||||||
@@ -13,6 +35,7 @@ findtool(){
|
|||||||
IFS=":"
|
IFS=":"
|
||||||
for path in $PATH
|
for path in $PATH
|
||||||
do
|
do
|
||||||
|
# echo "checks for $file in $path" >&2
|
||||||
if test -f "$path/$file"; then
|
if test -f "$path/$file"; then
|
||||||
echo "$path/$file"
|
echo "$path/$file"
|
||||||
return
|
return
|
||||||
@@ -85,8 +108,7 @@ fi
|
|||||||
|
|
||||||
echo "buildconf: automake version $am_version (ok)"
|
echo "buildconf: automake version $am_version (ok)"
|
||||||
|
|
||||||
ac=`findtool aclocal`
|
ac=`findtool ${ACLOCAL:-aclocal}`
|
||||||
|
|
||||||
if test -z "$ac"; then
|
if test -z "$ac"; then
|
||||||
echo "buildconf: aclocal not found. Weird automake installation!"
|
echo "buildconf: aclocal not found. Weird automake installation!"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -107,11 +129,16 @@ LIBTOOL_WANTED_VERSION=1.4.2
|
|||||||
# glibtool, with 'libtool' being something completely different.
|
# glibtool, with 'libtool' being something completely different.
|
||||||
libtool=`findtool glibtool 2>/dev/null`
|
libtool=`findtool glibtool 2>/dev/null`
|
||||||
if test ! -x "$libtool"; then
|
if test ! -x "$libtool"; then
|
||||||
libtool=`findtool libtool`
|
libtool=`findtool ${LIBTOOL:-libtool}`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
|
if test -z "$LIBTOOLIZE"; then
|
||||||
LIBTOOLIZE="${libtool}ize"
|
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
|
||||||
|
# $libtool is already the full path
|
||||||
|
libtoolize="${libtool}ize"
|
||||||
|
else
|
||||||
|
libtoolize=`findtool $LIBTOOLIZE`
|
||||||
|
fi
|
||||||
|
|
||||||
lt_pversion=`$libtool --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
|
lt_pversion=`$libtool --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
|
||||||
if test -z "$lt_pversion"; then
|
if test -z "$lt_pversion"; then
|
||||||
@@ -150,7 +177,7 @@ fi
|
|||||||
|
|
||||||
echo "buildconf: libtool version $lt_version (ok)"
|
echo "buildconf: libtool version $lt_version (ok)"
|
||||||
|
|
||||||
if test -f "$LIBTOOLIZE"; then
|
if test -f "$libtoolize"; then
|
||||||
echo "buildconf: libtoolize found"
|
echo "buildconf: libtoolize found"
|
||||||
else
|
else
|
||||||
echo "buildconf: libtoolize not found. Weird libtool installation!"
|
echo "buildconf: libtoolize not found. Weird libtool installation!"
|
||||||
@@ -173,14 +200,14 @@ fi
|
|||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# perl check
|
# perl check
|
||||||
#
|
#
|
||||||
PERL=`findtool perl`
|
PERL=`findtool ${PERL:-perl}`
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
# run the correct scripts now
|
# run the correct scripts now
|
||||||
|
|
||||||
echo "buildconf: running libtoolize"
|
echo "buildconf: running libtoolize"
|
||||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
$libtoolize --copy --automake --force || die "The libtoolize command failed"
|
||||||
echo "buildconf: running aclocal"
|
echo "buildconf: running aclocal"
|
||||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
|
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
|
||||||
if test -n "$PERL"; then
|
if test -n "$PERL"; then
|
||||||
@@ -199,12 +226,8 @@ ${AUTOCONF:-autoconf} || die "The autoconf command failed"
|
|||||||
|
|
||||||
if test -d ares; then
|
if test -d ares; then
|
||||||
cd ares
|
cd ares
|
||||||
echo "buildconf: running ares/libtoolize"
|
echo "buildconf: running in ares"
|
||||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
./buildconf
|
||||||
echo "buildconf: running ares/aclocal"
|
|
||||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The ares aclocal command failed"
|
|
||||||
echo "buildconf: running ares/autoconf"
|
|
||||||
${AUTOCONF:-autoconf} || die "The ares autoconf command failed"
|
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
167
configure.ac
167
configure.ac
@@ -1,4 +1,25 @@
|
|||||||
dnl $Id$
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
#
|
||||||
|
# This software is licensed as described in the file COPYING, which
|
||||||
|
# you should have received as part of this distribution. The terms
|
||||||
|
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
#
|
||||||
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
# copies of the Software, and permit persons to whom the Software is
|
||||||
|
# furnished to do so, under the terms of the COPYING file.
|
||||||
|
#
|
||||||
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, either express or implied.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
###########################################################################
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
@@ -140,6 +161,19 @@ dnl The install stuff has already been taken care of by the automake stuff
|
|||||||
dnl AC_PROG_INSTALL
|
dnl AC_PROG_INSTALL
|
||||||
AC_PROG_MAKE_SET
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl Make sure that our checks for headers windows.h winsock.h winsock2.h
|
||||||
|
dnl and ws2tcpip.h take precedence over any other further checks which
|
||||||
|
dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for
|
||||||
|
dnl this specific header files. And do them before its results are used.
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
CURL_CHECK_HEADER_WINDOWS
|
||||||
|
CURL_CHECK_HEADER_WINSOCK
|
||||||
|
CURL_CHECK_HEADER_WINSOCK2
|
||||||
|
CURL_CHECK_HEADER_WS2TCPIP
|
||||||
|
|
||||||
|
|
||||||
dnl ************************************************************
|
dnl ************************************************************
|
||||||
dnl switch off particular protocols
|
dnl switch off particular protocols
|
||||||
dnl
|
dnl
|
||||||
@@ -151,10 +185,8 @@ AC_HELP_STRING([--disable-http],[Disable HTTP support]),
|
|||||||
no)
|
no)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP])
|
AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP])
|
||||||
AC_MSG_WARN([disable HTTP disables FTP over proxy and GOPHER too])
|
AC_MSG_WARN([disable HTTP disables FTP over proxy])
|
||||||
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
|
|
||||||
AC_SUBST(CURL_DISABLE_HTTP, [1])
|
AC_SUBST(CURL_DISABLE_HTTP, [1])
|
||||||
AC_SUBST(CURL_DISABLE_GOPHER, [1])
|
|
||||||
;;
|
;;
|
||||||
*) AC_MSG_RESULT(yes)
|
*) AC_MSG_RESULT(yes)
|
||||||
;;
|
;;
|
||||||
@@ -176,21 +208,6 @@ AC_HELP_STRING([--disable-ftp],[Disable FTP support]),
|
|||||||
esac ],
|
esac ],
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
)
|
)
|
||||||
AC_MSG_CHECKING([whether to support gopher])
|
|
||||||
AC_ARG_ENABLE(gopher,
|
|
||||||
AC_HELP_STRING([--enable-gopher],[Enable GOPHER support])
|
|
||||||
AC_HELP_STRING([--disable-gopher],[Disable GOPHER support]),
|
|
||||||
[ case "$enableval" in
|
|
||||||
no)
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
|
|
||||||
AC_SUBST(CURL_DISABLE_GOPHER, [1])
|
|
||||||
;;
|
|
||||||
*) AC_MSG_RESULT(yes)
|
|
||||||
;;
|
|
||||||
esac ],
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
)
|
|
||||||
AC_MSG_CHECKING([whether to support file])
|
AC_MSG_CHECKING([whether to support file])
|
||||||
AC_ARG_ENABLE(file,
|
AC_ARG_ENABLE(file,
|
||||||
AC_HELP_STRING([--enable-file],[Enable FILE support])
|
AC_HELP_STRING([--enable-file],[Enable FILE support])
|
||||||
@@ -289,6 +306,12 @@ AC_HELP_STRING([--disable-manual],[Disable built-in manual]),
|
|||||||
dnl The actual use of the USE_MANUAL variable is done much later in this
|
dnl The actual use of the USE_MANUAL variable is done much later in this
|
||||||
dnl script to allow other actions to disable it as well.
|
dnl script to allow other actions to disable it as well.
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl check if this is the Intel ICC compiler, and if so make it stricter
|
||||||
|
dnl (convert warning 147 into an error) so that it properly can detect the
|
||||||
|
dnl gethostbyname_r() version
|
||||||
|
dnl **********************************************************************
|
||||||
|
CURL_DETECT_ICC([CFLAGS="$CFLAGS -we 147"])
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
@@ -449,10 +472,19 @@ dnl **********************************************************************
|
|||||||
dnl Check for the presence of the winmm library.
|
dnl Check for the presence of the winmm library.
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
AC_MSG_CHECKING([for timeGetTime in winmm])
|
case $host in
|
||||||
my_ac_save_LIBS=$LIBS
|
*-*-cygwin*)
|
||||||
LIBS="-lwinmm $LIBS"
|
dnl Under Cygwin, winmm exists but is not needed as WIN32 is not #defined
|
||||||
AC_TRY_LINK([#include <windef.h>
|
dnl and gettimeofday() will be used regardless of the outcome of this test.
|
||||||
|
dnl Skip this test, otherwise -lwinmm will be needlessly added to LIBS
|
||||||
|
dnl (and recorded as such in the .la file, potentially affecting downstream
|
||||||
|
dnl clients of the library.)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_CHECKING([for timeGetTime in winmm])
|
||||||
|
my_ac_save_LIBS=$LIBS
|
||||||
|
LIBS="-lwinmm $LIBS"
|
||||||
|
AC_TRY_LINK([#include <windef.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
],
|
],
|
||||||
[timeGetTime();],
|
[timeGetTime();],
|
||||||
@@ -463,6 +495,8 @@ AC_TRY_LINK([#include <windef.h>
|
|||||||
LIBS=$my_ac_save_LIBS
|
LIBS=$my_ac_save_LIBS
|
||||||
AC_MSG_RESULT(no)]
|
AC_MSG_RESULT(no)]
|
||||||
)
|
)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Checks for IPv6
|
dnl Checks for IPv6
|
||||||
@@ -795,7 +829,7 @@ OPT_SSL=off
|
|||||||
dnl Default to no CA bundle
|
dnl Default to no CA bundle
|
||||||
ca="no"
|
ca="no"
|
||||||
AC_ARG_WITH(ssl,dnl
|
AC_ARG_WITH(ssl,dnl
|
||||||
AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL installation (default: /usr/local/ssl)])
|
AC_HELP_STRING([--with-ssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option])
|
||||||
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||||
OPT_SSL=$withval)
|
OPT_SSL=$withval)
|
||||||
|
|
||||||
@@ -865,6 +899,12 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl This is for Msys/Mingw
|
dnl This is for Msys/Mingw
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin*)
|
||||||
|
dnl Under Cygwin this is extraneous and causes an unnecessary -lgdi32
|
||||||
|
dnl to be added to LIBS and recorded in the .la file.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
AC_MSG_CHECKING([for gdi32])
|
AC_MSG_CHECKING([for gdi32])
|
||||||
my_ac_save_LIBS=$LIBS
|
my_ac_save_LIBS=$LIBS
|
||||||
LIBS="-lgdi32 $LIBS"
|
LIBS="-lgdi32 $LIBS"
|
||||||
@@ -877,6 +917,8 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
LIBS=$my_ac_save_LIBS
|
LIBS=$my_ac_save_LIBS
|
||||||
AC_MSG_RESULT(no)]
|
AC_MSG_RESULT(no)]
|
||||||
)
|
)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
AC_CHECK_LIB(crypto, CRYPTO_lock,[
|
AC_CHECK_LIB(crypto, CRYPTO_lock,[
|
||||||
HAVECRYPTO="yes"
|
HAVECRYPTO="yes"
|
||||||
@@ -924,9 +966,18 @@ if test X"$OPT_SSL" != Xno; then
|
|||||||
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
||||||
|
|
||||||
if test $ac_cv_header_openssl_x509_h = no; then
|
if test $ac_cv_header_openssl_x509_h = no; then
|
||||||
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h,
|
dnl we don't use the "action" part of the AC_CHECK_HEADERS macro
|
||||||
|
dnl since 'err.h' might in fact find a krb4 header with the same
|
||||||
|
dnl name
|
||||||
|
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h)
|
||||||
|
|
||||||
|
if test $ac_cv_header_x509_h = yes &&
|
||||||
|
test $ac_cv_header_crypto_h = yes &&
|
||||||
|
test $ac_cv_header_ssl_h = yes; then
|
||||||
|
dnl three matches
|
||||||
curl_ssl_msg="enabled (OpenSSL)"
|
curl_ssl_msg="enabled (OpenSSL)"
|
||||||
OPENSSL_ENABLED=1)
|
OPENSSL_ENABLED=1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1047,10 +1098,10 @@ if test "$OPENSSL_ENABLED" != "1"; then
|
|||||||
fi
|
fi
|
||||||
if test -n "$addlib"; then
|
if test -n "$addlib"; then
|
||||||
|
|
||||||
CLEANLDFLAGS="$LDFLAGS"
|
CLEANLIBS="$LIBS"
|
||||||
CLEANCPPFLAGS="$CPPFLAGS"
|
CLEANCPPFLAGS="$CPPFLAGS"
|
||||||
|
|
||||||
LDFLAGS="$LDFLAGS $addlib"
|
LIBS="$LIBS $addlib"
|
||||||
if test "$addcflags" != "-I/usr/include"; then
|
if test "$addcflags" != "-I/usr/include"; then
|
||||||
CPPFLAGS="$CPPFLAGS $addcflags"
|
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||||
fi
|
fi
|
||||||
@@ -1063,7 +1114,7 @@ if test "$OPENSSL_ENABLED" != "1"; then
|
|||||||
curl_ssl_msg="enabled (GnuTLS)"
|
curl_ssl_msg="enabled (GnuTLS)"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
LDFLAGS="$CLEANLDFLAGS"
|
LIBS="$CLEANLIBS"
|
||||||
CPPFLAGS="$CLEANCPPFLAGS"
|
CPPFLAGS="$CLEANCPPFLAGS"
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1288,8 +1339,8 @@ AC_HELP_STRING([--enable-thread],[look for thread-safe functions]),
|
|||||||
|
|
||||||
if test X"$OPT_THREAD" = Xoff
|
if test X"$OPT_THREAD" = Xoff
|
||||||
then
|
then
|
||||||
AC_DEFINE(DISABLED_THREADSAFE, 1, \
|
AC_DEFINE(DISABLED_THREADSAFE, 1,
|
||||||
Set to explicitly specify we don't want to use thread-safe functions)
|
[Set to explicitly specify we don't want to use thread-safe functions])
|
||||||
else
|
else
|
||||||
if test "$ipv6" != "yes"; then
|
if test "$ipv6" != "yes"; then
|
||||||
dnl dig around for gethostbyname_r()
|
dnl dig around for gethostbyname_r()
|
||||||
@@ -1380,7 +1431,8 @@ if test x$cross_compiling != xyes; then
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
,
|
,
|
||||||
dnl not invoked when crosscompiling)
|
dnl not invoked when crosscompiling)
|
||||||
])
|
echo "hej"
|
||||||
|
)
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
dnl and for crosscompilings
|
dnl and for crosscompilings
|
||||||
@@ -1395,7 +1447,8 @@ dnl **********************************************************************
|
|||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
|
|
||||||
dnl First check for the very most basic headers. Then we can use these
|
|
||||||
|
dnl Now check for the very most basic headers. Then we can use these
|
||||||
dnl ones as default-headers when checking for the rest!
|
dnl ones as default-headers when checking for the rest!
|
||||||
AC_CHECK_HEADERS(
|
AC_CHECK_HEADERS(
|
||||||
sys/types.h \
|
sys/types.h \
|
||||||
@@ -1422,8 +1475,6 @@ AC_CHECK_HEADERS(
|
|||||||
fcntl.h \
|
fcntl.h \
|
||||||
dlfcn.h \
|
dlfcn.h \
|
||||||
alloca.h \
|
alloca.h \
|
||||||
winsock.h \
|
|
||||||
winsock2.h \
|
|
||||||
time.h \
|
time.h \
|
||||||
io.h \
|
io.h \
|
||||||
pwd.h \
|
pwd.h \
|
||||||
@@ -1493,7 +1544,9 @@ fi
|
|||||||
AC_CHECK_TYPE(ssize_t, ,
|
AC_CHECK_TYPE(ssize_t, ,
|
||||||
AC_DEFINE(ssize_t, int, [the signed version of size_t]))
|
AC_DEFINE(ssize_t, int, [the signed version of size_t]))
|
||||||
|
|
||||||
TYPE_SOCKLEN_T
|
# Check for socklen_t or equivalent
|
||||||
|
CURL_CHECK_TYPE_SOCKLEN_T
|
||||||
|
|
||||||
TYPE_IN_ADDR_T
|
TYPE_IN_ADDR_T
|
||||||
|
|
||||||
TYPE_SOCKADDR_STORAGE
|
TYPE_SOCKADDR_STORAGE
|
||||||
@@ -1543,8 +1596,10 @@ AC_CHECK_FUNCS( strtoll \
|
|||||||
ftruncate \
|
ftruncate \
|
||||||
pipe \
|
pipe \
|
||||||
poll \
|
poll \
|
||||||
|
getprotobyname \
|
||||||
getrlimit \
|
getrlimit \
|
||||||
setrlimit,
|
setrlimit \
|
||||||
|
fork,
|
||||||
dnl if found
|
dnl if found
|
||||||
[],
|
[],
|
||||||
dnl if not found, $ac_func is the name we check for
|
dnl if not found, $ac_func is the name we check for
|
||||||
@@ -1565,16 +1620,33 @@ fi
|
|||||||
|
|
||||||
dnl For some reason, the check above doesn't properly detect select() with
|
dnl For some reason, the check above doesn't properly detect select() with
|
||||||
dnl Msys/Mingw
|
dnl Msys/Mingw
|
||||||
if test "$ac_cv_func_select" != "yes"; then
|
if test "$ac_cv_func_select" = "no"; then
|
||||||
AC_MSG_CHECKING([for select in ws2_32])
|
AC_MSG_CHECKING([for select in ws2_32])
|
||||||
AC_TRY_LINK([#include <winsock2.h>],
|
AC_TRY_LINK([
|
||||||
[select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL);],
|
#undef inline
|
||||||
[ dnl worked!
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL);
|
||||||
|
],[
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
HAVE_SELECT="1"
|
HAVE_SELECT="1"
|
||||||
AC_DEFINE_UNQUOTED(HAVE_SELECT,1)],
|
AC_DEFINE_UNQUOTED(HAVE_SELECT, 1,
|
||||||
[AC_MSG_ERROR(You can't compile without a select)]
|
[Define to 1 if you have the select function.])
|
||||||
)
|
],[
|
||||||
|
AC_MSG_ERROR([You can't compile without a select])
|
||||||
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl sigsetjmp() might be a macro and no function so if it isn't found already
|
dnl sigsetjmp() might be a macro and no function so if it isn't found already
|
||||||
@@ -1613,6 +1685,10 @@ AC_CHECK_DECL(inet_pton, ,
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dnl Check if the getnameinfo function is available
|
||||||
|
dnl and get the types of five of its arguments.
|
||||||
|
CURL_CHECK_FUNC_GETNAMEINFO
|
||||||
|
|
||||||
AC_MSG_CHECKING([if we are Mac OS X (to disable poll)])
|
AC_MSG_CHECKING([if we are Mac OS X (to disable poll)])
|
||||||
disable_poll=no
|
disable_poll=no
|
||||||
case $host in
|
case $host in
|
||||||
@@ -1915,6 +1991,9 @@ AC_CONFIG_FILES([Makefile \
|
|||||||
packages/EPM/curl.list \
|
packages/EPM/curl.list \
|
||||||
packages/EPM/Makefile \
|
packages/EPM/Makefile \
|
||||||
packages/vms/Makefile \
|
packages/vms/Makefile \
|
||||||
|
packages/AIX/Makefile \
|
||||||
|
packages/AIX/RPM/Makefile \
|
||||||
|
packages/AIX/RPM/curl.spec \
|
||||||
curl-config \
|
curl-config \
|
||||||
libcurl.pc
|
libcurl.pc
|
||||||
])
|
])
|
||||||
|
@@ -1,10 +1,30 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 2001 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
#
|
||||||
|
# This software is licensed as described in the file COPYING, which
|
||||||
|
# you should have received as part of this distribution. The terms
|
||||||
|
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
#
|
||||||
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
# copies of the Software, and permit persons to whom the Software is
|
||||||
|
# furnished to do so, under the terms of the COPYING file.
|
||||||
|
#
|
||||||
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, either express or implied.
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
###########################################################################
|
||||||
#
|
#
|
||||||
# The idea to this kind of setup info script was stolen from numerous
|
# The idea to this kind of setup info script was stolen from numerous
|
||||||
# other packages, such as neon, libxml and gnome.
|
# other packages, such as neon, libxml and gnome.
|
||||||
#
|
#
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
includedir=@includedir@
|
includedir=@includedir@
|
||||||
@@ -19,6 +39,7 @@ Available values for OPTION include:
|
|||||||
--ca ca bundle install path
|
--ca ca bundle install path
|
||||||
--cc compiler
|
--cc compiler
|
||||||
--cflags pre-processor and compiler flags
|
--cflags pre-processor and compiler flags
|
||||||
|
--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
|
--protocols newline separated list of enabled protocols
|
||||||
--help display this help and exit
|
--help display this help and exit
|
||||||
@@ -101,9 +122,6 @@ while test $# -gt 0; do
|
|||||||
echo "FTPS"
|
echo "FTPS"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test "@CURL_DISABLE_GOPHER@" != "1"; then
|
|
||||||
echo "GOPHER"
|
|
||||||
fi
|
|
||||||
if test "@CURL_DISABLE_FILE@" != "1"; then
|
if test "@CURL_DISABLE_FILE@" != "1"; then
|
||||||
echo "FILE"
|
echo "FILE"
|
||||||
fi
|
fi
|
||||||
@@ -125,6 +143,26 @@ while test $# -gt 0; do
|
|||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--checkfor)
|
||||||
|
checkfor=$2
|
||||||
|
cmajor=`echo $checkfor | cut -d. -f1`
|
||||||
|
cminor=`echo $checkfor | cut -d. -f2`
|
||||||
|
# when extracting the patch part we strip off everything after a
|
||||||
|
# dash as that's used for things like version 1.2.3-CVS
|
||||||
|
cpatch=`echo $checkfor | cut -d. -f3 | cut -d- -f1`
|
||||||
|
checknum=`echo "$cmajor*256*256 + $cminor*256 + ${cpatch:-0}" | bc`
|
||||||
|
numuppercase=`echo @VERSIONNUM@ | tr 'a-f' 'A-F'`
|
||||||
|
nownum=`echo "obase=10; ibase=16; $numuppercase" | bc`
|
||||||
|
|
||||||
|
if test "$nownum" -ge "$checknum"; then
|
||||||
|
# silent success
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "requested version $checkfor is newer than existing @VERSION@"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
--vernum)
|
--vernum)
|
||||||
echo @VERSIONNUM@
|
echo @VERSIONNUM@
|
||||||
exit 0
|
exit 0
|
||||||
|
@@ -155,6 +155,11 @@ S-Lang
|
|||||||
S-Lang binding written by John E Davis
|
S-Lang binding written by John E Davis
|
||||||
http://www.jedsoft.org/slang/modules/curl.html
|
http://www.jedsoft.org/slang/modules/curl.html
|
||||||
|
|
||||||
|
SPL
|
||||||
|
|
||||||
|
SPL binding written by Clifford Wolf
|
||||||
|
http://www.clifford.at/spl/
|
||||||
|
|
||||||
Tcl
|
Tcl
|
||||||
|
|
||||||
Tclcurl is written by Andr<64>s Garc<72>a
|
Tclcurl is written by Andr<64>s Garc<72>a
|
||||||
@@ -173,3 +178,8 @@ wxWidgets
|
|||||||
|
|
||||||
Written by Casey O'Donnell
|
Written by Casey O'Donnell
|
||||||
http://homepage.mac.com/codonnell/wxcurldav/
|
http://homepage.mac.com/codonnell/wxcurldav/
|
||||||
|
|
||||||
|
XBLite
|
||||||
|
|
||||||
|
Written by David Szafranski
|
||||||
|
http://perso.wanadoo.fr/xblite/libraries.html
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
Date: October 27, 2005
|
Date: May 15, 2006
|
||||||
Author: Daniel Stenberg <daniel@haxx.se>
|
Author: Daniel Stenberg <daniel@haxx.se>
|
||||||
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
URL: http://curl.haxx.se/legal/distro-dilemma.html
|
||||||
|
|
||||||
Condition
|
Condition
|
||||||
|
|
||||||
This document is written to describe the situation as it is right
|
This document is written to describe the situation as it is right
|
||||||
now. libcurl 7.15.0 is currently the latest version available. Things may (or
|
now. libcurl 7.15.3 is currently the latest version available. Things may of
|
||||||
perhaps will) of course change in the future.
|
course change in the future.
|
||||||
|
|
||||||
This document reflects my view and understanding of these things. Please tell
|
This document reflects my view and understanding of these things. Please tell
|
||||||
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
me where and how you think I'm wrong, and I'll try to correct my mistakes.
|
||||||
@@ -16,11 +16,10 @@ Background
|
|||||||
The Free Software Foundation has deemed the Original BSD license[1] to be
|
The Free Software Foundation has deemed the Original BSD license[1] to be
|
||||||
"incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
|
"incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
|
||||||
the point is the same: if you distribute a binary version of a GPL program,
|
the point is the same: if you distribute a binary version of a GPL program,
|
||||||
it MUST NOT be linked with any Original BSD-licensed parts or
|
it MUST NOT be linked with any Original BSD-licensed parts or libraries.
|
||||||
libraries. Doing so will violate the GPL license. For a long time, very many
|
Doing so will violate the GPL license. For a long time, very many GPL
|
||||||
GPL licensed programs have avoided this license mess by adding an
|
licensed programs have avoided this license mess by adding an exception[8] to
|
||||||
exception[8] to their license. And many others have just closed their eyes
|
their license. And many others have just closed their eyes for this problem.
|
||||||
for this problem.
|
|
||||||
|
|
||||||
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
|
||||||
our plates?
|
our plates?
|
||||||
@@ -49,25 +48,13 @@ Part of the Operating System
|
|||||||
Debian does however not take this stance and has officially(?) claimed that
|
Debian does however not take this stance and has officially(?) claimed that
|
||||||
OpenSSL is not a required part of the Debian operating system
|
OpenSSL is not a required part of the Debian operating system
|
||||||
|
|
||||||
Debian-legal
|
|
||||||
|
|
||||||
In August 2004 I figured I should start pulling people's attention to this to
|
|
||||||
see if anyone has any bright ideas or if they would dismiss my worries based
|
|
||||||
on some elegant writing I had missed somewhere:
|
|
||||||
|
|
||||||
My post to debian-legal on August 12 2004:
|
|
||||||
|
|
||||||
http://lists.debian.org/debian-legal/2004/08/msg00279.html
|
|
||||||
|
|
||||||
Several people agreed then that this is a known and rather big problem, but
|
|
||||||
the following discussion didn't result in much.
|
|
||||||
|
|
||||||
GnuTLS
|
GnuTLS
|
||||||
|
|
||||||
With the release of libcurl 7.14.0 (May 2005), it can now get built to use
|
With the release of libcurl 7.14.0 (May 2005), libcurl can now get built to
|
||||||
GnuTLS instead of OpenSSL. GnuTLS is a LGPL[7] licensed library that offers a
|
use GnuTLS instead of OpenSSL. GnuTLS is an LGPL[7] licensed library that
|
||||||
matching set of features as OpenSSL does. Now, you can build and distribute
|
offers a matching set of features as OpenSSL does. Now, you can build and
|
||||||
an SSL capable libcurl without including any Original BSD licensed code.
|
distribute an TLS/SSL capable libcurl without including any Original BSD
|
||||||
|
licensed code.
|
||||||
|
|
||||||
I believe Debian is the first distro to provide libcurl/GnutTLS packages.
|
I believe Debian is the first distro to provide libcurl/GnutTLS packages.
|
||||||
|
|
||||||
@@ -80,23 +67,20 @@ GnuTLS vs OpenSSL
|
|||||||
and it has not been tested nor used very extensively, while the OpenSSL
|
and it has not been tested nor used very extensively, while the OpenSSL
|
||||||
equivalent code has been used and thus matured for more than seven (7) years.
|
equivalent code has been used and thus matured for more than seven (7) years.
|
||||||
|
|
||||||
In August 2005, the debian-devel mailing list discovered the license issue as
|
|
||||||
a GPL licensed application wanted SSL capabilities from libcurl and thus was
|
|
||||||
forced to use the GnuTLS powered libcurl. For a reason that is unknown to me,
|
|
||||||
the application authors didn't want to or was unable to add an exception to
|
|
||||||
their GPL license. Alas, the license problem hit the fan again.
|
|
||||||
|
|
||||||
GnuTLS
|
GnuTLS
|
||||||
- LGPL licensened
|
- LGPL licensened
|
||||||
- supports SRP
|
- supports SRP
|
||||||
- lacks SSLv2 support
|
- lacks SSLv2 support
|
||||||
- lacks MD2 support (used by at least some CA certs)
|
- lacks MD2 support (used by at least some CA certs)
|
||||||
|
- lacks the crypto functions libcurl uses for NTLM
|
||||||
|
|
||||||
OpenSSL
|
OpenSSL
|
||||||
- Original BSD licensened
|
- Original BSD licensened
|
||||||
- lacks SRP
|
- lacks SRP
|
||||||
- supports SSLv2
|
- supports SSLv2
|
||||||
- older and more widely used
|
- older and more widely used
|
||||||
|
- provides crypto functions libcurl uses for NTLM
|
||||||
|
- libcurl can do non-blocking connects with it in 7.15.4 and later
|
||||||
|
|
||||||
The Better License, Original BSD or LGPL?
|
The Better License, Original BSD or LGPL?
|
||||||
|
|
||||||
@@ -124,20 +108,21 @@ More SSL Libraries
|
|||||||
Application Angle of this Problem
|
Application Angle of this Problem
|
||||||
|
|
||||||
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
|
||||||
default), and applications are built/linked to use that single lib. Replacing
|
default) on the built/created lib file, and applications are built/linked to
|
||||||
one libcurl instance with another one that uses the other SSL/TLS library
|
use that single lib. Replacing one libcurl instance with another one that
|
||||||
might break one or more applications (due to ABI differences and/or different
|
uses the other SSL/TLS library might break one or more applications (due to
|
||||||
feature set). You want your application to use the libcurl it was built for.
|
ABI differences and/or different feature set). You want your application to
|
||||||
|
use the libcurl it was built for.
|
||||||
|
|
||||||
Project cURL Angle of this Problem
|
Project cURL Angle of this Problem
|
||||||
|
|
||||||
We distribute libcurl and everyone may build libcurl with either library. At
|
We distribute libcurl and everyone may build libcurl with either library at
|
||||||
their choice. This problem is not directly a problem of ours. It merely
|
their choice. This problem is not directly a problem of ours. It merely
|
||||||
affects users - GPL application authors only - of our lib as it comes
|
affects users - GPL application authors only - of our lib as it comes
|
||||||
included and delivered on some distros.
|
included and delivered on some distros.
|
||||||
|
|
||||||
libcurl has different ABI when built with different SSL/TLS libraries due to
|
libcurl has different ABI when built with different SSL/TLS libraries due to
|
||||||
two reasons:
|
these reasons:
|
||||||
|
|
||||||
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
1. No one has worked on fixing this. The mutex/lock callbacks should be set
|
||||||
with a generic libcurl function that should use the proper underlying
|
with a generic libcurl function that should use the proper underlying
|
||||||
@@ -146,25 +131,25 @@ Project cURL Angle of this Problem
|
|||||||
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
|
||||||
but simply requires OpenSSL.
|
but simply requires OpenSSL.
|
||||||
|
|
||||||
|
3. There might be some other subtle differences just because nobody has yet
|
||||||
|
tried to make a fixed ABI like this.
|
||||||
|
|
||||||
Distro Angle of this Problem
|
Distro Angle of this Problem
|
||||||
|
|
||||||
A distro can provide separate libcurls built with different SSL/TLS libraries
|
To my knowledge there is only one distro that ships libcurl built with either
|
||||||
to work around this, but at least Debian seems to be very hostile against
|
one of the SSL libs supported.
|
||||||
such an approach, probably since it makes things like devel packages for the
|
|
||||||
different libs collide since they would provide the same include files and
|
Debian Linux is now (since mid September 2005) providing two different
|
||||||
man pages etc.
|
libcurl packages, one for libcurl built with OpenSSL and one built with
|
||||||
|
GnuTLS. They use different .so names and can this both be installed in a
|
||||||
|
single system simultaneously. This has been said to be a transitional system
|
||||||
|
not desired to keep in the long run.
|
||||||
|
|
||||||
Fixing the Only Problem
|
Fixing the Only Problem
|
||||||
|
|
||||||
The only problem is thus for distributions that want to offer libcurl
|
The only problem is thus for distributions that want to offer libcurl
|
||||||
versions built with more than one SSL/TLS library.
|
versions built with more than one SSL/TLS library.
|
||||||
|
|
||||||
Debian is now (since mid September 2005) providing two different devel
|
|
||||||
packages, one for libcurl built with OpenSSL and one built with GnuTLS. They
|
|
||||||
use different .so names and can this both be installed in a single system
|
|
||||||
simultaneously. This has previously been said as a transitional system not
|
|
||||||
desired to keep in the long run.
|
|
||||||
|
|
||||||
Since multiple libcurl binaries using different names are ruled out, we need
|
Since multiple libcurl binaries using different names are ruled out, we need
|
||||||
to come up with a way to have one single libcurl that someone uses different
|
to come up with a way to have one single libcurl that someone uses different
|
||||||
underlying libraries. The best(?) approach currently suggested involves this:
|
underlying libraries. The best(?) approach currently suggested involves this:
|
||||||
@@ -194,9 +179,9 @@ Fixing the Only Problem
|
|||||||
|
|
||||||
When Will This Happen
|
When Will This Happen
|
||||||
|
|
||||||
Note again that this is not a problem in curl, it doesn't solve any actual
|
This is not a problem in curl, it doesn't solve any actual technical problems
|
||||||
technical problems in our project. Don't hold your breath for this to happen
|
in our project. Don't hold your breath for this to happen very soon (if at
|
||||||
very soon (if at all) unless you step forward and contribute.
|
all) unless you step forward and contribute.
|
||||||
|
|
||||||
The suggestion that is outlined above is still only a suggestion. Feel free
|
The suggestion that is outlined above is still only a suggestion. Feel free
|
||||||
to bring a better idea!
|
to bring a better idea!
|
||||||
@@ -206,7 +191,7 @@ When Will This Happen
|
|||||||
code like today (without the use of lib2), should you decide to ignore the
|
code like today (without the use of lib2), should you decide to ignore the
|
||||||
problems outlined in this document.
|
problems outlined in this document.
|
||||||
|
|
||||||
Update: Work on this has been initiated by Richard Atterer:
|
Work on this was suggested by Richard Atterer:
|
||||||
|
|
||||||
http://curl.haxx.se/mail/lib-2005-09/0066.html
|
http://curl.haxx.se/mail/lib-2005-09/0066.html
|
||||||
|
|
||||||
|
5
docs/FAQ
5
docs/FAQ
@@ -114,7 +114,7 @@ FAQ
|
|||||||
libcurl
|
libcurl
|
||||||
|
|
||||||
A free and easy-to-use client-side URL transfer library, supporting FTP,
|
A free and easy-to-use client-side URL transfer library, supporting FTP,
|
||||||
FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. libcurl supports
|
FTPS, HTTP, HTTPS, TELNET, DICT, FILE and LDAP. libcurl supports
|
||||||
HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP
|
HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP
|
||||||
form based upload, proxies, cookies, user+password authentication, file
|
form based upload, proxies, cookies, user+password authentication, file
|
||||||
transfer resume, http proxy tunneling and more!
|
transfer resume, http proxy tunneling and more!
|
||||||
@@ -132,8 +132,7 @@ FAQ
|
|||||||
A command line tool for getting or sending files using URL syntax.
|
A command line tool for getting or sending files using URL syntax.
|
||||||
|
|
||||||
Since curl uses libcurl, it supports a range of common Internet protocols,
|
Since curl uses libcurl, it supports a range of common Internet protocols,
|
||||||
currently including HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and
|
currently including HTTP, HTTPS, FTP, FTPS, LDAP, DICT, TELNET and FILE.
|
||||||
FILE.
|
|
||||||
|
|
||||||
We pronounce curl and cURL with an initial k sound: [kurl].
|
We pronounce curl and cURL with an initial k sound: [kurl].
|
||||||
|
|
||||||
|
@@ -91,8 +91,8 @@ FTP
|
|||||||
- no dir depth limit
|
- no dir depth limit
|
||||||
|
|
||||||
FTPS (*1)
|
FTPS (*1)
|
||||||
- explicit ftps:// support that use SSL on both connections
|
- implicit ftps:// support that use SSL on both connections
|
||||||
- implicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
|
- explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
|
||||||
connection to use SSL for both or one of the connections
|
connection to use SSL for both or one of the connections
|
||||||
|
|
||||||
TFTP
|
TFTP
|
||||||
@@ -109,10 +109,6 @@ LDAP (*2)
|
|||||||
DICT
|
DICT
|
||||||
- extended DICT URL support
|
- extended DICT URL support
|
||||||
|
|
||||||
GOPHER
|
|
||||||
- GET
|
|
||||||
- via http-proxy
|
|
||||||
|
|
||||||
FILE
|
FILE
|
||||||
- URL support
|
- URL support
|
||||||
- "uploads"
|
- "uploads"
|
||||||
|
@@ -260,7 +260,6 @@ Win32
|
|||||||
CURL_DISABLE_TELNET disables TELNET
|
CURL_DISABLE_TELNET disables TELNET
|
||||||
CURL_DISABLE_DICT disables DICT
|
CURL_DISABLE_DICT disables DICT
|
||||||
CURL_DISABLE_FILE disables FILE
|
CURL_DISABLE_FILE disables FILE
|
||||||
CURL_DISABLE_GOPHER disables GOPHER
|
|
||||||
|
|
||||||
If you want to set any of these defines you have the following
|
If you want to set any of these defines you have the following
|
||||||
possibilities:
|
possibilities:
|
||||||
|
@@ -3,7 +3,37 @@ 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!
|
||||||
|
|
||||||
28. The TFTP code is not portable and will fail on some architectures.
|
34. The SOCKS connection codes don't properly acknowledge (connect) timeouts.
|
||||||
|
|
||||||
|
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
|
||||||
|
run that might be needed only for building libcurl. Similarly, it might
|
||||||
|
include options that perhaps aren't suitable both for static and dynamic
|
||||||
|
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
|
||||||
|
IPv6 numerical addresses in URLs.
|
||||||
|
|
||||||
|
29. IPv6 URLs with zone ID is not supported.
|
||||||
|
http://www.ietf.org/internet-drafts/draft-fenner-literal-zone-02.txt
|
||||||
|
specifies the use of a plus sign instead of a percent when specifying zone
|
||||||
|
IDs in URLs to get around the problem of percent signs being
|
||||||
|
special. According to the reporter, Firefox deals with the URL _with_ a
|
||||||
|
percent letter (which seems like a blatant URL spec violation).
|
||||||
|
|
||||||
|
See http://curl.haxx.se/bug/view.cgi?id=1371118
|
||||||
|
|
||||||
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
|
||||||
"system context" will make it use wrong(?) user name - at least when compared
|
"system context" will make it use wrong(?) user name - at least when compared
|
||||||
@@ -15,15 +45,11 @@ may have been fixed since this was written!
|
|||||||
--proxy-anyauth. There's work in progress on this problem, and a recent
|
--proxy-anyauth. There's work in progress on this problem, and a recent
|
||||||
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
|
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
|
||||||
|
|
||||||
24. Harshal Pradhan's Use-after-free with libcurl+ares. This probably occurs
|
|
||||||
because there is a pending ares callback that gets called after the
|
|
||||||
connection struct has been freed in libcurl:
|
|
||||||
http://curl.haxx.se/mail/lib-2005-08/0022.html
|
|
||||||
Fixing this properly most likely requires a new c-ares function.
|
|
||||||
|
|
||||||
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
|
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
|
||||||
We don't have any test cases for SOCKS proxy. We probably have even more
|
We don't have any test cases for SOCKS proxy. We probably have even more
|
||||||
bugs and lack of features when a SOCKS proxy is used.
|
bugs and lack of features when a SOCKS proxy is used. And there seem to be a
|
||||||
|
problem with SOCKS when doing FTP: See
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=1371540
|
||||||
|
|
||||||
22. Sending files to a FTP server using curl on VMS, might lead to curl
|
22. Sending files to a FTP server using curl on VMS, might lead to curl
|
||||||
complaining on "unaligned file size" on completion. The problem is related
|
complaining on "unaligned file size" on completion. The problem is related
|
||||||
@@ -40,12 +66,11 @@ may have been fixed since this was written!
|
|||||||
specification). The receiver will convert the data from the standard
|
specification). The receiver will convert the data from the standard
|
||||||
form to his own internal form.
|
form to his own internal form.
|
||||||
|
|
||||||
|
Since 7.15.4 at least line endings are converted.
|
||||||
|
|
||||||
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
|
||||||
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
|
||||||
|
|
||||||
18. test case 57 has </test> that should be </client> but when corrected, the
|
|
||||||
test case fails!
|
|
||||||
|
|
||||||
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
|
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
|
||||||
<password>, and <fpath> components, encoded as "%00". The problem is that
|
<password>, and <fpath> components, encoded as "%00". The problem is that
|
||||||
curl_unescape does not detect this, but instead returns a shortened C
|
curl_unescape does not detect this, but instead returns a shortened C
|
||||||
@@ -103,8 +128,6 @@ may have been fixed since this was written!
|
|||||||
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
||||||
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
||||||
|
|
||||||
3. GOPHER transfers seem broken
|
|
||||||
|
|
||||||
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
||||||
violating the RFC2616), curl won't wait to read the response but just stop
|
violating the RFC2616), curl won't wait to read the response but just stop
|
||||||
reading and return back. If a second request (let's assume a GET) is then
|
reading and return back. If a second request (let's assume a GET) is then
|
||||||
|
@@ -56,9 +56,9 @@ krb4
|
|||||||
|
|
||||||
While nothing in particular says that a Kerberos4 library must use any
|
While nothing in particular says that a Kerberos4 library must use any
|
||||||
particular license, the one I've tried and used successfully so far
|
particular license, the one I've tried and used successfully so far
|
||||||
(kth-krb4) is Original BSD-licensed with the announcement clause. Some
|
(kth-krb4) is partly Original BSD-licensed with the announcement
|
||||||
of the code in libcurl that is written to deal with Kerberos4 likewise
|
clause. Some of the code in libcurl that is written to deal with
|
||||||
have such a license.
|
Kerberos4 is Modified BSD-licensed.
|
||||||
|
|
||||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||||
|
|
||||||
|
12
docs/MANUAL
12
docs/MANUAL
@@ -23,10 +23,6 @@ SIMPLE USAGE
|
|||||||
|
|
||||||
curl ftp://cool.haxx.se/
|
curl ftp://cool.haxx.se/
|
||||||
|
|
||||||
Get a gopher document from funet's gopher server:
|
|
||||||
|
|
||||||
curl gopher://gopher.funet.fi
|
|
||||||
|
|
||||||
Get the definition of curl from a dictionary:
|
Get the definition of curl from a dictionary:
|
||||||
|
|
||||||
curl dict://dict.org/m:curl
|
curl dict://dict.org/m:curl
|
||||||
@@ -94,10 +90,6 @@ USING PASSWORDS
|
|||||||
|
|
||||||
Probably most commonly used with private certificates, as explained below.
|
Probably most commonly used with private certificates, as explained below.
|
||||||
|
|
||||||
GOPHER
|
|
||||||
|
|
||||||
Curl features no password support for gopher.
|
|
||||||
|
|
||||||
PROXY
|
PROXY
|
||||||
|
|
||||||
Get an ftp file using a proxy named my-proxy that uses port 888:
|
Get an ftp file using a proxy named my-proxy that uses port 888:
|
||||||
@@ -734,7 +726,7 @@ LDAP
|
|||||||
Working with LDAP URLs":
|
Working with LDAP URLs":
|
||||||
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
|
http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
|
||||||
|
|
||||||
RFC 2255, "The LDAP URL Format" http://www.rfc-editor.org/rfc/rfc2255.txt
|
RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
|
||||||
|
|
||||||
To show you an example, this is now I can get all people from my local LDAP
|
To show you an example, this is now I can get all people from my local LDAP
|
||||||
server that has a certain sub-domain in their email address:
|
server that has a certain sub-domain in their email address:
|
||||||
@@ -748,7 +740,7 @@ ENVIRONMENT VARIABLES
|
|||||||
|
|
||||||
Curl reads and understands the following environment variables:
|
Curl reads and understands the following environment variables:
|
||||||
|
|
||||||
http_proxy, HTTPS_PROXY, FTP_PROXY, GOPHER_PROXY
|
http_proxy, HTTPS_PROXY, FTP_PROXY
|
||||||
|
|
||||||
They should be set for protocol-specific proxies. General proxy should be
|
They should be set for protocol-specific proxies. General proxy should be
|
||||||
set with
|
set with
|
||||||
|
35
docs/THANKS
35
docs/THANKS
@@ -14,13 +14,16 @@ Alex Suykov
|
|||||||
Alex aka WindEagle
|
Alex aka WindEagle
|
||||||
Alexander Kourakos
|
Alexander Kourakos
|
||||||
Alexander Krasnostavsky
|
Alexander Krasnostavsky
|
||||||
|
Alexander Lazic
|
||||||
Alexander Zhuravlev
|
Alexander Zhuravlev
|
||||||
Alexis Carvalho
|
Alexis Carvalho
|
||||||
|
Amol Pattekar
|
||||||
Andi Jahja
|
Andi Jahja
|
||||||
Andreas Damm
|
Andreas Damm
|
||||||
Andreas Olsson
|
Andreas Olsson
|
||||||
Andreas Rieke
|
Andreas Rieke
|
||||||
Andres Garcia
|
Andres Garcia
|
||||||
|
Andrew Benham
|
||||||
Andrew Bushnell
|
Andrew Bushnell
|
||||||
Andrew Francis
|
Andrew Francis
|
||||||
Andrew Fuller
|
Andrew Fuller
|
||||||
@@ -41,12 +44,12 @@ Bjorn Reese
|
|||||||
Bj<EFBFBD>rn Stenberg
|
Bj<EFBFBD>rn Stenberg
|
||||||
Bob Schader
|
Bob Schader
|
||||||
Brad Burdick
|
Brad Burdick
|
||||||
|
Bradford Bruce
|
||||||
Brent Beardsley
|
Brent Beardsley
|
||||||
Brian Akins
|
Brian Akins
|
||||||
Brian R Duffy
|
Brian R Duffy
|
||||||
Bruce Mitchener
|
Bruce Mitchener
|
||||||
Bryan Henderson
|
Bryan Henderson
|
||||||
Bryan Henderson
|
|
||||||
Bryan Kemp
|
Bryan Kemp
|
||||||
Caolan McNamara
|
Caolan McNamara
|
||||||
Casey O'Donnell
|
Casey O'Donnell
|
||||||
@@ -91,7 +94,9 @@ David Hull
|
|||||||
David J Meyer
|
David J Meyer
|
||||||
David James
|
David James
|
||||||
David Kimdon
|
David Kimdon
|
||||||
|
David Lang
|
||||||
David LeBlanc
|
David LeBlanc
|
||||||
|
David McCreedy
|
||||||
David Odin
|
David Odin
|
||||||
David Phillips
|
David Phillips
|
||||||
David Shaw
|
David Shaw
|
||||||
@@ -100,6 +105,7 @@ David Thiel
|
|||||||
David Yan
|
David Yan
|
||||||
Detlef Schmier
|
Detlef Schmier
|
||||||
Diego Casorran
|
Diego Casorran
|
||||||
|
Dima Barsky
|
||||||
Dimitris Sarris
|
Dimitris Sarris
|
||||||
Dinar
|
Dinar
|
||||||
Dirk Eddelbuettel
|
Dirk Eddelbuettel
|
||||||
@@ -112,6 +118,8 @@ Doug Kaufman
|
|||||||
Doug Porter
|
Doug Porter
|
||||||
Douglas E. Wegscheid
|
Douglas E. Wegscheid
|
||||||
Douglas R. Horner
|
Douglas R. Horner
|
||||||
|
Dov Murik
|
||||||
|
Duane Cathey
|
||||||
Dustin Boswell
|
Dustin Boswell
|
||||||
Dylan Ellicott
|
Dylan Ellicott
|
||||||
Dylan Salisbury
|
Dylan Salisbury
|
||||||
@@ -131,6 +139,7 @@ Eric Young
|
|||||||
Erick Nuwendam
|
Erick Nuwendam
|
||||||
Erwan Legrand
|
Erwan Legrand
|
||||||
Erwin Authried
|
Erwin Authried
|
||||||
|
Eugene Kotlyarov
|
||||||
Evan Jordan
|
Evan Jordan
|
||||||
Fabrizio Ammollo
|
Fabrizio Ammollo
|
||||||
Fedor Karpelevitch
|
Fedor Karpelevitch
|
||||||
@@ -191,8 +200,12 @@ James Gallagher
|
|||||||
James Griffiths
|
James Griffiths
|
||||||
James MacMillan
|
James MacMillan
|
||||||
Jamie Lokier
|
Jamie Lokier
|
||||||
|
Jamie Newton
|
||||||
Jamie Wilkinson
|
Jamie Wilkinson
|
||||||
|
Jan Kunder
|
||||||
Jason S. Priebe
|
Jason S. Priebe
|
||||||
|
Jaz Fresh
|
||||||
|
Jean Jacques Drouin
|
||||||
Jean-Claude Chauve
|
Jean-Claude Chauve
|
||||||
Jean-Louis Lemaire
|
Jean-Louis Lemaire
|
||||||
Jean-Marc Ranger
|
Jean-Marc Ranger
|
||||||
@@ -234,11 +247,13 @@ J
|
|||||||
Kai Sommerfeld
|
Kai Sommerfeld
|
||||||
Kai-Uwe Rommel
|
Kai-Uwe Rommel
|
||||||
Kang-Jin Lee
|
Kang-Jin Lee
|
||||||
|
Karl Moerder
|
||||||
Karol Pietrzak
|
Karol Pietrzak
|
||||||
Keith MacDonald
|
Keith MacDonald
|
||||||
Keith McGuigan
|
Keith McGuigan
|
||||||
Ken Hirsch
|
Ken Hirsch
|
||||||
Ken Rastatter
|
Ken Rastatter
|
||||||
|
Kent Boortz
|
||||||
Kevin Fisk
|
Kevin Fisk
|
||||||
Kevin Lussier
|
Kevin Lussier
|
||||||
Kevin Roth
|
Kevin Roth
|
||||||
@@ -279,6 +294,7 @@ Marco G. Salvagno
|
|||||||
Marcus Webster
|
Marcus Webster
|
||||||
Mario Schroeder
|
Mario Schroeder
|
||||||
Mark Butler
|
Mark Butler
|
||||||
|
Markus Koetter
|
||||||
Markus Moeller
|
Markus Moeller
|
||||||
Markus Oberhumer
|
Markus Oberhumer
|
||||||
Martijn Koster
|
Martijn Koster
|
||||||
@@ -297,9 +313,11 @@ Mekonikum
|
|||||||
Mettgut Jamalla
|
Mettgut Jamalla
|
||||||
Michael Benedict
|
Michael Benedict
|
||||||
Michael Curtis
|
Michael Curtis
|
||||||
|
Michael Jahn
|
||||||
Michael Mealling
|
Michael Mealling
|
||||||
Michael Wallner
|
Michael Wallner
|
||||||
Michal Bonino
|
Michal Bonino
|
||||||
|
Michal Marek
|
||||||
Mihai Ionescu
|
Mihai Ionescu
|
||||||
Mike Bytnar
|
Mike Bytnar
|
||||||
Mike Dobbs
|
Mike Dobbs
|
||||||
@@ -321,8 +339,10 @@ Nicolas Croiset
|
|||||||
Nicolas Fran<61>ois
|
Nicolas Fran<61>ois
|
||||||
Niels van Tongeren
|
Niels van Tongeren
|
||||||
Nikita Schmidt
|
Nikita Schmidt
|
||||||
|
Nis Jorgensen
|
||||||
Nodak Sodak
|
Nodak Sodak
|
||||||
Norbert Novotny
|
Norbert Novotny
|
||||||
|
Ofer
|
||||||
Oren Tirosh
|
Oren Tirosh
|
||||||
P R Schaffner
|
P R Schaffner
|
||||||
Patrick Bihan-Faou
|
Patrick Bihan-Faou
|
||||||
@@ -338,7 +358,9 @@ Pedro Neves
|
|||||||
Pete Su
|
Pete Su
|
||||||
Peter Bray
|
Peter Bray
|
||||||
Peter Forret
|
Peter Forret
|
||||||
|
Peter Heuchert
|
||||||
Peter Pentchev
|
Peter Pentchev
|
||||||
|
Peter Su
|
||||||
Peter Sylvester
|
Peter Sylvester
|
||||||
Peter Todd
|
Peter Todd
|
||||||
Peter Verhas
|
Peter Verhas
|
||||||
@@ -348,8 +370,10 @@ Phil Karn
|
|||||||
Philip Gladstone
|
Philip Gladstone
|
||||||
Philippe Hameau
|
Philippe Hameau
|
||||||
Philippe Raoult
|
Philippe Raoult
|
||||||
|
Philippe Vaucher
|
||||||
Pierre
|
Pierre
|
||||||
Puneet Pawaia
|
Puneet Pawaia
|
||||||
|
Quagmire
|
||||||
Rafael Sagula
|
Rafael Sagula
|
||||||
Ralph Beckmann
|
Ralph Beckmann
|
||||||
Ralph Mitchell
|
Ralph Mitchell
|
||||||
@@ -399,12 +423,14 @@ Sergio Ballestrero
|
|||||||
Seshubabu Pasam
|
Seshubabu Pasam
|
||||||
Shard
|
Shard
|
||||||
Shawn Poulson
|
Shawn Poulson
|
||||||
|
Shmulik Regev
|
||||||
Siddhartha Prakash Jain
|
Siddhartha Prakash Jain
|
||||||
Simon Dick
|
Simon Dick
|
||||||
Simon Josefsson
|
Simon Josefsson
|
||||||
Simon Liu
|
Simon Liu
|
||||||
Spiridonoff A.V
|
Spiridonoff A.V
|
||||||
Stadler Stephan
|
Stadler Stephan
|
||||||
|
Stefan Esser
|
||||||
Stefan Ulrich
|
Stefan Ulrich
|
||||||
Stephan Bergmann
|
Stephan Bergmann
|
||||||
Stephen Kick
|
Stephen Kick
|
||||||
@@ -421,6 +447,8 @@ Sven Neuhaus
|
|||||||
S<EFBFBD>bastien Willemijns
|
S<EFBFBD>bastien Willemijns
|
||||||
T. Bharath
|
T. Bharath
|
||||||
T. Yamada
|
T. Yamada
|
||||||
|
Temprimus
|
||||||
|
Thomas Klausner
|
||||||
Thomas Schwinge
|
Thomas Schwinge
|
||||||
Thomas Tonino
|
Thomas Tonino
|
||||||
Tim Baker
|
Tim Baker
|
||||||
@@ -429,6 +457,7 @@ Tim Costello
|
|||||||
Tim Sneddon
|
Tim Sneddon
|
||||||
Toby Peterson
|
Toby Peterson
|
||||||
Todd Kulesza
|
Todd Kulesza
|
||||||
|
Todd Vierling
|
||||||
Tom Benoist
|
Tom Benoist
|
||||||
Tom Lee
|
Tom Lee
|
||||||
Tom Mattison
|
Tom Mattison
|
||||||
@@ -446,7 +475,9 @@ Traian Nicolescu
|
|||||||
Troels Walsted Hansen
|
Troels Walsted Hansen
|
||||||
Troy Engel
|
Troy Engel
|
||||||
Tupone Alfredo
|
Tupone Alfredo
|
||||||
|
Ulf H<>rnhammar
|
||||||
Ulrich Zadow
|
Ulrich Zadow
|
||||||
|
Vilmos Nebehaj
|
||||||
Vincent Bronner
|
Vincent Bronner
|
||||||
Vincent Penquerc'h
|
Vincent Penquerc'h
|
||||||
Vincent Sanders
|
Vincent Sanders
|
||||||
@@ -459,7 +490,9 @@ Wesley Laxton
|
|||||||
Wez Furlong
|
Wez Furlong
|
||||||
Wilfredo Sanchez
|
Wilfredo Sanchez
|
||||||
Wojciech Zwiefka
|
Wojciech Zwiefka
|
||||||
|
Yang Tse
|
||||||
Yarram Sunil
|
Yarram Sunil
|
||||||
Zvi Har'El
|
Zvi Har'El
|
||||||
nk
|
nk
|
||||||
swalkaus at yahoo.com
|
swalkaus at yahoo.com
|
||||||
|
tommink[at]post.pl
|
||||||
|
44
docs/TODO
44
docs/TODO
@@ -14,12 +14,6 @@ TODO
|
|||||||
|
|
||||||
LIBCURL
|
LIBCURL
|
||||||
|
|
||||||
* Introduce an interface to libcurl that allows applications to easier get to
|
|
||||||
know what cookies that are received. CURLINFO_COOKIELIST to get a
|
|
||||||
curl_slist with cookies (netscape/mozilla cookie file formatted), and
|
|
||||||
CURLOPT_COOKIELIST to set a list of cookies (using the same format).
|
|
||||||
http://curl.haxx.se/mail/lib-2004-12/0195.html
|
|
||||||
|
|
||||||
* Introduce another callback interface for upload/download that makes one
|
* Introduce another callback interface for upload/download that makes one
|
||||||
less copy of data and thus a faster operation.
|
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]
|
||||||
@@ -43,15 +37,29 @@ TODO
|
|||||||
* Add option that changes the interval in which the progress callback is
|
* Add option that changes the interval in which the progress callback is
|
||||||
called at most.
|
called at most.
|
||||||
|
|
||||||
|
* 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!
|
||||||
|
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
|
||||||
|
bundle the c-ares source code in the libcurl source code releases).
|
||||||
|
|
||||||
|
* Support CONNECT 407 responses that kill the connection and expect the
|
||||||
|
client to reconnect to complete the authentication. Currently libcurl
|
||||||
|
assumes that a proxy connection will be kept alive.
|
||||||
|
|
||||||
|
* Make the curl/*.h headers include the proper system includes based on what
|
||||||
|
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).
|
||||||
|
|
||||||
LIBCURL - multi interface
|
LIBCURL - multi interface
|
||||||
|
|
||||||
* Add a curl_multi_fdset() alternative. this allows apps to avoid the
|
|
||||||
FD_SETSIZE problem with select().
|
|
||||||
|
|
||||||
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
|
||||||
|
|
||||||
* Make sure we don't ever loop because of non-blocking sockets return
|
* Make sure we don't ever loop because of non-blocking sockets return
|
||||||
EWOULDBLOCK or similar. This FTP command sending, the SSL connection etc.
|
EWOULDBLOCK or similar. The GnuTLS connection etc.
|
||||||
|
|
||||||
* Make transfers treated more carefully. We need a way to tell libcurl we
|
* 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
|
have data to write, as the current system expects us to upload data each
|
||||||
@@ -61,10 +69,6 @@ TODO
|
|||||||
ready to accept read data. Today libcurl feeds the data as soon as it is
|
ready to accept read data. Today libcurl feeds the data as soon as it is
|
||||||
available for reading, no matter what.
|
available for reading, no matter what.
|
||||||
|
|
||||||
* Add curl_multi_socket() and family to the multi interface that gets file
|
|
||||||
descriptors, as an alternative to the curl_multi_fdset(). This is necessary
|
|
||||||
to allow apps to properly avoid the FD_SETSIZE problem.
|
|
||||||
|
|
||||||
* Make curl_easy_perform() a wrapper-function that simply creates a multi
|
* 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
|
||||||
@@ -182,6 +186,11 @@ TODO
|
|||||||
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
||||||
on the TLS to provide name and password
|
on the TLS to provide name and password
|
||||||
|
|
||||||
|
* Fix the connection phase to be non-blocking when multi interface is used
|
||||||
|
|
||||||
|
* Add a way to check if the connection seems to be alive, to corrspond to the
|
||||||
|
SSL_peak() way we use with OpenSSL.
|
||||||
|
|
||||||
LDAP
|
LDAP
|
||||||
|
|
||||||
* 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
|
||||||
@@ -193,7 +202,8 @@ TODO
|
|||||||
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
|
||||||
|
|
||||||
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
|
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
|
||||||
should most probably use an existing ssh library, such as OpenSSH.
|
should most probably use an existing ssh library, such as OpenSSH. or
|
||||||
|
libssh2.org
|
||||||
|
|
||||||
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
|
* RSYNC (no RFCs 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.
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2006, 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.13.0" "curl-config manual"
|
.TH curl-config 1 "25 Jan 2004" "Curl 7.15.4" "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
|
||||||
@@ -37,6 +37,11 @@ Displays the compiler used to build libcurl.
|
|||||||
.IP "--cflags"
|
.IP "--cflags"
|
||||||
Set of compiler options (CFLAGS) to use when compiling files that use
|
Set of compiler options (CFLAGS) to use when compiling files that use
|
||||||
libcurl. Currently that is only thw include path to the curl include files.
|
libcurl. Currently that is only thw include path to the curl include files.
|
||||||
|
.IP "--checkfor [version]"
|
||||||
|
Specify the oldest possible libcurl version string you want, and this
|
||||||
|
script will return 0 if the current installation is new enough or it
|
||||||
|
returns 1 and outputs a text saying that the current version is not new
|
||||||
|
enough. (Added in 7.15.4)
|
||||||
.IP "--feature"
|
.IP "--feature"
|
||||||
Lists what particular main features the installed libcurl was built with. At
|
Lists what particular main features the installed libcurl was built with. At
|
||||||
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
|
||||||
@@ -53,10 +58,10 @@ in $prefix/lib and its header files are installed in $prefix/include and so
|
|||||||
on. The prefix is set with "configure --prefix".
|
on. The prefix is set with "configure --prefix".
|
||||||
.IP "--protocols"
|
.IP "--protocols"
|
||||||
Lists what particular protocols the installed libcurl was built to support. At
|
Lists what particular protocols the installed libcurl was built to support. At
|
||||||
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, GOPHER,
|
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
|
||||||
FILE, TELNET, LDAP, DICT. Do not assume any particular order. The protocols
|
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
|
||||||
will be listed using uppercase and are separated by newlines. There may be
|
be listed using uppercase and are separated by newlines. There may be none,
|
||||||
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 "--version"
|
.IP "--version"
|
||||||
Outputs version information about the installed libcurl.
|
Outputs version information about the installed libcurl.
|
||||||
.IP "--vernum"
|
.IP "--vernum"
|
||||||
|
210
docs/curl.1
210
docs/curl.1
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2006, 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 "24 Nov 2005" "Curl 7.15.1" "Curl Manual"
|
.TH curl 1 "21 Mar 2006" "Curl 7.15.4" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -30,8 +30,8 @@ curl \- transfer a URL
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B curl
|
.B curl
|
||||||
is a tool to transfer data from or to a server, using one of the supported
|
is a tool to transfer data from or to a server, using one of the supported
|
||||||
protocols (HTTP, HTTPS, FTP, FTPS, TFTP, GOPHER, DICT, TELNET, LDAP or
|
protocols (HTTP, HTTPS, FTP, FTPS, TFTP, DICT, TELNET, LDAP or FILE).
|
||||||
FILE). The command is designed to work without user interaction.
|
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 (https:) connections, cookies, file
|
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file
|
||||||
@@ -43,7 +43,7 @@ curl is powered by libcurl for all transfer-related features. See
|
|||||||
for details.
|
for details.
|
||||||
.SH URL
|
.SH URL
|
||||||
The URL syntax is protocol dependent. You'll find a detailed description in
|
The URL syntax is protocol dependent. You'll find a detailed description in
|
||||||
RFC 2396.
|
RFC 3986.
|
||||||
|
|
||||||
You can specify multiple URLs or parts of URLs by writing part sets within
|
You can specify multiple URLs or parts of URLs by writing part sets within
|
||||||
braces as in:
|
braces as in:
|
||||||
@@ -80,6 +80,24 @@ getting many files from the same server will not do multiple connects /
|
|||||||
handshakes. This improves speed. Of course this is only done on files
|
handshakes. This improves speed. Of course this is only done on files
|
||||||
specified on a single command line and cannot be used between separate curl
|
specified on a single command line and cannot be used between separate curl
|
||||||
invokes.
|
invokes.
|
||||||
|
.SH "PROGRESS METER"
|
||||||
|
curl normally displays a progress meter during operations, indicating amount
|
||||||
|
of transfered data, transfer speeds and estimated time left etc.
|
||||||
|
|
||||||
|
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
|
||||||
|
\fIdisables\fP the progress meter as otherwise it would mess up the output
|
||||||
|
mixing progress meter and response data.
|
||||||
|
|
||||||
|
If you want a progress meter for HTTP POST or PUT requests, you need to
|
||||||
|
redirect the response output to a file, using shell redirect (>), -o [file] or
|
||||||
|
similar.
|
||||||
|
|
||||||
|
It is not the same case for FTP upload as that operation is not spitting out
|
||||||
|
any response data to the terminal.
|
||||||
|
|
||||||
|
If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
|
||||||
|
friend.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IP "-a/--append"
|
.IP "-a/--append"
|
||||||
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
(FTP) When used in an FTP upload, this will tell curl to append to the target
|
||||||
@@ -100,7 +118,7 @@ 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 inducing an extra
|
||||||
network round-trip. This is used instead of setting a specific authentication
|
network round-trip. This is used instead of setting a specific authentication
|
||||||
method, which you can do with \fI--basic\fP, \fI--digest\fP, \fI--ntlm\fP, and
|
method, which you can do with \fI--basic\fP, \fI--digest\fP, \fI--ntlm\fP, and
|
||||||
\fI--negotiate\fP. (Added in 7.10.6)
|
\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
|
||||||
@@ -140,7 +158,7 @@ If this option is used twice, the second one will disable ASCII usage.
|
|||||||
(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
|
(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
|
||||||
this option is usually pointless, unless you use it to override a previously
|
this option is usually pointless, unless you use it to override a previously
|
||||||
set option that sets a different authentication method (such as \fI--ntlm\fP,
|
set option that sets a different authentication method (such as \fI--ntlm\fP,
|
||||||
\fI--digest\fP and \fI--negotiate\fP). (Added in 7.10.6)
|
\fI--digest\fP and \fI--negotiate\fP).
|
||||||
|
|
||||||
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.
|
||||||
@@ -198,7 +216,8 @@ To create remote directories when using FTP, try \fI--ftp-create-dirs\fP.
|
|||||||
.IP "--crlf"
|
.IP "--crlf"
|
||||||
(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390).
|
(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390).
|
||||||
|
|
||||||
If this option is used twice, the second will again disable crlf converting.
|
If this option is used several times, the following occurrences make no
|
||||||
|
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 a way
|
||||||
that can emulate as if a user has filled in a HTML form and pressed the submit
|
that can emulate as if a user has filled in a HTML form and pressed the submit
|
||||||
@@ -242,7 +261,7 @@ append data.
|
|||||||
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
|
||||||
combination with the normal \fI-u/--user\fP option to set user name and
|
combination with the normal \fI-u/--user\fP option to set user name and
|
||||||
password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for
|
password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for
|
||||||
related options. (Added in curl 7.10.6)
|
related options.
|
||||||
|
|
||||||
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.
|
||||||
@@ -252,7 +271,7 @@ active FTP transfers. Curl will normally always first attempt to use EPRT,
|
|||||||
then LPRT before using PORT, but with this option, it will use PORT right
|
then LPRT before using PORT, but with this option, it will use PORT right
|
||||||
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
|
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
|
||||||
on all servers but enable more functionality in a better way than the
|
on all servers but enable more functionality in a better way than the
|
||||||
traditional PORT command. (Added in 7.10.5)
|
traditional PORT command.
|
||||||
|
|
||||||
If this option is used several times, each occurrence will toggle this on/off.
|
If this option is used several times, each occurrence will toggle this on/off.
|
||||||
.IP "--disable-epsv"
|
.IP "--disable-epsv"
|
||||||
@@ -276,9 +295,9 @@ If this option is used several times, the last one will be used.
|
|||||||
.IP "-e/--referer <URL>"
|
.IP "-e/--referer <URL>"
|
||||||
(HTTP) Sends the "Referer Page" information to the HTTP server. This can also
|
(HTTP) Sends the "Referer Page" information to the HTTP server. This can also
|
||||||
be set with the \fI-H/--header\fP flag of course. When used with
|
be set with the \fI-H/--header\fP flag of course. When used with
|
||||||
\fI-L/--location\fP you can append ";auto" to the referer URL to make curl
|
\fI-L/--location\fP you can append ";auto" to the --referer URL to make curl
|
||||||
automatically set the previous URL when it follows a Location: header. The
|
automatically set the previous URL when it follows a Location: header. The
|
||||||
\&";auto" string can be used alone, even if you don't set an initial referer.
|
\&";auto" string can be used alone, even if you don't set an initial --referer.
|
||||||
|
|
||||||
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 "--engine <name>"
|
.IP "--engine <name>"
|
||||||
@@ -336,9 +355,9 @@ If this option is used several times, the last one will be used.
|
|||||||
.IP "-f/--fail"
|
.IP "-f/--fail"
|
||||||
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
||||||
like this to better enable scripts etc to better deal with failed attempts. In
|
like this to better enable scripts etc to better deal with failed attempts. In
|
||||||
normal cases when a HTTP server fails to deliver a document, it returns a HTML
|
normal cases when a HTTP server fails to deliver a document, it returns an
|
||||||
document stating so (which often also describes why and more). This flag will
|
HTML document stating so (which often also describes why and more). This flag
|
||||||
prevent curl from outputting that and fail silently instead.
|
will prevent curl from outputting that and return error 22.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable silent failure.
|
If this option is used twice, the second will again disable silent failure.
|
||||||
.IP "--ftp-account [data]"
|
.IP "--ftp-account [data]"
|
||||||
@@ -350,15 +369,33 @@ 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 URL/operation uses a path that doesn't currently exist on
|
(FTP) When an FTP URL/operation uses a path that doesn't currently exist on
|
||||||
the server, the standard behavior of curl is to fail. Using this option, curl
|
the server, the standard behavior of curl is to fail. Using this option, curl
|
||||||
will instead attempt to create missing directories. (Added in 7.10.7)
|
will instead attempt to create missing directories.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable silent failure.
|
If this option is used twice, the second will again disable directory creation.
|
||||||
|
.IP "--ftp-method [method]"
|
||||||
|
(FTP) Control what method curl should use to reach a file on a FTP(S)
|
||||||
|
server. The method argument should be one of the following alternatives:
|
||||||
|
.RS
|
||||||
|
.IP multicwd
|
||||||
|
curl does a single CWD operation for each path part in the given URL. For deep
|
||||||
|
hierarchies this means very many commands. This is how RFC1738 says it should
|
||||||
|
be done. This is the default but the slowest behavior.
|
||||||
|
.IP nocwd
|
||||||
|
curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full
|
||||||
|
path to the server for all these commands. This is the fastest behavior.
|
||||||
|
.IP singlecwd
|
||||||
|
curl does one CWD with the full target directory and then operates on the file
|
||||||
|
\&"normally" (like in the multicwd case). This is somewhat more standards
|
||||||
|
compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||||
|
.RE
|
||||||
.IP "--ftp-pasv"
|
.IP "--ftp-pasv"
|
||||||
(FTP) Use PASV when transferring. PASV is the internal default behavior, but
|
(FTP) Use PASV when transferring. PASV is the internal default behavior, but
|
||||||
using this option can be used to override a previous --ftp-port option. (Added
|
using this option can be used to override a previous --ftp-port option. (Added
|
||||||
in 7.11.0)
|
in 7.11.0)
|
||||||
|
|
||||||
If this option is used twice, the second will again disable silent failure.
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
|
|
||||||
.IP "--ftp-skip-pasv-ip"
|
.IP "--ftp-skip-pasv-ip"
|
||||||
(FTP) Tell curl to not use the IP address the server suggests in its response
|
(FTP) Tell curl to not use the IP address the server suggests in its response
|
||||||
to curl's PASV command when curl connects the data connection. Instead curl
|
to curl's PASV command when curl connects the data connection. Instead curl
|
||||||
@@ -367,7 +404,8 @@ connection. (Added in 7.14.2)
|
|||||||
|
|
||||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable silent failure.
|
If this option is used twice, the second will again use the server's suggested
|
||||||
|
address.
|
||||||
.IP "--ftp-ssl"
|
.IP "--ftp-ssl"
|
||||||
(FTP) Make the FTP connection switch to use SSL/TLS. (Added in 7.11.0)
|
(FTP) Make the FTP connection switch to use SSL/TLS. (Added in 7.11.0)
|
||||||
|
|
||||||
@@ -428,7 +466,8 @@ with a '?' separator.
|
|||||||
If used in combination with -I, the POST data will instead be appended to the
|
If used in combination with -I, the POST data will instead be appended to the
|
||||||
URL with a HEAD request.
|
URL with a HEAD request.
|
||||||
|
|
||||||
If used multiple times, nothing special happens.
|
If this option is used several times, the following occurrences make no
|
||||||
|
difference.
|
||||||
.IP "-h/--help"
|
.IP "-h/--help"
|
||||||
Usage help.
|
Usage help.
|
||||||
.IP "-H/--header <header>"
|
.IP "-H/--header <header>"
|
||||||
@@ -479,15 +518,14 @@ If this option is used twice, the second will again disable header only.
|
|||||||
(HTTP) When curl is told to read cookies from a given file, this option will
|
(HTTP) When curl is told to read cookies from a given file, this option will
|
||||||
make it discard all "session cookies". This will basically have the same effect
|
make it discard all "session cookies". This will basically have the same effect
|
||||||
as if a new session is started. Typical browsers always discard session
|
as if a new session is started. Typical browsers always discard session
|
||||||
cookies when they're closed down. (Added in 7.9.7)
|
cookies when they're closed down.
|
||||||
|
|
||||||
If this option is used several times, each occurrence will toggle this on/off.
|
If this option is used several times, each occurrence will toggle this on/off.
|
||||||
.IP "-k/--insecure"
|
.IP "-k/--insecure"
|
||||||
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
||||||
and transfers. Starting with curl 7.10, all SSL connections will be attempted
|
and transfers. All SSL connections are attempted to be made secure by using
|
||||||
to be made secure by using the CA certificate bundle installed by
|
the CA certificate bundle installed by default. This makes all connections
|
||||||
default. This makes all connections considered "insecure" to fail unless
|
considered "insecure" to fail unless \fI-k/--insecure\fP is used.
|
||||||
\fI-k/--insecure\fP is used.
|
|
||||||
|
|
||||||
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 "--key <key>"
|
.IP "--key <key>"
|
||||||
@@ -514,7 +552,7 @@ 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. If the parameter is
|
||||||
to contain white spaces, the parameter must be inclosed within quotes. If the
|
to contain white spaces, the parameter must be enclosed within quotes. 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.
|
treated as a comment.
|
||||||
|
|
||||||
@@ -554,8 +592,6 @@ If you are also using the \fI-Y/--speed-limit\fP option, that option will take
|
|||||||
precedence and might cripple the rate-limiting slightly, to help keeping the
|
precedence and might cripple the rate-limiting slightly, to help keeping the
|
||||||
speed-limit logic working.
|
speed-limit logic working.
|
||||||
|
|
||||||
This option was introduced in curl 7.10.
|
|
||||||
|
|
||||||
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 "-l/--list-only"
|
.IP "-l/--list-only"
|
||||||
(FTP)
|
(FTP)
|
||||||
@@ -569,15 +605,21 @@ list only files in their response to NLST; they do not include
|
|||||||
subdirectories and symbolic links.
|
subdirectories and symbolic links.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable list only.
|
If this option is used twice, the second will again disable list only.
|
||||||
|
.IP "--local-port <num>[-num]"
|
||||||
|
Set a prefered number or range of local port numbers to use for the
|
||||||
|
connection(s). Note that port numbers by nature is a scarce resource that
|
||||||
|
will be busy at times so setting this range to something too narrow might
|
||||||
|
cause unnecessary connection setup failures. (Added in 7.15.2)
|
||||||
.IP "-L/--location"
|
.IP "-L/--location"
|
||||||
(HTTP/HTTPS) If the server reports that the requested page has a different
|
(HTTP/HTTPS) If the server reports that the requested page has moved to a
|
||||||
location (indicated with the header line Location:) this flag will let curl
|
different location (indicated with a Location: header and a 3XX response code)
|
||||||
attempt to reattempt the get on the new place. If used together with
|
this option will make curl redo the request on the new place. If used together
|
||||||
\fI-i/--include\fP or \fI-I/--head\fP, headers from all requested pages will
|
with \fI-i/--include\fP or \fI-I/--head\fP, headers from all requested pages
|
||||||
be shown. If authentication is used, curl will only send its credentials to
|
will be shown. When authentication is used, curl only sends its credentials to
|
||||||
the initial host, so if a redirect takes curl to a different host, it won't
|
the initial host. If a redirect takes curl to a different host, it won't be
|
||||||
intercept the user+password. See also \fI--location-trusted\fP on how to
|
able to intercept the user+password. See also \fI--location-trusted\fP on how
|
||||||
change this.
|
to change this. You can limit the amount of redirects to follow by using the
|
||||||
|
\fI--max-redirs\fP option.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable location following.
|
If this option is used twice, the second will again disable location following.
|
||||||
.IP "--location-trusted"
|
.IP "--location-trusted"
|
||||||
@@ -631,7 +673,7 @@ Very similar to \fI--netrc\fP, but this option makes the .netrc usage
|
|||||||
designed by Microsoft and is used in their web applications. It is primarily
|
designed by Microsoft and is used in their web applications. It is primarily
|
||||||
meant as a support for Kerberos5 authentication but may be also used along
|
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. (Added in 7.10.6)
|
draft-brezak-spnego-http-04.txt.
|
||||||
|
|
||||||
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
|
||||||
@@ -656,7 +698,7 @@ designed by Microsoft and is used by IIS web servers. It is a proprietary
|
|||||||
protocol, reversed engineered by clever people and implemented in curl based
|
protocol, reversed engineered by clever people and implemented in curl based
|
||||||
on their efforts. This kind of behavior should not be endorsed, you should
|
on their efforts. This kind of behavior should not be endorsed, you should
|
||||||
encourage everyone who uses NTLM to switch to a public and documented
|
encourage everyone who uses NTLM to switch to a public and documented
|
||||||
authentication method instead. Such as Digest. (Added in 7.10.6)
|
authentication method instead. Such as Digest.
|
||||||
|
|
||||||
If you want to enable NTLM for your proxy authentication, then use
|
If you want to enable NTLM for your proxy authentication, then use
|
||||||
\fI--proxy-ntlm\fP.
|
\fI--proxy-ntlm\fP.
|
||||||
@@ -686,8 +728,8 @@ dynamically.
|
|||||||
Write output to a local file named like the remote file we get. (Only the file
|
Write output to a local file named like the remote file we get. (Only the file
|
||||||
part of the remote file is used, the path is cut off.)
|
part of the remote file is used, the path is cut off.)
|
||||||
|
|
||||||
The remote file name to use for saving is extracted from the given URL.
|
The remote file name to use for saving is extracted from the given URL,
|
||||||
Nothing else
|
nothing else.
|
||||||
|
|
||||||
You may use this option as many times as you have number of URLs.
|
You may use this option as many times as you have number of URLs.
|
||||||
.IP "--pass <phrase>"
|
.IP "--pass <phrase>"
|
||||||
@@ -696,8 +738,8 @@ You may use this option as many times as you have number of URLs.
|
|||||||
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 "--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 will cause an extra request/response round-trip. (Added
|
||||||
in curl 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
|
||||||
authentication.
|
authentication.
|
||||||
@@ -740,7 +782,8 @@ i.e "192.168.10.1" to specify exact IP number
|
|||||||
.IP "host name"
|
.IP "host name"
|
||||||
i.e "my.host.domain" to specify machine
|
i.e "my.host.domain" to specify machine
|
||||||
.IP "-"
|
.IP "-"
|
||||||
(any single-letter string) to make it pick the machine's default
|
make curl pick the same IP address that is already used for the control
|
||||||
|
connection
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. Disable the
|
If this option is used several times, the last one will be used. Disable the
|
||||||
@@ -821,7 +864,7 @@ for all forthcoming retries it will double the waiting time until it reaches
|
|||||||
10 minutes which then will be the delay between the rest of the retries. By
|
10 minutes which then will be the delay between the rest of the retries. By
|
||||||
using \fI--retry-delay\fP you disable this exponential backoff algorithm. See
|
using \fI--retry-delay\fP you disable this exponential backoff algorithm. See
|
||||||
also \fI--retry-max-time\fP to limit the total time allowed for
|
also \fI--retry-max-time\fP to limit the total time allowed for
|
||||||
retries. (Option added in 7.12.3)
|
retries. (Added in 7.12.3)
|
||||||
|
|
||||||
If this option is used multiple times, the last occurrence decide the amount.
|
If this option is used multiple times, the last occurrence decide the amount.
|
||||||
.IP "--retry-delay <seconds>"
|
.IP "--retry-delay <seconds>"
|
||||||
@@ -829,7 +872,7 @@ Make curl sleep this amount of time between each retry when a transfer has
|
|||||||
failed with a transient error (it changes the default backoff time algorithm
|
failed with a transient error (it changes the default backoff time algorithm
|
||||||
between retries). This option is only interesting if \fI--retry\fP is also
|
between retries). This option is only interesting if \fI--retry\fP is also
|
||||||
used. Setting this delay to zero will make curl use the default backoff time.
|
used. Setting this delay to zero will make curl use the default backoff time.
|
||||||
(Option added in 7.12.3)
|
(Added in 7.12.3)
|
||||||
|
|
||||||
If this option is used multiple times, the last occurrence decide the amount.
|
If this option is used multiple times, the last occurrence decide the amount.
|
||||||
.IP "--retry-max-time <seconds>"
|
.IP "--retry-max-time <seconds>"
|
||||||
@@ -838,26 +881,36 @@ done as usual (see \fI--retry\fP) as long as the timer hasn't reached this
|
|||||||
given limit. Notice that if the timer hasn't reached the limit, the request
|
given limit. Notice that if the timer hasn't reached the limit, the request
|
||||||
will be made and while performing, it may take longer than this given time
|
will be made and while performing, it may take longer than this given time
|
||||||
period. To limit a single request\'s maximum time, use \fI-m/--max-time\fP.
|
period. To limit a single request\'s maximum time, use \fI-m/--max-time\fP.
|
||||||
Set this option to zero to not timeout retries. (Option added in 7.12.3)
|
Set this option to zero to not timeout retries. (Added in 7.12.3)
|
||||||
|
|
||||||
If this option is used multiple times, the last occurrence decide the amount.
|
If this option is used multiple times, the last occurrence decide the amount.
|
||||||
.IP "-s/--silent"
|
.IP "-s/--silent"
|
||||||
Silent mode. Don't show progress meter or error messages. Makes
|
Silent mode. Don't show progress meter or error messages. Makes
|
||||||
Curl mute.
|
Curl mute.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable mute.
|
If this option is used twice, the second will again disable silent mode.
|
||||||
.IP "-S/--show-error"
|
.IP "-S/--show-error"
|
||||||
When used with -s it makes curl show error message if it fails.
|
When used with -s it makes curl show error message if it fails.
|
||||||
|
|
||||||
If this option is used twice, the second will again disable show error.
|
If this option is used twice, the second will again disable show error.
|
||||||
.IP "--socks <host[:port]>"
|
.IP "--socks4 <host[:port]>"
|
||||||
Use the specified SOCKS5 proxy. If the port number is not specified, it is
|
Use the specified SOCKS4 proxy. If the port number is not specified, it is
|
||||||
assumed at port 1080. (Option added in 7.11.1)
|
assumed at port 1080. (Added in 7.15.2)
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
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 "--socks5 <host[:port]>"
|
||||||
|
Use the specified SOCKS5 proxy. If the port number is not specified, it is
|
||||||
|
assumed at port 1080. (Added in 7.11.1)
|
||||||
|
|
||||||
|
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 "--stderr <file>"
|
.IP "--stderr <file>"
|
||||||
Redirect all writes to stderr to the specified file instead. If the file name
|
Redirect all writes to stderr to the specified file instead. If the file name
|
||||||
is a plain '-', it is instead written to stdout. This option has no point when
|
is a plain '-', it is instead written to stdout. This option has no point when
|
||||||
@@ -887,13 +940,10 @@ this is used on a http(s) server, the PUT command will be used.
|
|||||||
|
|
||||||
Use the file name "-" (a single dash) to use stdin instead of a given file.
|
Use the file name "-" (a single dash) to use stdin instead of a given file.
|
||||||
|
|
||||||
Before 7.10.8, when this option was used several times, the last one was used.
|
You can specify one -T for each URL on the command line. Each -T + URL pair
|
||||||
|
specifies what to upload and to where. curl also supports "globbing" of the -T
|
||||||
In curl 7.10.8 and later, you can specify one -T for each URL on the command
|
argument, meaning that you can upload multiple files to a single URL by using
|
||||||
line. Each -T + URL pair specifies what to upload and to where. curl also
|
the same URL globbing style supported in the URL, like this:
|
||||||
supports "globbing" of the -T argument, meaning that you can upload multiple
|
|
||||||
files to a single URL by using the same URL globbing style supported in the
|
|
||||||
URL, like this:
|
|
||||||
|
|
||||||
curl -T "{file1,file2}" http://www.uploadtothissite.com
|
curl -T "{file1,file2}" http://www.uploadtothissite.com
|
||||||
|
|
||||||
@@ -905,8 +955,7 @@ Enables a full trace dump of all incoming and outgoing data, including
|
|||||||
descriptive information, to the given output file. Use "-" as filename to have
|
descriptive information, to the given output file. Use "-" as filename to have
|
||||||
the output sent to stdout.
|
the output sent to stdout.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
If this option is used several times, the last one will be used.
|
||||||
7.9.7)
|
|
||||||
.IP "--trace-ascii <file>"
|
.IP "--trace-ascii <file>"
|
||||||
Enables a full trace dump of all incoming and outgoing data, including
|
Enables a full trace dump of all incoming and outgoing data, including
|
||||||
descriptive information, to the given output file. Use "-" as filename to have
|
descriptive information, to the given output file. Use "-" as filename to have
|
||||||
@@ -916,13 +965,12 @@ This is very similar to \fI--trace\fP, but leaves out the hex part and only
|
|||||||
shows the ASCII part of the dump. It makes smaller output that might be easier
|
shows the ASCII part of the dump. It makes smaller output that might be easier
|
||||||
to read for untrained humans.
|
to read for untrained humans.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
If this option is used several times, the last one will be used.
|
||||||
7.9.7)
|
|
||||||
.IP "--trace-time"
|
.IP "--trace-time"
|
||||||
Prepends a time stamp to each trace or verbose line that curl displays.
|
Prepends a time stamp to each trace or verbose line that curl displays.
|
||||||
|
(Added in 7.14.0)
|
||||||
|
|
||||||
If this option is used several times, each occurrence will toggle it on/off.
|
If this option is used several times, each occurrence will toggle it on/off.
|
||||||
(Added in 7.14.0 )
|
|
||||||
.IP "-u/--user <user:password>"
|
.IP "-u/--user <user:password>"
|
||||||
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.
|
||||||
@@ -1076,13 +1124,17 @@ The average download speed that curl measured for the complete download.
|
|||||||
The average upload speed that curl measured for the complete upload.
|
The average upload speed that curl measured for the complete upload.
|
||||||
.TP
|
.TP
|
||||||
.B content_type
|
.B content_type
|
||||||
The Content-Type of the requested document, if there was any. (Added in 7.9.5)
|
The Content-Type of the requested document, if there was any.
|
||||||
.TP
|
.TP
|
||||||
.B num_connects
|
.B num_connects
|
||||||
Number of new connects made in the recent transfer. (Added in 7.12.3)
|
Number of new connects made in the recent transfer. (Added in 7.12.3)
|
||||||
.TP
|
.TP
|
||||||
.B num_redirects
|
.B num_redirects
|
||||||
Number of redirects that were followed in the request. (Added in 7.12.3)
|
Number of redirects that were followed in the request. (Added in 7.12.3)
|
||||||
|
.TP
|
||||||
|
.B ftp_entry_path
|
||||||
|
The initial path libcurl ended up in when logging on to the remote FTP
|
||||||
|
server. (Added in 7.15.4)
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
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.
|
||||||
@@ -1175,11 +1227,11 @@ Note that not all FTP server allow 3rd party transfers. (Added in 7.13.0)
|
|||||||
.IP "-4/--ipv4"
|
.IP "-4/--ipv4"
|
||||||
If libcurl is capable of resolving an address to multiple IP versions (which
|
If libcurl is capable of resolving an address to multiple IP versions (which
|
||||||
it is if it is ipv6-capable), this option tells libcurl to resolve names to
|
it is if it is ipv6-capable), this option tells libcurl to resolve names to
|
||||||
IPv4 addresses only. (Added in 7.10.8)
|
IPv4 addresses only.
|
||||||
.IP "-6/--ipv6"
|
.IP "-6/--ipv6"
|
||||||
If libcurl is capable of resolving an address to multiple IP versions (which
|
If libcurl is capable of resolving an address to multiple IP versions (which
|
||||||
it is if it is ipv6-capable), this option tells libcurl to resolve names to
|
it is if it is ipv6-capable), this option tells libcurl to resolve names to
|
||||||
IPv6 addresses only. (Added in 7.10.8)
|
IPv6 addresses only.
|
||||||
.IP "-#/--progress-bar"
|
.IP "-#/--progress-bar"
|
||||||
Make curl display progress information as a progress bar instead of the
|
Make curl display progress information as a progress bar instead of the
|
||||||
default statistics.
|
default statistics.
|
||||||
@@ -1197,8 +1249,6 @@ Sets proxy server to use for HTTP.
|
|||||||
Sets proxy server to use for HTTPS.
|
Sets proxy server to use for HTTPS.
|
||||||
.IP "FTP_PROXY [protocol://]<host>[:port]"
|
.IP "FTP_PROXY [protocol://]<host>[:port]"
|
||||||
Sets proxy server to use for FTP.
|
Sets proxy server to use for FTP.
|
||||||
.IP "GOPHER_PROXY [protocol://]<host>[:port]"
|
|
||||||
Sets proxy server to use for GOPHER.
|
|
||||||
.IP "ALL_PROXY [protocol://]<host>[:port]"
|
.IP "ALL_PROXY [protocol://]<host>[:port]"
|
||||||
Sets proxy server to use if no protocol-specific proxy is set.
|
Sets proxy server to use if no protocol-specific proxy is set.
|
||||||
.IP "NO_PROXY <comma-separated list of hosts>"
|
.IP "NO_PROXY <comma-separated list of hosts>"
|
||||||
@@ -1343,6 +1393,32 @@ Unrecognized transfer encoding
|
|||||||
Invalid LDAP URL
|
Invalid LDAP URL
|
||||||
.IP 63
|
.IP 63
|
||||||
Maximum file size exceeded
|
Maximum file size exceeded
|
||||||
|
.IP 64
|
||||||
|
Requested FTP SSL level failed
|
||||||
|
.IP 65
|
||||||
|
Sending the data requires a rewind that failed
|
||||||
|
.IP 66
|
||||||
|
Failed to initialise SSL Engine
|
||||||
|
.IP 67
|
||||||
|
User, password or similar was not accepted and curl failed to login
|
||||||
|
.IP 68
|
||||||
|
File not found on TFTP server
|
||||||
|
.IP 69
|
||||||
|
Permission problem on TFTP server
|
||||||
|
.IP 70
|
||||||
|
Out of disk space on TFTP server
|
||||||
|
.IP 71
|
||||||
|
Illegal TFTP operation
|
||||||
|
.IP 72
|
||||||
|
Unknown TFTP transfer ID
|
||||||
|
.IP 73
|
||||||
|
File already exists (TFTP)
|
||||||
|
.IP 74
|
||||||
|
No such user (TFTP)
|
||||||
|
.IP 75
|
||||||
|
Character conversion failed
|
||||||
|
.IP 76
|
||||||
|
Character conversion functions required
|
||||||
.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.
|
||||||
|
@@ -11,7 +11,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
|||||||
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
||||||
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
|
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
|
||||||
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \
|
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \
|
||||||
cookie_interface.c cacertinmem.c
|
cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "done"
|
@echo "done"
|
||||||
|
@@ -33,6 +33,8 @@ we expect you to actually torture our web site with your tests! Thanks.
|
|||||||
EXAMPLES
|
EXAMPLES
|
||||||
|
|
||||||
anyauthput.c - HTTP PUT using "any" authentication method
|
anyauthput.c - HTTP PUT using "any" authentication method
|
||||||
|
cacertinmem.c - Use a built-in PEM certificate to retrieve a https page
|
||||||
|
cookie_interface.c - shows usage of simple cookie interface
|
||||||
curlgtk.c - download using a GTK progress bar
|
curlgtk.c - download using a GTK progress bar
|
||||||
curlx.c - getting file info from the remote cert data
|
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
|
||||||
@@ -55,6 +57,7 @@ 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 transfering multiple files
|
||||||
|
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 persistant 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
|
||||||
@@ -62,3 +65,4 @@ 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
|
||||||
|
154
docs/examples/ftpuploadresume.c
Normal file
154
docs/examples/ftpuploadresume.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Upload to FTP, resuming failed transfers
|
||||||
|
*
|
||||||
|
* Compile for MinGW like this:
|
||||||
|
* gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
|
||||||
|
* -lcurl -lmsvcr70
|
||||||
|
*
|
||||||
|
* Written by Philip Bock
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* The MinGW headers are missing a few Win32 function definitions,
|
||||||
|
you shouldn't need this if you use VC++ */
|
||||||
|
int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
/* parse headers for Content-Length */
|
||||||
|
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||||
|
int r;
|
||||||
|
long len = 0;
|
||||||
|
|
||||||
|
/* _snscanf() is Win32 specific */
|
||||||
|
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
|
||||||
|
|
||||||
|
if (r) /* Microsoft: we don't read the specs */
|
||||||
|
*((long *) stream) = len;
|
||||||
|
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* discard downloaded data */
|
||||||
|
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read data to upload */
|
||||||
|
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
FILE *f = stream;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (ferror(f))
|
||||||
|
return CURL_READFUNC_ABORT;
|
||||||
|
|
||||||
|
n = fread(ptr, size, nmemb, f) * size;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
|
||||||
|
long timeout, long tries)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
long uploaded_len = 0;
|
||||||
|
CURLcode r = CURLE_GOT_NOTHING;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
f = fopen(localpath, "rb");
|
||||||
|
if (f == NULL) {
|
||||||
|
perror(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, TRUE);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, TRUE);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, TRUE);
|
||||||
|
|
||||||
|
for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
|
||||||
|
/* are we resuming? */
|
||||||
|
if (c) { /* yes */
|
||||||
|
/* determine the length of the file already written */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With NOBODY and NOHEADER, libcurl will issue a SIZE
|
||||||
|
* command, but the only way to retrieve the result is
|
||||||
|
* to parse the returned Content-Length header. Thus,
|
||||||
|
* getcontentlengthfunc(). We need discardfunc() above
|
||||||
|
* because HEADER will dump the headers to stdout
|
||||||
|
* without it.
|
||||||
|
*/
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, TRUE);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADER, TRUE);
|
||||||
|
|
||||||
|
r = curl_easy_perform(curlhandle);
|
||||||
|
if (r != CURLE_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, FALSE);
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_HEADER, FALSE);
|
||||||
|
|
||||||
|
fseek(f, uploaded_len, SEEK_SET);
|
||||||
|
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPAPPEND, TRUE);
|
||||||
|
}
|
||||||
|
else { /* no */
|
||||||
|
curl_easy_setopt(curlhandle, CURLOPT_FTPAPPEND, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = curl_easy_perform(curlhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (r == CURLE_OK)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s\n", curl_easy_strerror(r));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int c, char **argv) {
|
||||||
|
CURL *curlhandle = NULL;
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
curlhandle = curl_easy_init();
|
||||||
|
|
||||||
|
upload(curlhandle, "ftp://user:pass@host/path/file", "C:\\file", 0, 3);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curlhandle);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -24,12 +24,13 @@ int main(int argc, char *argv[])
|
|||||||
CURLM *multi_handle;
|
CURLM *multi_handle;
|
||||||
int still_running;
|
int still_running;
|
||||||
|
|
||||||
struct HttpPost *formpost=NULL;
|
struct curl_httppost *formpost=NULL;
|
||||||
struct HttpPost *lastptr=NULL;
|
struct curl_httppost *lastptr=NULL;
|
||||||
struct curl_slist *headerlist=NULL;
|
struct curl_slist *headerlist=NULL;
|
||||||
char buf[] = "Expect:";
|
char buf[] = "Expect:";
|
||||||
|
|
||||||
/* Fill in the file upload field */
|
/* Fill in the file upload field. This makes libcurl load data from
|
||||||
|
the given file name when curl_easy_perform() is called. */
|
||||||
curl_formadd(&formpost,
|
curl_formadd(&formpost,
|
||||||
&lastptr,
|
&lastptr,
|
||||||
CURLFORM_COPYNAME, "sendfile",
|
CURLFORM_COPYNAME, "sendfile",
|
||||||
@@ -43,7 +44,6 @@ int main(int argc, char *argv[])
|
|||||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||||
CURLFORM_END);
|
CURLFORM_END);
|
||||||
|
|
||||||
|
|
||||||
/* Fill in the submit field too, even if this is rarely needed */
|
/* Fill in the submit field too, even if this is rarely needed */
|
||||||
curl_formadd(&formpost,
|
curl_formadd(&formpost,
|
||||||
&lastptr,
|
&lastptr,
|
||||||
|
@@ -78,7 +78,7 @@ int main(void)
|
|||||||
curl_slist *chunk = NULL;
|
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);
|
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||||
/* use curl_slist_free_all() after the *perform() call to free this
|
/* use curl_slist_free_all() after the *perform() call to free this
|
||||||
list again */
|
list again */
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ int main(void)
|
|||||||
curl_slist *chunk = NULL;
|
curl_slist *chunk = NULL;
|
||||||
|
|
||||||
chunk = curl_slist_append(chunk, "Expect:");
|
chunk = curl_slist_append(chunk, "Expect:");
|
||||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER);
|
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||||
/* use curl_slist_free_all() after the *perform() call to free this
|
/* use curl_slist_free_all() after the *perform() call to free this
|
||||||
list again */
|
list again */
|
||||||
}
|
}
|
||||||
|
95
docs/examples/sampleconv.c
Normal file
95
docs/examples/sampleconv.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
This is a simple example showing how a program on a non-ASCII platform
|
||||||
|
would invoke callbacks to do its own codeset conversions instead of
|
||||||
|
using the built-in iconv functions in libcurl.
|
||||||
|
|
||||||
|
The IBM-1047 EBCDIC codeset is used for this example but the code
|
||||||
|
would be similar for other non-ASCII codesets.
|
||||||
|
|
||||||
|
Three callback functions are created below:
|
||||||
|
my_conv_from_ascii_to_ebcdic,
|
||||||
|
my_conv_from_ebcdic_to_ascii, and
|
||||||
|
my_conv_from_utf8_to_ebcdic
|
||||||
|
|
||||||
|
The "platform_xxx" calls represent platform-specific conversion routines.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_a2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_e2a(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
char *tempptrin, *tempptrout;
|
||||||
|
size_t bytes = length;
|
||||||
|
int rc;
|
||||||
|
tempptrin = tempptrout = buffer;
|
||||||
|
rc = platform_u2e(&tempptrin, &bytes, &tempptrout, &bytes);
|
||||||
|
if (rc == PLATFORM_CONV_OK) {
|
||||||
|
return(CURLE_OK);
|
||||||
|
} else {
|
||||||
|
return(CURLE_CONV_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
|
||||||
|
|
||||||
|
/* use platform-specific functions for codeset conversions */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||||
|
my_conv_from_ascii_to_ebcdic);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION,
|
||||||
|
my_conv_from_ebcdic_to_ascii);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION,
|
||||||
|
my_conv_from_utf8_to_ebcdic);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
|
/* always cleanup */
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
339
docs/examples/synctime.c
Normal file
339
docs/examples/synctime.c
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This example code only builds as-is on Windows.
|
||||||
|
*
|
||||||
|
* Synchronising your computer clock via Internet time server usually relies
|
||||||
|
* on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate
|
||||||
|
* time synchronisation but it does not work very well through a
|
||||||
|
* firewall/proxy. Some adjustment has to be made to the firewall/proxy for
|
||||||
|
* these protocols to work properly.
|
||||||
|
*
|
||||||
|
* There is an indirect method. Since most webserver provide server time in
|
||||||
|
* their HTTP header, therefore you could synchronise your computer clock
|
||||||
|
* using HTTP protocol which has no problem with firewall/proxy.
|
||||||
|
*
|
||||||
|
* For this software to work, you should take note of these items.
|
||||||
|
* 1. Your firewall/proxy must allow your computer to surf internet.
|
||||||
|
* 2. Webserver system time must in sync with the NTP time server,
|
||||||
|
* or at least provide an accurate time keeping.
|
||||||
|
* 3. Webserver HTTP header does not provide the milliseconds units,
|
||||||
|
* so there is no way to get very accurate time.
|
||||||
|
* 4. This software could only provide an accuracy of +- a few seconds,
|
||||||
|
* as Round-Trip delay time is not taken into consideration.
|
||||||
|
* Compensation of network, firewall/proxy delay cannot be simply divide
|
||||||
|
* the Round-Trip delay time by half.
|
||||||
|
* 5. Win32 SetSystemTime() API will set your computer clock according to
|
||||||
|
* GMT/UTC time. Therefore your computer timezone must be properly set.
|
||||||
|
* 6. Webserver data should not be cached by the proxy server. Some
|
||||||
|
* webserver provide Cache-Control to prevent caching.
|
||||||
|
*
|
||||||
|
* References:
|
||||||
|
* http://tf.nist.gov/timefreq/service/its.htm
|
||||||
|
* http://tf.nist.gov/timefreq/service/firewall.htm
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* This software will synchronise your computer clock only when you issue
|
||||||
|
* it with --synctime. By default, it only display the webserver's clock.
|
||||||
|
*
|
||||||
|
* Written by: Frank (contributed to libcurl)
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||||
|
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR OF THIS SOFTWARE BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||||
|
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_STRING 256
|
||||||
|
#define MAX_STRING1 MAX_STRING+1
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char http_proxy[MAX_STRING1];
|
||||||
|
char proxy_user[MAX_STRING1];
|
||||||
|
char timeserver[MAX_STRING1];
|
||||||
|
} conf_t;
|
||||||
|
|
||||||
|
char DefaultTimeServer[4][MAX_STRING1] =
|
||||||
|
{
|
||||||
|
"http://nist.time.gov/timezone.cgi?UTC/s/0",
|
||||||
|
"http://www.google.com/",
|
||||||
|
"http://www.worldtimeserver.com/current_time_in_UTC.aspx",
|
||||||
|
"http://www.worldtime.com/cgi-bin/wt.cgi"
|
||||||
|
};
|
||||||
|
|
||||||
|
char *DayStr[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
char *MthStr[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||||
|
|
||||||
|
int ShowAllHeader;
|
||||||
|
int AutoSyncTime;
|
||||||
|
SYSTEMTIME SYSTime;
|
||||||
|
SYSTEMTIME LOCALTime;
|
||||||
|
|
||||||
|
#define HTTP_COMMAND_HEAD 0
|
||||||
|
#define HTTP_COMMAND_GET 1
|
||||||
|
|
||||||
|
|
||||||
|
size_t SyncTime_CURL_WriteOutput(void *ptr, size_t size, size_t nmemb,
|
||||||
|
void *stream)
|
||||||
|
{
|
||||||
|
fwrite(ptr, size, nmemb, stream);
|
||||||
|
return(nmemb*size);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb,
|
||||||
|
void *stream)
|
||||||
|
{
|
||||||
|
int i, RetVal;
|
||||||
|
char TmpStr1[26], TmpStr2[26];
|
||||||
|
|
||||||
|
if (ShowAllHeader == 1)
|
||||||
|
fprintf(stderr, "%s", (char *)(ptr));
|
||||||
|
|
||||||
|
if (strncmp((char *)(ptr), "Date:", 5) == 0) {
|
||||||
|
if (ShowAllHeader == 0)
|
||||||
|
fprintf(stderr, "HTTP Server. %s", (char *)(ptr));
|
||||||
|
|
||||||
|
if (AutoSyncTime == 1) {
|
||||||
|
*TmpStr1 = 0;
|
||||||
|
*TmpStr2 = 0;
|
||||||
|
if (strlen((char *)(ptr)) > 50) /* Can prevent buffer overflow to
|
||||||
|
TmpStr1 & 2? */
|
||||||
|
AutoSyncTime = 0;
|
||||||
|
else {
|
||||||
|
RetVal = sscanf ((char *)(ptr), "Date: %s %d %s %d %d:%d:%d",
|
||||||
|
TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear,
|
||||||
|
&SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond);
|
||||||
|
|
||||||
|
if (RetVal == 7) {
|
||||||
|
|
||||||
|
SYSTime.wMilliseconds = 500; /* adjust to midpoint, 0.5 sec */
|
||||||
|
for (i=0; i<12; i++) {
|
||||||
|
if (strcmp(MthStr[i], TmpStr2) == 0) {
|
||||||
|
SYSTime.wMonth = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AutoSyncTime = 3; /* Computer clock will be adjusted */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AutoSyncTime = 0; /* Error in sscanf() fields conversion */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp((char *)(ptr), "X-Cache: HIT", 12) == 0) {
|
||||||
|
fprintf(stderr, "ERROR: HTTP Server data is cached."
|
||||||
|
" Server Date is no longer valid.\n");
|
||||||
|
AutoSyncTime = 0;
|
||||||
|
}
|
||||||
|
return(nmemb*size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyncTime_CURL_Init(CURL *curl, char *proxy_port,
|
||||||
|
char *proxy_user_password)
|
||||||
|
{
|
||||||
|
if (strlen(proxy_port) > 0)
|
||||||
|
curl_easy_setopt(curl, CURLOPT_PROXY, proxy_port);
|
||||||
|
|
||||||
|
if (strlen(proxy_user_password) > 0)
|
||||||
|
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_user_password);
|
||||||
|
|
||||||
|
/* Trick Webserver by claiming that you are using Microsoft WinXP SP2, IE6 */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERAGENT,
|
||||||
|
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, *SyncTime_CURL_WriteOutput);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, *SyncTime_CURL_WriteHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SyncTime_CURL_Fetch(CURL *curl, char *URL_Str, char *OutFileName,
|
||||||
|
int HttpGetBody)
|
||||||
|
{
|
||||||
|
FILE *outfile;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
outfile = NULL;
|
||||||
|
if (HttpGetBody == HTTP_COMMAND_HEAD)
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
||||||
|
else {
|
||||||
|
outfile = fopen(OutFileName, "wb");
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, URL_Str);
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
if (outfile != NULL)
|
||||||
|
fclose(outfile);
|
||||||
|
return res; /* (CURLE_OK) */
|
||||||
|
}
|
||||||
|
|
||||||
|
void showUsage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SYNCTIME: Synchronising computer clock with time server"
|
||||||
|
" using HTTP protocol.\n");
|
||||||
|
fprintf(stderr, "Usage : SYNCTIME [Option]\n");
|
||||||
|
fprintf(stderr, "Options :\n");
|
||||||
|
fprintf(stderr, " --server=WEBSERVER Use this time server instead"
|
||||||
|
" of default.\n");
|
||||||
|
fprintf(stderr, " --showall Show all HTTP header.\n");
|
||||||
|
fprintf(stderr, " --synctime Synchronising computer clock"
|
||||||
|
" with time server.\n");
|
||||||
|
fprintf(stderr, " --proxy-user=USER[:PASS] Set proxy username and"
|
||||||
|
" password.\n");
|
||||||
|
fprintf(stderr, " --proxy=HOST[:PORT] Use HTTP proxy on given"
|
||||||
|
" port.\n");
|
||||||
|
fprintf(stderr, " --help Print this help.\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int conf_init(conf_t *conf)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*conf->http_proxy = 0;
|
||||||
|
for (i=0; i<MAX_STRING1; i++)
|
||||||
|
conf->proxy_user[i] = 0; /* Clean up password from memory */
|
||||||
|
*conf->timeserver = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
conf_t conf[1];
|
||||||
|
int OptionIndex;
|
||||||
|
struct tm *lt;
|
||||||
|
struct tm *gmt;
|
||||||
|
time_t tt;
|
||||||
|
time_t tt_local;
|
||||||
|
time_t tt_gmt;
|
||||||
|
double tzonediffFloat;
|
||||||
|
int tzonediffWord;
|
||||||
|
char timeBuf[61];
|
||||||
|
char tzoneBuf[16];
|
||||||
|
int RetValue;
|
||||||
|
|
||||||
|
OptionIndex = 0;
|
||||||
|
ShowAllHeader = 0; /* Do not show HTTP Header */
|
||||||
|
AutoSyncTime = 0; /* Do not synchronise computer clock */
|
||||||
|
RetValue = 0; /* Successful Exit */
|
||||||
|
conf_init(conf);
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
while (OptionIndex < argc) {
|
||||||
|
if (strncmp(argv[OptionIndex], "--server=", 9) == 0)
|
||||||
|
snprintf(conf->timeserver, MAX_STRING, "%s", &argv[OptionIndex][9]);
|
||||||
|
|
||||||
|
if (strcmp(argv[OptionIndex], "--showall") == 0)
|
||||||
|
ShowAllHeader = 1;
|
||||||
|
|
||||||
|
if (strcmp(argv[OptionIndex], "--synctime") == 0)
|
||||||
|
AutoSyncTime = 1;
|
||||||
|
|
||||||
|
if (strncmp(argv[OptionIndex], "--proxy-user=", 13) == 0)
|
||||||
|
snprintf(conf->proxy_user, MAX_STRING, "%s", &argv[OptionIndex][13]);
|
||||||
|
|
||||||
|
if (strncmp(argv[OptionIndex], "--proxy=", 8) == 0)
|
||||||
|
snprintf(conf->http_proxy, MAX_STRING, "%s", &argv[OptionIndex][8]);
|
||||||
|
|
||||||
|
if ((strcmp(argv[OptionIndex], "--help") == 0) ||
|
||||||
|
(strcmp(argv[OptionIndex], "/?") == 0)) {
|
||||||
|
showUsage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
OptionIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*conf->timeserver == 0) /* Use default server for time information */
|
||||||
|
snprintf(conf->timeserver, MAX_STRING, "%s", DefaultTimeServer[0]);
|
||||||
|
|
||||||
|
/* Init CURL before usage */
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if (curl) {
|
||||||
|
SyncTime_CURL_Init(curl, conf->http_proxy, conf->proxy_user);
|
||||||
|
|
||||||
|
/* Calculating time diff between GMT and localtime */
|
||||||
|
tt = time(0);
|
||||||
|
lt = localtime(&tt);
|
||||||
|
tt_local = mktime(lt);
|
||||||
|
gmt = gmtime(&tt);
|
||||||
|
tt_gmt = mktime(gmt);
|
||||||
|
tzonediffFloat = difftime(tt_local, tt_gmt);
|
||||||
|
tzonediffWord = (int)(tzonediffFloat/3600.0);
|
||||||
|
|
||||||
|
if ((double)(tzonediffWord * 3600) == tzonediffFloat)
|
||||||
|
snprintf(tzoneBuf, 15, "%+03d'00'", tzonediffWord);
|
||||||
|
else
|
||||||
|
snprintf(tzoneBuf, 15, "%+03d'30'", tzonediffWord);
|
||||||
|
|
||||||
|
/* Get current system time and local time */
|
||||||
|
GetSystemTime(&SYSTime);
|
||||||
|
GetLocalTime(&LOCALTime);
|
||||||
|
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||||
|
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||||
|
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||||
|
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||||
|
LOCALTime.wMilliseconds);
|
||||||
|
fprintf(stderr, "\nBefore HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
|
||||||
|
|
||||||
|
/* HTTP HEAD command to the Webserver */
|
||||||
|
fprintf(stderr, "Fetch: %s\n", conf->timeserver);
|
||||||
|
SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm",
|
||||||
|
HTTP_COMMAND_HEAD);
|
||||||
|
|
||||||
|
GetLocalTime(&LOCALTime);
|
||||||
|
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||||
|
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||||
|
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||||
|
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||||
|
LOCALTime.wMilliseconds);
|
||||||
|
fprintf(stderr, "\nAfter HTTP. Date: %s%s\n", timeBuf, tzoneBuf);
|
||||||
|
|
||||||
|
if (AutoSyncTime == 3) {
|
||||||
|
/* Synchronising computer clock */
|
||||||
|
if (!SetSystemTime(&SYSTime)) { /* Set system time */
|
||||||
|
fprintf(stderr, "ERROR: Unable to set system time.\n");
|
||||||
|
RetValue = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Successfully re-adjusted computer clock */
|
||||||
|
GetLocalTime(&LOCALTime);
|
||||||
|
snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
|
||||||
|
DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
|
||||||
|
MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
|
||||||
|
LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
|
||||||
|
LOCALTime.wMilliseconds);
|
||||||
|
fprintf(stderr, "\nNew System's Date: %s%s\n", timeBuf, tzoneBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup before exit */
|
||||||
|
conf_init(conf);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
return RetValue;
|
||||||
|
}
|
@@ -9,14 +9,16 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
|||||||
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
|
||||||
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
|
||||||
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
|
||||||
curl_strequal.3 curl_mprintf.3 curl_global_init.3 \
|
curl_strequal.3 curl_mprintf.3 curl_global_init.3 curl_global_cleanup.3 \
|
||||||
curl_global_cleanup.3 curl_multi_add_handle.3 curl_multi_cleanup.3 \
|
curl_multi_add_handle.3 curl_multi_cleanup.3 curl_multi_fdset.3 \
|
||||||
curl_multi_fdset.3 curl_multi_info_read.3 curl_multi_init.3 \
|
curl_multi_info_read.3 curl_multi_init.3 curl_multi_perform.3 \
|
||||||
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
|
curl_multi_remove_handle.3 curl_share_cleanup.3 curl_share_init.3 \
|
||||||
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
|
curl_share_setopt.3 libcurl.3 libcurl-easy.3 libcurl-multi.3 \
|
||||||
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
|
libcurl-share.3 libcurl-errors.3 curl_easy_strerror.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
|
libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
|
||||||
|
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||||
|
curl_multi_timeout.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 \
|
||||||
@@ -25,30 +27,31 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
|||||||
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
curl_slist_free_all.html curl_version.html curl_version_info.html \
|
||||||
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
|
||||||
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
|
||||||
curl_multi_add_handle.html curl_multi_cleanup.html \
|
curl_multi_add_handle.html curl_multi_cleanup.html curl_multi_fdset.html \
|
||||||
curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
|
curl_multi_info_read.html curl_multi_init.html curl_multi_perform.html \
|
||||||
curl_multi_perform.html curl_multi_remove_handle.html \
|
curl_multi_remove_handle.html curl_share_cleanup.html \
|
||||||
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
|
curl_share_init.html curl_share_setopt.html libcurl.html \
|
||||||
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
libcurl-multi.html libcurl-easy.html libcurl-share.html \
|
||||||
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
|
||||||
curl_share_strerror.html curl_global_init_mem.html \
|
curl_share_strerror.html curl_global_init_mem.html libcurl-tutorial.html \
|
||||||
libcurl-tutorial.html curl_easy_reset.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
|
||||||
|
|
||||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf curl_easy_init.pdf \
|
||||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
curl_easy_perform.pdf curl_easy_setopt.pdf curl_easy_duphandle.pdf \
|
||||||
curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
|
curl_formadd.pdf curl_formfree.pdf curl_getdate.pdf curl_getenv.pdf \
|
||||||
curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
|
curl_slist_append.pdf curl_slist_free_all.pdf curl_version.pdf \
|
||||||
curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
|
curl_version_info.pdf curl_escape.pdf curl_unescape.pdf curl_free.pdf \
|
||||||
curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
|
curl_strequal.pdf curl_mprintf.pdf curl_global_init.pdf \
|
||||||
curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
|
curl_global_cleanup.pdf curl_multi_add_handle.pdf curl_multi_cleanup.pdf \
|
||||||
curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
|
curl_multi_fdset.pdf curl_multi_info_read.pdf curl_multi_init.pdf \
|
||||||
curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
|
curl_multi_perform.pdf curl_multi_remove_handle.pdf \
|
||||||
curl_multi_remove_handle.pdf curl_share_cleanup.pdf \
|
curl_share_cleanup.pdf curl_share_init.pdf curl_share_setopt.pdf \
|
||||||
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
|
libcurl.pdf libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
||||||
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
|
|
||||||
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
|
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.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_reset.pdf curl_easy_escape.pdf curl_easy_unescape.pdf \
|
||||||
|
curl_multi_setopt.pdf curl_multi_socket.pdf curl_multi_timeout.pdf
|
||||||
|
|
||||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
|
47
docs/libcurl/curl_easy_escape.3
Normal file
47
docs/libcurl/curl_easy_escape.3
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH curl_easy_escape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_easy_escape - URL encodes the given string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #include <curl/curl.h>
|
||||||
|
.sp
|
||||||
|
.BI "char *curl_easy_escape( CURL *" curl ", char *" url ", int "length " );"
|
||||||
|
.ad
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This function converts the given input string to an URL encoded string and
|
||||||
|
returns that as a new allocated string. All input characters that are not a-z,
|
||||||
|
A-Z or 0-9 are converted to their "URL escaped" version (%NN where NN is a
|
||||||
|
two-digit hexadecimal number).
|
||||||
|
|
||||||
|
If the \fBlength\fP argument is set to 0 (zero), curl_easy_escape() uses
|
||||||
|
strlen() on the input \fBurl\fP to find out the size.
|
||||||
|
|
||||||
|
You must \fIcurl_free(3)\fP the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in 7.15.4 and replaces the old curl_escape() function.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_easy_unescape "(3), " curl_free "(3), " RFC 2396
|
@@ -1,8 +1,27 @@
|
|||||||
.\" You can view this file with:
|
.\" **************************************************************************
|
||||||
.\" nroff -man [file]
|
.\" * _ _ ____ _
|
||||||
.\" $Id$
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_getinfo 3 "6 Oct 2005" "libcurl 7.12.3" "libcurl Manual"
|
.TH curl_easy_getinfo 3 "21 Mar 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_getinfo - extract information from a curl handle
|
curl_easy_getinfo - extract information from a curl handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -44,10 +63,8 @@ information before the transfer is made, by using the CURLOPT_FILETIME option
|
|||||||
to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
|
to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
|
||||||
in 7.5)
|
in 7.5)
|
||||||
.IP CURLINFO_TOTAL_TIME
|
.IP CURLINFO_TOTAL_TIME
|
||||||
Pass a pointer to a double to receive the total transaction time in seconds
|
Pass a pointer to a double to receive the total time in seconds for the
|
||||||
for the previous transfer. This time does not include the connect time, so if
|
previous transfer, including name resolving, TCP connect etc.
|
||||||
you want the complete operation time, you should add the
|
|
||||||
CURLINFO_CONNECT_TIME.
|
|
||||||
.IP CURLINFO_NAMELOOKUP_TIME
|
.IP CURLINFO_NAMELOOKUP_TIME
|
||||||
Pass a pointer to a double to receive the time, in seconds, it took from the
|
Pass a pointer to a double to receive the time, in seconds, it took from the
|
||||||
start until the name resolving was completed.
|
start until the name resolving was completed.
|
||||||
@@ -141,17 +158,29 @@ cookies cURL knows (expired ones, too). Don't forget to
|
|||||||
cookies (cookies for the handle have not been enabled or simply none have been
|
cookies (cookies for the handle have not been enabled or simply none have been
|
||||||
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
||||||
7.14.1)
|
7.14.1)
|
||||||
|
.IP CURLINFO_LASTSOCKET
|
||||||
|
Pass a pointer to a long to receive the last socket used by this curl
|
||||||
|
session. If the socket is no longer valid, -1 is returned. When you finish
|
||||||
|
working with the socket, you must call curl_easy_cleanup() as usual and let
|
||||||
|
libcurl close the socket and cleanup other resources associated with the
|
||||||
|
handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY\fP.
|
||||||
|
(Added in 7.15.2)
|
||||||
|
.IP CURLINFO_FTP_ENTRY_PATH
|
||||||
|
Pass a pointer to a 'char *' to receive a pointer to a string holding the path
|
||||||
|
of the entry path. That is the initial path libcurl ended up in when logging
|
||||||
|
on to the remote FTP server. This stores a NULL as pointer if something is
|
||||||
|
wrong. (Added in 7.15.4)
|
||||||
.SH TIMES
|
.SH TIMES
|
||||||
.NF
|
.NF
|
||||||
An overview of the six time values available from curl_easy_getinfo()
|
An overview of the six time values available from curl_easy_getinfo()
|
||||||
|
|
||||||
curk_easy_perform()
|
curl_easy_perform()
|
||||||
|
|
|
|
||||||
|--NT
|
|--NT
|
||||||
|--|--CT
|
|--|--CT
|
||||||
|--|--|--PT
|
|--|--|--PT
|
||||||
|--|--|--|--ST
|
|--|--|--|--ST
|
||||||
|--|--|--TT
|
|--|--|--|--|--TT
|
||||||
|--|--|--|--|--RT
|
|--|--|--|--|--RT
|
||||||
.FI
|
.FI
|
||||||
.IP NT
|
.IP NT
|
||||||
@@ -168,9 +197,7 @@ and negotiations that are specific to the particular protocol(s) involved.
|
|||||||
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
|
||||||
first byte is just about to be transferred.
|
first byte is just about to be transferred.
|
||||||
.IP TT
|
.IP TT
|
||||||
\fICURLINFO_TOTAL_TIME\fP. Time of the previous transfer. This time does not
|
\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
|
||||||
include the connect time (CT), so if you want the complete operation time, you
|
|
||||||
should add that.
|
|
||||||
.IP RT
|
.IP RT
|
||||||
\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
|
\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
|
||||||
include name lookup, connect, pretransfer and transfer before final
|
include name lookup, connect, pretransfer and transfer before final
|
||||||
|
@@ -14,6 +14,17 @@ handle that you must use as input to other easy-functions. curl_easy_init
|
|||||||
initializes curl and this call \fBMUST\fP have a corresponding call to
|
initializes curl and this call \fBMUST\fP have a corresponding call to
|
||||||
\fIcurl_easy_cleanup(3)\fP when the operation is complete.
|
\fIcurl_easy_cleanup(3)\fP when the operation is complete.
|
||||||
|
|
||||||
|
If you did not already call \fIcurl_global_init(3)\fP,
|
||||||
|
\fIcurl_easy_init(3)\fP does it automatically.
|
||||||
|
This may be lethal in multi-threaded cases, since \fIcurl_global_init(3)\fP is
|
||||||
|
not thread-safe, and it may result in resource problems because there is
|
||||||
|
no corresponding cleanup.
|
||||||
|
|
||||||
|
You are strongly advised to not allow this automatic behaviour, by
|
||||||
|
calling \fIcurl_global_init(3)\fP yourself properly.
|
||||||
|
See the description in \fBlibcurl\fP(3) of global environment
|
||||||
|
requirements for details of how to use this function.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
If this function returns NULL, something went wrong and you cannot use the
|
If this function returns NULL, something went wrong and you cannot use the
|
||||||
other curl functions.
|
other curl functions.
|
||||||
|
@@ -15,8 +15,8 @@ it was just created with \fIcurl_easy_init(3)\fP.
|
|||||||
|
|
||||||
It does not change the following information kept in the handle: live
|
It does not change the following information kept in the handle: live
|
||||||
connections, the Session ID cache, the DNS cache, the cookies and shares.
|
connections, the Session ID cache, the DNS cache, the cookies and shares.
|
||||||
|
.SH AVAILABILITY
|
||||||
This function was added in libcurl 7.12.1.
|
This function was added in libcurl 7.12.1
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Nothing
|
Nothing
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2006, 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,9 +21,9 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "27 Oct 2005" "libcurl 7.14.2" "libcurl Manual"
|
.TH curl_easy_setopt 3 "19 Apr 2006" "libcurl 7.15.4" "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
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
@@ -169,11 +169,16 @@ added in 7.12.3)
|
|||||||
.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
|
||||||
its internal equivalent with a frequent interval during data transfer.
|
its internal equivalent with a frequent interval during data transfer (roughly
|
||||||
Unknown/unused argument values will be set to zero (like if you only download
|
once per second). Unknown/unused argument values pass to the callback will be
|
||||||
data, the upload size will remain 0). Returning a non-zero value from this
|
set to zero (like if you only download data, the upload size will remain
|
||||||
callback will cause libcurl to abort the transfer and return
|
0). Returning a non-zero value from this callback will cause libcurl to abort
|
||||||
\fICURLE_ABORTED_BY_CALLBACK\fP.
|
the transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
|
||||||
|
|
||||||
|
If you transfer data with the multi interface, this function will not be
|
||||||
|
called during periods of idleness unless you call the appropriate libcurl
|
||||||
|
function that performs transfers. Usage of the \fBCURLOPT_PROGRESSFUNCTION\fP
|
||||||
|
callback is not recommended when using the multi interface.
|
||||||
|
|
||||||
\fICURLOPT_NOPROGRESS\fP must be set to FALSE to make this function actually
|
\fICURLOPT_NOPROGRESS\fP must be set to FALSE to make this function actually
|
||||||
get called.
|
get called.
|
||||||
@@ -258,6 +263,51 @@ and trust file settings.
|
|||||||
Data pointer to pass to the ssl context callback set by the option
|
Data pointer to pass to the ssl context callback set by the option
|
||||||
\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third
|
\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third
|
||||||
parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
|
parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
|
||||||
|
.IP CURLOPT_CONV_TO_NETWORK_FUNCTION
|
||||||
|
.IP CURLOPT_CONV_FROM_NETWORK_FUNCTION
|
||||||
|
.IP CURLOPT_CONV_FROM_UTF8_FUNCTION
|
||||||
|
Function pointers that should match the following prototype: CURLcode
|
||||||
|
function(char *ptr, size_t length);
|
||||||
|
|
||||||
|
These three options apply to non-ASCII platforms only. They are available
|
||||||
|
only if \fBCURL_DOES_CONVERSIONS\fP was defined when libcurl was built. When
|
||||||
|
this is the case, \fIcurl_version_info(3)\fP will return the CURL_VERSION_CONV
|
||||||
|
feature bit set.
|
||||||
|
|
||||||
|
The data to be converted is in a buffer pointed to by the ptr parameter. The
|
||||||
|
amount of data to convert is indicated by the length parameter. The converted
|
||||||
|
data overlays the input data in the buffer pointed to by the ptr parameter.
|
||||||
|
CURLE_OK should be returned upon successful conversion. A CURLcode return
|
||||||
|
value defined by curl.h, such as CURLE_CONV_FAILED, should be returned if an
|
||||||
|
error was encountered.
|
||||||
|
|
||||||
|
\fBCURLOPT_CONV_TO_NETWORK_FUNCTION\fP and
|
||||||
|
\fBCURLOPT_CONV_FROM_NETWORK_FUNCTION\fP convert between the host encoding and
|
||||||
|
the network encoding. They are used when commands or ASCII data are
|
||||||
|
sent/received over the network.
|
||||||
|
|
||||||
|
\fBCURLOPT_CONV_FROM_UTF8_FUNCTION\fP is called to convert from UTF8 into the
|
||||||
|
host encoding. It is required only for SSL processing.
|
||||||
|
|
||||||
|
If you set a callback pointer to NULL, or don't set it at all, the built-in
|
||||||
|
libcurl iconv functions will be used. If HAVE_ICONV was not defined when
|
||||||
|
libcurl was built, and no callback has been established, conversion will
|
||||||
|
return the CURLE_CONV_REQD error code.
|
||||||
|
|
||||||
|
If HAVE_ICONV is defined, CURL_ICONV_CODESET_OF_HOST must also be defined.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
|
||||||
|
|
||||||
|
The iconv code in libcurl will default the network and UTF8 codeset names as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
|
||||||
|
|
||||||
|
\&#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
|
||||||
|
|
||||||
|
You will need to override these definitions if they are different on your
|
||||||
|
system.
|
||||||
.SH ERROR OPTIONS
|
.SH ERROR OPTIONS
|
||||||
.IP CURLOPT_ERRORBUFFER
|
.IP CURLOPT_ERRORBUFFER
|
||||||
Pass a char * to a buffer that the libcurl may store human readable error
|
Pass a char * to a buffer that the libcurl may store human readable error
|
||||||
@@ -275,7 +325,7 @@ Pass a FILE * as parameter. Tell libcurl to use this stream instead of stderr
|
|||||||
when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
|
when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
|
||||||
.IP CURLOPT_FAILONERROR
|
.IP CURLOPT_FAILONERROR
|
||||||
A non-zero parameter tells the library to fail silently if the HTTP code
|
A non-zero parameter tells the library to fail silently if the HTTP code
|
||||||
returned is equal to or larger than 300. The default action would be to return
|
returned is equal to or larger than 400. The default action would be to return
|
||||||
the page normally, ignoring that code.
|
the page normally, ignoring that code.
|
||||||
.SH NETWORK OPTIONS
|
.SH NETWORK OPTIONS
|
||||||
.IP CURLOPT_URL
|
.IP CURLOPT_URL
|
||||||
@@ -290,7 +340,10 @@ given protocol of the set URL is not supported, libcurl will return on error
|
|||||||
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
|
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
|
||||||
on which protocols that are supported.
|
on which protocols that are supported.
|
||||||
|
|
||||||
\fICURLOPT_URL\fP is the only option that must be set before
|
The string given to CURLOPT_URL must be url-encoded and following the RFC 2396
|
||||||
|
(http://curl.haxx.se/rfc/rfc2396.txt).
|
||||||
|
|
||||||
|
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
|
||||||
\fIcurl_easy_perform(3)\fP is called.
|
\fIcurl_easy_perform(3)\fP is called.
|
||||||
.IP CURLOPT_PROXY
|
.IP CURLOPT_PROXY
|
||||||
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
|
||||||
@@ -319,8 +372,8 @@ 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 and \fICURLPROXY_SOCKS5\fP, with the HTTP one
|
this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_SOCKS4\fP (added in 7.15.2)
|
||||||
being default. (Added in 7.10)
|
\fICURLPROXY_SOCKS5\fP. 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
|
||||||
@@ -330,6 +383,19 @@ don't want this tunneling option.
|
|||||||
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
|
||||||
name.
|
name.
|
||||||
|
.IP CURLOPT_LOCALPORT
|
||||||
|
Pass a long. This sets the local port number of the socket used for
|
||||||
|
connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and
|
||||||
|
you are recommended to use \fICURLOPT_LOCALPORTRANGE\fP as well when this is
|
||||||
|
set. Note that port numbers are only valid 1 - 65535. (Added in 7.15.2)
|
||||||
|
.IP CURLOPT_LOCALPORTRANGE
|
||||||
|
Pass a long. This is the number of attempts libcurl should do to find a
|
||||||
|
working local port number. It starts with the given \fICURLOPT_LOCALPORT\fP
|
||||||
|
and adds one to the number for each retry. Setting this value to 1 or below
|
||||||
|
will make libcurl do only one try for exact port number. Note that port
|
||||||
|
numbers by nature is a scarce resource that will be busy at times so setting
|
||||||
|
this value to something too low might cause unnecessary connection setup
|
||||||
|
failures. (Added in 7.15.2)
|
||||||
.IP CURLOPT_DNS_CACHE_TIMEOUT
|
.IP CURLOPT_DNS_CACHE_TIMEOUT
|
||||||
Pass a long, this sets the timeout in seconds. Name resolves will be kept in
|
Pass a long, this sets the timeout in seconds. Name resolves will be kept in
|
||||||
memory for this number of seconds. Set to zero (0) to completely disable
|
memory for this number of seconds. Set to zero (0) to completely disable
|
||||||
@@ -615,15 +681,17 @@ list. If you add a header that is otherwise generated and used by libcurl
|
|||||||
internally, your added one will be used instead. If you add a header with no
|
internally, your added one will be used instead. If you add a header with no
|
||||||
contents as in 'Accept:' (no data on the right side of the colon), the
|
contents as in 'Accept:' (no data on the right side of the colon), the
|
||||||
internally used header will get disabled. Thus, using this option you can add
|
internally used header will get disabled. Thus, using this option you can add
|
||||||
new headers, replace internal headers and remove internal headers. The
|
new headers, replace internal headers and remove internal headers. To add a
|
||||||
headers included in the linked list must not be CRLF-terminated, because
|
header with no contents, make the contents be two quotes: \&"". The headers
|
||||||
curl adds CRLF after each header item. Failure to comply with this will
|
included in the linked list must not be CRLF-terminated, because curl adds
|
||||||
result in strange bugs because the server will most likely ignore part
|
CRLF after each header item. Failure to comply with this will result in
|
||||||
of the headers you specified.
|
strange bugs because the server will most likely ignore part of the headers
|
||||||
|
you specified.
|
||||||
|
|
||||||
The first line in a request (usually containing a GET or POST) is not a header
|
The first line in a request (containing the method, usually a GET or POST) is
|
||||||
and cannot be replaced using this option. Only the lines following the
|
not a header and cannot be replaced using this option. Only the lines
|
||||||
request-line are headers.
|
following the request-line are headers. Adding this method line in this list
|
||||||
|
of headers will only cause your request to send an invalid header.
|
||||||
|
|
||||||
Pass a NULL to this to reset back to no custom headers.
|
Pass a NULL to this to reset back to no custom headers.
|
||||||
|
|
||||||
@@ -694,6 +762,8 @@ Pass a char * to a cookie string. Cookie can be either in Netscape / Mozilla
|
|||||||
format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL
|
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
|
||||||
|
by cURL. (Added in 7.15.4)
|
||||||
.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
|
||||||
@@ -838,6 +908,23 @@ Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host.
|
|||||||
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
|
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
|
||||||
server asks for "account data" after user name and password has been provided,
|
server asks for "account data" after user name and password has been provided,
|
||||||
this data is sent off using the ACCT command. (Added in 7.13.0)
|
this data is sent off using the ACCT command. (Added in 7.13.0)
|
||||||
|
.IP CURLOPT_FTP_FILEMETHOD
|
||||||
|
Pass a long that should have one of the following values. This option controls
|
||||||
|
what method libcurl should use to reach a file on a FTP(S) server. The
|
||||||
|
argument should be one of the following alternatives:
|
||||||
|
.RS
|
||||||
|
.IP CURLFTPMETHOD_MULTICWD
|
||||||
|
libcurl does a single CWD operation for each path part in the given URL. For
|
||||||
|
deep hierarchies this means very many commands. This is how RFC1738 says it
|
||||||
|
should be done. This is the default but the slowest behavior.
|
||||||
|
.IP CURLFTPMETHOD_NOCWD
|
||||||
|
libcurl does no CWD at all. libcurl will do SIZE, RETR, STOR etc and give a
|
||||||
|
full path to the server for all these commands. This is the fastest behavior.
|
||||||
|
.IP CURLFTPMETHOD_SINGLECWD
|
||||||
|
libcurl does one CWD with the full target directory and then operates on the
|
||||||
|
file \&"normally" (like in the multicwd case). This is somewhat more standards
|
||||||
|
compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||||
|
.RE
|
||||||
.SH PROTOCOL OPTIONS
|
.SH PROTOCOL OPTIONS
|
||||||
.IP CURLOPT_TRANSFERTEXT
|
.IP CURLOPT_TRANSFERTEXT
|
||||||
A non-zero parameter tells the library to use ASCII mode for ftp transfers,
|
A non-zero parameter tells the library to use ASCII mode for ftp transfers,
|
||||||
@@ -1024,6 +1111,14 @@ Resolve to ipv4 addresses.
|
|||||||
.IP CURL_IPRESOLVE_V6
|
.IP CURL_IPRESOLVE_V6
|
||||||
Resolve to ipv6 addresses.
|
Resolve to ipv6 addresses.
|
||||||
.RE
|
.RE
|
||||||
|
.SH CURLOPT_CONNECT_ONLY
|
||||||
|
Pass a long. A non-zero parameter tells the library to perform any required
|
||||||
|
proxy authentication and connection setup, but no data transfer.
|
||||||
|
|
||||||
|
This option is useful with the \fICURLINFO_LASTSOCKET\fP option to
|
||||||
|
\fIcurl_easy_getinfo(3)\fP. The library can set up the connection and then the
|
||||||
|
application can obtain the most recently used socket for special data
|
||||||
|
transfers. (Added in 7.15.2)
|
||||||
.SH SSL and SECURITY OPTIONS
|
.SH SSL and SECURITY OPTIONS
|
||||||
.IP CURLOPT_SSLCERT
|
.IP CURLOPT_SSLCERT
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||||
@@ -1114,6 +1209,9 @@ certificates to verify the peer with. This makes sense only when used in
|
|||||||
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
||||||
even indicate an accessible file.
|
even indicate an accessible file.
|
||||||
|
|
||||||
|
Note that option is by default set to the system path where libcurl's cacert
|
||||||
|
bundle is assumed to be stored, as established at build time.
|
||||||
.IP CURLOPT_CAPATH
|
.IP CURLOPT_CAPATH
|
||||||
Pass a char * to a zero terminated string naming a directory holding
|
Pass a char * to a zero terminated string naming a directory holding
|
||||||
multiple CA certificates to verify the peer with. The certificate
|
multiple CA certificates to verify the peer with. The certificate
|
||||||
|
@@ -12,7 +12,7 @@ curl_easy_strerror - return string describing error code
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The curl_easy_strerror() function returns a string describing the CURLcode
|
The curl_easy_strerror() function returns a string describing the CURLcode
|
||||||
error code passed in the argument \fIerrornum\fP.
|
error code passed in the argument \fIerrornum\fP.
|
||||||
|
.SH AVAILABILITY
|
||||||
This function was added in libcurl 7.12.0
|
This function was added in libcurl 7.12.0
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string.
|
A pointer to a zero terminated string.
|
||||||
|
52
docs/libcurl/curl_easy_unescape.3
Normal file
52
docs/libcurl/curl_easy_unescape.3
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH curl_easy_unescape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_easy_unescape - URL decodes the given string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B #include <curl/curl.h>
|
||||||
|
.sp
|
||||||
|
.BI "char *curl_easy_unescape( CURL *" curl ", char *" url ", int "inlength
|
||||||
|
.BI ", int *" outlength " );"
|
||||||
|
.ad
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This function converts the given URL encoded input string to a "plain string"
|
||||||
|
and returns that in an allocated memory area. All input characters that are
|
||||||
|
URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to
|
||||||
|
their binary versions.
|
||||||
|
|
||||||
|
If the \fBlength\fP argument is set to 0 (zero), curl_easy_unescape() will use
|
||||||
|
strlen() on the input \fIurl\fP string to find out the size.
|
||||||
|
|
||||||
|
If \fBoutlength\fP is non-NULL, the function will write the length of the
|
||||||
|
returned string in the integer it points to. This allows an escaped string
|
||||||
|
containing %00 to still get used properly after unescaping.
|
||||||
|
|
||||||
|
You must \fIcurl_free(3)\fP the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in 7.15.4 and replaces the old curl_unescape() function.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.I curl_easy_escape(3), curl_free(3), RFC 2396
|
@@ -11,6 +11,8 @@ curl_escape - URL encodes the given string
|
|||||||
.BI "char *curl_escape( char *" url ", int "length " );"
|
.BI "char *curl_escape( char *" url ", int "length " );"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
Obsolete function. Use \fIcurl_easy_escape(3)\fP instead!
|
||||||
|
|
||||||
This function will convert the given input string to an URL encoded string and
|
This function will convert the given input string to an URL encoded string and
|
||||||
return that as a new allocated string. All input characters that are not a-z,
|
return that as a new allocated string. All input characters that are not a-z,
|
||||||
A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a
|
A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a
|
||||||
@@ -20,6 +22,9 @@ If the 'length' argument is set to 0, curl_escape() will use strlen() on the
|
|||||||
input 'url' string to find out the size.
|
input 'url' string to find out the size.
|
||||||
|
|
||||||
You must curl_free() the returned string when you're done with it.
|
You must curl_free() the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Since 7.15.4, \fIcurl_easy_escape(3)\fP should be used. This function will
|
||||||
|
be removed in a future release.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string or NULL if it failed.
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -18,10 +18,9 @@ will instead be made "available" by source code access only, and then as
|
|||||||
curlx_getenv().
|
curlx_getenv().
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
If successful, curl_getenv() returns a pointer to the value of the specified
|
If successful, curl_getenv() returns a pointer to the value of the specified
|
||||||
environment. The memory it refers to is malloc()ed why the application must
|
environment. The memory it refers to is malloc()ed so the application must
|
||||||
free() this when the data has completed to serve its purpose. When
|
free() this when the data is no longer needed. When \fIcurl_getenv(3)\fP fails
|
||||||
.I curl_getenv(3)
|
to find the specified name, it returns a null pointer.
|
||||||
fails to find the specified name, it returns a null pointer.
|
|
||||||
.SH NOTE
|
.SH NOTE
|
||||||
Under unix operating systems, there isn't any point in returning an allocated
|
Under unix operating systems, there isn't any point in returning an allocated
|
||||||
memory, although other systems won't work properly if this isn't done. The
|
memory, although other systems won't work properly if this isn't done. The
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man [file]
|
.\" nroff -man [file]
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_global_cleanup 3 "28 May 2001" "libcurl 7.8" "libcurl Manual"
|
.TH curl_global_cleanup 3 "17 Feb 2006" "libcurl 7.8" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_global_cleanup - global libcurl cleanup
|
curl_global_cleanup - global libcurl cleanup
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -11,13 +11,22 @@ curl_global_cleanup - global libcurl cleanup
|
|||||||
.BI "void curl_global_cleanup(void);"
|
.BI "void curl_global_cleanup(void);"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
curl_global_cleanup must be called once (no matter how many threads or libcurl
|
This function releases resources acquired by \fBcurl_global_init(3)\fP.
|
||||||
sessions that'll be used) by every application that uses libcurl, after all
|
|
||||||
uses of libcurl is complete.
|
|
||||||
|
|
||||||
This is the opposite of \fIcurl_global_init(3)\fP.
|
You should call \fIcurl_global_cleanup(3)\fP once for each call you make to
|
||||||
|
\fIcurl_global_init(3)\fP, after you are done using libcurl.
|
||||||
|
|
||||||
|
\fBThis function is not thread safe.\fP You must not call it when any other
|
||||||
|
thread in the program (i.e. a thread sharing the same memory) is running.
|
||||||
|
This doesn't just mean no other thread that is using libcurl. Because
|
||||||
|
\fBcurl_global_cleanup(3)\fP calls functions of other libraries that are
|
||||||
|
similarly thread unsafe, it could conflict with any other thread that uses
|
||||||
|
these other libraries.
|
||||||
|
|
||||||
|
See the description in \fBlibcurl(3)\fP of global environment requirements for
|
||||||
|
details of how to use this function.
|
||||||
|
|
||||||
Not calling this function may result in memory leaks.
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_global_init "(3), "
|
.BR curl_global_init "(3), "
|
||||||
|
.BR libcurl "(3), "
|
||||||
|
|
||||||
|
@@ -11,19 +11,30 @@ curl_global_init - Global libcurl initialisation
|
|||||||
.BI "CURLcode curl_global_init(long " flags ");"
|
.BI "CURLcode curl_global_init(long " flags ");"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function should only be called once (no matter how many threads or
|
This function sets up the program environment that libcurl needs. Think
|
||||||
libcurl sessions that'll be used) by every application that uses libcurl.
|
of it as an extension of the library loader.
|
||||||
|
|
||||||
If this function hasn't been invoked when \fIcurl_easy_init(3)\fP is called,
|
This function must be called at least once within a program (a program is
|
||||||
it will be done automatically by libcurl.
|
all the code that shares a memory space) before the program calls any other
|
||||||
|
function in libcurl. The environment it sets up is constant for the life
|
||||||
|
of the program and is the same for every program, so multiple calls have
|
||||||
|
the same effect as one call.
|
||||||
|
|
||||||
The flags option is a bit pattern that tells libcurl exact what features to
|
The flags option is a bit pattern that tells libcurl exactly what features to
|
||||||
init, as described below. Set the desired bits by ORing the values together.
|
init, as described below. Set the desired bits by ORing the values together.
|
||||||
|
In normal operation, you must specify CURL_GLOBAL_ALL. Don't use any other
|
||||||
|
value unless you are familiar with and mean to control internal operations
|
||||||
|
of libcurl.
|
||||||
|
|
||||||
You must however \fBalways\fP use the \fIcurl_global_cleanup(3)\fP function,
|
\fBThis function is not thread safe.\fP You must not call it when any
|
||||||
as that cannot be called automatically for you by libcurl.
|
other thread in the program (i.e. a thread sharing the same memory) is
|
||||||
|
running. This doesn't just mean no other thread that is using
|
||||||
|
libcurl. Because \fIcurl_global_init()\fP calls functions of other
|
||||||
|
libraries that are similarly thread unsafe, it could conflict with any
|
||||||
|
other thread that uses these other libraries.
|
||||||
|
|
||||||
Calling this function more than once will cause unpredictable results.
|
See the description in \fBlibcurl\fP(3) of global environment
|
||||||
|
requirements for details of how to use this function.
|
||||||
|
|
||||||
.SH FLAGS
|
.SH FLAGS
|
||||||
.TP 5
|
.TP 5
|
||||||
@@ -44,3 +55,5 @@ other curl functions.
|
|||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_global_init_mem "(3), "
|
.BR curl_global_init_mem "(3), "
|
||||||
.BR curl_global_cleanup "(3), "
|
.BR curl_global_cleanup "(3), "
|
||||||
|
.BR curl_easy_init "(3) "
|
||||||
|
.BR libcurl "(3) "
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_multi_fdset 3 "25 Apr 2005" "libcurl 7.9.5" "libcurl Manual"
|
.TH curl_multi_fdset 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_multi_fdset - extracts file descriptor information from a multi handle
|
curl_multi_fdset - extracts file descriptor information from a multi handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -30,8 +30,12 @@ rather small (single-digit number of seconds) timeout and call
|
|||||||
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
|
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
|
||||||
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
|
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
|
||||||
you'd think and want.
|
you'd think and want.
|
||||||
|
|
||||||
|
Starting with libcurl 7.16.0, you should use \fBcurl_multi_timeout\fP to
|
||||||
|
figure out how long to wait for action.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
CURLMcode type, general libcurl multi interface error code. See
|
CURLMcode type, general libcurl multi interface error code. See
|
||||||
\fIlibcurl-errors(3)\fP
|
\fIlibcurl-errors(3)\fP
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)"
|
.BR curl_multi_cleanup "(3)," curl_multi_init "(3), "
|
||||||
|
.BR curl_multi_timeout "(3) "
|
||||||
|
@@ -36,9 +36,9 @@ NOTE that this only returns errors etc regarding the whole multi stack. There
|
|||||||
might still have occurred problems on individual transfers even when this
|
might still have occurred problems on individual transfers even when this
|
||||||
function returns OK.
|
function returns OK.
|
||||||
.SH "TYPICAL USAGE"
|
.SH "TYPICAL USAGE"
|
||||||
Most application will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
||||||
file descriptors, then it'll wait for action on them using select() and as
|
file descriptors, then it'll wait for action on them using \fBselect(3)\fP and
|
||||||
soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
|
as soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
|
||||||
called.
|
called.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||||
|
42
docs/libcurl/curl_multi_setopt.3
Normal file
42
docs/libcurl/curl_multi_setopt.3
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.TH curl_multi_setopt 3 "8 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_multi_setopt \- set options for a curl multi handle
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By
|
||||||
|
using the appropriate options to \fIcurl_multi_setopt\fP, you can change
|
||||||
|
libcurl's behaviour when using that multi handle. All options are set with
|
||||||
|
the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be
|
||||||
|
a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a
|
||||||
|
\fBcurl_off_t\fP type, depending on what the specific option expects. Read
|
||||||
|
this manual carefully as bad input values may cause libcurl to behave badly!
|
||||||
|
You can only set one option in each function call.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.IP CURLMOPT_SOCKETFUNCTION
|
||||||
|
Pass a pointer to a function matching the curl_socket_callback prototype. The
|
||||||
|
\fIcurl_multi_socket(3)\fP functions inform the application about updates in
|
||||||
|
the socket (file descriptor) status by doing none, one or multiple calls to
|
||||||
|
the curl_socket_callback given in the \fBparam\fP argument. They update the
|
||||||
|
status with changes since the previous time a \fIcurl_multi_socket(3)\fP
|
||||||
|
function was called. If the given callback pointer is NULL, no callback will
|
||||||
|
be called. Set the callback's fourth argument with \fICURLMOPT_SOCKETDATA\fP.
|
||||||
|
See \fIcurl_multi_socket(3)\fP for more callback details.
|
||||||
|
.IP CURLMOPT_SOCKETDATA
|
||||||
|
Pass a pointer to whatever you want passed to the curl_socket_callback's forth
|
||||||
|
argument, the userp pointer. This is not used by libcurl but only passed-thru
|
||||||
|
as-is. Set the callback pointer with \fICURLMOPT_SOCKETFUNCTION\fP.
|
||||||
|
.SH RETURNS
|
||||||
|
The standard CURLMcode for multi interface error codes. Note that it returns a
|
||||||
|
CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl
|
||||||
|
doesn't know of.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
This function was added in libcurl 7.16.0
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||||
|
.BR curl_multi_socket "(3), " curl_multi_info_read "(3)"
|
96
docs/libcurl/curl_multi_socket.3
Normal file
96
docs/libcurl/curl_multi_socket.3
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.TH curl_multi_socket 3 "21 Dec 2005" "libcurl 7.16.0" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_multi_socket \- reads/writes available data
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd);
|
||||||
|
|
||||||
|
CURLMcode curl_multi_socket_all(CURLM *multi_handle);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Alternative versions of \fIcurl_multi_perform()\fP that allows the application
|
||||||
|
to pass in one of the file descriptors/sockets that have been detected to have
|
||||||
|
\&"action" on them and let libcurl perform. This allows libcurl to not have to
|
||||||
|
scan through all possible file descriptors to check for action. When the
|
||||||
|
application has detected action on a socket handled by libcurl, it should call
|
||||||
|
\fIcurl_multi_perform()\fP with the \fBsockfd\fP argument set to the socket
|
||||||
|
with the action.
|
||||||
|
|
||||||
|
These functions inform the application about updates in the socket (file
|
||||||
|
descriptor) status by doing none, one or multiple calls to the
|
||||||
|
curl_socket_callback given with the CURLMOPT_SOCKETFUNCTION option to
|
||||||
|
\fIcurl_multi_setopt(3)\fP. They update the status with changes since the
|
||||||
|
previous time this function was called.
|
||||||
|
|
||||||
|
If you want to force libcurl to (re-)check all its internal sockets and
|
||||||
|
transfers instead of just a single one, you call
|
||||||
|
\fBcurl_multi_socket_all(3)\fP instead.
|
||||||
|
|
||||||
|
An application should call \fBcurl_multi_timeout(3)\fP to figure out how long
|
||||||
|
it should wait for socket actions \- at most \- before doing the timeout
|
||||||
|
action: call the \fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP
|
||||||
|
argument set to CURL_SOCKET_TIMEOUT.
|
||||||
|
|
||||||
|
The socket \fBcallback\fP function uses a prototype like this
|
||||||
|
.nf
|
||||||
|
|
||||||
|
int curl_socket_callback(CURL *easy, /* easy handle */
|
||||||
|
curl_socket_t s, /* socket */
|
||||||
|
int action, /* see values below */
|
||||||
|
void *userp); /* "private" pointer */
|
||||||
|
|
||||||
|
.fi
|
||||||
|
The callback MUST return 0.
|
||||||
|
|
||||||
|
The \fIaction\fP (third) argument to the callback has one of five values:
|
||||||
|
.RS
|
||||||
|
.IP "CURL_POLL_NONE (0)"
|
||||||
|
register, not interested in readiness (yet)
|
||||||
|
.IP "CURL_POLL_IN (1)"
|
||||||
|
register, interested in read readiness
|
||||||
|
.IP "CURL_POLL_OUT (2)"
|
||||||
|
register, interested in write readiness
|
||||||
|
.IP "CURL_POLL_INOUT (3)"
|
||||||
|
register, interested in both read and write readiness
|
||||||
|
.IP "CURL_POLL_REMOVE (4)"
|
||||||
|
deregister
|
||||||
|
.RE
|
||||||
|
.SH "RETURN VALUE"
|
||||||
|
CURLMcode type, general libcurl multi interface error code.
|
||||||
|
|
||||||
|
If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you
|
||||||
|
should call \fIcurl_multi_perform\fP again, before you wait for more actions
|
||||||
|
on libcurl's sockets. You don't have to do it immediately, but the return code
|
||||||
|
means that libcurl may have more data available to return or that there may be
|
||||||
|
more data to send off before it is "satisfied".
|
||||||
|
|
||||||
|
NOTE that this only returns errors etc regarding the whole multi stack. There
|
||||||
|
might still have occurred problems on individual transfers even when this
|
||||||
|
function returns OK.
|
||||||
|
.SH "TYPICAL USAGE"
|
||||||
|
1. Create a multi handle
|
||||||
|
|
||||||
|
2. Set the socket callback with CURLMOPT_SOCKETFUNCTION
|
||||||
|
|
||||||
|
3. Add easy handles
|
||||||
|
|
||||||
|
4. Call curl_multi_socket_all() first once
|
||||||
|
|
||||||
|
5. Setup a "collection" of sockets to supervise when your socket
|
||||||
|
callback is called.
|
||||||
|
|
||||||
|
6. Use curl_multi_timeout() to figure out how long to wait for action
|
||||||
|
|
||||||
|
7. Wait for action on any of libcurl's sockets
|
||||||
|
|
||||||
|
8, When action happens, call curl_multi_socket() for the socket(s) that got
|
||||||
|
action.
|
||||||
|
|
||||||
|
9. Go back to step 6.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
This function was added in libcurl 7.16.0
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||||
|
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3)"
|
1
docs/libcurl/curl_multi_socket_all.3
Normal file
1
docs/libcurl/curl_multi_socket_all.3
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.so man3/curl_multi_socket.3
|
@@ -12,7 +12,7 @@ curl_multi_strerror - return string describing error code
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The curl_multi_strerror() function returns a string describing the CURLMcode
|
The curl_multi_strerror() function returns a string describing the CURLMcode
|
||||||
error code passed in the argument \fIerrornum\fP.
|
error code passed in the argument \fIerrornum\fP.
|
||||||
|
.SH AVAILABILITY
|
||||||
This function was added in libcurl 7.12.0
|
This function was added in libcurl 7.12.0
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string.
|
A pointer to a zero terminated string.
|
||||||
|
38
docs/libcurl/curl_multi_timeout.3
Normal file
38
docs/libcurl/curl_multi_timeout.3
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.TH curl_multi_timeout 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
|
||||||
|
.SH NAME
|
||||||
|
curl_multi_timeout \- how long to wait for action before proceeding
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *timeout);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
|
||||||
|
An application using the libcurl multi interface should call
|
||||||
|
\fBcurl_multi_timeout(3)\fP to figure out how long it should wait for socket
|
||||||
|
actions \- at most \- before proceeding.
|
||||||
|
|
||||||
|
Proceeding means either doing the socket-style timeout action: call the
|
||||||
|
\fBcurl_multi_socket(3)\fP function with the \fBsockfd\fP argument set to
|
||||||
|
CURL_SOCKET_TIMEOUT and the \fBeasy\fP argument set to CURL_EASY_TIMEOUT, or
|
||||||
|
simply calling \fBcurl_multi_perform(3)\fP if you're using the simpler and
|
||||||
|
older multi interface approach.
|
||||||
|
|
||||||
|
The timeout value returned in the long \fBtimeout\fP points to, is in number
|
||||||
|
of milliseconds at this very moment. If 0, it means you should proceed
|
||||||
|
immediately without waiting for anything. If it returns -1, there's no timeout
|
||||||
|
at all set.
|
||||||
|
.SH "RETURN VALUE"
|
||||||
|
The standard CURLMcode for multi interface error codes.
|
||||||
|
.SH "TYPICAL USAGE"
|
||||||
|
Call \fBcurl_multi_timeout(3)\fP, then wait for action on the sockets. You
|
||||||
|
figure out which sockets to wait for by calling \fBcurl_multi_fdset(3)\fP or
|
||||||
|
by a previous call to \fBcurl_multi_socket(3)\fP.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
This function was added in libcurl 7.16.0
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||||
|
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
|
||||||
|
.BR curl_multi_socket "(3) "
|
||||||
|
|
@@ -12,7 +12,7 @@ curl_share_strerror - return string describing error code
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The curl_share_strerror() function returns a string describing the CURLSHcode
|
The curl_share_strerror() function returns a string describing the CURLSHcode
|
||||||
error code passed in the argument \fIerrornum\fP.
|
error code passed in the argument \fIerrornum\fP.
|
||||||
|
.SH AVAILABILITY
|
||||||
This function was added in libcurl 7.12.0
|
This function was added in libcurl 7.12.0
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string.
|
A pointer to a zero terminated string.
|
||||||
|
@@ -11,6 +11,8 @@ curl_unescape - URL decodes the given string
|
|||||||
.BI "char *curl_unescape( char *" url ", int "length " );"
|
.BI "char *curl_unescape( char *" url ", int "length " );"
|
||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
Obsolete function. Use \fIcurl_easy_unescape(3)\fP instead!
|
||||||
|
|
||||||
This function will convert the given URL encoded input string to a "plain
|
This function will convert the given URL encoded input string to a "plain
|
||||||
string" and return that as a new allocated string. All input characters that
|
string" and return that as a new allocated string. All input characters that
|
||||||
are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
|
are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
|
||||||
@@ -20,7 +22,10 @@ If the 'length' argument is set to 0, curl_unescape() will use strlen() on the
|
|||||||
input 'url' string to find out the size.
|
input 'url' string to find out the size.
|
||||||
|
|
||||||
You must curl_free() the returned string when you're done with it.
|
You must curl_free() the returned string when you're done with it.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Since 7.15.4, \fIcurl_easy_unescape(3)\fP should be used. This function will
|
||||||
|
be removed in a future release.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to a zero terminated string or NULL if it failed.
|
A pointer to a zero terminated string or NULL if it failed.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.I curl_escape(3), curl_free(3), RFC 2396
|
.I curl_easy_escape(3), curl_easy_unescape(3), curl_free(3), RFC 2396
|
||||||
|
@@ -1,6 +1,27 @@
|
|||||||
.\" $Id$
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" * $Id$
|
||||||
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_version_info 3 "11 Mar 2005" "libcurl 7.13.2" "libcurl Manual"
|
.TH curl_version_info 3 "19 Apr 2006" "libcurl 7.15.4" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_version_info - returns run-time libcurl version info
|
curl_version_info - returns run-time libcurl version info
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -98,6 +119,9 @@ libcurl was built with support for SSPI. This is only available on Windows and
|
|||||||
makes libcurl use Windows-provided functions for NTLM authentication. It also
|
makes libcurl use Windows-provided functions for NTLM authentication. It also
|
||||||
allows libcurl to use the current user and the current user's password without
|
allows libcurl to use the current user and the current user's password without
|
||||||
the app having to pass them on. (Added in 7.13.2)
|
the app having to pass them on. (Added in 7.13.2)
|
||||||
|
.IP CURL_VERSION_CONV
|
||||||
|
libcurl was built with support for character conversions, as provided by the
|
||||||
|
CUURLOPT_CONV_* callbacks. (Added in 7.15.4)
|
||||||
.RE
|
.RE
|
||||||
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
|
||||||
has no SSL support, this is NULL.
|
has no SSL support, this is NULL.
|
||||||
|
@@ -30,7 +30,7 @@ or problem.
|
|||||||
.IP "CURLE_URL_MALFORMAT (3)"
|
.IP "CURLE_URL_MALFORMAT (3)"
|
||||||
The URL was not properly formatted.
|
The URL was not properly formatted.
|
||||||
.IP "CURLE_URL_MALFORMAT_USER (4)"
|
.IP "CURLE_URL_MALFORMAT_USER (4)"
|
||||||
URL user malformatted. The user-part of the URL syntax was not correct.
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_COULDNT_RESOLVE_PROXY (5)"
|
.IP "CURLE_COULDNT_RESOLVE_PROXY (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 "CURLE_COULDNT_RESOLVE_HOST (6)"
|
.IP "CURLE_COULDNT_RESOLVE_HOST (6)"
|
||||||
@@ -38,16 +38,14 @@ Couldn't resolve host. The given remote host was not resolved.
|
|||||||
.IP "CURLE_COULDNT_CONNECT (7)"
|
.IP "CURLE_COULDNT_CONNECT (7)"
|
||||||
Failed to connect() to host or proxy.
|
Failed to connect() to host or proxy.
|
||||||
.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
|
.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
|
||||||
After connecting to an FTP server, libcurl expects to get a certain reply back.
|
After connecting to an FTP server, libcurl expects to get a certain reply
|
||||||
This error code implies that it god a strange or bad reply. The given remote
|
back. This error code implies that it got a strange or bad reply. The given
|
||||||
server is probably not an OK FTP server.
|
remote server is probably not an OK FTP server.
|
||||||
.IP "CURLE_FTP_ACCESS_DENIED (9)"
|
.IP "CURLE_FTP_ACCESS_DENIED (9)"
|
||||||
We were denied access when trying to login to an FTP server or when trying to
|
We were denied access when trying to login to an FTP server or when trying to
|
||||||
change working directory to the one given in the URL.
|
change working directory to the one given in the URL.
|
||||||
.IP "CURLE_FTP_USER_PASSWORD_INCORRECT (10)"
|
.IP "CURLE_FTP_USER_PASSWORD_INCORRECT (10)"
|
||||||
The FTP server rejected access to the server after the password was sent to
|
This is never returned by current libcurl.
|
||||||
it. It might be because the username and/or the password were incorrect or
|
|
||||||
just that the server is not allowing you access for the moment etc.
|
|
||||||
.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
|
.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
|
||||||
After having sent the FTP password to the server, libcurl expects a proper
|
After having sent the FTP password to the server, libcurl expects a proper
|
||||||
reply. This error code indicates that an unexpected code was returned.
|
reply. This error code indicates that an unexpected code was returned.
|
||||||
@@ -87,7 +85,7 @@ returns an error code that is >= 400.
|
|||||||
An error occurred when writing received data to a local file, or an error was
|
An error occurred when writing received data to a local file, or an error was
|
||||||
returned to libcurl from a write callback.
|
returned to libcurl from a write callback.
|
||||||
.IP "CURLE_MALFORMAT_USER (24)"
|
.IP "CURLE_MALFORMAT_USER (24)"
|
||||||
Malformat user. User name badly specified. *Not currently used*
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_FTP_COULDNT_STOR_FILE (25)"
|
.IP "CURLE_FTP_COULDNT_STOR_FILE (25)"
|
||||||
FTP couldn't STOR file. The server denied the STOR operation. The error buffer
|
FTP couldn't STOR file. The server denied the STOR operation. The error buffer
|
||||||
usually contains the server's explanation to this.
|
usually contains the server's explanation to this.
|
||||||
@@ -138,15 +136,13 @@ Aborted by callback. A callback returned "abort" to libcurl.
|
|||||||
.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)"
|
.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)"
|
||||||
Internal error. A function was called with a bad parameter.
|
Internal error. A function was called with a bad parameter.
|
||||||
.IP "CURLE_BAD_CALLING_ORDER (44)"
|
.IP "CURLE_BAD_CALLING_ORDER (44)"
|
||||||
Internal error. A function was called in a bad order.
|
This is never returned by current libcurl.
|
||||||
.IP "CURLE_HTTP_PORT_FAILED (45)"
|
.IP "CURLE_HTTP_PORT_FAILED (45)"
|
||||||
Interface error. A specified outgoing interface could not be used. Set which
|
Interface error. A specified outgoing interface could not be used. Set which
|
||||||
interface to use for outgoing connections' source IP address with
|
interface to use for outgoing connections' source IP address with
|
||||||
CURLOPT_INTERFACE.
|
CURLOPT_INTERFACE.
|
||||||
.IP "CURLE_BAD_PASSWORD_ENTERED (46)"
|
.IP "CURLE_BAD_PASSWORD_ENTERED (46)"
|
||||||
Bad password entered. An error was signaled when the password was
|
This is never returned by current libcurl.
|
||||||
entered. This can also be the result of a "bad password" returned from a
|
|
||||||
specified password callback.
|
|
||||||
.IP "CURLE_TOO_MANY_REDIRECTS (47)"
|
.IP "CURLE_TOO_MANY_REDIRECTS (47)"
|
||||||
Too many redirects. When following redirects, libcurl hit the maximum amount.
|
Too many redirects. When following redirects, libcurl hit the maximum amount.
|
||||||
Set your limit with CURLOPT_MAXREDIRS.
|
Set your limit with CURLOPT_MAXREDIRS.
|
||||||
@@ -194,6 +190,24 @@ rewinding operation failed
|
|||||||
Initiating the SSL Engine failed
|
Initiating the SSL Engine failed
|
||||||
.IP "CURLE_LOGIN_DENIED (67)"
|
.IP "CURLE_LOGIN_DENIED (67)"
|
||||||
The remote server denied curl to login (Added in 7.13.1)
|
The remote server denied curl to login (Added in 7.13.1)
|
||||||
|
.IP "CURLE_TFTP_NOTFOUND (68)"
|
||||||
|
File not found on TFTP server
|
||||||
|
.IP "CURLE_TFTP_PERM (69"
|
||||||
|
Permission problem on TFTP server
|
||||||
|
.IP "CURLE_TFTP_DISKFULL (70)"
|
||||||
|
Out of disk space on TFTP server
|
||||||
|
.IP "CURLE_TFTP_ILLEGAL (71)"
|
||||||
|
Illegal TFTP operation
|
||||||
|
.IP "CURLE_TFTP_UNKNOWNID (72)"
|
||||||
|
Unknown TFTP transfer ID
|
||||||
|
.IP "CURLE_TFTP_EXISTS (73)"
|
||||||
|
TFTP File already exists
|
||||||
|
.IP "CURLE_TFTP_NOSUCHUSER (74)"
|
||||||
|
No such TFTP user
|
||||||
|
.IP "CURLE_CONV_FAILED (75)"
|
||||||
|
Character conversion failed
|
||||||
|
.IP "CURLE_CONV_REQD (76)"
|
||||||
|
Caller must register conversion callbacks
|
||||||
.SH "CURLMcode"
|
.SH "CURLMcode"
|
||||||
This is the generic return code used by functions in the libcurl multi
|
This is the generic return code used by functions in the libcurl multi
|
||||||
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
interface. Also consider \fIcurl_multi_strerror(3)\fP.
|
||||||
@@ -210,6 +224,9 @@ An easy handle was not good/valid.
|
|||||||
You are doomed.
|
You are doomed.
|
||||||
.IP "CURLM_INTERNAL_ERROR (4)"
|
.IP "CURLM_INTERNAL_ERROR (4)"
|
||||||
This can only be returned if libcurl bugs. Please report it to us!
|
This can only be returned if libcurl bugs. Please report it to us!
|
||||||
|
.IP "CURLM_BAD_SOCKET (5)"
|
||||||
|
The passed-in socket is not a valid one that libcurl already knows about.
|
||||||
|
(Added in 7.16.0)
|
||||||
.SH "CURLSHcode"
|
.SH "CURLSHcode"
|
||||||
The "share" interface will return a CURLSHcode to indicate when an error has
|
The "share" interface will return a CURLSHcode to indicate when an error has
|
||||||
occurred. Also consider \fIcurl_share_strerror(3)\fP.
|
occurred. Also consider \fIcurl_share_strerror(3)\fP.
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2006, 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
|
||||||
@@ -133,10 +133,11 @@ Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP
|
|||||||
should be avoided. They should only be called once each.
|
should be avoided. They should only be called once each.
|
||||||
|
|
||||||
.SH "Features libcurl Provides"
|
.SH "Features libcurl Provides"
|
||||||
It is considered best-practice to determine libcurl features run-time rather
|
It is considered best-practice to determine libcurl features at run-time
|
||||||
than build-time (if possible of course). By calling curl_version_info() and
|
rather than at build-time (if possible of course). By calling
|
||||||
checking tout he details of the returned struct, your program can figure out
|
\fIcurl_version_info(3)\fP and checking out the details of the returned
|
||||||
exactly what the currently running libcurl supports.
|
struct, your program can figure out exactly what the currently running libcurl
|
||||||
|
supports.
|
||||||
|
|
||||||
.SH "Handle the Easy libcurl"
|
.SH "Handle the Easy libcurl"
|
||||||
libcurl first introduced the so called easy interface. All operations in the
|
libcurl first introduced the so called easy interface. All operations in the
|
||||||
@@ -267,11 +268,13 @@ GnuTLS
|
|||||||
|
|
||||||
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
|
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
|
||||||
|
|
||||||
When using multiple threads you should set the CURLOPT_NOSIGNAL option to
|
When using multiple threads you should set the CURLOPT_NOSIGNAL option to TRUE
|
||||||
TRUE for all handles. Everything will work fine except that timeouts are not
|
for all handles. Everything will or might work fine except that timeouts are
|
||||||
honored during the DNS lookup - which you can work around by building libcurl
|
not honored during the DNS lookup - which you can work around by building
|
||||||
with c-ares support. c-ares is a library that provides asynchronous name
|
libcurl with c-ares support. c-ares is a library that provides asynchronous
|
||||||
resolves. Unfortunately, c-ares does not yet support IPv6.
|
name resolves. Unfortunately, c-ares does not yet fully support IPv6. On some
|
||||||
|
platforms, libcurl simply will not function properly multi-threaded unless
|
||||||
|
this option is set.
|
||||||
|
|
||||||
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
|
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
|
||||||
|
|
||||||
@@ -887,12 +890,12 @@ data size is unknown.
|
|||||||
|
|
||||||
There's only one aspect left in the HTTP requests that we haven't yet
|
There's only one aspect left in the HTTP requests that we haven't yet
|
||||||
mentioned how to modify: the version field. All HTTP requests includes the
|
mentioned how to modify: the version field. All HTTP requests includes the
|
||||||
version number to tell the server which version we support. libcurl speak
|
version number to tell the server which version we support. libcurl speak HTTP
|
||||||
HTTP 1.1 by default. Some very old servers don't like getting 1.1-requests
|
1.1 by default. Some very old servers don't like getting 1.1-requests and when
|
||||||
and when dealing with stubborn old things like that, you can tell libcurl
|
dealing with stubborn old things like that, you can tell libcurl to use 1.0
|
||||||
to use 1.0 instead by doing something like this:
|
instead by doing something like this:
|
||||||
|
|
||||||
curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURLHTTP_VERSION_1_0);
|
curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||||
|
|
||||||
.IP "FTP Custom Commands"
|
.IP "FTP Custom Commands"
|
||||||
|
|
||||||
|
@@ -13,10 +13,11 @@ in-depth understanding on how to program with libcurl.
|
|||||||
There are more than a twenty custom bindings available that bring libcurl
|
There are more than a twenty custom bindings available that bring libcurl
|
||||||
access to your favourite language. Look elsewhere for documentation on those.
|
access to your favourite language. Look elsewhere for documentation on those.
|
||||||
|
|
||||||
All applications that use libcurl should call \fIcurl_global_init(3)\fP
|
libcurl has a global constant environment that you must set up and
|
||||||
exactly once before any libcurl function can be used. After all usage of
|
maintain while using libcurl. This essentially means you call
|
||||||
libcurl is complete, it \fBmust\fP call \fIcurl_global_cleanup(3)\fP. In
|
\fIcurl_global_init(3)\fP at the start of your program and
|
||||||
between those two calls, you can use libcurl as described below.
|
\fIcurl_global_cleanup(3)\fP at the end. See GLOBAL CONSTANTS below
|
||||||
|
for details.
|
||||||
|
|
||||||
To transfer files, you always set up an "easy handle" using
|
To transfer files, you always set up an "easy handle" using
|
||||||
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
|
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
|
||||||
@@ -86,6 +87,10 @@ Never ever call curl-functions simultaneously using the same handle from
|
|||||||
several threads. libcurl is thread-safe and can be used in any number of
|
several threads. libcurl is thread-safe and can be used in any number of
|
||||||
threads, but you must use separate curl handles if you want to use libcurl in
|
threads, but you must use separate curl handles if you want to use libcurl in
|
||||||
more than one thread simultaneously.
|
more than one thread simultaneously.
|
||||||
|
|
||||||
|
The global environment functions are not thread-safe. See GLOBAL CONSTANTS
|
||||||
|
below for details.
|
||||||
|
|
||||||
.SH "PERSISTENT CONNECTIONS"
|
.SH "PERSISTENT CONNECTIONS"
|
||||||
Persistent connections means that libcurl can re-use the same connection for
|
Persistent connections means that libcurl can re-use the same connection for
|
||||||
several transfers, if the conditions are right.
|
several transfers, if the conditions are right.
|
||||||
@@ -103,3 +108,96 @@ libcurl will be closed and forgotten.
|
|||||||
|
|
||||||
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used in on
|
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used in on
|
||||||
every repeated \fIcurl_easy_perform(3)\fP call.
|
every repeated \fIcurl_easy_perform(3)\fP call.
|
||||||
|
|
||||||
|
.SH "GLOBAL CONSTANTS"
|
||||||
|
There are a variety of constants that libcurl uses, mainly through its
|
||||||
|
internal use of other libraries, which are too complicated for the
|
||||||
|
library loader to set up. Therefore, a program must call a library
|
||||||
|
function after the program is loaded and running to finish setting up
|
||||||
|
the library code. For example, when libcurl is built for SSL
|
||||||
|
capability via the GNU TLS library, there is an elaborate tree inside
|
||||||
|
that library that describes the SSL protocol.
|
||||||
|
|
||||||
|
\fIcurl_global_init()\fP is the function that you must call. This may
|
||||||
|
allocate resources (e.g. the memory for the GNU TLS tree mentioned
|
||||||
|
above), so the companion function \fIcurl_global_cleanup()\fP releases
|
||||||
|
them.
|
||||||
|
|
||||||
|
The basic rule for constructing a program that uses libcurl is this:
|
||||||
|
Call \fIcurl_global_init()\fP, with a \fICURL_GLOBAL_ALL\fP argument,
|
||||||
|
immediately after the program starts, while it is still only one
|
||||||
|
thread and before it uses libcurl at all. Call
|
||||||
|
\fIcurl_global_cleanup()\fP immediately before the program exits, when
|
||||||
|
the program is again only one thread and after its last use of
|
||||||
|
libcurl.
|
||||||
|
|
||||||
|
You can call both of these multiple times, as long as all calls meet
|
||||||
|
these requirements and the number of calls to each is the same.
|
||||||
|
|
||||||
|
It isn't actually required that the functions be called at the beginning
|
||||||
|
and end of the program -- that's just usually the easiest way to do it.
|
||||||
|
It \fIis\fP required that the functions be called when no other thread
|
||||||
|
in the program is running.
|
||||||
|
|
||||||
|
These global constant functions are \fInot thread safe\fP, so you must
|
||||||
|
not call them when any other thread in the program is running. It
|
||||||
|
isn't good enough that no other thread is using libcurl at the time,
|
||||||
|
because these functions internally call similar functions of other
|
||||||
|
libraries, and those functions are similarly thread-unsafe. You can't
|
||||||
|
generally know what these libraries are, or whether other threads are
|
||||||
|
using them.
|
||||||
|
|
||||||
|
The global constant situation merits special consideration when the
|
||||||
|
code you are writing to use libcurl is not the main program, but rather
|
||||||
|
a modular piece of a program, e.g. another library. As a module,
|
||||||
|
your code doesn't know about other parts of the program -- it doesn't
|
||||||
|
know whether they use libcurl or not. And its code doesn't necessarily
|
||||||
|
run at the start and end of the whole program.
|
||||||
|
|
||||||
|
A module like this must have global constant functions of its own,
|
||||||
|
just like \fIcurl_global_init()\fP and \fIcurl_global_cleanup()\fP.
|
||||||
|
The module thus has control at the beginning and end of the program
|
||||||
|
and has a place to call the libcurl functions. Note that if multiple
|
||||||
|
modules in the program use libcurl, they all will separately call the
|
||||||
|
libcurl functions, and that's OK because only the first
|
||||||
|
\fIcurl_global_init()\fP and the last \fIcurl_global_cleanup()\fP in a
|
||||||
|
program changes anything. (libcurl uses a reference count in static
|
||||||
|
memory).
|
||||||
|
|
||||||
|
In a C++ module, it is common to deal with the global constant
|
||||||
|
situation by defining a special class that represents the global
|
||||||
|
constant environment of the module. A program always has exactly one
|
||||||
|
object of the class, in static storage. That way, the program
|
||||||
|
automatically calls the constructor of the object as the program
|
||||||
|
starts up and the destructor as it terminates. As the author of this
|
||||||
|
libcurl-using module, you can make the constructor call
|
||||||
|
\fIcurl_global_init()\fP and the destructor call
|
||||||
|
\fIcurl_global_cleanup()\fP and satisfy libcurl's requirements without
|
||||||
|
your user having to think about it.
|
||||||
|
|
||||||
|
\fIcurl_global_init()\fP has an argument that tells what particular
|
||||||
|
parts of the global constant environment to set up. In order to
|
||||||
|
successfully use any value except \fICURL_GLOBAL_ALL\fP (which says to
|
||||||
|
set up the whole thing), you must have specific knowledge of internal
|
||||||
|
workings of libcurl and all other parts of the program of which it is
|
||||||
|
part.
|
||||||
|
|
||||||
|
A special part of the global constant environment is the identity of
|
||||||
|
the memory allocator. \fIcurl_global_init()\fP selects the system
|
||||||
|
default memory allocator, but you can use \fIcurl_global_init_mem()\fP
|
||||||
|
to supply one of your own. However, there is no way to use
|
||||||
|
\fIcurl_global_init_mem()\fP in a modular program -- all modules in
|
||||||
|
the program that might use libcurl would have to agree on one
|
||||||
|
allocator.
|
||||||
|
|
||||||
|
There is a failsafe in libcurl that makes it usable in simple
|
||||||
|
situations without you having to worry about the global constant
|
||||||
|
environment at all: \fIcurl_easy_init()\fP sets up the environment
|
||||||
|
itself if it hasn't been done yet. The resources it acquires to do so
|
||||||
|
get released by the operating system automatically when the program
|
||||||
|
exits.
|
||||||
|
|
||||||
|
This failsafe feature exists mainly for backward compatibility because
|
||||||
|
there was a time when the global functions didn't exist. Because it
|
||||||
|
is sufficient only in the simplest of programs, it is not recommended
|
||||||
|
for any program to rely on it.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
||||||
# [ACTION-IF-YES], [ACTION-IF-NO])
|
# [ACTION-IF-YES], [ACTION-IF-NO])
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
# David Shaw <dshaw@jabberwocky.com> Jun-21-2005
|
# David Shaw <dshaw@jabberwocky.com> May-09-2006
|
||||||
#
|
#
|
||||||
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
||||||
# specify whether to default to --with-libcurl or --without-libcurl.
|
# specify whether to default to --with-libcurl or --without-libcurl.
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
# ACTION-IF-NO is a list of shell commands that are run otherwise.
|
# ACTION-IF-NO is a list of shell commands that are run otherwise.
|
||||||
# Note that using --without-libcurl does run ACTION-IF-NO.
|
# Note that using --without-libcurl does run ACTION-IF-NO.
|
||||||
#
|
#
|
||||||
# This macro defines HAVE_LIBCURL if a working libcurl setup is found,
|
# This macro #defines HAVE_LIBCURL if a working libcurl setup is
|
||||||
# and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary values.
|
# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
|
||||||
# Other useful defines are LIBCURL_FEATURE_xxx where xxx are the
|
# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are
|
||||||
# various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
|
# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
|
||||||
# where yyy are the various protocols supported by libcurl. Both xxx
|
# where yyy are the various protocols supported by libcurl. Both xxx
|
||||||
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
|
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
|
||||||
# the macro for the complete list of possible defines. Shell
|
# the macro for the complete list of possible defines. Shell
|
||||||
@@ -32,7 +32,8 @@
|
|||||||
# found is after version 7.7.2, the first version that included the
|
# found is after version 7.7.2, the first version that included the
|
||||||
# curl-config script. Note that it is very important for people
|
# curl-config script. Note that it is very important for people
|
||||||
# packaging binary versions of libcurl to include this script!
|
# packaging binary versions of libcurl to include this script!
|
||||||
# Without curl-config, we can only guess what protocols are available.
|
# Without curl-config, we can only guess what protocols are available,
|
||||||
|
# or use curl_version_info to figure it out at runtime.
|
||||||
|
|
||||||
AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
||||||
[
|
[
|
||||||
@@ -41,16 +42,19 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
|||||||
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
|
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
|
||||||
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
|
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
|
||||||
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
|
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
|
||||||
|
AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
|
||||||
|
AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
|
||||||
|
AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
|
||||||
|
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_GOPHER],[Defined if libcurl supports GOPHER])
|
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
|
||||||
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
|
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
|
||||||
|
AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
|
||||||
|
|
||||||
AC_ARG_WITH(libcurl,
|
AC_ARG_WITH(libcurl,
|
||||||
AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]),
|
AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]),
|
||||||
@@ -65,11 +69,12 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
|||||||
_libcurl_try_link=yes
|
_libcurl_try_link=yes
|
||||||
|
|
||||||
if test -d "$_libcurl_with" ; then
|
if test -d "$_libcurl_with" ; then
|
||||||
CPPFLAGS="${CPPFLAGS} -I$withval/include"
|
LIBCURL_CPPFLAGS="-I$withval/include"
|
||||||
LDFLAGS="${LDFLAGS} -L$withval/lib"
|
_libcurl_ldflags="-L$withval/lib"
|
||||||
fi
|
AC_PATH_PROG([_libcurl_config],["$withval/bin/curl-config"])
|
||||||
|
else
|
||||||
AC_PATH_PROG([_libcurl_config],[curl-config])
|
AC_PATH_PROG([_libcurl_config],[curl-config])
|
||||||
|
fi
|
||||||
|
|
||||||
if test x$_libcurl_config != "x" ; then
|
if test x$_libcurl_config != "x" ; then
|
||||||
AC_CACHE_CHECK([for the version of libcurl],
|
AC_CACHE_CHECK([for the version of libcurl],
|
||||||
@@ -126,15 +131,15 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
|||||||
|
|
||||||
# we didn't find curl-config, so let's see if the user-supplied
|
# we didn't find curl-config, so let's see if the user-supplied
|
||||||
# link line (or failing that, "-lcurl") is enough.
|
# link line (or failing that, "-lcurl") is enough.
|
||||||
LIBCURL=${LIBCURL-"-lcurl"}
|
LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
|
||||||
|
|
||||||
AC_CACHE_CHECK([whether libcurl is usable],
|
AC_CACHE_CHECK([whether libcurl is usable],
|
||||||
[libcurl_cv_lib_curl_usable],
|
[libcurl_cv_lib_curl_usable],
|
||||||
[
|
[
|
||||||
_libcurl_save_cppflags=$CPPFLAGS
|
_libcurl_save_cppflags=$CPPFLAGS
|
||||||
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
|
CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
|
||||||
_libcurl_save_libs=$LIBS
|
_libcurl_save_libs=$LIBS
|
||||||
LIBS="$LIBS $LIBCURL"
|
LIBS="$LIBCURL $LIBS"
|
||||||
|
|
||||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <curl/curl.h>],[
|
AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <curl/curl.h>],[
|
||||||
/* Try and use a few common options to force a failure if we are
|
/* Try and use a few common options to force a failure if we are
|
||||||
@@ -188,7 +193,7 @@ x=CURLOPT_VERBOSE;
|
|||||||
|
|
||||||
# We don't have --protocols, so just assume that all
|
# We don't have --protocols, so just assume that all
|
||||||
# protocols are available
|
# protocols are available
|
||||||
_libcurl_protocols="HTTP FTP GOPHER FILE TELNET LDAP DICT"
|
_libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT"
|
||||||
|
|
||||||
if test x$libcurl_feature_SSL = xyes ; then
|
if test x$libcurl_feature_SSL = xyes ; then
|
||||||
_libcurl_protocols="$_libcurl_protocols HTTPS"
|
_libcurl_protocols="$_libcurl_protocols HTTPS"
|
||||||
@@ -205,6 +210,9 @@ x=CURLOPT_VERBOSE;
|
|||||||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
|
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
|
||||||
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
|
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
|
||||||
done
|
done
|
||||||
|
else
|
||||||
|
unset LIBCURL
|
||||||
|
unset LIBCURL_CPPFLAGS
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -216,6 +224,7 @@ x=CURLOPT_VERBOSE;
|
|||||||
unset _libcurl_protocol
|
unset _libcurl_protocol
|
||||||
unset _libcurl_protocols
|
unset _libcurl_protocols
|
||||||
unset _libcurl_version
|
unset _libcurl_version
|
||||||
|
unset _libcurl_ldflags
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
|
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
|
||||||
|
@@ -1,11 +1,14 @@
|
|||||||
#
|
#
|
||||||
# Build a little app for the Hiper project
|
# Build test apps for the Hiper project
|
||||||
# During dev at least, we use a static libcurl.
|
# During dev at least, we use a static libcurl.
|
||||||
#
|
#
|
||||||
|
|
||||||
LDFLAGS = -lcrypt -lidn -lssl -lcrypto -ldl -lz -lresolv -L../ares/.libs -lcares
|
LDFLAGS = -lcrypt -lidn -lssl -lcrypto -ldl -lz -lresolv -L../ares/.libs \
|
||||||
|
-lcares
|
||||||
LIBCURL = -L../lib/.libs/ -lcurl
|
LIBCURL = -L../lib/.libs/ -lcurl
|
||||||
CFLAGS = -I../include -g -DHAVE_CURL_MULTI_SOCKET
|
CFLAGS = -I../include -g
|
||||||
|
|
||||||
|
all: shiper hiper hipev ulimiter
|
||||||
|
|
||||||
hiper: hiper.o $(LIBCURL)
|
hiper: hiper.o $(LIBCURL)
|
||||||
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
||||||
@@ -13,8 +16,23 @@ hiper: hiper.o $(LIBCURL)
|
|||||||
hiper.o: hiper.c
|
hiper.o: hiper.c
|
||||||
$(CC) $(CFLAGS) -c $<
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
hipev: hipev.o $(LIBCURL)
|
||||||
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS) -levent
|
||||||
|
|
||||||
|
hipev.o: hipev.c
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
shiper: shiper.o $(LIBCURL)
|
||||||
|
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
|
||||||
|
|
||||||
|
shiper.o: shiper.c
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
ulimiter: ulimiter.c
|
||||||
|
$(CC) -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm hiper.o hiper
|
rm -f hiper.o hiper shiper shiper.o *~ ulimiter
|
||||||
|
|
||||||
$(LIBCURL):
|
$(LIBCURL):
|
||||||
(cd ../lib && make)
|
(cd ../lib && make)
|
||||||
|
269
hiper/STATUS
Normal file
269
hiper/STATUS
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
Date: January 5, 2006
|
||||||
|
Author: Daniel Stenberg
|
||||||
|
|
||||||
|
Status of project Hiper - high performance libcurl modifications
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
What is Hiper
|
||||||
|
|
||||||
|
You won't find such a description in this document. See
|
||||||
|
http://curl.haxx.se/libcurl/hiper/ for further details.
|
||||||
|
|
||||||
|
Live Progress Info
|
||||||
|
|
||||||
|
During my work, I've posted occational updates on the curl-library mailing
|
||||||
|
list but more importantly done frequent updates of
|
||||||
|
http://curl.haxx.se/libcurl/hiper/schedule.html
|
||||||
|
|
||||||
|
Schedule
|
||||||
|
|
||||||
|
I took time off my regular job during Decemember 2005 and the first week of
|
||||||
|
January 2006 to work on hiper full-time.
|
||||||
|
|
||||||
|
Step 1 - Measure the Existing Solution
|
||||||
|
|
||||||
|
I started full-time work on project Hiper on December 1st 2005. I began by
|
||||||
|
putting together a test application that used the existing API to allow me
|
||||||
|
to properly and with accuracy measure execution and transfer speeds when
|
||||||
|
doing a large amount of transfers.
|
||||||
|
|
||||||
|
I soon discovered that it was impossible to do any sensible measurements by
|
||||||
|
using live and actual URLs since the transfers were too unrelialble and
|
||||||
|
uncontrolled. I then enhanced the current HTTP server in the curl test suite
|
||||||
|
and made that support a large amount of transfers and some extra magic
|
||||||
|
"commands" that would make the server either just sit "idle" or "stream"
|
||||||
|
(continuously sending data in a never-ending stream). I then wrote up two
|
||||||
|
files using the curl test suite file format and by acessing the properly
|
||||||
|
formatted URLs on my localhost the HTTP server would either run "idle" or
|
||||||
|
run "stream".
|
||||||
|
|
||||||
|
Having this working, I patched libcurl to always only recv() a single byte
|
||||||
|
off the network each time, just to make sure that the time spent on reading
|
||||||
|
data is constant and never very long.
|
||||||
|
|
||||||
|
I adjusted the test application (actually called 'hiper') to create Y idle
|
||||||
|
transfers and Z stream transfers, had it run for N seconds and then quit and
|
||||||
|
produce a summary on stdout. Now I got very solid and repeatable results. I
|
||||||
|
started to run repeated tests and save the results when I ran into the
|
||||||
|
dreaded 1024 socket maximum limit.
|
||||||
|
|
||||||
|
One side of the problem is that the fd_set type only allows 1024 file
|
||||||
|
descriptors (on my Linux), which I had to solve by simply making my own type
|
||||||
|
with room for more connections and do ugly typecasts in the code. The other
|
||||||
|
side of the problem is that user applications have a limit imposed by the
|
||||||
|
system on the maximum amount of file descriptors it can have open and I had
|
||||||
|
to work around that by writing a special tool that runs setuid root that
|
||||||
|
increases the limit, downgrades to a normal user again and then run the
|
||||||
|
command line of your choice. This second approach has to be used for both
|
||||||
|
'hiper' and the test HTTP server. (You need to build the HTTP server with
|
||||||
|
CURL_SWS_FORK_ENABLED defined to have it do forks since it isn't desirable
|
||||||
|
to do so when running the normal curl tests.)
|
||||||
|
|
||||||
|
Now I could run my test program without problems. I decided to run the tests
|
||||||
|
with 1 stream connection and a varying amount of idle ones. I did 1001,
|
||||||
|
2001, 3001, 5001 and 9001 connections and measured how long select() and
|
||||||
|
curl_multi_perform() (including the curl_multi_fdset() call) would take in
|
||||||
|
average, over a period of 20 seconds. I ran each test 5-6 times and I used
|
||||||
|
the average time of all the runs.
|
||||||
|
|
||||||
|
The times in number of microseconds:
|
||||||
|
|
||||||
|
Connections multi_perform select
|
||||||
|
1001 3504 951
|
||||||
|
2001 7606 1988
|
||||||
|
3001 11045 2715
|
||||||
|
5001 16406 4024
|
||||||
|
9001 32147 8030
|
||||||
|
|
||||||
|
Test system
|
||||||
|
CPU: Athlon XP 2800
|
||||||
|
RAM: 1 GB
|
||||||
|
Linux: 2.6
|
||||||
|
glibc: 2.3.5
|
||||||
|
libcurl: 7.15.1
|
||||||
|
|
||||||
|
The only reason I stopped at 9001 connections is that my test machine ran
|
||||||
|
out of avaiable memory by then as I ran the test server on the same machine,
|
||||||
|
and I didn't want to risk the test result accuracy by having it start using
|
||||||
|
the swap during the tests.
|
||||||
|
|
||||||
|
It means that at 9000 connections we spend 40ms for each socket action, even
|
||||||
|
when only one socket ever have action.
|
||||||
|
|
||||||
|
With these 32000 microseconds curl_multi_perform() takes for 9000
|
||||||
|
connections, it loops 18000 laps which makes less than 2 microseconds per
|
||||||
|
lap. (Of course counting time/laps is an oversimplification, but anyway.)
|
||||||
|
Hopefully we should achieve less than 10 microseconds for each call to
|
||||||
|
curl_multi_socket() for an active connection.
|
||||||
|
|
||||||
|
The timing graph displayed on the libevent site (duplicated on the hiper
|
||||||
|
project page) suggests that libevent is pretty much fixed at 50 microseconds
|
||||||
|
(although I don't know what test box was used in their testing, we can
|
||||||
|
compare the select()-times from my tests and see that they are at least
|
||||||
|
resonably close).
|
||||||
|
|
||||||
|
Summing up, the current ~40 ms spent at 9000 connections could then possibly
|
||||||
|
be lowered to something around 60 us!
|
||||||
|
|
||||||
|
Step 2 - Implement curl_multi_socket API
|
||||||
|
|
||||||
|
Most of the design decisions and debates about this new API have already
|
||||||
|
been held on the curl-library mailing list a long time ago so I had a basic
|
||||||
|
idea on what approach to use. The main ideas of the new API are simply:
|
||||||
|
|
||||||
|
1 - The application can use whatever event system it likes as it gets info
|
||||||
|
from libcurl about what file descriptors libcurl waits for what action
|
||||||
|
on. (The previous API returns fd_sets which is very select()-centric).
|
||||||
|
|
||||||
|
2 - When the application discovers action on a single socket, it calls
|
||||||
|
libcurl and informs that there was action on this particular socket and
|
||||||
|
libcurl can then act on that socket/transfer only and not care about
|
||||||
|
any other transfers. (The previous API always had to scan through all
|
||||||
|
the existing transfers.)
|
||||||
|
|
||||||
|
The idea is that curl_multi_socket() calls a given callback with information
|
||||||
|
about what socket to wait for what action on, and the callback only gets
|
||||||
|
called if the status of that socket has changed.
|
||||||
|
|
||||||
|
In the API draft from before, we have a timeout argument on a per socket
|
||||||
|
basis and we also allowed curl_multi_socket() to pass in an 'easy handle'
|
||||||
|
instead of socket to allow libcurl to shortcut a lookup and work on the
|
||||||
|
affected easy handle right away. Both these turned out to be bad ideas.
|
||||||
|
|
||||||
|
The timeout argument was removed from the socket callback since after much
|
||||||
|
thinking I came to the conclusion that we really don't want to handle
|
||||||
|
timeouts on a per socket basis. We need it on a per transfer (easy handle)
|
||||||
|
basis and thus we can't provide it in the callbacks in a nice way. Instead,
|
||||||
|
we have to offer a curl_multi_timeout() that returns the largest amount of
|
||||||
|
time we should wait before we call the "timeout action" of libcurl, to
|
||||||
|
trigger the proper internal timeout action on the affected transfer. To get
|
||||||
|
this to work, I added a struct to each easy handle in which we store an
|
||||||
|
"expire time" (if any). The structs are then "splay sorted" so that we can
|
||||||
|
add and remove times from the linked list and yet somewhat swiftly figure
|
||||||
|
out 1 - how long time there is until the next timer expires and 2 - which
|
||||||
|
timer (handle) should we take care of now. Of course, the upside of all this
|
||||||
|
is that we get a curl_multi_timeout() that should also work with old-style
|
||||||
|
applications that use curl_multi_perform().
|
||||||
|
|
||||||
|
The easy handle argument was removed fom the curl_multi_socket() function
|
||||||
|
because having it there would require the application to do a socket to easy
|
||||||
|
handle conversion on its own. I find it very unlikely that applications
|
||||||
|
would want to do that and since libcurl would need such a lookup on its own
|
||||||
|
anyway since we didn't want to force applications to do that translation
|
||||||
|
code (it would be optional), it seemed like an unnecessary option. I also
|
||||||
|
realized that when we use underlying libraries such as c-ares (for DNS
|
||||||
|
asynch resolving) there might in fact be more than one transfer waiting for
|
||||||
|
action on the same socket and thus it makes the lookup even tricker and even
|
||||||
|
less likely to ever get done by applications. Instead I created an internal
|
||||||
|
"socket to easy handles" hash table that given a socket (file descriptor)
|
||||||
|
returns a list of easy handles that waits for some action on that socket.
|
||||||
|
|
||||||
|
To make libcurl be able to report plain sockets in the socket callback, I
|
||||||
|
had to re-organize the internals of the curl_multi_fdset() etc so that the
|
||||||
|
conversion from sockets to fd_sets for that function is only done in the
|
||||||
|
last step before the data is returned. I also had to extend c-ares to get a
|
||||||
|
function that can return plain sockets, as that library too returned only
|
||||||
|
fd_sets and that is no longer good enough. The changes done to c-ares have
|
||||||
|
been committed and are available in the c-ares CVS repository destined to be
|
||||||
|
included in the upcoming c-ares 1.3.1 release.
|
||||||
|
|
||||||
|
The 'shiper' tool is the test application I wrote that uses the new
|
||||||
|
curl_multi_socket() in its current state. It seems to be working and it uses
|
||||||
|
the API as it is documented and supposed to work. It is still using
|
||||||
|
select(), because I needed that during development (like until I had the
|
||||||
|
socket hash implemented etc) and because I haven't yet learned how to use
|
||||||
|
libevent or similar.
|
||||||
|
|
||||||
|
The hiper/shiper tools are very simple and initiates lots of connections and
|
||||||
|
have them running for the test period and then kills them all.
|
||||||
|
|
||||||
|
Since I wasn't done with the implementation until early January I haven't
|
||||||
|
had time to run very many measurements and checks, but I have done a few
|
||||||
|
runs with up to a few hundred connections (with a single active one). The
|
||||||
|
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
|
||||||
|
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
|
||||||
|
add connections, it certainly matches my in my opinion very ambitious goal.
|
||||||
|
We are now below the 60 microseconds "per socket action" goal. It is
|
||||||
|
destined to be somewhat higher the more connections we have since the hash
|
||||||
|
table gets more populated and the splay tree will grow etc.
|
||||||
|
|
||||||
|
Some tests at 7000 and 9000 connections showed that the socket hash lookup
|
||||||
|
is somewhat of a bottle neck. Its current implementation may be a bit too
|
||||||
|
limiting. It simply has a fixed-size array, and on each entry in the array
|
||||||
|
it has a linked list with entries. So the hash only checks which list to
|
||||||
|
scan through. The code I had used so for used a list with merely 7 slots (as
|
||||||
|
that is what the DNS hash uses) but with 7000 connections that would make an
|
||||||
|
average of 1000 nodes in each list to run through. I upped that to 97 slots
|
||||||
|
(I believe a prime is suitable) and noticed a significant speed increase. I
|
||||||
|
need to reconsider the hash implementation or use a rather large default
|
||||||
|
value like this. At 9000 connections I was still below 10us per call.
|
||||||
|
|
||||||
|
Status Right Now
|
||||||
|
|
||||||
|
The curl_multi_socket() API is implemented according to how it is
|
||||||
|
documented. The man pages for curl_multi_socket and curl_multi_timeout are
|
||||||
|
both committed to CVS and are available online for easy browsing:
|
||||||
|
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_socket.html
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
|
||||||
|
|
||||||
|
The hiper-5.patch I made available early morning January 5th, 2006 should
|
||||||
|
apply fine on a recent CVS checkout (at the time of this writing curl 7.15.1
|
||||||
|
is the latest public curl release but the hiper patch does not apply fine on
|
||||||
|
that).
|
||||||
|
|
||||||
|
What is Left for the curl_multi_socket API
|
||||||
|
|
||||||
|
1 - More measuring with more extreme number of connections
|
||||||
|
|
||||||
|
2 - More testing with actual URLs and complete from start to end transfers.
|
||||||
|
|
||||||
|
I'm quite sure we don't set expire times all over in the code properly, so
|
||||||
|
there is bound to be some timeout bugs left.
|
||||||
|
|
||||||
|
What it really takes is for me to commit the code and to make an official
|
||||||
|
release with it so that we get people "out there" to help out testing it.
|
||||||
|
|
||||||
|
What is Left for project Hiper
|
||||||
|
|
||||||
|
1 - Add HTTP pipelining support
|
||||||
|
|
||||||
|
2 - Add a zero (or at least close to zero) copy interface
|
||||||
|
|
||||||
|
Neither of these points have been planned or detailed exactly how they will
|
||||||
|
be implemented.
|
||||||
|
|
||||||
|
Roadmap Ahead
|
||||||
|
|
||||||
|
I plan and hope to return to full-time hiper work later on this spring or
|
||||||
|
possibly summer to continue where I pause now. Of course some spare time
|
||||||
|
might also be spent until then to get us moving forward.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
April 11, 2006
|
||||||
|
|
||||||
|
While sitting staring on my screen trying to write up a *nice* sample script
|
||||||
|
using libevent, it strikes me that since libevent is pretty much based around
|
||||||
|
its structs that you setup for each event/file descriptor, my application
|
||||||
|
wants to figure out the correct struct that is associted with the file
|
||||||
|
descriptor that libcurl provides in the socket callback.
|
||||||
|
|
||||||
|
This feels like an operation most applications will need when using the
|
||||||
|
multi_socket API, so it feels like I should better try to figure out a decent
|
||||||
|
way to offer this basic functionality already in libcurl - and the fact that
|
||||||
|
we already have the file descriptors in a hash we can probably just as well
|
||||||
|
extend it somewhat and store some custom pointers as well.
|
||||||
|
|
||||||
|
We need to offer the app a way to set a private pointer to be associated with
|
||||||
|
the particular file descriptor, and then be able to provide that pointer on
|
||||||
|
subsequent callback calls.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
April 20, 2006
|
||||||
|
|
||||||
|
I was wrong when I previously claimed we could have more than one easy handle
|
||||||
|
using the same socket. I've cleaned up and simplified code now to adjust to
|
||||||
|
this.
|
||||||
|
|
251
hiper/hiper.c
251
hiper/hiper.c
@@ -7,12 +7,20 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Connect to N sites simultanouesly and download data.
|
* Connect N connections. Z are idle, and X are active. Transfer as fast as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Run for a specific amount of time (10 secs for now). Output detailed timing
|
||||||
|
* information.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* The maximum number of simultanoues connections/transfers we support */
|
||||||
|
#define NCONNECTIONS 50000
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -20,12 +28,10 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/* The number of simultanoues connections/transfers we do */
|
#define MICROSEC 1000000 /* number of microseconds in one second */
|
||||||
#define NCONNECTIONS 2000
|
|
||||||
|
|
||||||
/* The least number of connections we are interested in, so when we go below
|
/* The maximum time (in microseconds) we run the test */
|
||||||
this amount we can just as well stop */
|
#define RUN_FOR_THIS_LONG (20*MICROSEC)
|
||||||
#define NMARGIN 50
|
|
||||||
|
|
||||||
/* Number of loops (seconds) we allow the total download amount and alive
|
/* Number of loops (seconds) we allow the total download amount and alive
|
||||||
connections to remain the same until we bail out. Set this slightly higher
|
connections to remain the same until we bail out. Set this slightly higher
|
||||||
@@ -39,11 +45,21 @@ struct globalinfo {
|
|||||||
struct connection {
|
struct connection {
|
||||||
CURL *e;
|
CURL *e;
|
||||||
int id; /* just a counter for easy browsing */
|
int id; /* just a counter for easy browsing */
|
||||||
char url[80];
|
char *url;
|
||||||
size_t dlcounter;
|
size_t dlcounter;
|
||||||
struct globalinfo *global;
|
struct globalinfo *global;
|
||||||
|
char error[CURL_ERROR_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* on port 8999 we run a modified (fork-) sws that supports pure idle and full
|
||||||
|
stream mode */
|
||||||
|
#define PORT "8999"
|
||||||
|
|
||||||
|
#define HOST "192.168.1.13"
|
||||||
|
|
||||||
|
#define URL_IDLE "http://" HOST ":" PORT "/1000"
|
||||||
|
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
{
|
{
|
||||||
@@ -87,8 +103,6 @@ struct conncount {
|
|||||||
long maxtime;
|
long maxtime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct conncount timecount[NCONNECTIONS+1];
|
|
||||||
|
|
||||||
static struct timeval timerpause;
|
static struct timeval timerpause;
|
||||||
static void timer_pause(void)
|
static void timer_pause(void)
|
||||||
{
|
{
|
||||||
@@ -101,13 +115,6 @@ static void timer_pause(void)
|
|||||||
long lap;
|
long lap;
|
||||||
|
|
||||||
lap = tvdiff(&timerpause, &cont);
|
lap = tvdiff(&timerpause, &cont);
|
||||||
|
|
||||||
timecount[still_running].time_us += lap;
|
|
||||||
timecount[still_running].laps++; /* number of times added */
|
|
||||||
|
|
||||||
if(lap > timecount[still_running].maxtime) {
|
|
||||||
timecount[still_running].maxtime = lap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +131,7 @@ static void timer_continue(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long total; /* amount of us from start to stop */
|
static long total; /* amount of us from start to stop */
|
||||||
static void timer_stop(void)
|
static void timer_total(void)
|
||||||
{
|
{
|
||||||
struct timeval stop;
|
struct timeval stop;
|
||||||
/* Capture the time of the operation stopped moment, now calculate how long
|
/* Capture the time of the operation stopped moment, now calculate how long
|
||||||
@@ -136,7 +143,7 @@ static void timer_stop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct globalinfo info;
|
struct globalinfo info;
|
||||||
struct connection conns[NCONNECTIONS];
|
struct connection *conns;
|
||||||
|
|
||||||
long selects;
|
long selects;
|
||||||
long selectsalive;
|
long selectsalive;
|
||||||
@@ -147,35 +154,36 @@ long performalive;
|
|||||||
long performselect;
|
long performselect;
|
||||||
long topselect;
|
long topselect;
|
||||||
|
|
||||||
|
int num_total;
|
||||||
|
int num_idle;
|
||||||
|
int num_active;
|
||||||
|
|
||||||
static void report(void)
|
static void report(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
long active = total - paused;
|
long active = total - paused;
|
||||||
long numdl = 0;
|
long numdl = 0;
|
||||||
|
|
||||||
for(i=0; i < NCONNECTIONS; i++) {
|
for(i=0; i < num_total; i++) {
|
||||||
if(conns[i].dlcounter)
|
if(conns[i].dlcounter)
|
||||||
numdl++;
|
numdl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Summary from %d simultanoues transfers:\n",
|
printf("Summary from %d simultanoues transfers (%d active)\n",
|
||||||
NCONNECTIONS);
|
num_total, num_active);
|
||||||
|
printf("%d out of %d connections provided data\n", numdl, num_total);
|
||||||
|
|
||||||
printf("Total time %ldus - Paused %ldus = Active %ldus =\n Active/total"
|
printf("Total time: %ldus select(): %ldus curl_multi_perform(): %ldus\n",
|
||||||
" %ldus\n",
|
total, paused, active);
|
||||||
total, paused, active, active/NCONNECTIONS);
|
|
||||||
|
|
||||||
printf(" Active/(connections that delivered data) = %ldus\n",
|
printf("%d calls to curl_multi_perform() average %d alive "
|
||||||
active/numdl);
|
|
||||||
|
|
||||||
printf("%d out of %d connections provided data\n", numdl, NCONNECTIONS);
|
|
||||||
|
|
||||||
printf("%d calls to curl_multi_perform(), average %d alive. "
|
|
||||||
"Average time: %dus\n",
|
"Average time: %dus\n",
|
||||||
perform, performalive/perform, active/perform);
|
perform, performalive/perform, active/perform);
|
||||||
|
|
||||||
printf("%d calls to select(), average %d alive\n",
|
printf("%d calls to select(), average %d alive "
|
||||||
selects, selectsalive/selects);
|
"Average time: %dus\n",
|
||||||
|
selects, selectsalive/selects,
|
||||||
|
paused/selects);
|
||||||
printf(" Average number of readable connections per select() return: %d\n",
|
printf(" Average number of readable connections per select() return: %d\n",
|
||||||
performselect/selects);
|
performselect/selects);
|
||||||
printf(" Max number of readable connections for a single select() "
|
printf(" Max number of readable connections for a single select() "
|
||||||
@@ -184,9 +192,16 @@ static void report(void)
|
|||||||
|
|
||||||
printf("%ld select() timeouts\n", timeouts);
|
printf("%ld select() timeouts\n", timeouts);
|
||||||
|
|
||||||
for(i=1; i< NCONNECTIONS; i++) {
|
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
|
||||||
|
info.dlcounter,
|
||||||
|
info.dlcounter/(total/1000000),
|
||||||
|
total/info.dlcounter);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for(i=1; i< num_total; i++) {
|
||||||
if(timecount[i].laps) {
|
if(timecount[i].laps) {
|
||||||
printf("Time %d connections, average %ld max %ld (%ld laps) average/conn: %ld\n",
|
printf("Time %d connections, average %ld max %ld (%ld laps) "
|
||||||
|
"average/conn: %ld\n",
|
||||||
i,
|
i,
|
||||||
timecount[i].time_us/timecount[i].laps,
|
timecount[i].time_us/timecount[i].laps,
|
||||||
timecount[i].maxtime,
|
timecount[i].maxtime,
|
||||||
@@ -194,8 +209,16 @@ static void report(void)
|
|||||||
(timecount[i].time_us/timecount[i].laps)/i );
|
(timecount[i].time_us/timecount[i].laps)/i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ourfdset {
|
||||||
|
char fdbuffer[NCONNECTIONS/8];
|
||||||
|
};
|
||||||
|
#define FD2_ZERO(x) FD_ZERO((fd_set *)x)
|
||||||
|
|
||||||
|
typedef struct ourfdset fd2_set;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
CURLM *multi_handle;
|
CURLM *multi_handle;
|
||||||
@@ -204,61 +227,68 @@ int main(int argc, char **argv)
|
|||||||
CURLMcode mcode = CURLM_OK;
|
CURLMcode mcode = CURLM_OK;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
FILE *urls;
|
|
||||||
int startindex=0;
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
int prevalive=-1;
|
int prevalive=-1;
|
||||||
int prevsamecounter=0;
|
int prevsamecounter=0;
|
||||||
int prevtotal = -1;
|
int prevtotal = -1;
|
||||||
|
fd2_set fdsizecheck;
|
||||||
|
int selectmaxamount;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(struct globalinfo));
|
memset(&info, 0, sizeof(struct globalinfo));
|
||||||
|
|
||||||
if(argc < 2) {
|
selectmaxamount = sizeof(fdsizecheck) * 8;
|
||||||
printf("Usage: hiper [file] [start index]\n");
|
printf("select() supports max %d connections\n", selectmaxamount);
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("Usage: hiper [num idle] [num active]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
urls = fopen(argv[1], "r");
|
num_idle = atoi(argv[1]);
|
||||||
if(!urls)
|
num_active = atoi(argv[2]);
|
||||||
/* failed to open list of urls */
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if(argc > 2)
|
num_total = num_idle + num_active;
|
||||||
startindex = atoi(argv[2]);
|
|
||||||
|
|
||||||
if(startindex) {
|
if(num_total > selectmaxamount) {
|
||||||
/* Pass this many lines before we start using URLs from the file. On
|
printf("Requested more connections than supported!\n");
|
||||||
repeated invokes, try using different indexes to avoid torturing the
|
return 4;
|
||||||
same servers. */
|
|
||||||
while(startindex--) {
|
|
||||||
if(!fgets(buffer, sizeof(buffer), urls))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conns = calloc(num_total, sizeof(struct connection));
|
||||||
|
if(!conns) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_total >= NCONNECTIONS) {
|
||||||
|
printf("Increase NCONNECTIONS!\n");
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init the multi stack */
|
/* init the multi stack */
|
||||||
multi_handle = curl_multi_init();
|
multi_handle = curl_multi_init();
|
||||||
|
|
||||||
for(i=0; i< NCONNECTIONS; i++) {
|
for(i=0; i< num_total; i++) {
|
||||||
CURL *e;
|
CURL *e;
|
||||||
char *nl;
|
char *nl;
|
||||||
|
|
||||||
memset(&conns[i], 0, sizeof(struct connection));
|
memset(&conns[i], 0, sizeof(struct connection));
|
||||||
|
|
||||||
/* read a line from the file of URLs */
|
if(i < num_idle)
|
||||||
if(!fgets(conns[i].url, sizeof(conns[i].url), urls))
|
conns[i].url = URL_IDLE;
|
||||||
/* failed to read a line */
|
else
|
||||||
break;
|
conns[i].url = URL_ACTIVE;
|
||||||
|
|
||||||
/* strip off trailing newlines */
|
|
||||||
nl = strchr(conns[i].url, '\n');
|
|
||||||
if(nl)
|
|
||||||
*nl=0; /* cut */
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
printf("%d: Add URL %s\n", i, conns[i].url);
|
printf("%d: Add URL %s\n", i, conns[i].url);
|
||||||
|
#endif
|
||||||
e = curl_easy_init();
|
e = curl_easy_init();
|
||||||
|
|
||||||
|
if(!e) {
|
||||||
|
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
conns[i].e = e;
|
conns[i].e = e;
|
||||||
conns[i].id = i;
|
conns[i].id = i;
|
||||||
conns[i].global = &info;
|
conns[i].global = &info;
|
||||||
@@ -266,50 +296,64 @@ int main(int argc, char **argv)
|
|||||||
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
|
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
|
||||||
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
|
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
|
||||||
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
|
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
|
||||||
#if 0
|
#if 1
|
||||||
curl_easy_setopt(e, CURLOPT_VERBOSE, 1);
|
curl_easy_setopt(e, CURLOPT_VERBOSE, 1);
|
||||||
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, errorbuffer);
|
|
||||||
#endif
|
#endif
|
||||||
|
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
|
||||||
|
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
|
||||||
|
|
||||||
/* add the easy to the multi */
|
/* add the easy to the multi */
|
||||||
curl_multi_add_handle(multi_handle, e);
|
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
|
||||||
|
printf("curl_multi_add_handle() returned error for %d\n", i);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we start some action by calling perform right away */
|
/* we start some action by calling perform right away */
|
||||||
while(CURLM_CALL_MULTI_PERFORM ==
|
while(CURLM_CALL_MULTI_PERFORM ==
|
||||||
curl_multi_perform(multi_handle, &still_running));
|
curl_multi_perform(multi_handle, &still_running));
|
||||||
|
|
||||||
printf("Starting timer!\n");
|
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
|
||||||
timer_start();
|
timer_start();
|
||||||
|
|
||||||
while(still_running) {
|
while(still_running == num_total) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int rc; /* select() return code */
|
int rc; /* select() return code */
|
||||||
|
long timeout_ms;
|
||||||
|
|
||||||
fd_set fdread;
|
fd2_set fdread;
|
||||||
fd_set fdwrite;
|
fd2_set fdwrite;
|
||||||
fd_set fdexcep;
|
fd2_set fdexcep;
|
||||||
int maxfd;
|
int maxfd;
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD2_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD2_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
FD2_ZERO(&fdexcep);
|
||||||
|
|
||||||
/* set a suitable timeout to play around with */
|
curl_multi_timeout(multi_handle, &timeout_ms);
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 50000;
|
/* set timeout to wait */
|
||||||
|
timeout.tv_sec = timeout_ms/1000;
|
||||||
|
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||||
|
|
||||||
/* get file descriptors from the transfers */
|
/* get file descriptors from the transfers */
|
||||||
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
curl_multi_fdset(multi_handle,
|
||||||
|
(fd_set *)&fdread,
|
||||||
|
(fd_set *)&fdwrite,
|
||||||
|
(fd_set *)&fdexcep, &maxfd);
|
||||||
|
|
||||||
timer_pause();
|
timer_pause();
|
||||||
selects++;
|
selects++;
|
||||||
selectsalive += still_running;
|
selectsalive += still_running;
|
||||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
rc = select(maxfd+1,
|
||||||
|
(fd_set *)&fdread,
|
||||||
|
(fd_set *)&fdwrite,
|
||||||
|
(fd_set *)&fdexcep, &timeout);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Output this here to make it outside the timer */
|
/* Output this here to make it outside the timer */
|
||||||
printf("Running: %d (%d bytes)\n", still_running, info.dlcounter);
|
printf("Running: %d (%d bytes)\n", still_running, info.dlcounter);
|
||||||
|
#endif
|
||||||
timer_continue();
|
timer_continue();
|
||||||
|
|
||||||
switch(rc) {
|
switch(rc) {
|
||||||
@@ -332,43 +376,38 @@ int main(int argc, char **argv)
|
|||||||
topselect = rc;
|
topselect = rc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(still_running < NMARGIN) {
|
|
||||||
printf("Only %d connections left alive, existing\n",
|
if(total > RUN_FOR_THIS_LONG) {
|
||||||
still_running);
|
printf("Stopped after %ldus\n", total);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((prevalive == still_running) && (prevtotal == info.dlcounter) &&
|
if(prevalive != still_running) {
|
||||||
info.dlcounter) {
|
printf("%d connections alive\n", still_running);
|
||||||
/* The same amount of still alive transfers as last lap, increase
|
|
||||||
counter. Only do this if _anything_ has been downloaded since it
|
|
||||||
tends to come here during the initial name lookup phase when using
|
|
||||||
asynch DNS libcurl otherwise.
|
|
||||||
*/
|
|
||||||
prevsamecounter++;
|
|
||||||
|
|
||||||
if(prevsamecounter >= IDLE_TIME) {
|
|
||||||
/* for the sake of being efficient, we stop the operation when
|
|
||||||
IDLE_TIME has passed without any bytes transfered */
|
|
||||||
printf("Idle time (%d secs) reached (with %d still claimed alive),"
|
|
||||||
" exiting\n",
|
|
||||||
IDLE_TIME, still_running);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prevsamecounter=0;
|
|
||||||
}
|
}
|
||||||
prevalive = still_running;
|
prevalive = still_running;
|
||||||
prevtotal = info.dlcounter;
|
|
||||||
|
timer_total(); /* calculate the total time spent so far */
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_stop();
|
if(still_running != num_total) {
|
||||||
|
/* something made connections fail, extract the reason and tell */
|
||||||
|
int msgs_left;
|
||||||
|
struct connection *cptr;
|
||||||
|
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||||
|
if (msg->msg == CURLMSG_DONE) {
|
||||||
|
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
|
||||||
|
|
||||||
|
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
curl_multi_cleanup(multi_handle);
|
curl_multi_cleanup(multi_handle);
|
||||||
|
|
||||||
/* cleanup all the easy handles */
|
/* cleanup all the easy handles */
|
||||||
for(i=0; i< NCONNECTIONS; i++)
|
for(i=0; i< num_total; i++)
|
||||||
curl_easy_cleanup(conns[i].e);
|
curl_easy_cleanup(conns[i].e);
|
||||||
|
|
||||||
report();
|
report();
|
||||||
|
550
hiper/hipev.c
Normal file
550
hiper/hipev.c
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Connect N connections. Z are idle, and X are active. Transfer as fast as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Run for a specific amount of time (10 secs for now). Output detailed timing
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* Uses libevent.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The maximum number of simultanoues connections/transfers we support */
|
||||||
|
#define NCONNECTIONS 50000
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include <event.h> /* for libevent */
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MICROSEC 1000000 /* number of microseconds in one second */
|
||||||
|
|
||||||
|
/* The maximum time (in microseconds) we run the test */
|
||||||
|
#define RUN_FOR_THIS_LONG (5*MICROSEC)
|
||||||
|
|
||||||
|
/* Number of loops (seconds) we allow the total download amount and alive
|
||||||
|
connections to remain the same until we bail out. Set this slightly higher
|
||||||
|
when using asynch supported libcurl. */
|
||||||
|
#define IDLE_TIME 10
|
||||||
|
|
||||||
|
struct ourfdset {
|
||||||
|
/* __fds_bits is what the Linux glibc headers use when they declare the
|
||||||
|
fd_set struct so by using this we can actually avoid the typecase for the
|
||||||
|
FD_SET() macro usage but it would hardly be portable */
|
||||||
|
char __fds_bits[NCONNECTIONS/8];
|
||||||
|
};
|
||||||
|
#define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset))
|
||||||
|
|
||||||
|
typedef struct ourfdset fd2_set;
|
||||||
|
|
||||||
|
struct globalinfo {
|
||||||
|
size_t dlcounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct connection {
|
||||||
|
CURL *e;
|
||||||
|
int id; /* just a counter for easy browsing */
|
||||||
|
char *url;
|
||||||
|
size_t dlcounter;
|
||||||
|
struct globalinfo *global;
|
||||||
|
char error[CURL_ERROR_SIZE];
|
||||||
|
struct event ev[3]; /* maximum 3 events per handle NOTE: should this rather
|
||||||
|
be a define in a public curl header file or possibly
|
||||||
|
just documented somewhere or... ? */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fdinfo {
|
||||||
|
/* create a link list of fdinfo structs */
|
||||||
|
struct fdinfo *next;
|
||||||
|
struct fdinfo *prev;
|
||||||
|
curl_socket_t sockfd;
|
||||||
|
CURL *easy;
|
||||||
|
int action; /* as set by libcurl */
|
||||||
|
long timeout; /* as set by libcurl */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fdinfo *allsocks;
|
||||||
|
|
||||||
|
static struct fdinfo *findsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
/* return the struct for the given socket */
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
return fdp; /* a struct pointer or NULL */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
if(!fdp)
|
||||||
|
/* did not find socket to remove! */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(fdp->prev)
|
||||||
|
fdp->prev->next = fdp->next;
|
||||||
|
if(fdp->next)
|
||||||
|
fdp->next->prev = fdp->prev;
|
||||||
|
else
|
||||||
|
/* this was the last entry */
|
||||||
|
allsocks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
|
||||||
|
int action)
|
||||||
|
{
|
||||||
|
fdp->sockfd = s;
|
||||||
|
fdp->action = action;
|
||||||
|
fdp->easy = easy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addsock(curl_socket_t s, CURL *easy, int action)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
|
||||||
|
|
||||||
|
setsock(fdp, s, easy, action);
|
||||||
|
|
||||||
|
if(allsocks) {
|
||||||
|
fdp->next = allsocks;
|
||||||
|
allsocks->prev = fdp;
|
||||||
|
|
||||||
|
/* now set allsocks to point to the new struct */
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
int writable=0;
|
||||||
|
|
||||||
|
FD2_ZERO(fdread);
|
||||||
|
FD2_ZERO(fdwrite);
|
||||||
|
|
||||||
|
*maxfd = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Wait for: ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->action & CURL_POLL_IN) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdread);
|
||||||
|
}
|
||||||
|
if(fdp->action & CURL_POLL_OUT) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdwrite);
|
||||||
|
writable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%d (%s%s) ",
|
||||||
|
fdp->sockfd,
|
||||||
|
(fdp->action & CURL_POLL_IN)?"r":"",
|
||||||
|
(fdp->action & CURL_POLL_OUT)?"w":"");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(fdp->sockfd > *maxfd)
|
||||||
|
*maxfd = fdp->sockfd;
|
||||||
|
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if(writable)
|
||||||
|
printf("Check for %d writable sockets\n", writable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */
|
||||||
|
#define PORT "8999"
|
||||||
|
|
||||||
|
#define HOST "192.168.1.13"
|
||||||
|
|
||||||
|
#define URL_IDLE "http://" HOST ":" PORT "/1000"
|
||||||
|
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
|
||||||
|
|
||||||
|
|
||||||
|
static int socket_callback(CURL *easy, /* easy handle */
|
||||||
|
curl_socket_t s, /* socket */
|
||||||
|
int what, /* see above */
|
||||||
|
void *userp) /* "private" pointer */
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
printf("socket %d easy %p what %d\n", s, easy, what);
|
||||||
|
|
||||||
|
if(what == CURL_POLL_REMOVE)
|
||||||
|
remsock(s);
|
||||||
|
else {
|
||||||
|
fdp = findsock(s);
|
||||||
|
|
||||||
|
if(!fdp) {
|
||||||
|
addsock(s, easy, what);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we already know about it, just change action/timeout */
|
||||||
|
printf("Changing info for socket %d from %d to %d\n",
|
||||||
|
s, fdp->action, what);
|
||||||
|
setsock(fdp, s, easy, what);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* return code meaning? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
|
{
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct connection *c = (struct connection *)data;
|
||||||
|
|
||||||
|
c->dlcounter += realsize;
|
||||||
|
c->global->dlcounter += realsize;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%02d: %d, total %d\n",
|
||||||
|
c->id, c->dlcounter, c->global->dlcounter);
|
||||||
|
#endif
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the diff between two timevals, in us */
|
||||||
|
static long tvdiff(struct timeval *newer, struct timeval *older)
|
||||||
|
{
|
||||||
|
return (newer->tv_sec-older->tv_sec)*1000000+
|
||||||
|
(newer->tv_usec-older->tv_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* store the start time of the program in this variable */
|
||||||
|
static struct timeval timer;
|
||||||
|
|
||||||
|
static void timer_start(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the start moment */
|
||||||
|
gettimeofday(&timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timeval cont; /* at this moment we continued */
|
||||||
|
|
||||||
|
int still_running; /* keep number of running handles */
|
||||||
|
|
||||||
|
struct conncount {
|
||||||
|
long time_us;
|
||||||
|
long laps;
|
||||||
|
long maxtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct timeval timerpause;
|
||||||
|
static void timer_pause(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the pause moment */
|
||||||
|
gettimeofday(&timerpause, NULL);
|
||||||
|
|
||||||
|
/* If we have a previous continue (all times except the first), we can now
|
||||||
|
store the time for a whole "lap" */
|
||||||
|
if(cont.tv_sec) {
|
||||||
|
long lap;
|
||||||
|
|
||||||
|
lap = tvdiff(&timerpause, &cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long paused; /* amount of us we have been pausing */
|
||||||
|
|
||||||
|
static void timer_continue(void)
|
||||||
|
{
|
||||||
|
/* Capture the time of the restored operation moment, now calculate how long
|
||||||
|
time we were paused and added that to the 'paused' variable.
|
||||||
|
*/
|
||||||
|
gettimeofday(&cont, NULL);
|
||||||
|
|
||||||
|
paused += tvdiff(&cont, &timerpause);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long total; /* amount of us from start to stop */
|
||||||
|
static void timer_total(void)
|
||||||
|
{
|
||||||
|
struct timeval stop;
|
||||||
|
/* Capture the time of the operation stopped moment, now calculate how long
|
||||||
|
time we were running and how much of that pausing.
|
||||||
|
*/
|
||||||
|
gettimeofday(&stop, NULL);
|
||||||
|
|
||||||
|
total = tvdiff(&stop, &timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct globalinfo info;
|
||||||
|
struct connection *conns;
|
||||||
|
|
||||||
|
long selects;
|
||||||
|
long timeouts;
|
||||||
|
|
||||||
|
long multi_socket;
|
||||||
|
long performalive;
|
||||||
|
long performselect;
|
||||||
|
long topselect;
|
||||||
|
|
||||||
|
int num_total;
|
||||||
|
int num_idle;
|
||||||
|
int num_active;
|
||||||
|
|
||||||
|
static void report(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long active = total - paused;
|
||||||
|
long numdl = 0;
|
||||||
|
|
||||||
|
for(i=0; i < num_total; i++) {
|
||||||
|
if(conns[i].dlcounter)
|
||||||
|
numdl++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Summary from %d simultanoues transfers (%d active)\n",
|
||||||
|
num_total, num_active);
|
||||||
|
printf("%d out of %d connections provided data\n", numdl, num_total);
|
||||||
|
|
||||||
|
printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n",
|
||||||
|
total, paused, active);
|
||||||
|
|
||||||
|
printf("%d calls to select() "
|
||||||
|
"Average time: %dus\n",
|
||||||
|
selects, paused/selects);
|
||||||
|
printf(" Average number of readable connections per select() return: %d\n",
|
||||||
|
performselect/selects);
|
||||||
|
|
||||||
|
printf(" Max number of readable connections for a single select() "
|
||||||
|
"return: %d\n",
|
||||||
|
topselect);
|
||||||
|
|
||||||
|
printf("%ld calls to multi_socket(), "
|
||||||
|
"Average time: %ldus\n",
|
||||||
|
multi_socket, active/multi_socket);
|
||||||
|
|
||||||
|
printf("%ld select() timeouts\n", timeouts);
|
||||||
|
|
||||||
|
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
|
||||||
|
info.dlcounter,
|
||||||
|
info.dlcounter/(total/1000000),
|
||||||
|
total/info.dlcounter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
CURLM *multi_handle;
|
||||||
|
CURLMsg *msg;
|
||||||
|
CURLcode code = CURLE_OK;
|
||||||
|
CURLMcode mcode = CURLM_OK;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
fd2_set fdsizecheck;
|
||||||
|
int selectmaxamount;
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
char act;
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(struct globalinfo));
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("Usage: hiper-event [num idle] [num active]\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_idle = atoi(argv[1]);
|
||||||
|
num_active = atoi(argv[2]);
|
||||||
|
|
||||||
|
num_total = num_idle + num_active;
|
||||||
|
|
||||||
|
conns = calloc(num_total, sizeof(struct connection));
|
||||||
|
if(!conns) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_total >= NCONNECTIONS) {
|
||||||
|
printf("Too many connections requested, increase NCONNECTIONS!\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_init(); /* Initalize the event library */
|
||||||
|
|
||||||
|
printf("About to do %d connections\n", num_total);
|
||||||
|
|
||||||
|
/* init the multi stack */
|
||||||
|
multi_handle = curl_multi_init();
|
||||||
|
|
||||||
|
for(i=0; i< num_total; i++) {
|
||||||
|
CURL *e;
|
||||||
|
char *nl;
|
||||||
|
|
||||||
|
memset(&conns[i], 0, sizeof(struct connection));
|
||||||
|
|
||||||
|
if(i < num_idle)
|
||||||
|
conns[i].url = URL_IDLE;
|
||||||
|
else
|
||||||
|
conns[i].url = URL_ACTIVE;
|
||||||
|
|
||||||
|
e = curl_easy_init();
|
||||||
|
|
||||||
|
if(!e) {
|
||||||
|
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
conns[i].e = e;
|
||||||
|
conns[i].id = i;
|
||||||
|
conns[i].global = &info;
|
||||||
|
|
||||||
|
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
|
||||||
|
curl_easy_setopt(e, CURLOPT_VERBOSE, 0);
|
||||||
|
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
|
||||||
|
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
|
||||||
|
|
||||||
|
/* add the easy to the multi */
|
||||||
|
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
|
||||||
|
printf("curl_multi_add_handle() returned error for %d\n", i);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL);
|
||||||
|
|
||||||
|
/* we start the action by calling *socket() right away */
|
||||||
|
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle));
|
||||||
|
|
||||||
|
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
|
||||||
|
timer_start();
|
||||||
|
timer_pause();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
struct timeval timeout;
|
||||||
|
int rc; /* select() return code */
|
||||||
|
long timeout_ms;
|
||||||
|
|
||||||
|
fd2_set fdread;
|
||||||
|
fd2_set fdwrite;
|
||||||
|
int maxfd;
|
||||||
|
|
||||||
|
curl_multi_timeout(multi_handle, &timeout_ms);
|
||||||
|
|
||||||
|
/* set timeout to wait */
|
||||||
|
timeout.tv_sec = timeout_ms/1000;
|
||||||
|
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||||
|
|
||||||
|
/* convert file descriptors from the transfers to fd_sets */
|
||||||
|
fdinfo2fdset(&fdread, &fdwrite, &maxfd);
|
||||||
|
|
||||||
|
selects++;
|
||||||
|
rc = select(maxfd+1,
|
||||||
|
(fd_set *)&fdread,
|
||||||
|
(fd_set *)&fdwrite,
|
||||||
|
NULL, &timeout);
|
||||||
|
switch(rc) {
|
||||||
|
case -1:
|
||||||
|
/* select error */
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
timeouts++;
|
||||||
|
curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* timeout or readable/writable sockets */
|
||||||
|
|
||||||
|
for(i=0, fdp = allsocks; fdp; fdp = fdp->next) {
|
||||||
|
act = 0;
|
||||||
|
if((fdp->action & CURL_POLL_IN) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdread)) {
|
||||||
|
act |= CURL_POLL_IN;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if((fdp->action & CURL_POLL_OUT) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdwrite)) {
|
||||||
|
act |= CURL_POLL_OUT;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(act) {
|
||||||
|
multi_socket++;
|
||||||
|
timer_continue();
|
||||||
|
if(act & CURL_POLL_OUT)
|
||||||
|
act--;
|
||||||
|
curl_multi_socket(multi_handle, fdp->sockfd);
|
||||||
|
timer_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
performselect += rc;
|
||||||
|
if(rc > topselect)
|
||||||
|
topselect = rc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_total(); /* calculate the total time spent so far */
|
||||||
|
|
||||||
|
if(total > RUN_FOR_THIS_LONG) {
|
||||||
|
printf("Stopped after %ldus\n", total);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(still_running != num_total) {
|
||||||
|
/* something made connections fail, extract the reason and tell */
|
||||||
|
int msgs_left;
|
||||||
|
struct connection *cptr;
|
||||||
|
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||||
|
if (msg->msg == CURLMSG_DONE) {
|
||||||
|
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
|
||||||
|
|
||||||
|
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_cleanup(multi_handle);
|
||||||
|
|
||||||
|
/* cleanup all the easy handles */
|
||||||
|
for(i=0; i< num_total; i++)
|
||||||
|
curl_easy_cleanup(conns[i].e);
|
||||||
|
|
||||||
|
report();
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
555
hiper/shiper.c
Normal file
555
hiper/shiper.c
Normal file
@@ -0,0 +1,555 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Connect N connections. Z are idle, and X are active. Transfer as fast as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Run for a specific amount of time (10 secs for now). Output detailed timing
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* The same is hiper.c but instead using the new *socket() API instead of the
|
||||||
|
* "old" *perform() call.
|
||||||
|
*
|
||||||
|
* Uses a select() approach but only for keeping the code simple and
|
||||||
|
* stand-alone. See hipev.c for a libevent-based example.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The maximum number of simultanoues connections/transfers we support */
|
||||||
|
#define NCONNECTIONS 50000
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MICROSEC 1000000 /* number of microseconds in one second */
|
||||||
|
|
||||||
|
/* The maximum time (in microseconds) we run the test */
|
||||||
|
#define RUN_FOR_THIS_LONG (5*MICROSEC)
|
||||||
|
|
||||||
|
/* Number of loops (seconds) we allow the total download amount and alive
|
||||||
|
connections to remain the same until we bail out. Set this slightly higher
|
||||||
|
when using asynch supported libcurl. */
|
||||||
|
#define IDLE_TIME 10
|
||||||
|
|
||||||
|
struct ourfdset {
|
||||||
|
/* __fds_bits is what the Linux glibc headers use when they declare the
|
||||||
|
fd_set struct so by using this we can actually avoid the typecase for the
|
||||||
|
FD_SET() macro usage but it would hardly be portable */
|
||||||
|
char __fds_bits[NCONNECTIONS/8];
|
||||||
|
};
|
||||||
|
#define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset))
|
||||||
|
|
||||||
|
typedef struct ourfdset fd2_set;
|
||||||
|
|
||||||
|
struct globalinfo {
|
||||||
|
size_t dlcounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct connection {
|
||||||
|
CURL *e;
|
||||||
|
int id; /* just a counter for easy browsing */
|
||||||
|
char *url;
|
||||||
|
size_t dlcounter;
|
||||||
|
struct globalinfo *global;
|
||||||
|
char error[CURL_ERROR_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fdinfo {
|
||||||
|
/* create a link list of fdinfo structs */
|
||||||
|
struct fdinfo *next;
|
||||||
|
struct fdinfo *prev;
|
||||||
|
curl_socket_t sockfd;
|
||||||
|
CURL *easy;
|
||||||
|
int action; /* as set by libcurl */
|
||||||
|
long timeout; /* as set by libcurl */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fdinfo *allsocks;
|
||||||
|
|
||||||
|
static struct fdinfo *findsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
/* return the struct for the given socket */
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
return fdp; /* a struct pointer or NULL */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remsock(curl_socket_t s)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->sockfd == s)
|
||||||
|
break;
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
if(!fdp)
|
||||||
|
/* did not find socket to remove! */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(fdp->prev)
|
||||||
|
fdp->prev->next = fdp->next;
|
||||||
|
if(fdp->next)
|
||||||
|
fdp->next->prev = fdp->prev;
|
||||||
|
else
|
||||||
|
/* this was the last entry */
|
||||||
|
allsocks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
|
||||||
|
int action)
|
||||||
|
{
|
||||||
|
fdp->sockfd = s;
|
||||||
|
fdp->action = action;
|
||||||
|
fdp->easy = easy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addsock(curl_socket_t s, CURL *easy, int action)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
|
||||||
|
|
||||||
|
setsock(fdp, s, easy, action);
|
||||||
|
|
||||||
|
if(allsocks) {
|
||||||
|
fdp->next = allsocks;
|
||||||
|
allsocks->prev = fdp;
|
||||||
|
|
||||||
|
/* now set allsocks to point to the new struct */
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
allsocks = fdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd)
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp = allsocks;
|
||||||
|
int writable=0;
|
||||||
|
|
||||||
|
FD2_ZERO(fdread);
|
||||||
|
FD2_ZERO(fdwrite);
|
||||||
|
|
||||||
|
*maxfd = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Wait for: ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(fdp) {
|
||||||
|
if(fdp->action & CURL_POLL_IN) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdread);
|
||||||
|
}
|
||||||
|
if(fdp->action & CURL_POLL_OUT) {
|
||||||
|
FD_SET(fdp->sockfd, (fd_set *)fdwrite);
|
||||||
|
writable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%d (%s%s) ",
|
||||||
|
fdp->sockfd,
|
||||||
|
(fdp->action & CURL_POLL_IN)?"r":"",
|
||||||
|
(fdp->action & CURL_POLL_OUT)?"w":"");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(fdp->sockfd > *maxfd)
|
||||||
|
*maxfd = fdp->sockfd;
|
||||||
|
|
||||||
|
fdp = fdp->next;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if(writable)
|
||||||
|
printf("Check for %d writable sockets\n", writable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */
|
||||||
|
#define PORT "8999"
|
||||||
|
|
||||||
|
#define HOST "192.168.1.13"
|
||||||
|
|
||||||
|
#define URL_IDLE "http://" HOST ":" PORT "/1000"
|
||||||
|
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
|
||||||
|
|
||||||
|
|
||||||
|
static int socket_callback(CURL *easy, /* easy handle */
|
||||||
|
curl_socket_t s, /* socket */
|
||||||
|
int what, /* see above */
|
||||||
|
void *userp) /* "private" pointer */
|
||||||
|
{
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
printf("socket %d easy %p what %d\n", s, easy, what);
|
||||||
|
|
||||||
|
if(what == CURL_POLL_REMOVE)
|
||||||
|
remsock(s);
|
||||||
|
else {
|
||||||
|
fdp = findsock(s);
|
||||||
|
|
||||||
|
if(!fdp) {
|
||||||
|
addsock(s, easy, what);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we already know about it, just change action/timeout */
|
||||||
|
printf("Changing info for socket %d from %d to %d\n",
|
||||||
|
s, fdp->action, what);
|
||||||
|
setsock(fdp, s, easy, what);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* return code meaning? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
|
{
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct connection *c = (struct connection *)data;
|
||||||
|
|
||||||
|
c->dlcounter += realsize;
|
||||||
|
c->global->dlcounter += realsize;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%02d: %d, total %d\n",
|
||||||
|
c->id, c->dlcounter, c->global->dlcounter);
|
||||||
|
#endif
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the diff between two timevals, in us */
|
||||||
|
static long tvdiff(struct timeval *newer, struct timeval *older)
|
||||||
|
{
|
||||||
|
return (newer->tv_sec-older->tv_sec)*1000000+
|
||||||
|
(newer->tv_usec-older->tv_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* store the start time of the program in this variable */
|
||||||
|
static struct timeval timer;
|
||||||
|
|
||||||
|
static void timer_start(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the start moment */
|
||||||
|
gettimeofday(&timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timeval cont; /* at this moment we continued */
|
||||||
|
|
||||||
|
int still_running; /* keep number of running handles */
|
||||||
|
|
||||||
|
struct conncount {
|
||||||
|
long time_us;
|
||||||
|
long laps;
|
||||||
|
long maxtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct timeval timerpause;
|
||||||
|
static void timer_pause(void)
|
||||||
|
{
|
||||||
|
/* capture the time of the pause moment */
|
||||||
|
gettimeofday(&timerpause, NULL);
|
||||||
|
|
||||||
|
/* If we have a previous continue (all times except the first), we can now
|
||||||
|
store the time for a whole "lap" */
|
||||||
|
if(cont.tv_sec) {
|
||||||
|
long lap;
|
||||||
|
|
||||||
|
lap = tvdiff(&timerpause, &cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long paused; /* amount of us we have been pausing */
|
||||||
|
|
||||||
|
static void timer_continue(void)
|
||||||
|
{
|
||||||
|
/* Capture the time of the restored operation moment, now calculate how long
|
||||||
|
time we were paused and added that to the 'paused' variable.
|
||||||
|
*/
|
||||||
|
gettimeofday(&cont, NULL);
|
||||||
|
|
||||||
|
paused += tvdiff(&cont, &timerpause);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long total; /* amount of us from start to stop */
|
||||||
|
static void timer_total(void)
|
||||||
|
{
|
||||||
|
struct timeval stop;
|
||||||
|
/* Capture the time of the operation stopped moment, now calculate how long
|
||||||
|
time we were running and how much of that pausing.
|
||||||
|
*/
|
||||||
|
gettimeofday(&stop, NULL);
|
||||||
|
|
||||||
|
total = tvdiff(&stop, &timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct globalinfo info;
|
||||||
|
struct connection *conns;
|
||||||
|
|
||||||
|
long selects;
|
||||||
|
long timeouts;
|
||||||
|
|
||||||
|
long multi_socket;
|
||||||
|
long performalive;
|
||||||
|
long performselect;
|
||||||
|
long topselect;
|
||||||
|
|
||||||
|
int num_total;
|
||||||
|
int num_idle;
|
||||||
|
int num_active;
|
||||||
|
|
||||||
|
static void report(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long active = total - paused;
|
||||||
|
long numdl = 0;
|
||||||
|
|
||||||
|
for(i=0; i < num_total; i++) {
|
||||||
|
if(conns[i].dlcounter)
|
||||||
|
numdl++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Summary from %d simultanoues transfers (%d active)\n",
|
||||||
|
num_total, num_active);
|
||||||
|
printf("%d out of %d connections provided data\n", numdl, num_total);
|
||||||
|
|
||||||
|
printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n",
|
||||||
|
total, paused, active);
|
||||||
|
|
||||||
|
printf("%d calls to select() "
|
||||||
|
"Average time: %dus\n",
|
||||||
|
selects, paused/selects);
|
||||||
|
printf(" Average number of readable connections per select() return: %d\n",
|
||||||
|
performselect/selects);
|
||||||
|
|
||||||
|
printf(" Max number of readable connections for a single select() "
|
||||||
|
"return: %d\n",
|
||||||
|
topselect);
|
||||||
|
|
||||||
|
printf("%ld calls to multi_socket(), "
|
||||||
|
"Average time: %ldus\n",
|
||||||
|
multi_socket, active/multi_socket);
|
||||||
|
|
||||||
|
printf("%ld select() timeouts\n", timeouts);
|
||||||
|
|
||||||
|
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
|
||||||
|
info.dlcounter,
|
||||||
|
info.dlcounter/(total/1000000),
|
||||||
|
total/info.dlcounter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
CURLM *multi_handle;
|
||||||
|
CURLMsg *msg;
|
||||||
|
CURLcode code = CURLE_OK;
|
||||||
|
CURLMcode mcode = CURLM_OK;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
fd2_set fdsizecheck;
|
||||||
|
int selectmaxamount;
|
||||||
|
struct fdinfo *fdp;
|
||||||
|
char act;
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(struct globalinfo));
|
||||||
|
|
||||||
|
selectmaxamount = sizeof(fdsizecheck) * 8;
|
||||||
|
printf("select() supports max %d connections\n", selectmaxamount);
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("Usage: hiper [num idle] [num active]\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_idle = atoi(argv[1]);
|
||||||
|
num_active = atoi(argv[2]);
|
||||||
|
|
||||||
|
num_total = num_idle + num_active;
|
||||||
|
|
||||||
|
if(num_total > selectmaxamount) {
|
||||||
|
printf("Requested more connections than supported!\n");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
conns = calloc(num_total, sizeof(struct connection));
|
||||||
|
if(!conns) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(num_total >= NCONNECTIONS) {
|
||||||
|
printf("Too many connections requested, increase NCONNECTIONS!\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("About to do %d connections\n", num_total);
|
||||||
|
|
||||||
|
/* init the multi stack */
|
||||||
|
multi_handle = curl_multi_init();
|
||||||
|
|
||||||
|
for(i=0; i< num_total; i++) {
|
||||||
|
CURL *e;
|
||||||
|
char *nl;
|
||||||
|
|
||||||
|
memset(&conns[i], 0, sizeof(struct connection));
|
||||||
|
|
||||||
|
if(i < num_idle)
|
||||||
|
conns[i].url = URL_IDLE;
|
||||||
|
else
|
||||||
|
conns[i].url = URL_ACTIVE;
|
||||||
|
|
||||||
|
e = curl_easy_init();
|
||||||
|
|
||||||
|
if(!e) {
|
||||||
|
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
conns[i].e = e;
|
||||||
|
conns[i].id = i;
|
||||||
|
conns[i].global = &info;
|
||||||
|
|
||||||
|
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
|
||||||
|
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
|
||||||
|
curl_easy_setopt(e, CURLOPT_VERBOSE, 0);
|
||||||
|
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
|
||||||
|
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
|
||||||
|
|
||||||
|
/* add the easy to the multi */
|
||||||
|
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
|
||||||
|
printf("curl_multi_add_handle() returned error for %d\n", i);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
|
||||||
|
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL);
|
||||||
|
|
||||||
|
/* we start the action by calling *socket() right away */
|
||||||
|
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle));
|
||||||
|
|
||||||
|
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
|
||||||
|
timer_start();
|
||||||
|
timer_pause();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
struct timeval timeout;
|
||||||
|
int rc; /* select() return code */
|
||||||
|
long timeout_ms;
|
||||||
|
|
||||||
|
fd2_set fdread;
|
||||||
|
fd2_set fdwrite;
|
||||||
|
int maxfd;
|
||||||
|
|
||||||
|
curl_multi_timeout(multi_handle, &timeout_ms);
|
||||||
|
|
||||||
|
/* set timeout to wait */
|
||||||
|
timeout.tv_sec = timeout_ms/1000;
|
||||||
|
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||||
|
|
||||||
|
/* convert file descriptors from the transfers to fd_sets */
|
||||||
|
fdinfo2fdset(&fdread, &fdwrite, &maxfd);
|
||||||
|
|
||||||
|
selects++;
|
||||||
|
rc = select(maxfd+1,
|
||||||
|
(fd_set *)&fdread,
|
||||||
|
(fd_set *)&fdwrite,
|
||||||
|
NULL, &timeout);
|
||||||
|
switch(rc) {
|
||||||
|
case -1:
|
||||||
|
/* select error */
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
timeouts++;
|
||||||
|
curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* timeout or readable/writable sockets */
|
||||||
|
|
||||||
|
for(i=0, fdp = allsocks; fdp; fdp = fdp->next) {
|
||||||
|
act = 0;
|
||||||
|
if((fdp->action & CURL_POLL_IN) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdread)) {
|
||||||
|
act |= CURL_POLL_IN;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if((fdp->action & CURL_POLL_OUT) &&
|
||||||
|
FD_ISSET(fdp->sockfd, &fdwrite)) {
|
||||||
|
act |= CURL_POLL_OUT;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(act) {
|
||||||
|
multi_socket++;
|
||||||
|
timer_continue();
|
||||||
|
if(act & CURL_POLL_OUT)
|
||||||
|
act--;
|
||||||
|
curl_multi_socket(multi_handle, fdp->sockfd);
|
||||||
|
timer_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
performselect += rc;
|
||||||
|
if(rc > topselect)
|
||||||
|
topselect = rc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_total(); /* calculate the total time spent so far */
|
||||||
|
|
||||||
|
if(total > RUN_FOR_THIS_LONG) {
|
||||||
|
printf("Stopped after %ldus\n", total);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(still_running != num_total) {
|
||||||
|
/* something made connections fail, extract the reason and tell */
|
||||||
|
int msgs_left;
|
||||||
|
struct connection *cptr;
|
||||||
|
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||||
|
if (msg->msg == CURLMSG_DONE) {
|
||||||
|
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
|
||||||
|
|
||||||
|
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_cleanup(multi_handle);
|
||||||
|
|
||||||
|
/* cleanup all the easy handles */
|
||||||
|
for(i=0; i< num_total; i++)
|
||||||
|
curl_easy_cleanup(conns[i].e);
|
||||||
|
|
||||||
|
report();
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
101
hiper/ulimiter.c
Normal file
101
hiper/ulimiter.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Little tool to raise the amount of maximum file descriptor and then run the
|
||||||
|
* given command line (using the hard-coded uid/gid).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h> /* for errno translation */
|
||||||
|
|
||||||
|
/* ulimiter
|
||||||
|
*
|
||||||
|
* Source code inspiration from:
|
||||||
|
* http://www.cs.wisc.edu/condor/condorg/linux_scalability.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UID 1000 /* the user who must run this */
|
||||||
|
|
||||||
|
#define GID 1000 /* group id to run the program as */
|
||||||
|
|
||||||
|
/* Number of open files to increase to */
|
||||||
|
#define NEW_MAX 10000
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct rlimit rl;
|
||||||
|
char *brgv[20];
|
||||||
|
int brgc=argc-1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=1; i< argc; i++)
|
||||||
|
brgv[i-1]=argv[i];
|
||||||
|
brgv[i-1]=NULL; /* terminate the list */
|
||||||
|
|
||||||
|
if(getuid() != UID) {
|
||||||
|
fprintf(stderr, "Only uid %d is allowed to run this\n", UID);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = getrlimit(RLIMIT_NOFILE, &rl);
|
||||||
|
if(ret != 0) {
|
||||||
|
fprintf(stderr, "Unable to read open file limit.\n"
|
||||||
|
"(getrlimit(RLIMIT_NOFILE, &rl) failed)\n"
|
||||||
|
"(%d, %s)", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Limit was %d (max %d), setting to %d\n",
|
||||||
|
rl.rlim_cur, rl.rlim_max, NEW_MAX);
|
||||||
|
|
||||||
|
rl.rlim_cur = rl.rlim_max = NEW_MAX;
|
||||||
|
ret = setrlimit(RLIMIT_NOFILE, &rl);
|
||||||
|
if(ret != 0) {
|
||||||
|
fprintf(stderr, "Unable to set open file limit.\n"
|
||||||
|
"(setrlimit(RLIMIT_NOFILE, &rl) failed)\n"
|
||||||
|
"(%d, %s)", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = getrlimit(RLIMIT_NOFILE, &rl);
|
||||||
|
if(ret != 0) {
|
||||||
|
fprintf(stderr, "Unable to read new open file limit.\n"
|
||||||
|
"(getrlimit(RLIMIT_NOFILE, &rl) failed)\n"
|
||||||
|
"(%d, %s)", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(rl.rlim_cur < NEW_MAX) {
|
||||||
|
fprintf(stderr, "Failed to set new open file limit.\n"
|
||||||
|
"Limit is %d, expected %d\n",
|
||||||
|
rl.rlim_cur, NEW_MAX);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setgid(GID) != 0) {
|
||||||
|
fprintf(stderr, "setgid failed (%d, %s)\n", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(setuid(UID) != 0) {
|
||||||
|
fprintf(stderr, "setuid failed (%d, %s)\n", errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = execv(brgv[0], brgv);
|
||||||
|
|
||||||
|
fprintf(stderr, "execl returned, failure\n"
|
||||||
|
"returned %d, errno is %d (%s)\n",
|
||||||
|
ret, errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, 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
|
||||||
@@ -65,9 +65,11 @@ extern "C" {
|
|||||||
* We want the typedef curl_off_t setup for large file support on all
|
* We want the typedef curl_off_t setup for large file support on all
|
||||||
* platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf
|
* platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf
|
||||||
* format strings when outputting a variable of type curl_off_t.
|
* format strings when outputting a variable of type curl_off_t.
|
||||||
|
*
|
||||||
|
* Note: "pocc -Ze" is MSVC compatibily mode and this sets _MSC_VER!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__LCC__)
|
#if (defined(_MSC_VER) && !defined(__POCC__)) || (defined(__LCC__) && defined(WIN32))
|
||||||
/* MSVC */
|
/* MSVC */
|
||||||
#ifdef _WIN32_WCE
|
#ifdef _WIN32_WCE
|
||||||
typedef long curl_off_t;
|
typedef long curl_off_t;
|
||||||
@@ -76,7 +78,7 @@ extern "C" {
|
|||||||
typedef signed __int64 curl_off_t;
|
typedef signed __int64 curl_off_t;
|
||||||
#define CURL_FORMAT_OFF_T "%I64d"
|
#define CURL_FORMAT_OFF_T "%I64d"
|
||||||
#endif
|
#endif
|
||||||
#else /* _MSC_VER || __LCC__ */
|
#else /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */
|
||||||
#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__)
|
#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__)
|
||||||
/* gcc on windows or Watcom */
|
/* gcc on windows or Watcom */
|
||||||
typedef long long curl_off_t;
|
typedef long long curl_off_t;
|
||||||
@@ -108,7 +110,7 @@ extern "C" {
|
|||||||
#define CURL_FORMAT_OFF_T "%ld"
|
#define CURL_FORMAT_OFF_T "%ld"
|
||||||
#endif
|
#endif
|
||||||
#endif /* GCC or Watcom on Windows */
|
#endif /* GCC or Watcom on Windows */
|
||||||
#endif /* _MSC_VER || __LCC__ */
|
#endif /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */
|
||||||
|
|
||||||
#ifdef UNDEF_FILE_OFFSET_BITS
|
#ifdef UNDEF_FILE_OFFSET_BITS
|
||||||
/* this was defined above for our checks, undefine it again */
|
/* this was defined above for our checks, undefine it again */
|
||||||
@@ -240,7 +242,7 @@ typedef enum {
|
|||||||
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
|
||||||
CURLE_FAILED_INIT, /* 2 */
|
CURLE_FAILED_INIT, /* 2 */
|
||||||
CURLE_URL_MALFORMAT, /* 3 */
|
CURLE_URL_MALFORMAT, /* 3 */
|
||||||
CURLE_URL_MALFORMAT_USER, /* 4 (NOT USED) */
|
CURLE_URL_MALFORMAT_USER, /* 4 - NOT USED */
|
||||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||||
CURLE_COULDNT_CONNECT, /* 7 */
|
CURLE_COULDNT_CONNECT, /* 7 */
|
||||||
@@ -248,7 +250,7 @@ typedef enum {
|
|||||||
CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
|
CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
|
||||||
due to lack of access - when login fails
|
due to lack of access - when login fails
|
||||||
this is not returned. */
|
this is not returned. */
|
||||||
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 */
|
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */
|
||||||
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
|
||||||
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
|
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
|
||||||
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
||||||
@@ -266,6 +268,10 @@ typedef enum {
|
|||||||
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
|
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
|
||||||
CURLE_READ_ERROR, /* 26 - could open/read from file */
|
CURLE_READ_ERROR, /* 26 - could open/read from file */
|
||||||
CURLE_OUT_OF_MEMORY, /* 27 */
|
CURLE_OUT_OF_MEMORY, /* 27 */
|
||||||
|
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
|
||||||
|
instead of a memory allocation error if CURL_DOES_CONVERSIONS
|
||||||
|
is defined
|
||||||
|
*/
|
||||||
CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */
|
CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */
|
||||||
CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
|
CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
|
||||||
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
|
||||||
@@ -316,9 +322,18 @@ typedef enum {
|
|||||||
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
|
||||||
CURLE_TFTP_EXISTS, /* 73 - File already exists */
|
CURLE_TFTP_EXISTS, /* 73 - File already exists */
|
||||||
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
|
||||||
|
CURLE_CONV_FAILED, /* 75 - conversion failed */
|
||||||
|
CURLE_CONV_REQD, /* 76 - caller must register conversion
|
||||||
|
callbacks using curl_easy_setopt options
|
||||||
|
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
|
||||||
|
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
|
||||||
|
CURLOPT_CONV_FROM_UTF8_FUNCTION */
|
||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
|
|
||||||
|
/* This prototype applies to all conversion callbacks */
|
||||||
|
typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
|
||||||
|
|
||||||
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
|
||||||
void *ssl_ctx, /* actually an
|
void *ssl_ctx, /* actually an
|
||||||
OpenSSL SSL_CTX */
|
OpenSSL SSL_CTX */
|
||||||
@@ -379,6 +394,15 @@ typedef enum {
|
|||||||
CURLFTPAUTH_LAST /* not an option, never use */
|
CURLFTPAUTH_LAST /* not an option, never use */
|
||||||
} curl_ftpauth;
|
} curl_ftpauth;
|
||||||
|
|
||||||
|
/* parameter for the CURLOPT_FTP_FILEMETHOD option */
|
||||||
|
typedef enum {
|
||||||
|
CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
|
||||||
|
CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
|
||||||
|
CURLFTPMETHOD_NOCWD, /* no CWD at all */
|
||||||
|
CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
|
||||||
|
CURLFTPMETHOD_LAST /* not an option, never use */
|
||||||
|
} curl_ftpmethod;
|
||||||
|
|
||||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||||
but 32 */
|
but 32 */
|
||||||
#define CURLOPTTYPE_LONG 0
|
#define CURLOPTTYPE_LONG 0
|
||||||
@@ -400,7 +424,8 @@ typedef enum {
|
|||||||
* platforms.
|
* platforms.
|
||||||
*/
|
*/
|
||||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__)
|
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||||
|
defined(__POCC__) || defined(__SALFORDC__)
|
||||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||||
#define CURL_ISOCPP
|
#define CURL_ISOCPP
|
||||||
#else
|
#else
|
||||||
@@ -909,9 +934,35 @@ typedef enum {
|
|||||||
control connection. */
|
control connection. */
|
||||||
CINIT(FTP_SKIP_PASV_IP, LONG, 137),
|
CINIT(FTP_SKIP_PASV_IP, LONG, 137),
|
||||||
|
|
||||||
/* Select "file method" to use when doing FTP */
|
/* Select "file method" to use when doing FTP, see the curl_ftpmethod
|
||||||
|
above. */
|
||||||
CINIT(FTP_FILEMETHOD, LONG, 138),
|
CINIT(FTP_FILEMETHOD, LONG, 138),
|
||||||
|
|
||||||
|
/* Local port number to bind the socket to */
|
||||||
|
CINIT(LOCALPORT, LONG, 139),
|
||||||
|
|
||||||
|
/* Number of ports to try, including the first one set with LOCALPORT.
|
||||||
|
Thus, setting it to 1 will make no additional attempts but the first.
|
||||||
|
*/
|
||||||
|
CINIT(LOCALPORTRANGE, LONG, 140),
|
||||||
|
|
||||||
|
/* no transfer, set up connection and let application use the socket by
|
||||||
|
extracting it with CURLINFO_LASTSOCKET */
|
||||||
|
CINIT(CONNECT_ONLY, LONG, 141),
|
||||||
|
|
||||||
|
/* Function that will be called to convert from the
|
||||||
|
network encoding (instead of using the iconv calls in libcurl) */
|
||||||
|
CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
|
||||||
|
|
||||||
|
/* Function that will be called to convert to the
|
||||||
|
network encoding (instead of using the iconv calls in libcurl) */
|
||||||
|
CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
|
||||||
|
|
||||||
|
/* Function that will be called to convert from UTF8
|
||||||
|
(instead of using the iconv calls in libcurl)
|
||||||
|
Note that this is used only for SSL certificate processing */
|
||||||
|
CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -1121,7 +1172,7 @@ CURL_EXTERN char *curl_getenv(const char *variable);
|
|||||||
CURL_EXTERN char *curl_version(void);
|
CURL_EXTERN char *curl_version(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_escape()
|
* NAME curl_easy_escape()
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
@@ -1129,18 +1180,34 @@ CURL_EXTERN char *curl_version(void);
|
|||||||
* %XX versions). This function returns a new allocated string or NULL if an
|
* %XX versions). This function returns a new allocated string or NULL if an
|
||||||
* error occurred.
|
* error occurred.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN char *curl_escape(const char *string, int length);
|
CURL_EXTERN char *curl_easy_escape(CURL *handle,
|
||||||
|
const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
|
/* the previous version: */
|
||||||
|
CURL_EXTERN char *curl_escape(const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_unescape()
|
* NAME curl_easy_unescape()
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
*
|
*
|
||||||
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
* Unescapes URL encoding in strings (converts all %XX codes to their 8bit
|
||||||
* versions). This function returns a new allocated string or NULL if an error
|
* versions). This function returns a new allocated string or NULL if an error
|
||||||
* occurred.
|
* occurred.
|
||||||
|
* Conversion Note: On non-ASCII platforms the ASCII %XX codes are
|
||||||
|
* converted into the host encoding.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN char *curl_unescape(const char *string, int length);
|
CURL_EXTERN char *curl_easy_unescape(CURL *handle,
|
||||||
|
const char *string,
|
||||||
|
int length,
|
||||||
|
int *outlength);
|
||||||
|
|
||||||
|
/* the previous version */
|
||||||
|
CURL_EXTERN char *curl_unescape(const char *string,
|
||||||
|
int length);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_free()
|
* NAME curl_free()
|
||||||
@@ -1266,9 +1333,11 @@ typedef enum {
|
|||||||
CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
|
CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
|
||||||
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
||||||
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
||||||
|
CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
|
||||||
|
CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
|
||||||
/* Fill in new entries below here! */
|
/* Fill in new entries below here! */
|
||||||
|
|
||||||
CURLINFO_LASTONE = 28
|
CURLINFO_LASTONE = 30
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
@@ -1405,6 +1474,8 @@ typedef struct {
|
|||||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||||
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
||||||
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
||||||
|
#define CURL_VERSION_CONV (1<<12) /* character conversions are
|
||||||
|
supported */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_version_info()
|
* NAME curl_version_info()
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, 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
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.15.1-CVS"
|
#define LIBCURL_VERSION "7.15.4-CVS"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 15
|
#define LIBCURL_VERSION_MINOR 15
|
||||||
#define LIBCURL_VERSION_PATCH 1
|
#define LIBCURL_VERSION_PATCH 4
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||||
@@ -51,6 +51,6 @@
|
|||||||
and it is always a greater number in a more recent release. It makes
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x070f01
|
#define LIBCURL_VERSION_NUM 0x070f04
|
||||||
|
|
||||||
#endif /* __CURL_CURLVER_H */
|
#endif /* __CURL_CURLVER_H */
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, 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
|
||||||
@@ -42,11 +42,18 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
|||||||
#ifdef _MPRINTF_REPLACE
|
#ifdef _MPRINTF_REPLACE
|
||||||
# define printf curl_mprintf
|
# define printf curl_mprintf
|
||||||
# define fprintf curl_mfprintf
|
# define fprintf curl_mfprintf
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
/* When built with CURLDEBUG we define away the sprintf() functions since we
|
||||||
|
don't want internal code to be using them */
|
||||||
|
# define sprintf sprintf_was_used
|
||||||
|
# define vsprintf vsprintf_was_used
|
||||||
|
#else
|
||||||
# define sprintf curl_msprintf
|
# define sprintf curl_msprintf
|
||||||
|
# define vsprintf curl_mvsprintf
|
||||||
|
#endif
|
||||||
# define snprintf curl_msnprintf
|
# define snprintf curl_msnprintf
|
||||||
# define vprintf curl_mvprintf
|
# define vprintf curl_mvprintf
|
||||||
# define vfprintf curl_mvfprintf
|
# define vfprintf curl_mvfprintf
|
||||||
# define vsprintf curl_mvsprintf
|
|
||||||
# define vsnprintf curl_mvsnprintf
|
# define vsnprintf curl_mvsnprintf
|
||||||
# define aprintf curl_maprintf
|
# define aprintf curl_maprintf
|
||||||
# define vaprintf curl_mvaprintf
|
# define vaprintf curl_mvaprintf
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, 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
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||||
libc5-based Linux systems. Only include it on system that are known to
|
libc5-based Linux systems. Only include it on system that are known to
|
||||||
require it! */
|
require it! */
|
||||||
#if defined(_AIX) || defined(NETWARE)
|
#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__)
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -83,8 +83,6 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void CURLM;
|
typedef void CURLM;
|
||||||
|
|
||||||
#ifdef HAVE_CURL_MULTI_SOCKET /* this is not set by anything yet */
|
|
||||||
|
|
||||||
#ifndef curl_socket_typedef
|
#ifndef curl_socket_typedef
|
||||||
/* Public socket typedef */
|
/* Public socket typedef */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -97,8 +95,6 @@ typedef int curl_socket_t;
|
|||||||
#define curl_socket_typedef
|
#define curl_socket_typedef
|
||||||
#endif /* curl_socket_typedef */
|
#endif /* curl_socket_typedef */
|
||||||
|
|
||||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() soon */
|
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() soon */
|
||||||
CURLM_OK,
|
CURLM_OK,
|
||||||
@@ -106,6 +102,8 @@ typedef enum {
|
|||||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||||
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||||
|
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
|
||||||
|
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
|
||||||
CURLM_LAST
|
CURLM_LAST
|
||||||
} CURLMcode;
|
} CURLMcode;
|
||||||
|
|
||||||
@@ -243,57 +241,14 @@ CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
|||||||
*/
|
*/
|
||||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||||
|
|
||||||
#ifdef HAVE_CURL_MULTI_SOCKET
|
|
||||||
/*
|
/*
|
||||||
* Name: curl_multi_socket() and
|
* Name: curl_multi_socket() and
|
||||||
* curl_multi_socket_all()
|
* curl_multi_socket_all()
|
||||||
*
|
*
|
||||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||||
* application to pass in one of the file descriptors that have been
|
* application to pass in one of the file descriptors that have been
|
||||||
* detected to have "action" on them and let libcurl perform. This
|
* detected to have "action" on them and let libcurl perform.
|
||||||
* allows libcurl to not have to scan through all possible file
|
* See man page for details.
|
||||||
* descriptors to check for this. The app is recommended to pass in
|
|
||||||
* the 'easy' argument (or set it to CURL_EASY_NONE) to make libcurl
|
|
||||||
* figure out the internal structure even faster and easier. If the
|
|
||||||
* easy argument is set to something else than CURL_EASY_NONE, the
|
|
||||||
* 's' (socket) argument will be ignored by libcurl.
|
|
||||||
*
|
|
||||||
* It also informs the application about updates in the socket (file
|
|
||||||
* descriptor) status by doing none, one or multiple calls to the
|
|
||||||
* curl_socket_callback. It thus updates the status with changes
|
|
||||||
* since the previous time this function was used. If 'callback' is
|
|
||||||
* NULL, no callback will be called. A status change may also be a
|
|
||||||
* new timeout only, having the same IN/OUT status as before.
|
|
||||||
*
|
|
||||||
* If a previous wait for socket action(s) timed out, you should call
|
|
||||||
* this function with the socket argument set to
|
|
||||||
* CURL_SOCKET_TIMEOUT. If you want to force libcurl to (re-)check
|
|
||||||
* all its internal sockets, and call the callback with status for
|
|
||||||
* all sockets no matter what the previous state is, you call
|
|
||||||
* curl_multi_socket_all() instead.
|
|
||||||
*
|
|
||||||
* curl_multi_perform() is thus the equivalent of calling
|
|
||||||
* curl_multi_socket_all(handle, NULL, NULL);
|
|
||||||
*
|
|
||||||
* IMPLEMENTATION: libcurl will need an internal hash table to map
|
|
||||||
* socket numbers to internal easy handles for the cases when 'easy'
|
|
||||||
* is set to CURL_EASY_NONE.
|
|
||||||
*
|
|
||||||
* Regarding the timeout argument in the callback: it is the timeout
|
|
||||||
* (in milliseconds) for waiting on action on this socket (and the
|
|
||||||
* given time period starts when the callback is called) until you
|
|
||||||
* should call curl_multi_socket() with the timeout stuff mentioned
|
|
||||||
* above. If "actions" happens on the socket before the timeout
|
|
||||||
* happens, remember that the timout timer keeps ticking until told
|
|
||||||
* otherwise.
|
|
||||||
*
|
|
||||||
* The "what" argument has one of five values:
|
|
||||||
*
|
|
||||||
* 0 CURL_POLL_NONE (0) - register, not interested in readiness
|
|
||||||
* 1 CURL_POLL_IN - register, interested in read readiness
|
|
||||||
* 2 CURL_POLL_OUT - register, interested in write readiness
|
|
||||||
* 3 CURL_POLL_INOUT - register, interested in both
|
|
||||||
* 4 CURL_POLL_REMOVE - deregister
|
|
||||||
*/
|
*/
|
||||||
#define CURL_POLL_NONE 0
|
#define CURL_POLL_NONE 0
|
||||||
#define CURL_POLL_IN 1
|
#define CURL_POLL_IN 1
|
||||||
@@ -301,25 +256,16 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
|||||||
#define CURL_POLL_INOUT 3
|
#define CURL_POLL_INOUT 3
|
||||||
#define CURL_POLL_REMOVE 4
|
#define CURL_POLL_REMOVE 4
|
||||||
|
|
||||||
#define CURL_EASY_NONE (CURL *)0
|
|
||||||
#define CURL_EASY_TIMEOUT (CURL *)0
|
|
||||||
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||||
|
|
||||||
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||||
curl_socket_t s, /* socket */
|
curl_socket_t s, /* socket */
|
||||||
int what, /* see above */
|
int what, /* see above */
|
||||||
long ms, /* timeout for wait */
|
|
||||||
void *userp); /* "private" pointer */
|
void *userp); /* "private" pointer */
|
||||||
|
|
||||||
CURLMcode curl_multi_socket(CURLM *multi_handle,
|
CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s);
|
||||||
curl_socket_t s,
|
|
||||||
CURL *easy,
|
|
||||||
curl_socket_callback callback,
|
|
||||||
void *userp); /* passed to callback */
|
|
||||||
|
|
||||||
CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
CURLMcode curl_multi_socket_all(CURLM *multi_handle);
|
||||||
curl_socket_callback callback,
|
|
||||||
void *userp); /* passed to callback */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Name: curl_multi_timeout()
|
* Name: curl_multi_timeout()
|
||||||
@@ -332,7 +278,39 @@ CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
|||||||
*/
|
*/
|
||||||
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
||||||
|
|
||||||
#endif /* HAVE_CURL_MULTI_SOCKET */
|
#undef CINIT /* re-using the same name as in curl.h */
|
||||||
|
|
||||||
|
#ifdef CURL_ISOCPP
|
||||||
|
#define CINIT(name,type,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number
|
||||||
|
#else
|
||||||
|
/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
|
||||||
|
#define LONG CURLOPTTYPE_LONG
|
||||||
|
#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
|
||||||
|
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
|
||||||
|
#define OFF_T CURLOPTTYPE_OFF_T
|
||||||
|
#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* This is the socket callback function pointer */
|
||||||
|
CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
|
||||||
|
|
||||||
|
/* This is the argument passed to the socket callback */
|
||||||
|
CINIT(SOCKETDATA, OBJECTPOINT, 2),
|
||||||
|
|
||||||
|
CURLMOPT_LASTENTRY /* the last unused */
|
||||||
|
} CURLMoption;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: curl_multi_setopt()
|
||||||
|
*
|
||||||
|
* Desc: Sets options for the multi handle.
|
||||||
|
*
|
||||||
|
* Returns: CURLM error code.
|
||||||
|
*/
|
||||||
|
CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||||
|
CURLMoption option, ...);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
|
@@ -45,7 +45,8 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
|||||||
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
||||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||||
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||||
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj
|
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj &
|
||||||
|
$(OBJ_DIR)\splay.obj
|
||||||
|
|
||||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
# | (__| |_| | _ <| |___
|
# | (__| |_| | _ <| |___
|
||||||
# \___|\___/|_| \_\_____|
|
# \___|\___/|_| \_\_____|
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
# Copyright (C) 1998 - 2006, 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
|
||||||
@@ -30,7 +30,8 @@ EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos $(DSP) \
|
|||||||
README.ares README.curlx makefile.dj config.dj libcurl.framework.make \
|
README.ares README.curlx makefile.dj config.dj libcurl.framework.make \
|
||||||
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \
|
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \
|
||||||
Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \
|
Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \
|
||||||
config-win32ce.h README.httpauth Makefile.Watcom README.hostip
|
config-win32ce.h README.httpauth Makefile.Watcom README.hostip \
|
||||||
|
README.multi_socket config-tpf.h
|
||||||
|
|
||||||
CLEANFILES = $(DSP)
|
CLEANFILES = $(DSP)
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
|||||||
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
||||||
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
||||||
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
||||||
select.c gtls.c sslgen.c tftp.c
|
select.c gtls.c sslgen.c tftp.c splay.c
|
||||||
|
|
||||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||||
@@ -18,6 +18,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
|||||||
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
||||||
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
||||||
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||||
gtls.h tftp.h sockaddr.h
|
gtls.h tftp.h sockaddr.h splay.h
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../openssl-0.9.8
|
OPENSSL_PATH = ../../openssl-0.9.8a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INSTDIR
|
ifndef INSTDIR
|
||||||
@@ -29,7 +29,7 @@ endif
|
|||||||
# Edit the vars below to change NLM target settings.
|
# Edit the vars below to change NLM target settings.
|
||||||
TARGET = libcurl
|
TARGET = libcurl
|
||||||
VERSION = $(LIBCURL_VERSION)
|
VERSION = $(LIBCURL_VERSION)
|
||||||
COPYR = Copyright (C) 1996 - 2005, Daniel Stenberg, <daniel@haxx.se>
|
COPYR = Copyright (C) 1996 - 2006, Daniel Stenberg, <daniel@haxx.se>
|
||||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
||||||
MTSAFE = YES
|
MTSAFE = YES
|
||||||
STACK = 64000
|
STACK = 64000
|
||||||
@@ -95,7 +95,7 @@ LD = nlmconv
|
|||||||
LDFLAGS = -T
|
LDFLAGS = -T
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||||
CFLAGS += -Wall # -pedantic
|
CFLAGS += -Wall # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
|
@@ -154,10 +154,10 @@ CFGSET = TRUE
|
|||||||
# release-ssl-dll
|
# release-ssl-dll
|
||||||
|
|
||||||
!IF "$(CFG)" == "release-ssl-dll"
|
!IF "$(CFG)" == "release-ssl-dll"
|
||||||
TARGET = $(LIB_NAME).dll
|
TARGET = $(LIB_NAME).lib
|
||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) $(SSLLIBS) $(LFLAGSSSL) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
@@ -480,6 +480,7 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\select.obj \
|
$(DIROBJ)\select.obj \
|
||||||
$(DIROBJ)\content_encoding.obj \
|
$(DIROBJ)\content_encoding.obj \
|
||||||
$(DIROBJ)\tftp.obj \
|
$(DIROBJ)\tftp.obj \
|
||||||
|
$(DIROBJ)\splay.obj \
|
||||||
$(RESOURCE)
|
$(RESOURCE)
|
||||||
|
|
||||||
all : $(TARGET)
|
all : $(TARGET)
|
||||||
|
@@ -54,7 +54,7 @@ and the Content-Encoding type is not checked.
|
|||||||
* The curl interface:
|
* The curl interface:
|
||||||
|
|
||||||
Use the --compressed option with curl to cause it to ask servers to compress
|
Use the --compressed option with curl to cause it to ask servers to compress
|
||||||
responses using deflate.
|
responses using any format supported by curl.
|
||||||
|
|
||||||
James Gallagher <jgallagher@gso.uri.edu>
|
James Gallagher <jgallagher@gso.uri.edu>
|
||||||
Dan Fandrich <dan@coneharvesters.com>
|
Dan Fandrich <dan@coneharvesters.com>
|
||||||
|
112
lib/README.multi_socket
Normal file
112
lib/README.multi_socket
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
Implementation of the curl_multi_socket API
|
||||||
|
|
||||||
|
Most of the design decisions and debates about this new API have already
|
||||||
|
been held on the curl-library mailing list a long time ago so I had a basic
|
||||||
|
idea on what approach to use. The main ideas of the new API are simply:
|
||||||
|
|
||||||
|
1 - The application can use whatever event system it likes as it gets info
|
||||||
|
from libcurl about what file descriptors libcurl waits for what action
|
||||||
|
on. (The previous API returns fd_sets which is very select()-centric).
|
||||||
|
|
||||||
|
2 - When the application discovers action on a single socket, it calls
|
||||||
|
libcurl and informs that there was action on this particular socket and
|
||||||
|
libcurl can then act on that socket/transfer only and not care about
|
||||||
|
any other transfers. (The previous API always had to scan through all
|
||||||
|
the existing transfers.)
|
||||||
|
|
||||||
|
The idea is that curl_multi_socket() calls a given callback with information
|
||||||
|
about what socket to wait for what action on, and the callback only gets
|
||||||
|
called if the status of that socket has changed.
|
||||||
|
|
||||||
|
In the API draft from before, we have a timeout argument on a per socket
|
||||||
|
basis and we also allowed curl_multi_socket() to pass in an 'easy handle'
|
||||||
|
instead of socket to allow libcurl to shortcut a lookup and work on the
|
||||||
|
affected easy handle right away. Both these turned out to be bad ideas.
|
||||||
|
|
||||||
|
The timeout argument was removed from the socket callback since after much
|
||||||
|
thinking I came to the conclusion that we really don't want to handle
|
||||||
|
timeouts on a per socket basis. We need it on a per transfer (easy handle)
|
||||||
|
basis and thus we can't provide it in the callbacks in a nice way. Instead,
|
||||||
|
we have to offer a curl_multi_timeout() that returns the largest amount of
|
||||||
|
time we should wait before we call the "timeout action" of libcurl, to
|
||||||
|
trigger the proper internal timeout action on the affected transfer. To get
|
||||||
|
this to work, I added a struct to each easy handle in which we store an
|
||||||
|
"expire time" (if any). The structs are then "splay sorted" so that we can
|
||||||
|
add and remove times from the linked list and yet somewhat swiftly figure
|
||||||
|
out 1 - how long time there is until the next timer expires and 2 - which
|
||||||
|
timer (handle) should we take care of now. Of course, the upside of all this
|
||||||
|
is that we get a curl_multi_timeout() that should also work with old-style
|
||||||
|
applications that use curl_multi_perform().
|
||||||
|
|
||||||
|
The easy handle argument was removed fom the curl_multi_socket() function
|
||||||
|
because having it there would require the application to do a socket to easy
|
||||||
|
handle conversion on its own. I find it very unlikely that applications
|
||||||
|
would want to do that and since libcurl would need such a lookup on its own
|
||||||
|
anyway since we didn't want to force applications to do that translation
|
||||||
|
code (it would be optional), it seemed like an unnecessary option.
|
||||||
|
|
||||||
|
Instead I created an internal "socket to easy handles" hash table that given
|
||||||
|
a socket (file descriptor) return the easy handle that waits for action on
|
||||||
|
that socket. This hash is made using the already existing hash code
|
||||||
|
(previously only used for the DNS cache).
|
||||||
|
|
||||||
|
To make libcurl be able to report plain sockets in the socket callback, I
|
||||||
|
had to re-organize the internals of the curl_multi_fdset() etc so that the
|
||||||
|
conversion from sockets to fd_sets for that function is only done in the
|
||||||
|
last step before the data is returned. I also had to extend c-ares to get a
|
||||||
|
function that can return plain sockets, as that library too returned only
|
||||||
|
fd_sets and that is no longer good enough. The changes done to c-ares have
|
||||||
|
been committed and are available in the c-ares CVS repository destined to be
|
||||||
|
included in the upcoming c-ares 1.3.1 release.
|
||||||
|
|
||||||
|
The 'shiper' tool is the test application I wrote that uses the new
|
||||||
|
curl_multi_socket() in its current state. It seems to be working and it uses
|
||||||
|
the API as it is documented and supposed to work. It is still using
|
||||||
|
select(), because I needed that during development (like until I had the
|
||||||
|
socket hash implemented etc) and because I haven't yet learned how to use
|
||||||
|
libevent or similar.
|
||||||
|
|
||||||
|
The hiper/shiper tools are very simple and initiates lots of connections and
|
||||||
|
have them running for the test period and then kills them all.
|
||||||
|
|
||||||
|
Since I wasn't done with the implementation until early January I haven't
|
||||||
|
had time to run very many measurements and checks, but I have done a few
|
||||||
|
runs with up to a few hundred connections (with a single active one). The
|
||||||
|
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
|
||||||
|
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
|
||||||
|
add connections, it certainly matches my in my opinion very ambitious goal.
|
||||||
|
We are now below the 60 microseconds "per socket action" goal. It is
|
||||||
|
destined to be somewhat higher the more connections we have since the hash
|
||||||
|
table gets more populated and the splay tree will grow etc.
|
||||||
|
|
||||||
|
Some tests at 7000 and 9000 connections showed that the socket hash lookup
|
||||||
|
is somewhat of a bottle neck. Its current implementation may be a bit too
|
||||||
|
limiting. It simply has a fixed-size array, and on each entry in the array
|
||||||
|
it has a linked list with entries. So the hash only checks which list to
|
||||||
|
scan through. The code I had used so for used a list with merely 7 slots (as
|
||||||
|
that is what the DNS hash uses) but with 7000 connections that would make an
|
||||||
|
average of 1000 nodes in each list to run through. I upped that to 97 slots
|
||||||
|
(I believe a prime is suitable) and noticed a significant speed increase. I
|
||||||
|
need to reconsider the hash implementation or use a rather large default
|
||||||
|
value like this. At 9000 connections I was still below 10us per call.
|
||||||
|
|
||||||
|
Status Right Now
|
||||||
|
|
||||||
|
The curl_multi_socket() API is implemented according to how it is
|
||||||
|
documented.
|
||||||
|
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_socket.html
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
|
||||||
|
http://curl.haxx.se/libcurl/c/curl_multi_setopt.html
|
||||||
|
|
||||||
|
What is Left for the curl_multi_socket API
|
||||||
|
|
||||||
|
1 - More measuring with more extreme number of connections
|
||||||
|
|
||||||
|
2 - More testing with actual URLs and complete from start to end transfers.
|
||||||
|
|
||||||
|
I'm quite sure we don't set expire times all over in the code properly, so
|
||||||
|
there is bound to be some timeout bugs left.
|
||||||
|
|
||||||
|
What it really takes is for me to commit the code and to make an official
|
||||||
|
release with it so that we get people "out there" to help out testing it.
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, 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
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user