Compare commits
254 Commits
curl-7_11_
...
curl-7_11_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c96f7f13da | ||
![]() |
1bdc4b2006 | ||
![]() |
3915fecf80 | ||
![]() |
f94f06825c | ||
![]() |
2ddbf8975a | ||
![]() |
68a3cbe384 | ||
![]() |
b9432d1296 | ||
![]() |
e202a29a9a | ||
![]() |
3755bffcc2 | ||
![]() |
2a0a305300 | ||
![]() |
70e2aadc18 | ||
![]() |
a1c8aaf666 | ||
![]() |
8ee470aaeb | ||
![]() |
37e4858cd0 | ||
![]() |
a27072bebb | ||
![]() |
47059f45fe | ||
![]() |
daced8041d | ||
![]() |
b053ae6a65 | ||
![]() |
42f60ecb36 | ||
![]() |
550862f41a | ||
![]() |
6838f74fe0 | ||
![]() |
2ff30d067c | ||
![]() |
84406b3e2c | ||
![]() |
c323969bdd | ||
![]() |
43cbbdbea0 | ||
![]() |
1d3f76df71 | ||
![]() |
33cb93ad0b | ||
![]() |
4dc9179f4b | ||
![]() |
26a5ec9aa0 | ||
![]() |
883ea3113c | ||
![]() |
62b7c08bb3 | ||
![]() |
a85fa66cc8 | ||
![]() |
9ba010c629 | ||
![]() |
3ef3f2b6f0 | ||
![]() |
1401d909e8 | ||
![]() |
3233322622 | ||
![]() |
e373f1fd73 | ||
![]() |
dc25cd6f3a | ||
![]() |
0e31d41d4e | ||
![]() |
b7a7600465 | ||
![]() |
111a2f3057 | ||
![]() |
760cecac8d | ||
![]() |
6f8b4395ec | ||
![]() |
5506f8767c | ||
![]() |
5887945828 | ||
![]() |
25e98179be | ||
![]() |
78ebe3fa5a | ||
![]() |
a8e8e51b14 | ||
![]() |
f97d194934 | ||
![]() |
4661cc7403 | ||
![]() |
bc11929395 | ||
![]() |
caf37bc92e | ||
![]() |
5de447b0cb | ||
![]() |
5dbaced4a2 | ||
![]() |
43f8a1f5de | ||
![]() |
f57efa1899 | ||
![]() |
592522ceaf | ||
![]() |
4f84e6d9e2 | ||
![]() |
6f08903f07 | ||
![]() |
220cd010bd | ||
![]() |
68e8a0f0d9 | ||
![]() |
b23dbf9f34 | ||
![]() |
1d0b5b507a | ||
![]() |
b83d8104cd | ||
![]() |
bf6e1053cf | ||
![]() |
c3dd928e29 | ||
![]() |
aba6c2b89d | ||
![]() |
9c0a386246 | ||
![]() |
bba3bb7556 | ||
![]() |
c1422864b5 | ||
![]() |
31a693b99a | ||
![]() |
804534fbc9 | ||
![]() |
1bc6532c16 | ||
![]() |
b48bf7470d | ||
![]() |
1ca9ce5ef4 | ||
![]() |
789f2ecbe7 | ||
![]() |
ee7d1d0701 | ||
![]() |
4e3aa250c4 | ||
![]() |
3647a6ddcd | ||
![]() |
79aaa85a51 | ||
![]() |
392a543eff | ||
![]() |
eb6345de60 | ||
![]() |
0fd3b7a00a | ||
![]() |
bd51b80fa5 | ||
![]() |
15c900839b | ||
![]() |
2fd463e979 | ||
![]() |
de8660a96a | ||
![]() |
1e9cb272f1 | ||
![]() |
72b1144b8c | ||
![]() |
348fe0e210 | ||
![]() |
cf1f46e1ca | ||
![]() |
f052cbee19 | ||
![]() |
1f5e8670e1 | ||
![]() |
3b491d0f73 | ||
![]() |
26a2b8d26d | ||
![]() |
a7fd6f9007 | ||
![]() |
8ed44e8dfb | ||
![]() |
f617c1131a | ||
![]() |
5ca47f19d7 | ||
![]() |
9044fcbb5f | ||
![]() |
7a82810b59 | ||
![]() |
0ccdf3d0e6 | ||
![]() |
ca7f0852df | ||
![]() |
780b962336 | ||
![]() |
bbeb840916 | ||
![]() |
f4ec465bfc | ||
![]() |
57c86a953d | ||
![]() |
0fff8656e9 | ||
![]() |
7b929636ee | ||
![]() |
76835a2e00 | ||
![]() |
1b171b02ac | ||
![]() |
a8dc362572 | ||
![]() |
7c72f8ee6c | ||
![]() |
c39a54609b | ||
![]() |
ce6b767b47 | ||
![]() |
7ba4d3464f | ||
![]() |
03def138fe | ||
![]() |
9d99af5329 | ||
![]() |
c8d850dbad | ||
![]() |
01ea357744 | ||
![]() |
ad9e83a90f | ||
![]() |
6c9d96e811 | ||
![]() |
f840e5192c | ||
![]() |
ba9272dd05 | ||
![]() |
675db3a211 | ||
![]() |
1fc7ff878e | ||
![]() |
b643d148b1 | ||
![]() |
5804c995e1 | ||
![]() |
13a6f85320 | ||
![]() |
8b4582f111 | ||
![]() |
cd3bf7c56f | ||
![]() |
ee1595dcd5 | ||
![]() |
310086deed | ||
![]() |
5d27f50f2f | ||
![]() |
9d0330d5bd | ||
![]() |
d5074f74bb | ||
![]() |
ea0cf7c87b | ||
![]() |
a56164c8e0 | ||
![]() |
cd95bb22ea | ||
![]() |
1745ecd8ac | ||
![]() |
75d66b9c62 | ||
![]() |
2ff9f55001 | ||
![]() |
ce446dbdc2 | ||
![]() |
dd2add82ee | ||
![]() |
40d9855df2 | ||
![]() |
ecf7adba15 | ||
![]() |
931c847e2b | ||
![]() |
8230d9bff8 | ||
![]() |
64cc14e9e6 | ||
![]() |
d5b8971ff3 | ||
![]() |
7ea837a18c | ||
![]() |
b8b8473b6d | ||
![]() |
894dbae455 | ||
![]() |
2c11425868 | ||
![]() |
a2ea0abf7f | ||
![]() |
be8f8e66a4 | ||
![]() |
9fadfffb9d | ||
![]() |
76f23acfa1 | ||
![]() |
6950aeafcc | ||
![]() |
cd160a66c9 | ||
![]() |
a7376968d2 | ||
![]() |
fd96a2af34 | ||
![]() |
a90cd1a45c | ||
![]() |
8e92600ddd | ||
![]() |
5e75c310ba | ||
![]() |
20cab07c29 | ||
![]() |
f466d7a6f1 | ||
![]() |
dc46f535ae | ||
![]() |
27fd5d6d6a | ||
![]() |
18a3c3302f | ||
![]() |
97959a00d7 | ||
![]() |
5e92b2906b | ||
![]() |
126ed14313 | ||
![]() |
712d0374f7 | ||
![]() |
4b49b2e3cf | ||
![]() |
d85c21994f | ||
![]() |
6b33a5f954 | ||
![]() |
ed22afe5fb | ||
![]() |
843391c745 | ||
![]() |
ad6699e0c4 | ||
![]() |
43137cf595 | ||
![]() |
db6dc49b0b | ||
![]() |
593170d1de | ||
![]() |
0eace2fefe | ||
![]() |
abd65e21c6 | ||
![]() |
e21104a865 | ||
![]() |
3ecf63fa66 | ||
![]() |
762dcf0780 | ||
![]() |
75ee9b5333 | ||
![]() |
e161bdc5be | ||
![]() |
bb3d6e8552 | ||
![]() |
189c2f4989 | ||
![]() |
f28389c87b | ||
![]() |
7461592a16 | ||
![]() |
50b0e72f7b | ||
![]() |
76e73cfec8 | ||
![]() |
5d8ec172a6 | ||
![]() |
0953140b53 | ||
![]() |
6c2825997a | ||
![]() |
accc6eb91a | ||
![]() |
eab8cdc640 | ||
![]() |
dc9d0f256d | ||
![]() |
b60d6404d8 | ||
![]() |
08fe4b3210 | ||
![]() |
0e60a118d0 | ||
![]() |
4b78b4124e | ||
![]() |
0d6d9af7ab | ||
![]() |
41cd36b830 | ||
![]() |
242be55771 | ||
![]() |
7cf47ea5b5 | ||
![]() |
6fb0012833 | ||
![]() |
9d1ce9c0df | ||
![]() |
5947e4e9fd | ||
![]() |
e992aa6a54 | ||
![]() |
2cf218610e | ||
![]() |
fe6f0aeb26 | ||
![]() |
bd04c6fb67 | ||
![]() |
c5637baa06 | ||
![]() |
f8426a2c44 | ||
![]() |
0c791d1e76 | ||
![]() |
c4a89d29f6 | ||
![]() |
306ff5649a | ||
![]() |
1c652dfc5d | ||
![]() |
1f61e7f8f4 | ||
![]() |
1a5f190e47 | ||
![]() |
570033448c | ||
![]() |
f44b655513 | ||
![]() |
0aa720fa26 | ||
![]() |
d44f3f84f8 | ||
![]() |
d426db3d27 | ||
![]() |
0fd88d7c8f | ||
![]() |
4e84ac4db8 | ||
![]() |
da5c8a121f | ||
![]() |
76c36688d0 | ||
![]() |
651c8d3bc4 | ||
![]() |
a8a946d71d | ||
![]() |
c5c005609e | ||
![]() |
97886f9353 | ||
![]() |
a784bd0797 | ||
![]() |
4aacf65678 | ||
![]() |
dd1ba7633e | ||
![]() |
a4ea5a4054 | ||
![]() |
69060b1382 | ||
![]() |
a6562ea77d | ||
![]() |
ad3563096a | ||
![]() |
c5f02c1986 | ||
![]() |
7ef5d20cad | ||
![]() |
98b619c3a7 | ||
![]() |
5b75919f95 | ||
![]() |
20b76e09e3 | ||
![]() |
67fca4cb01 | ||
![]() |
606715b2cd | ||
![]() |
ce04b35032 | ||
![]() |
ec7f244ee9 |
1572
CHANGES.2003
Normal file
1572
CHANGES.2003
Normal file
File diff suppressed because it is too large
Load Diff
@@ -82,8 +82,8 @@ amiga:
|
|||||||
cd ./src && make -f makefile.amiga
|
cd ./src && make -f makefile.amiga
|
||||||
|
|
||||||
netware:
|
netware:
|
||||||
cd lib && make -f Makefile.netware
|
cd lib && make -f Makefile.netware
|
||||||
cd src && make -f Makefile.netware
|
cd src && make -f Makefile.netware
|
||||||
|
|
||||||
unix: all
|
unix: all
|
||||||
|
|
||||||
|
17
README
17
README
@@ -32,25 +32,30 @@ WEB SITE
|
|||||||
|
|
||||||
Sweden -- http://curl.haxx.se/
|
Sweden -- http://curl.haxx.se/
|
||||||
Australia -- http://curl.planetmirror.com/
|
Australia -- http://curl.planetmirror.com/
|
||||||
Estonia -- http://curl.dope-brothers.com/
|
Denmark -- http://curl.cofman.dk/
|
||||||
|
Estonia -- http://curl.wildyou.net/
|
||||||
Germany -- http://curl.mirror.at.stealer.net/
|
Germany -- http://curl.mirror.at.stealer.net/
|
||||||
|
Germany -- http://curl.netmirror.org/
|
||||||
Russia -- http://curl.tsuren.net/
|
Russia -- http://curl.tsuren.net/
|
||||||
Thailand -- http://curl.siamu.ac.th/
|
Thailand -- http://curl.siamu.ac.th/
|
||||||
US (CA) -- http://curl.mirror.redwire.net/
|
US (CA) -- http://curl.mirror.redwire.net/
|
||||||
|
US -- http://curl.signal42.com/
|
||||||
|
|
||||||
DOWNLOAD
|
DOWNLOAD
|
||||||
|
|
||||||
The official download mirror sites are:
|
The official download mirror sites are:
|
||||||
|
|
||||||
Australia -- http://curl.planetmirror.com/download/
|
Australia -- http://curl.planetmirror.com/download.html
|
||||||
Estonia -- http://curl.dope-brothers.com/download/
|
Estonia -- http://curl.wildyou.net/download.html
|
||||||
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
|
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
|
||||||
|
Germany -- http://curl.mirror.at.stealer.net/download.html
|
||||||
|
Germany -- http://curl.netmirror.org/download.html
|
||||||
Hongkong -- http://www.execve.net/curl/
|
Hongkong -- http://www.execve.net/curl/
|
||||||
Russia -- http://curl.tsuren.net/download/
|
Russia -- http://curl.tsuren.net/download.html
|
||||||
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
|
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||||
Sweden -- http://cool.haxx.se/curl/
|
Sweden -- http://cool.haxx.se/curl/
|
||||||
Thailand -- http://curl.siamu.ac.th/download/
|
Thailand -- http://curl.siamu.ac.th/download.html
|
||||||
US (CA) -- http://curl.mirror.redwire.net/download/
|
US (CA) -- http://curl.mirror.redwire.net/download.html
|
||||||
|
|
||||||
CVS
|
CVS
|
||||||
|
|
||||||
|
129
RELEASE-NOTES
129
RELEASE-NOTES
@@ -1,89 +1,74 @@
|
|||||||
Curl and libcurl 7.11.1. A bugfix release.
|
Curl and libcurl 7.11.2. A bugfix release.
|
||||||
|
|
||||||
Public curl release number: 79
|
Public curl release number: 80
|
||||||
Releases counted from the very beginning: 106
|
Releases counted from the very beginning: 107
|
||||||
Available command line options: 94
|
Available command line options: 94
|
||||||
Available curl_easy_setopt() options: 112
|
Available curl_easy_setopt() options: 113
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o CURLOPT_POSTFIELDSIZE_LARGE added to offer POSTs larger than 2GB
|
o removed maximum user+password+hostname size limit
|
||||||
o CURL_VERSION_LARGEFILE is a feature bit returned by libcurls that feature
|
o removed maximum dir depth limit for FTP
|
||||||
large file support
|
o the ares build now requires c-ares 1.2.0 or later
|
||||||
o libcurl only requires winsock 1.1 on windows now
|
o --tcp-nodelay and CURLOPT_TCP_NODELAY were added
|
||||||
o when doing FTP, curl now sends QUIT before disconnecting
|
o curl/curlver.h contains the libcurl version info now
|
||||||
o name resolves can now timeout on windows too
|
|
||||||
o $HOME is now recognized better when looking for .netrc files
|
|
||||||
o now re-uses the ares handle when re-using curl handles
|
|
||||||
o SO_BINDTODEVICE is used for network interface binding
|
|
||||||
o configure --disable-manual disables the built-in huge manual from the
|
|
||||||
command line tool
|
|
||||||
o the default Accept: header used in HTTP requests changed
|
|
||||||
o asynch dns lookups now require the c-ares library
|
|
||||||
o curl --socks can be used to set a SOCKS5 proxy to use
|
|
||||||
o response-headers received after a (proxy) CONNECT request are now passed
|
|
||||||
to the header callback just like other headers
|
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o builds and runs on Novell NetWare
|
o configure --disable-manual works better
|
||||||
o Windows builds now report OS as "i386-pc-win32"
|
o removed a memory leak when doing a windows threaded resolve and it failed
|
||||||
o received signals during SSL connect is handled better
|
o --proxy-ntlm now checks if libcurl supports NTLM before using it
|
||||||
o improved PUT/POST with NTLM/Digest authentication
|
o minor --fail with authentication bugfix
|
||||||
o following redirects and doing NTLM/Digest (where the first connection gets
|
o CURLOPT_IPRESOLVE set to CURL_IPRESOLVE_V6 will now cause a returned error
|
||||||
closed) with the multi interface work better now
|
if the host only can resolve ipv4 addresses
|
||||||
o file: progress meter and getinfo variables work now
|
o curl -4/-6 now actually sets the requested option in libcurl
|
||||||
o CURLOPT_FRESH_CONNECT and CURLAUTH_NTLM now work when set together
|
o multi interface on Windows without ares works again
|
||||||
o share interface usage without (un)lock functions segfaulted
|
o improved resolution for the CURLINFO_*_TIME info variables
|
||||||
o --limit-rate no longer cripples the --speed-limit feature
|
o getting only a 100 Continue response and nothing else, when talking HTTP,
|
||||||
o fixed verbose output problem with ipv6-enabled re-used connections
|
is now treated as an error by libcurl
|
||||||
o fixed the socks5 code to check version in the socks response properly
|
o fixed minor memory leak in libcurl for Windows when statically linked
|
||||||
o dns cache bug - fixed the 'inuse' counter
|
o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better
|
||||||
o large file fix for Content-Length
|
o --limit-rate with high speed rates is a lot more accurate now, and supports
|
||||||
o better docs for the share interface
|
limiting to speeds >2GB/sec on systems with Large File support.
|
||||||
o several configure fixes for mingw/msys
|
o curl_strnqual.3 "refer-to" man page fix
|
||||||
o setting a Host: header is no longer affecting the Host: header used when
|
o fixed a minor very old progress meter final update bug
|
||||||
libcurl follows a Location:
|
o added checks for a working NI_WITHSCOPEID before that is used
|
||||||
o fixed numerous compiler warnings on several operating systems and compilers
|
o fixed a flaw that prevented ares name resolve timeouts to occur
|
||||||
o PUTing from stdin couldn't disable chunked transfer-encoding
|
o getting user name from http_proxy env variable works now
|
||||||
o corrected the mingw makefiles
|
o fixed too early name resolve timeouts with ares
|
||||||
o improved the configure libz detection
|
o HTTP Digest "re-negotiation" works now
|
||||||
o fixed EPRT/PORT use when doing FTP on ipv6-enabled AIX hosts
|
o CURLOPT_FAILONERROR (-f/--fail) works with all kinds of authentication
|
||||||
o *nroff commands that only support -mandoc and not -man are now supported
|
o better thread-safety thanks to the internal strerror() replacement
|
||||||
(for the built-in manual text in the command line tool)
|
o better thread-safety on AIX thanks to better function detection
|
||||||
o fixed the unconditional #include of config.h in hugehelp.c
|
o minor ipv6 build fix for windows
|
||||||
o builds fine on MPE/iX
|
o the test suite runs fine with mingw-built curl
|
||||||
o upload using chunked transfer-encoding now sends the last chunk properly
|
o the postit2.c example works now
|
||||||
teriminated with an extra CRLF
|
o better error message when --interface fails on windows
|
||||||
o Fixed the progress meter display for files >2GB
|
o the progress meter now displays very long times better
|
||||||
o persistant connections over a proxy messed up the proxy name/password
|
o CURLINFO_CONTENT_LENGTH_DOWNLOAD with CURLOPT_NOBODY set TRUE now works
|
||||||
o the socks5 code segfaulted if no username/password was set
|
o passwords longer than 14 letters work with NTLM
|
||||||
o the *_LARGE options now take curl_off_t types as parameters and this will
|
o 'make netware' in the root dir works now
|
||||||
make it possible to handle large files on windows too
|
o builds fine on VMS again and even nicer than before
|
||||||
o builds with large file support even on systems without strtoll()
|
|
||||||
|
|
||||||
Other curl-related news since the previous public release:
|
Other curl-related news since the previous public release:
|
||||||
|
|
||||||
o Many platforms are being used to autobuild and autotest curl on a daily
|
o PycURL 7.11.1 was released: http://pycurl.sf.net/
|
||||||
basis. Please join in and test curl on your systems:
|
o CURLHandle 1.9 was released: http://curlhandle.sourceforge.net/
|
||||||
http://curl.haxx.se/auto/
|
o A curl module for the Q language was announced:
|
||||||
o the curl mailing lists moved, (re-)subscribe to the new ones from here:
|
http://q-lang.sourceforge.net/
|
||||||
http://curl.haxx.se/mail/
|
o c-ares 1.2.0 was released: http://daniel.haxx.se/projects/c-ares/
|
||||||
o c-ares 1.1.0 was relased: http://daniel.haxx.se/projects/c-ares/
|
o New curl web mirrors:
|
||||||
o TclCurl 0.11.0 was released:
|
Germany http://curl.netmirror.org/
|
||||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
USA http://curl.signal42.com/
|
||||||
o PycURL 7.11.0 was released: http://pycurl.sourceforge.net/
|
Denmark http://curl.cofman.dk/
|
||||||
o the libcurl D binding was released:
|
|
||||||
http://www.atari-soldiers.com/libcurl.html
|
|
||||||
o new Estonian web site mirror: http://curl.dope-brothers.com/
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
Gisle Vanem, Vincent Bronner, Richard Bramante, Dirk Manske, Dan Fandrich,
|
Thomas Schwinge, Marty Kuhrt, G<>nter Knauf, Kevin Roth, Glen Nakamura, Gisle
|
||||||
Ken Hirsch, Stadler Stephan, Domenico Andreoli, Patrick Smith, Tor Arntsen,
|
Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz
|
||||||
Andr<64>s Garc<72>a, Tim Baker, Len Krause, Gilad, Ken Rastatter, P R Schaffner,
|
Wark, Andr<64>s Garc<72>a, Robin Kay, Alan Pinstein, David Byron, Nathan
|
||||||
Greg Hewgill, Ben Greear, Jeff Lawson, Grigory Entin, Doug Porter, David
|
O'Sullivan, Erwin Authried
|
||||||
Byron, Andy Serpa, Joe Halpin, Christopher R. Palmer, G<>nter Knauf
|
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
66
TODO-RELEASE
66
TODO-RELEASE
@@ -3,51 +3,35 @@ Issues not sorted in any particular order.
|
|||||||
UNASSIGNED means that no person has publicly stated to work on the issue.
|
UNASSIGNED means that no person has publicly stated to work on the issue.
|
||||||
DELETE means the issue is subject for dismissal
|
DELETE means the issue is subject for dismissal
|
||||||
|
|
||||||
To get fixed in 7.11.1 (planned release in March 2004)
|
To get fixed in 7.11.2 (planned release late April 2004)
|
||||||
======================
|
======================
|
||||||
|
|
||||||
To get fixed in 7.11.2 (planned release May/June 2004)
|
|
||||||
======================
|
|
||||||
|
|
||||||
6. REST fix for servers not behaving well on >2GB requests. This should fail
|
To get fixed in 7.12.0 (no date)
|
||||||
if the server doesn't set the pointer to the requested index. The tricky
|
|
||||||
part is to figure out if the server did the right thing or not.
|
|
||||||
UNASSIGNED
|
|
||||||
|
|
||||||
10. Anton Fedorov's "dumpcert" patch UNASSIGNED
|
|
||||||
http://curl.haxx.se/mail/lib-2004-03/0088.html
|
|
||||||
|
|
||||||
14. Evaluate/apply Gertjan van Wingerde's SSL patches, UNASSIGNED
|
|
||||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
|
||||||
|
|
||||||
23. Peter Sylvester's "Most Significant Common Name" change. Feedback welcome.
|
|
||||||
At least the UTF8 conversion and comparison should be done. Patch?
|
|
||||||
UNASSIGNED
|
|
||||||
|
|
||||||
24. Make the progress meter use one digit more for the hour time fields.
|
|
||||||
Accomplish this by removing one of the times displayed.
|
|
||||||
|
|
||||||
27. Put the version defines in their own header file, so that lib/libcurl.rc
|
|
||||||
can include only that to reduce problems with MSVC.
|
|
||||||
|
|
||||||
28. Optimize the way libcurl uses CWD on each new request over a persistent
|
|
||||||
connection (on FTP) even if it doesn't have to.
|
|
||||||
|
|
||||||
29. Define USE_NTRESPONSES in the NTLM code to work properly with >14 letter
|
|
||||||
passwords against IIS servers. Requires test cases to be updated
|
|
||||||
accordingly. #915609
|
|
||||||
|
|
||||||
30. Digest re-negotiation is not supported, we wrongly assume a new 401
|
|
||||||
response to signify an authenticaion error. We need to detect the
|
|
||||||
difference between a 401 due to a bad Digest authorization header and a
|
|
||||||
401 because the server wants to re-negotiate.
|
|
||||||
|
|
||||||
Mitz Wark provided details and traces here:
|
|
||||||
http://curl.haxx.se/mail/lib-2004-03/0299.html
|
|
||||||
|
|
||||||
To get fixed in 7.12.0
|
|
||||||
======================
|
======================
|
||||||
|
|
||||||
25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
|
25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
|
||||||
|
Code already in CVS. Messages need overview/improvements.
|
||||||
|
Medium prio.
|
||||||
|
|
||||||
26. i18n of error messages
|
26. i18n of error messages?
|
||||||
|
Low prio. Nobody has volunteered. Subject for removal.
|
||||||
|
|
||||||
|
33. Add a function to replace the malloc-calls within libcurl.
|
||||||
|
Low prio. Seshubabu Pasam works on this.
|
||||||
|
|
||||||
|
35. Rearrange lib/hostip.c to reduce the amount of #ifdefs and make it easier
|
||||||
|
to understand and edit. Daniel works on this. See
|
||||||
|
http://curl.haxx.se/beta/hostip-cleanup1.patch
|
||||||
|
Medium prio.
|
||||||
|
|
||||||
|
36. Add support for a threaded getaddrinfo() on Windows and IPv6 enabled
|
||||||
|
libcurl.
|
||||||
|
|
||||||
|
37. Configure option "--with-libidn" to support IDNA (Internationalising
|
||||||
|
Domain Names in Applications). Translate to/from ACE encoded domain
|
||||||
|
names as needed.
|
||||||
|
|
||||||
|
38. Make the ldap protocol work with Windows' built-in LDAP-client.
|
||||||
|
I.e. dynamically link to WLDAP32.DLL and add ldap URL parsing
|
||||||
|
(WLDAP32.DLL doesn't have an UTF-8 ldap_url_parse).
|
||||||
|
161
acinclude.m4
161
acinclude.m4
@@ -64,7 +64,7 @@ dnl the code was bad, try a different program now, test 3
|
|||||||
],[
|
],[
|
||||||
/* ioctlsocket source code */
|
/* ioctlsocket source code */
|
||||||
int socket;
|
int socket;
|
||||||
int flags = ioctlsocket(socket, FIONBIO, &flags);
|
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||||
],[
|
],[
|
||||||
dnl ioctlsocket test was good
|
dnl ioctlsocket test was good
|
||||||
nonblock="ioctlsocket"
|
nonblock="ioctlsocket"
|
||||||
@@ -245,7 +245,8 @@ AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
void main(void) {
|
int main(void)
|
||||||
|
{
|
||||||
struct addrinfo hints, *ai;
|
struct addrinfo hints, *ai;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -254,11 +255,9 @@ void main(void) {
|
|||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||||
if (error) {
|
if (error) {
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
|
||||||
else {
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
],[
|
],[
|
||||||
ac_cv_working_getaddrinfo="yes"
|
ac_cv_working_getaddrinfo="yes"
|
||||||
@@ -276,10 +275,72 @@ if test "$ac_cv_working_getaddrinfo" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl ************************************************************
|
||||||
|
dnl check for working NI_WITHSCOPEID in getnameinfo()
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([CURL_CHECK_NI_WITHSCOPEID],[
|
||||||
|
AC_CACHE_CHECK(for working NI_WITHSCOPEID, ac_cv_working_ni_withscopeid,[
|
||||||
|
|
||||||
|
AC_RUN_IFELSE([[
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
int sslen = sizeof(ss);
|
||||||
|
int rc;
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
int fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
|
if(fd < 0) {
|
||||||
|
perror("socket()");
|
||||||
|
return 1; /* couldn't create socket of either kind */
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = getsockname(fd, (struct sockaddr *)&ss, &sslen);
|
||||||
|
if(rc) {
|
||||||
|
perror("getsockname()");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf),
|
||||||
|
NULL, 0,
|
||||||
|
NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID);
|
||||||
|
|
||||||
|
if(rc) {
|
||||||
|
printf("rc = %s\n", gai_strerror(rc));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* everything works fine, use NI_WITHSCOPEID! */
|
||||||
|
#else
|
||||||
|
return 4; /* we don't seem to have the definition, don't use it */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
]],
|
||||||
|
dnl program worked:
|
||||||
|
[ ac_cv_working_ni_withscopeid="yes" ],
|
||||||
|
dnl program failed:
|
||||||
|
[ ac_cv_working_ni_withscopeid="no" ],
|
||||||
|
dnl we cross-compile:
|
||||||
|
[ ac_cv_working_ni_withscopeid="yes" ]
|
||||||
|
) dnl end of AC_RUN_IFELSE
|
||||||
|
|
||||||
|
]) dnl end of AC_CACHE_CHECK
|
||||||
|
|
||||||
|
if test "$ac_cv_working_ni_withscopeid" = "yes"; then
|
||||||
|
AC_DEFINE(HAVE_NI_WITHSCOPEID, 1,
|
||||||
|
[Define if NI_WITHSCOPEID exists and works])
|
||||||
|
fi
|
||||||
|
|
||||||
|
]) dnl end of AC_DEFUN
|
||||||
|
|
||||||
|
|
||||||
AC_DEFUN([CURL_CHECK_LOCALTIME_R],
|
AC_DEFUN([CURL_CHECK_LOCALTIME_R],
|
||||||
[
|
[
|
||||||
dnl check for a few thread-safe functions
|
dnl check for localtime_r
|
||||||
AC_CHECK_FUNCS(localtime_r,[
|
AC_CHECK_FUNCS(localtime_r,[
|
||||||
AC_MSG_CHECKING(whether localtime_r is declared)
|
AC_MSG_CHECKING(whether localtime_r is declared)
|
||||||
AC_EGREP_CPP(localtime_r,[
|
AC_EGREP_CPP(localtime_r,[
|
||||||
@@ -295,6 +356,92 @@ AC_DEFUN([CURL_CHECK_LOCALTIME_R],
|
|||||||
AC_MSG_RESULT(no))])])
|
AC_MSG_RESULT(no))])])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl This function checks for strerror_r(). If it isn't found at first, it
|
||||||
|
dnl retries with _THREAD_SAFE defined, as that is what AIX seems to require
|
||||||
|
dnl in order to find this function.
|
||||||
|
dnl
|
||||||
|
dnl If the function is found, it will then proceed to check how the function
|
||||||
|
dnl actually works: glibc-style or POSIX-style.
|
||||||
|
dnl
|
||||||
|
dnl glibc:
|
||||||
|
dnl char *strerror_r(int errnum, char *buf, size_t n);
|
||||||
|
dnl
|
||||||
|
dnl What this one does is to return the error string (no surprises there),
|
||||||
|
dnl but it doesn't usually copy anything into buf! The 'buf' and 'n'
|
||||||
|
dnl parameters are only meant as an optional working area, in case strerror_r
|
||||||
|
dnl needs it. A quick test on a few systems shows that it's generally not
|
||||||
|
dnl touched at all.
|
||||||
|
dnl
|
||||||
|
dnl POSIX:
|
||||||
|
dnl int strerror_r(int errnum, char *buf, size_t n);
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([CURL_CHECK_STRERROR_R],
|
||||||
|
[
|
||||||
|
dnl determine of strerror_r is present
|
||||||
|
AC_CHECK_FUNCS(strerror_r,[
|
||||||
|
AC_MSG_CHECKING(whether strerror_r is declared)
|
||||||
|
AC_EGREP_CPP(strerror_r,[
|
||||||
|
#include <string.h>],[
|
||||||
|
strerror_r="yes"
|
||||||
|
AC_MSG_RESULT(yes)],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
AC_MSG_CHECKING(whether strerror_r with -D_THREAD_SAFE is declared)
|
||||||
|
AC_EGREP_CPP(strerror_r,[
|
||||||
|
#define _THREAD_SAFE
|
||||||
|
#include <string.h>],[
|
||||||
|
strerror_r="yes"
|
||||||
|
CPPFLAGS="-D_THREAD_SAFE $CPPFLAGS"
|
||||||
|
AC_MSG_RESULT(yes)],
|
||||||
|
AC_MSG_RESULT(no))])])
|
||||||
|
|
||||||
|
if test "x$strerror_r" = "xyes"; then
|
||||||
|
dnl determine if this strerror_r() is glibc or POSIX
|
||||||
|
AC_MSG_CHECKING([for a glibc strerror_r API])
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
int
|
||||||
|
main () {
|
||||||
|
char buffer[1024]; /* big enough to play with */
|
||||||
|
char *string =
|
||||||
|
strerror_r(EACCES, buffer, sizeof(buffer));
|
||||||
|
/* this should've returned a string */
|
||||||
|
if(!string || !string[0])
|
||||||
|
return 99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()])
|
||||||
|
AC_MSG_RESULT([yes]),
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for a POSIX strerror_r API])
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
int
|
||||||
|
main () {
|
||||||
|
char buffer[1024]; /* big enough to play with */
|
||||||
|
int error =
|
||||||
|
strerror_r(EACCES, buffer, sizeof(buffer));
|
||||||
|
/* This should've returned zero, and written an error string in the
|
||||||
|
buffer.*/
|
||||||
|
if(!buffer[0] || error)
|
||||||
|
return 99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
|
||||||
|
AC_MSG_RESULT([yes]),
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
)
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([CURL_CHECK_INET_NTOA_R],
|
AC_DEFUN([CURL_CHECK_INET_NTOA_R],
|
||||||
[
|
[
|
||||||
dnl determine if function definition for inet_ntoa_r exists.
|
dnl determine if function definition for inet_ntoa_r exists.
|
||||||
|
26
ares/CHANGES
26
ares/CHANGES
@@ -1,3 +1,27 @@
|
|||||||
|
Changelog for the c-ares project
|
||||||
|
|
||||||
|
Version 1.2.0 (April 13, 2004)
|
||||||
|
|
||||||
|
* April 2, 2004
|
||||||
|
- Updated various man pages to look nicer when converted to HTML on the web
|
||||||
|
site.
|
||||||
|
|
||||||
|
* April 1, 2004
|
||||||
|
- Dirk Manske provided a new function that is now named ares_cancel(). It is
|
||||||
|
used to cancel/cleanup a resolve/request made using ares functions on the
|
||||||
|
given ares channel. It does not destroy/kill the ares channel itself.
|
||||||
|
|
||||||
|
- Dominick Meglio cleaned up the formatting in several man pages.
|
||||||
|
|
||||||
|
* March 30, 2004
|
||||||
|
- Dominick Meglio's new ares_expand_string. A helper function when decoding
|
||||||
|
incoming DNS packages.
|
||||||
|
|
||||||
|
- Daniel Stenberg modified the Makefile.in to use a for loop for the man page
|
||||||
|
installation to improve overview and make it easier to add man pages.
|
||||||
|
|
||||||
|
Version 1.1.0 (March 11, 2004)
|
||||||
|
|
||||||
* March 9, 2004
|
* March 9, 2004
|
||||||
- Gisle Vanem improved build on Windows.
|
- Gisle Vanem improved build on Windows.
|
||||||
|
|
||||||
@@ -74,3 +98,5 @@ Version 1.0-pre1 (8 October 2003)
|
|||||||
- Daniel Stenberg adjusted the windows port
|
- Daniel Stenberg adjusted the windows port
|
||||||
|
|
||||||
- liren at vivisimo.com made the initial windows port
|
- liren at vivisimo.com made the initial windows port
|
||||||
|
|
||||||
|
* Imported the sources from ares 1.1.1
|
||||||
|
@@ -21,8 +21,6 @@ vc/adig/adig.dsp
|
|||||||
vc/adig/adig.mak
|
vc/adig/adig.mak
|
||||||
vc/adig/adig.plg
|
vc/adig/adig.plg
|
||||||
vc/vc.dsw
|
vc/vc.dsw
|
||||||
vc/vc.ncb
|
|
||||||
vc/vc.opt
|
|
||||||
vc/ahost/ahost.dep
|
vc/ahost/ahost.dep
|
||||||
vc/ahost/ahost.dsp
|
vc/ahost/ahost.dsp
|
||||||
vc/ahost/ahost.mak
|
vc/ahost/ahost.mak
|
||||||
|
@@ -25,7 +25,15 @@ OBJS= ares__close_sockets.o ares__get_hostent.o ares__read_line.o \
|
|||||||
ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \
|
ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \
|
||||||
ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \
|
ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \
|
||||||
ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \
|
ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \
|
||||||
ares_send.o ares_strerror.o ares_timeout.o ares_version.o
|
ares_send.o ares_strerror.o ares_timeout.o ares_version.o \
|
||||||
|
ares_expand_string.o ares_cancel.o
|
||||||
|
|
||||||
|
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
||||||
|
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
||||||
|
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
|
||||||
|
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
|
||||||
|
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
|
||||||
|
ares_version.3 ares_cancel.3
|
||||||
|
|
||||||
$(LIB): ${OBJS}
|
$(LIB): ${OBJS}
|
||||||
ar cru $@ ${OBJS}
|
ar cru $@ ${OBJS}
|
||||||
@@ -60,31 +68,9 @@ install:
|
|||||||
chmod u-w ${DESTDIR}${libdir}/$(LIB)
|
chmod u-w ${DESTDIR}${libdir}/$(LIB)
|
||||||
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
|
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir}
|
${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir}
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3
|
(for man in $(MANPAGES); do \
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3
|
${INSTALL} -m 444 ${srcdir}/$${man} ${DESTDIR}${mandir}/man3; \
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3
|
done)
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_free_hostent.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_free_string.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_gethostbyaddr.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_gethostbyname.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_init.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_init_options.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_mkquery.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_parse_a_reply.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_parse_ptr_reply.3 \
|
|
||||||
${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_process.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_query.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_search.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_send.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_strerror.3 ${DESTDIR}${mandir}/man3
|
|
||||||
${INSTALL} -m 444 ${srcdir}/ares_timeout.3 ${DESTDIR}${mandir}/man3
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${OBJS} $(LIB) adig.o adig ahost.o ahost
|
rm -f ${OBJS} $(LIB) adig.o adig ahost.o ahost
|
||||||
|
@@ -1,19 +1,21 @@
|
|||||||
|
c-ares
|
||||||
|
======
|
||||||
|
|
||||||
This package is based on ares 1.1.1 (written by Greg Hudson). I've decided to
|
This package is based on ares 1.1.1 (written by Greg Hudson). I decided to
|
||||||
put together and release my own ares archives since the ares maintainer
|
fork and release a separate project since the ares author didn't want the
|
||||||
doesn't want these improvements.
|
improvements that were vital for our use of it.
|
||||||
|
|
||||||
The package is thus dubbed 'c-ares' since I (Daniel Stenberg) want this for
|
This package is dubbed 'c-ares' since I (Daniel Stenberg) wanted this for use
|
||||||
use within the curl project (hence the letter C) and it makes a nice
|
within the curl project (hence the letter C) and it makes a nice pun. Also,
|
||||||
pun. Also, c-ares will not remain API compatible with the original ares, so
|
c-ares is not API compatible with ares: a new name makes that more obvious to
|
||||||
picking a new name makes it more obvious to the public.
|
the public.
|
||||||
|
|
||||||
The full source code is available in the 'c-ares' release archives, and in the
|
The full source code is available in the 'c-ares' release archives, and in the
|
||||||
'ares' subdir of the curl CVS source repostitory.
|
'ares' subdir of the curl CVS source repostitory.
|
||||||
|
|
||||||
If you find bugs, correct flaws, have questions or have comments in general in
|
If you find bugs, correct flaws, have questions or have comments in general in
|
||||||
regard to c-ares (or by all means the original ares too), get in touch with us
|
regard to c-ares (or by all means the original ares too), get in touch with us
|
||||||
on the curl-library mailing list.
|
on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares
|
||||||
|
|
||||||
c-ares is of course distributed under the same MIT-style license as the
|
c-ares is of course distributed under the same MIT-style license as the
|
||||||
original ares.
|
original ares.
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#define ARES_EFILE 14
|
#define ARES_EFILE 14
|
||||||
#define ARES_ENOMEM 15
|
#define ARES_ENOMEM 15
|
||||||
#define ARES_EDESTRUCTION 16
|
#define ARES_EDESTRUCTION 16
|
||||||
|
#define ARES_EBADSTR 17
|
||||||
|
|
||||||
/* Flag values */
|
/* Flag values */
|
||||||
#define ARES_FLAG_USEVC (1 << 0)
|
#define ARES_FLAG_USEVC (1 << 0)
|
||||||
@@ -104,7 +105,7 @@ int ares_init(ares_channel *channelptr);
|
|||||||
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||||
int optmask);
|
int optmask);
|
||||||
void ares_destroy(ares_channel channel);
|
void ares_destroy(ares_channel channel);
|
||||||
|
void ares_cancel(ares_channel channel);
|
||||||
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
||||||
ares_callback callback, void *arg);
|
ares_callback callback, void *arg);
|
||||||
void ares_query(ares_channel channel, const char *name, int dnsclass,
|
void ares_query(ares_channel channel, const char *name, int dnsclass,
|
||||||
@@ -125,6 +126,8 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
|
|||||||
int rd, unsigned char **buf, int *buflen);
|
int rd, unsigned char **buf, int *buflen);
|
||||||
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
||||||
int alen, char **s, long *enclen);
|
int alen, char **s, long *enclen);
|
||||||
|
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
|
||||||
|
int alen, unsigned char **s, long *enclen);
|
||||||
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
int ares_parse_a_reply(const unsigned char *abuf, int alen,
|
||||||
struct hostent **host);
|
struct hostent **host);
|
||||||
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
||||||
|
37
ares/ares_cancel.3
Normal file
37
ares/ares_cancel.3
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.\" Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this
|
||||||
|
.\" software and its documentation for any purpose and without
|
||||||
|
.\" fee is hereby granted, provided that the above copyright
|
||||||
|
.\" notice appear in all copies and that both that copyright
|
||||||
|
.\" notice and this permission notice appear in supporting
|
||||||
|
.\" documentation, and that the name of M.I.T. not be used in
|
||||||
|
.\" advertising or publicity pertaining to distribution of the
|
||||||
|
.\" software without specific, written prior permission.
|
||||||
|
.\" M.I.T. makes no representations about the suitability of
|
||||||
|
.\" this software for any purpose. It is provided "as is"
|
||||||
|
.\" without express or implied warranty.
|
||||||
|
.\"
|
||||||
|
.TH ARES_CANCEL 3 "31 March 2004"
|
||||||
|
.SH NAME
|
||||||
|
ares_cancel \- Cancel a resolve
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
.B #include <ares.h>
|
||||||
|
.PP
|
||||||
|
.B int ares_cancel(ares_channel \fIchannel\fP)
|
||||||
|
.fi
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The \fBares_cancel\fP function cancels all lookups/requests made on the the
|
||||||
|
name service channel identified by \fIchannel\fP. \fBares_cancel\fP invokes
|
||||||
|
the callbacks for each pending query on the channel, passing a status of
|
||||||
|
.BR ARES_ETIMEOUT .
|
||||||
|
These calls give the callbacks a chance to clean up any state which
|
||||||
|
might have been stored in their arguments.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR ares_init (3)
|
||||||
|
.BR ares_destroy (3)
|
||||||
|
.SH AUTHOR
|
||||||
|
Dirk Manske
|
44
ares/ares_cancel.c
Normal file
44
ares/ares_cancel.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose and without
|
||||||
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
* notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of M.I.T. not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* M.I.T. makes no representations about the suitability of
|
||||||
|
* this software for any purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ares.h"
|
||||||
|
#include "ares_private.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ares_cancel() cancels a ongoing request/resolve that might be going on on
|
||||||
|
* the given channel. It does NOT kill the channel, use ares_destroy() for
|
||||||
|
* that.
|
||||||
|
*/
|
||||||
|
void ares_cancel(ares_channel channel)
|
||||||
|
{
|
||||||
|
struct query *query, *next;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (query = channel->queries; query; query = next)
|
||||||
|
{
|
||||||
|
next = query->next;
|
||||||
|
query->callback(query->arg, ARES_ETIMEOUT, NULL, 0);
|
||||||
|
free(query->tcpbuf);
|
||||||
|
free(query->skip_server);
|
||||||
|
free(query);
|
||||||
|
}
|
||||||
|
channel->queries = NULL;
|
||||||
|
if (!(channel->flags & ARES_FLAG_STAYOPEN))
|
||||||
|
{
|
||||||
|
for (i = 0; i < channel->nservers; i++)
|
||||||
|
ares__close_sockets(&channel->servers[i]);
|
||||||
|
}
|
||||||
|
}
|
@@ -36,7 +36,8 @@ status of
|
|||||||
These calls give the callbacks a chance to clean up any state which
|
These calls give the callbacks a chance to clean up any state which
|
||||||
might have been stored in their arguments.
|
might have been stored in their arguments.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_init (3)
|
.BR ares_init (3),
|
||||||
|
.BR ares_cancel (3)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Greg Hudson, MIT Information Systems
|
Greg Hudson, MIT Information Systems
|
||||||
.br
|
.br
|
||||||
|
62
ares/ares_expand_string.3
Normal file
62
ares/ares_expand_string.3
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
.\" $Id$
|
||||||
|
.\"
|
||||||
|
.\" Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this
|
||||||
|
.\" software and its documentation for any purpose and without
|
||||||
|
.\" fee is hereby granted, provided that the above copyright
|
||||||
|
.\" notice appear in all copies and that both that copyright
|
||||||
|
.\" notice and this permission notice appear in supporting
|
||||||
|
.\" documentation, and that the name of M.I.T. not be used in
|
||||||
|
.\" advertising or publicity pertaining to distribution of the
|
||||||
|
.\" software without specific, written prior permission.
|
||||||
|
.\" M.I.T. makes no representations about the suitability of
|
||||||
|
.\" this software for any purpose. It is provided "as is"
|
||||||
|
.\" without express or implied warranty.
|
||||||
|
.\"
|
||||||
|
.TH ARES_EXPAND_NAME 3 "23 July 1998"
|
||||||
|
.SH NAME
|
||||||
|
ares_expand_string \- Expand a length encoded string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
.B #include <ares.h>
|
||||||
|
.PP
|
||||||
|
.B int ares_expand_string(const unsigned char *\fIencoded\fP,
|
||||||
|
.B const unsigned char *\fIabuf\fP, int \fIalen\fP, unsigned char **\fIs\fP,
|
||||||
|
.B int *\fIenclen\fP)
|
||||||
|
.fi
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B ares_expand_string
|
||||||
|
function converts a length encoded string to a NULL terminated C
|
||||||
|
string. The argument
|
||||||
|
.I encoded
|
||||||
|
gives the beginning of the encoded string, and the arguments
|
||||||
|
.I abuf
|
||||||
|
and
|
||||||
|
.I alen
|
||||||
|
give the containing message buffer (necessary for the processing of
|
||||||
|
indirection pointers within the encoded domain name). The result is
|
||||||
|
placed in a NUL-terminated allocated buffer, a pointer to which is
|
||||||
|
stored in the variable pointed to by
|
||||||
|
.IR s .
|
||||||
|
The length of the encoded string is stored in the variable pointed to by
|
||||||
|
.I enclen
|
||||||
|
so that the caller can advance past the encoded string to read
|
||||||
|
further data in the message.
|
||||||
|
.SH RETURN VALUES
|
||||||
|
.B ares_expand_string
|
||||||
|
can return any of the following values:
|
||||||
|
.TP 15
|
||||||
|
.B ARES_SUCCESS
|
||||||
|
Expansion of the encoded string succeeded.
|
||||||
|
.TP 15
|
||||||
|
.B ARES_EBADSTR
|
||||||
|
The encoded string was malformed and could not be expanded.
|
||||||
|
.TP 15
|
||||||
|
.B ARES_ENOMEM
|
||||||
|
Memory was exhausted.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR ares_free_string (3)
|
||||||
|
.SH AUTHOR
|
||||||
|
Dominick Meglio
|
65
ares/ares_expand_string.c
Normal file
65
ares/ares_expand_string.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose and without
|
||||||
|
* fee is hereby granted, provided that the above copyright
|
||||||
|
* notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of M.I.T. not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* M.I.T. makes no representations about the suitability of
|
||||||
|
* this software for any purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "nameser.h"
|
||||||
|
#else
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ares.h"
|
||||||
|
#include "ares_private.h" /* for the memdebug */
|
||||||
|
|
||||||
|
/* Simply decodes a length-encoded character string. The first byte of the
|
||||||
|
* input is the length of the string to be returned and the bytes thereafter
|
||||||
|
* are the characters of the string. The returned result will be NULL
|
||||||
|
* terminated.
|
||||||
|
*/
|
||||||
|
int ares_expand_string(const unsigned char *encoded,
|
||||||
|
const unsigned char *abuf,
|
||||||
|
int alen,
|
||||||
|
unsigned char **s,
|
||||||
|
long *enclen)
|
||||||
|
{
|
||||||
|
unsigned char *q;
|
||||||
|
long len;
|
||||||
|
if (encoded == abuf+alen)
|
||||||
|
return ARES_EBADSTR;
|
||||||
|
|
||||||
|
len = *encoded;
|
||||||
|
if (encoded+len+1 > abuf+alen)
|
||||||
|
return ARES_EBADSTR;
|
||||||
|
|
||||||
|
encoded++;
|
||||||
|
|
||||||
|
*s = malloc(len+1);
|
||||||
|
if (*s == NULL)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
q = *s;
|
||||||
|
strncpy((char *)q, (char *)encoded, len);
|
||||||
|
q[len] = '\0';
|
||||||
|
|
||||||
|
*s = q;
|
||||||
|
|
||||||
|
*enclen = len+1;
|
||||||
|
|
||||||
|
return ARES_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@@ -28,21 +28,16 @@ The
|
|||||||
.I ares_free_hostent
|
.I ares_free_hostent
|
||||||
function frees a
|
function frees a
|
||||||
.B struct hostent
|
.B struct hostent
|
||||||
allocated by one of the functions
|
allocated by one of the functions \fIares_parse_a_reply(3)\fP or
|
||||||
.I ares_parse_a_reply
|
\fIares_parse_ptr_reply(3)\fP.
|
||||||
or
|
.SH NOTES
|
||||||
.IR ares_parse_ptr_reply .
|
It is not necessary (and is not correct) to free the host structure passed to
|
||||||
|
the callback functions for \fIares_gethostbyname(3)\fP or
|
||||||
|
\fIares_gethostbyaddr(3)\fP. The ares library will automatically free such
|
||||||
|
host structures when the callback returns.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_parse_a_reply (3),
|
.BR ares_parse_a_reply (3),
|
||||||
.BR ares_parse_ptr_reply (3)
|
.BR ares_parse_ptr_reply (3)
|
||||||
.SH NOTES
|
|
||||||
It is not necessary (and is not correct) to free the host structure
|
|
||||||
passed to the callback functions for
|
|
||||||
.I ares_gethostbyname
|
|
||||||
or
|
|
||||||
.IR ares_gethostbyaddr .
|
|
||||||
The ares library will automatically free such host structures when the
|
|
||||||
callback returns.
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Greg Hudson, MIT Information Systems
|
Greg Hudson, MIT Information Systems
|
||||||
.br
|
.br
|
||||||
|
@@ -26,11 +26,10 @@ ares_free_string \- Free strings allocated by ares functions
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.I ares_free_string
|
.I ares_free_string
|
||||||
function frees a string allocated by the
|
function frees a string allocated by an ares function.
|
||||||
.I ares_mkquery
|
|
||||||
function.
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_mkquery (3)
|
.BR ares_mkquery (3)
|
||||||
|
.BR ares_expand_string (3)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Greg Hudson, MIT Information Systems
|
Greg Hudson, MIT Information Systems
|
||||||
.br
|
.br
|
||||||
|
@@ -40,14 +40,10 @@ and
|
|||||||
.I addrlen
|
.I addrlen
|
||||||
give the address as a series of bytes, and
|
give the address as a series of bytes, and
|
||||||
.I family
|
.I family
|
||||||
gives the type of address. When the query is complete or has failed,
|
gives the type of address. When the query is complete or has failed, the ares
|
||||||
the ares library will invoke
|
library will invoke \fIcallback\fP. Completion or failure of the query may
|
||||||
.IR callback .
|
happen immediately, or may happen during a later call to
|
||||||
Completion or failure of the query may happen immediately, or may
|
\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.
|
||||||
happen during a later call to
|
|
||||||
.BR ares_process (3)
|
|
||||||
or
|
|
||||||
.BR ares_destroy (3).
|
|
||||||
.PP
|
.PP
|
||||||
The callback argument
|
The callback argument
|
||||||
.I arg
|
.I arg
|
||||||
@@ -93,7 +89,8 @@ did not complete successfully,
|
|||||||
will be
|
will be
|
||||||
.BR NULL .
|
.BR NULL .
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_process (3)
|
.BR ares_process (3),
|
||||||
|
.BR ares_gethostbyname (3)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Greg Hudson, MIT Information Systems
|
Greg Hudson, MIT Information Systems
|
||||||
.br
|
.br
|
||||||
|
@@ -87,10 +87,10 @@ static void next_lookup(struct addr_query *aquery)
|
|||||||
{
|
{
|
||||||
case 'b':
|
case 'b':
|
||||||
addr = ntohl(aquery->addr.s_addr);
|
addr = ntohl(aquery->addr.s_addr);
|
||||||
a1 = (int)(addr >> 24) & 0xff;
|
a1 = (int)((addr >> 24) & 0xff);
|
||||||
a2 = (int)(addr >> 16) & 0xff;
|
a2 = (int)((addr >> 16) & 0xff);
|
||||||
a3 = (int)(addr >> 8) & 0xff;
|
a3 = (int)((addr >> 8) & 0xff);
|
||||||
a4 = (int)addr & 0xff;
|
a4 = (int)(addr & 0xff);
|
||||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
||||||
aquery->remaining_lookups = p + 1;
|
aquery->remaining_lookups = p + 1;
|
||||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||||
|
@@ -37,14 +37,11 @@ The parameter
|
|||||||
.I name
|
.I name
|
||||||
gives the hostname as a NUL-terminated C string, and
|
gives the hostname as a NUL-terminated C string, and
|
||||||
.I family
|
.I family
|
||||||
gives the desired type of address for the resulting host entry. When
|
gives the desired type of address for the resulting host entry. When the
|
||||||
the query is complete or has failed, the ares library will invoke
|
query is complete or has failed, the ares library will invoke \fIcallback\fP.
|
||||||
.IR callback .
|
Completion or failure of the query may happen immediately, or may happen
|
||||||
Completion or failure of the query may happen immediately, or may
|
during a later call to \fIares_process(3)\fP, \fIares_destroy(3)\fP or
|
||||||
happen during a later call to
|
\fIares_cancel(3)\fP.
|
||||||
.BR ares_process (3)
|
|
||||||
or
|
|
||||||
.BR ares_destroy (3).
|
|
||||||
.PP
|
.PP
|
||||||
The callback argument
|
The callback argument
|
||||||
.I arg
|
.I arg
|
||||||
@@ -96,7 +93,8 @@ did not complete successfully,
|
|||||||
will be
|
will be
|
||||||
.BR NULL .
|
.BR NULL .
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_process (3)
|
.BR ares_process (3),
|
||||||
|
.BR ares_gethostbyaddr (3)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Greg Hudson, MIT Information Systems
|
Greg Hudson, MIT Information Systems
|
||||||
.br
|
.br
|
||||||
|
@@ -21,11 +21,9 @@ ares_mkquery \- Compose a single-question DNS query buffer
|
|||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
|
||||||
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
|
.B unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
|
||||||
.B
|
.B int *\fIbuflen\fP)
|
||||||
unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
|
|
||||||
int *\fIbuflen\fP)
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
@@ -52,8 +50,7 @@ stored in the variable pointed to by
|
|||||||
and the length of which will be stored in the variable pointed to by
|
and the length of which will be stored in the variable pointed to by
|
||||||
.IR buflen .
|
.IR buflen .
|
||||||
It is the caller's responsibility to free this buffer using
|
It is the caller's responsibility to free this buffer using
|
||||||
.B ares_free_string
|
\fIares_free_string(3)\fP when it is no longer needed.
|
||||||
when it is no longer needed.
|
|
||||||
.SH RETURN VALUES
|
.SH RETURN VALUES
|
||||||
.B ares_mkquery
|
.B ares_mkquery
|
||||||
can return any of the following values:
|
can return any of the following values:
|
||||||
|
@@ -21,9 +21,8 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent
|
|||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB,
|
.B struct hostent **\fIhost\fP);
|
||||||
.B struct hostent **\fIhost\fB);
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
@@ -21,11 +21,9 @@ ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent
|
|||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
.B #include <ares.h>
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
int ares_parse_ptr_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB,
|
.B const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
|
||||||
.B
|
.B struct hostent **\fIhost\fP);
|
||||||
const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
|
|
||||||
.B struct hostent **\fIhost\fB);
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
@@ -35,13 +35,10 @@ The file descriptor sets pointed to by
|
|||||||
and
|
and
|
||||||
.I write_fds
|
.I write_fds
|
||||||
should have file descriptors set in them according to whether the file
|
should have file descriptors set in them according to whether the file
|
||||||
descriptors specified by
|
descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
|
||||||
.BR ares_fds (3)
|
(The easiest way to determine this information is to invoke
|
||||||
are ready for reading and writing. (The easiest way to determine this
|
|
||||||
information is to invoke
|
|
||||||
.B select
|
.B select
|
||||||
with a timeout no greater than the timeout given by
|
with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ).
|
||||||
.BR ares_timeout (3)).
|
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.B ares_process
|
.B ares_process
|
||||||
|
@@ -24,8 +24,7 @@ ares_send \- Initiate a DNS query
|
|||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP)
|
.B unsigned char *\fIabuf\fP, int \fIalen\fP)
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
||||||
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
|
||||||
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
@@ -35,7 +35,9 @@ const char *ares_strerror(int code)
|
|||||||
"Timeout while contacting DNS servers",
|
"Timeout while contacting DNS servers",
|
||||||
"End of file",
|
"End of file",
|
||||||
"Error reading file",
|
"Error reading file",
|
||||||
"Out of memory"
|
"Out of memory",
|
||||||
|
"Channel is being destroyed",
|
||||||
|
"Misformatted string"
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));
|
assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));
|
||||||
|
@@ -27,10 +27,8 @@ ares_fds \- Get file descriptors to select on for name service
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B ares_timeout
|
.B ares_timeout
|
||||||
function determines the maximum time for which the caller should wait
|
function determines the maximum time for which the caller should wait before
|
||||||
before invoking
|
invoking \fIares_process(3)\fP to process timeouts. The parameter
|
||||||
.BR ares_process (3)
|
|
||||||
to process timeouts. The parameter
|
|
||||||
.I maxtv
|
.I maxtv
|
||||||
specifies a existing maximum timeout, or
|
specifies a existing maximum timeout, or
|
||||||
.B NULL
|
.B NULL
|
||||||
|
@@ -4,12 +4,12 @@
|
|||||||
#define ARES__VERSION_H
|
#define ARES__VERSION_H
|
||||||
|
|
||||||
#define ARES_VERSION_MAJOR 1
|
#define ARES_VERSION_MAJOR 1
|
||||||
#define ARES_VERSION_MINOR 0
|
#define ARES_VERSION_MINOR 2
|
||||||
#define ARES_VERSION_PATCH 0
|
#define ARES_VERSION_PATCH 0
|
||||||
#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.0.0"
|
#define ARES_VERSION_STR "1.2.0"
|
||||||
|
|
||||||
const char *ares_version(int *version);
|
const char *ares_version(int *version);
|
||||||
|
|
||||||
|
4
ares/buildconf
Executable file
4
ares/buildconf
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
aclocal
|
||||||
|
autoconf
|
@@ -96,3 +96,5 @@ for(@entries) {
|
|||||||
`gzip -9 $name-$version.tar`;
|
`gzip -9 $name-$version.tar`;
|
||||||
# remove the dir
|
# remove the dir
|
||||||
`rm -rf $name-$version`;
|
`rm -rf $name-$version`;
|
||||||
|
|
||||||
|
print "NOTE: now cvs tag this release!\n";
|
||||||
|
BIN
ares/vc/vc.ncb
BIN
ares/vc/vc.ncb
Binary file not shown.
BIN
ares/vc/vc.opt
BIN
ares/vc/vc.opt
Binary file not shown.
@@ -67,7 +67,7 @@ echo "buildconf: autoheader version $ah_version (ok)"
|
|||||||
# automake 1.7 or newer
|
# automake 1.7 or newer
|
||||||
#
|
#
|
||||||
need_automake="1.7"
|
need_automake="1.7"
|
||||||
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
|
||||||
if test -z "$am_version"; then
|
if test -z "$am_version"; then
|
||||||
echo "buildconf: automake not found."
|
echo "buildconf: automake not found."
|
||||||
echo " You need automake version $need_automake or newer installed."
|
echo " You need automake version $need_automake or newer installed."
|
||||||
@@ -159,7 +159,7 @@ fi
|
|||||||
echo "buildconf: running libtoolize"
|
echo "buildconf: running libtoolize"
|
||||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
|
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
|
||||||
echo "buildconf: running aclocal"
|
echo "buildconf: running aclocal"
|
||||||
${ACLOCAL:-aclocal} || die "The command '${AUTOHEADER:-aclocal}' failed"
|
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
|
||||||
echo "buildconf: running aclocal hack to convert all mv to mv -f"
|
echo "buildconf: running aclocal hack to convert all mv to mv -f"
|
||||||
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
||||||
echo "buildconf: running autoheader"
|
echo "buildconf: running autoheader"
|
||||||
@@ -170,7 +170,7 @@ ${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
|||||||
if test -d ares; then
|
if test -d ares; then
|
||||||
cd ares
|
cd ares
|
||||||
echo "buildconf: running aclocal in the ares directory"
|
echo "buildconf: running aclocal in the ares directory"
|
||||||
${ACLOCAL:-aclocal} || die "The command '${ACLOCAL:-aclocal}' failed"
|
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
|
||||||
echo "buildconf: running autoconf in the ares directory"
|
echo "buildconf: running autoconf in the ares directory"
|
||||||
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||||
cd ..
|
cd ..
|
||||||
|
62
configure.ac
62
configure.ac
@@ -24,14 +24,14 @@ AC_PATH_PROG( AR, ar, , $PATH:/usr/bin:/usr/local/bin:/usr/ccs/bin)
|
|||||||
AC_SUBST(AR)
|
AC_SUBST(AR)
|
||||||
|
|
||||||
dnl figure out the libcurl version
|
dnl figure out the libcurl version
|
||||||
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h`
|
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
|
||||||
AM_INIT_AUTOMAKE(curl,$VERSION)
|
AM_INIT_AUTOMAKE(curl,$VERSION)
|
||||||
AC_MSG_CHECKING([curl version])
|
AC_MSG_CHECKING([curl version])
|
||||||
AC_MSG_RESULT($VERSION)
|
AC_MSG_RESULT($VERSION)
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl we extract the numerical version for curl-config only
|
dnl we extract the numerical version for curl-config only
|
||||||
VERSIONNUM=`$SED -ne 's/^#define LIBCURL_VERSION_NUM 0x\(.*\)/\1/p' ${srcdir}/include/curl/curl.h`
|
VERSIONNUM=`$SED -ne 's/^#define LIBCURL_VERSION_NUM 0x\(.*\)/\1/p' ${srcdir}/include/curl/curlver.h`
|
||||||
AC_SUBST(VERSIONNUM)
|
AC_SUBST(VERSIONNUM)
|
||||||
|
|
||||||
dnl Solaris pkgadd support definitions
|
dnl Solaris pkgadd support definitions
|
||||||
@@ -384,6 +384,8 @@ main()
|
|||||||
|
|
||||||
if test "$ipv6" = "yes"; then
|
if test "$ipv6" = "yes"; then
|
||||||
CURL_CHECK_WORKING_GETADDRINFO
|
CURL_CHECK_WORKING_GETADDRINFO
|
||||||
|
|
||||||
|
CURL_CHECK_NI_WITHSCOPEID
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -693,7 +695,7 @@ AC_HELP_STRING([--without-ssl], [disable SSL]),
|
|||||||
|
|
||||||
if test X"$OPT_SSL" = Xno
|
if test X"$OPT_SSL" = Xno
|
||||||
then
|
then
|
||||||
AC_MSG_WARN(SSL/https support disabled)
|
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
|
||||||
else
|
else
|
||||||
|
|
||||||
dnl Check for and handle argument to --with-ssl.
|
dnl Check for and handle argument to --with-ssl.
|
||||||
@@ -915,6 +917,7 @@ printf("just fine");
|
|||||||
#endif
|
#endif
|
||||||
],
|
],
|
||||||
[ AC_MSG_RESULT([yes])
|
[ AC_MSG_RESULT([yes])
|
||||||
|
RECENTAIX=yes
|
||||||
OPT_THREAD=off ],
|
OPT_THREAD=off ],
|
||||||
[ AC_MSG_RESULT([no]) ]
|
[ AC_MSG_RESULT([no]) ]
|
||||||
)
|
)
|
||||||
@@ -952,10 +955,31 @@ else
|
|||||||
dnl is there a localtime_r()
|
dnl is there a localtime_r()
|
||||||
CURL_CHECK_LOCALTIME_R()
|
CURL_CHECK_LOCALTIME_R()
|
||||||
|
|
||||||
AC_CHECK_FUNCS( gmtime_r )
|
dnl is there a strerror_r()
|
||||||
|
CURL_CHECK_STRERROR_R()
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS( gmtime_r )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl for recent AIX versions, we skip all the thread-safe checks above since
|
||||||
|
dnl they claim a thread-safe libc using the standard API. But there are
|
||||||
|
dnl some functions still not thread-safe. Check for these!
|
||||||
|
|
||||||
|
dnl Let's hope this split URL remains working:
|
||||||
|
dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
|
||||||
|
dnl genprogc/thread_quick_ref.htm
|
||||||
|
|
||||||
|
if test "x$RECENTAIX" = "xyes"; then
|
||||||
|
dnl is there a localtime_r()
|
||||||
|
CURL_CHECK_LOCALTIME_R()
|
||||||
|
|
||||||
|
dnl is there a strerror_r()
|
||||||
|
CURL_CHECK_STRERROR_R()
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS( gmtime_r )
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Back to "normal" configuring
|
dnl Back to "normal" configuring
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -979,6 +1003,7 @@ AC_CHECK_HEADERS(
|
|||||||
arpa/inet.h \
|
arpa/inet.h \
|
||||||
net/if.h \
|
net/if.h \
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
|
netinet/tcp.h \
|
||||||
netdb.h \
|
netdb.h \
|
||||||
sys/sockio.h \
|
sys/sockio.h \
|
||||||
sys/stat.h \
|
sys/stat.h \
|
||||||
@@ -1015,6 +1040,9 @@ dnl default includes
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1226,6 +1254,7 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
|||||||
dnl ares so it should not be a problem.
|
dnl ares so it should not be a problem.
|
||||||
if test "x$enableval" = "xyes" ; then
|
if test "x$enableval" = "xyes" ; then
|
||||||
if test -d "$srcdir/ares"; then
|
if test -d "$srcdir/ares"; then
|
||||||
|
aresembedded="yes"
|
||||||
AC_CONFIG_SUBDIRS(ares)
|
AC_CONFIG_SUBDIRS(ares)
|
||||||
aresinc=`cd $srcdir/ares && pwd`
|
aresinc=`cd $srcdir/ares && pwd`
|
||||||
CPPFLAGS="$CPPFLAGS -I$aresinc"
|
CPPFLAGS="$CPPFLAGS -I$aresinc"
|
||||||
@@ -1240,6 +1269,31 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
|||||||
CPPFLAGS="$CPPFLAGS -I$enableval/include"
|
CPPFLAGS="$CPPFLAGS -I$enableval/include"
|
||||||
LDFLAGS="$LDFLAGS -L$enableval/lib"
|
LDFLAGS="$LDFLAGS -L$enableval/lib"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -z "$aresembedded"; then
|
||||||
|
dnl verify that a sufficient c-ares is here if we have pointed one
|
||||||
|
dnl out and don't use the "embedded" ares dir (in which case we don't
|
||||||
|
dnl check it because it might not have been built yet)
|
||||||
|
AC_MSG_CHECKING([that c-ares is good and recent enough])
|
||||||
|
AC_LINK_IFELSE( [
|
||||||
|
#include <ares.h>
|
||||||
|
/* provide a set of dummy functions in case c-ares was built with debug */
|
||||||
|
void curl_dofree() { }
|
||||||
|
void curl_sclose() { }
|
||||||
|
void curl_domalloc() { }
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
ares_channel channel;
|
||||||
|
ares_cancel(channel);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AC_MSG_RESULT(yes),
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
AC_MSG_ERROR([c-ares library defective or too old])
|
||||||
|
)
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
esac ],
|
esac ],
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
@@ -2,17 +2,8 @@
|
|||||||
;;;; $Id$
|
;;;; $Id$
|
||||||
|
|
||||||
;;; The curl hacker's C conventions.
|
;;; The curl hacker's C conventions.
|
||||||
|
;;; See the sample.emacs file on how this file can be made to take
|
||||||
;;; After loading this file and added the mode-hook you can in C
|
;;; effect automatically when editing curl source files.
|
||||||
;;; files, put something like this to use the curl style
|
|
||||||
;;; automatically:
|
|
||||||
;;
|
|
||||||
;; /* -----------------------------------------------------------------
|
|
||||||
;; * local variables:
|
|
||||||
;; * eval: (set c-file-style "curl")
|
|
||||||
;; * end:
|
|
||||||
;; */
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defconst curl-c-style
|
(defconst curl-c-style
|
||||||
'((c-basic-offset . 2)
|
'((c-basic-offset . 2)
|
||||||
@@ -37,7 +28,7 @@
|
|||||||
(setq tab-width 8
|
(setq tab-width 8
|
||||||
indent-tabs-mode nil ; Use spaces. Not tabs.
|
indent-tabs-mode nil ; Use spaces. Not tabs.
|
||||||
comment-column 40
|
comment-column 40
|
||||||
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t" "curl_off_t" "curl_socket_t"))
|
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t" "curl_off_t" "curl_socket_t" "in_addr_t" "CURLSHcode" "CURLMcode"))
|
||||||
)
|
)
|
||||||
;; keybindings for C, C++, and Objective-C. We can put these in
|
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||||
;; c-mode-base-map because of inheritance ...
|
;; c-mode-base-map because of inheritance ...
|
||||||
|
@@ -3,8 +3,9 @@ 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!
|
||||||
|
|
||||||
* NTLM authentication with passwords longer than 14 letters fail. There is
|
* --limit-rate using -d or -F does not work. This is because the limit logic
|
||||||
a known fix for this, planned to come in curl 7.11.2
|
is provided by the curl app in its read/write callbacks, and when doing
|
||||||
|
-d/-F the callbacks aren't used!
|
||||||
|
|
||||||
* Doing resumed upload over HTTP does not work with '-C -', because curl
|
* Doing resumed upload over HTTP does not work with '-C -', because curl
|
||||||
doesn't do a HEAD first to get the initial size. This needs to be done
|
doesn't do a HEAD first to get the initial size. This needs to be done
|
||||||
@@ -22,13 +23,6 @@ may have been fixed since this was written!
|
|||||||
indicate that the user wants to reach the root dir (this exception SHALL
|
indicate that the user wants to reach the root dir (this exception SHALL
|
||||||
remain even when this bug is fixed).
|
remain even when this bug is fixed).
|
||||||
|
|
||||||
* 1) libcurl does a POST
|
|
||||||
2) receives a 100-continue
|
|
||||||
3) sends away the POST
|
|
||||||
Now, if nothing else is returned from the server, libcurl MUST return
|
|
||||||
CURLE_GOT_NOTHING, but it seems it returns CURLE_OK as it seems to count
|
|
||||||
the 100-continue reply as a good enough reply.
|
|
||||||
|
|
||||||
* libcurl doesn't treat the content-length of compressed data properly, as
|
* libcurl doesn't treat the content-length of compressed data properly, as
|
||||||
it seems HTTP servers send the *uncompressed* length in that header and
|
it seems HTTP servers send the *uncompressed* length in that header and
|
||||||
libcurl thinks of it as the *compressed* lenght. Some explanations are here:
|
libcurl thinks of it as the *compressed* lenght. Some explanations are here:
|
||||||
@@ -38,9 +32,6 @@ may have been fixed since this was written!
|
|||||||
locally, which is because libcurl doesn't call the write callback with zero
|
locally, which is because libcurl doesn't call the write callback with zero
|
||||||
bytes. Explained here: http://curl.haxx.se/mail/archive-2003-04/0143.html
|
bytes. Explained here: http://curl.haxx.se/mail/archive-2003-04/0143.html
|
||||||
|
|
||||||
* Using CURLOPT_FAILONERROR (-f/--fail) will make authentication to stop
|
|
||||||
working if you use anything but plain Basic auth.
|
|
||||||
|
|
||||||
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
|
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
|
||||||
struct. It has been reported to work on AIX 5.1 though.
|
struct. It has been reported to work on AIX 5.1 though.
|
||||||
|
|
||||||
|
11
docs/MANUAL
11
docs/MANUAL
@@ -63,6 +63,11 @@ USING PASSWORDS
|
|||||||
|
|
||||||
curl -u name:passwd ftp://machine.domain:port/full/path/to/file
|
curl -u name:passwd ftp://machine.domain:port/full/path/to/file
|
||||||
|
|
||||||
|
FTPS
|
||||||
|
|
||||||
|
It is just like for FTP, but you may also want to specify and use
|
||||||
|
SSL-specific options for certificates etc.
|
||||||
|
|
||||||
HTTP
|
HTTP
|
||||||
|
|
||||||
The HTTP URL doesn't support user and password in the URL string. Curl
|
The HTTP URL doesn't support user and password in the URL string. Curl
|
||||||
@@ -75,6 +80,12 @@ USING PASSWORDS
|
|||||||
|
|
||||||
curl -u name:passwd http://machine.domain/full/path/to/file
|
curl -u name:passwd http://machine.domain/full/path/to/file
|
||||||
|
|
||||||
|
HTTP offers many different methods of authentication and curl supports
|
||||||
|
several: Basic, Digest, NTLM and Negotiate. Without telling which method to
|
||||||
|
use, curl defaults to Basic. You can also ask curl to pick the most secure
|
||||||
|
ones out of the ones that the server accepts for the given URL, by using
|
||||||
|
--anyauth.
|
||||||
|
|
||||||
NOTE! Since HTTP URLs don't support user and password, you can't use that
|
NOTE! Since HTTP URLs don't support user and password, you can't use that
|
||||||
style when using Curl via a proxy. You _must_ use the -u style fetch
|
style when using Curl via a proxy. You _must_ use the -u style fetch
|
||||||
during such circumstances.
|
during such circumstances.
|
||||||
|
@@ -28,6 +28,12 @@ server, do one of the following:
|
|||||||
|
|
||||||
With the curl command tool: --cacert [file]
|
With the curl command tool: --cacert [file]
|
||||||
|
|
||||||
|
3. Add the CA cert for your server to the existing default CA cert bundle.
|
||||||
|
The default path of the CA bundle installed with the curl package is:
|
||||||
|
/usr/local/share/curl/curl-ca-bundle.crt, which can be changed by running
|
||||||
|
configure with the --with-ca-bundle option pointing out the path of your
|
||||||
|
choice.
|
||||||
|
|
||||||
Neglecting to use one of the above menthods when dealing with a server using a
|
Neglecting to use one of the above menthods when dealing with a server using a
|
||||||
certficate that isn't signed by one of the certficates in the installed CA
|
certficate that isn't signed by one of the certficates in the installed CA
|
||||||
cert bundle, will cause SSL to report an error ("certificate verify failed")
|
cert bundle, will cause SSL to report an error ("certificate verify failed")
|
||||||
@@ -40,7 +46,3 @@ connections that previously weren't really secure. It turned out many people
|
|||||||
were using previous versions of curl/libcurl without realizing the need for
|
were using previous versions of curl/libcurl without realizing the need for
|
||||||
the CA cert options to get truly secure SSL connections.
|
the CA cert options to get truly secure SSL connections.
|
||||||
|
|
||||||
The default path of the CA bundle installed with the curl package is:
|
|
||||||
/usr/local/share/curl/curl-ca-bundle.crt, which can be changed by running
|
|
||||||
configure with the --with-ca-bundle option pointing out the path of your
|
|
||||||
choice.
|
|
||||||
|
16
docs/TODO
16
docs/TODO
@@ -57,6 +57,13 @@ TODO
|
|||||||
|
|
||||||
FTP
|
FTP
|
||||||
|
|
||||||
|
* Optimize the way libcurl uses CWD on each new request over a persistent
|
||||||
|
connection (on FTP) even if it doesn't have to.
|
||||||
|
|
||||||
|
* REST fix for servers not behaving well on >2GB requests. This should fail
|
||||||
|
if the server doesn't set the pointer to the requested index. The tricky
|
||||||
|
part is to figure out if the server did the right thing or not.
|
||||||
|
|
||||||
* Support the most common FTP proxies, Philip Newton provided a list
|
* Support the most common FTP proxies, Philip Newton provided a list
|
||||||
allegedly from ncftp:
|
allegedly from ncftp:
|
||||||
http://curl.haxx.se/mail/archive-2003-04/0126.html
|
http://curl.haxx.se/mail/archive-2003-04/0126.html
|
||||||
@@ -91,6 +98,15 @@ TODO
|
|||||||
|
|
||||||
SSL
|
SSL
|
||||||
|
|
||||||
|
* Anton Fedorov's "dumpcert" patch:
|
||||||
|
http://curl.haxx.se/mail/lib-2004-03/0088.html
|
||||||
|
|
||||||
|
* Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||||
|
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||||
|
|
||||||
|
* Peter Sylvester's "Most Significant Common Name" change. Feedback welcome.
|
||||||
|
At least the UTF8 conversion and comparison should be done. Patch?
|
||||||
|
|
||||||
* If you really want to improve the SSL situation, you should probably have a
|
* If you really want to improve the SSL situation, you should probably have a
|
||||||
look at SSL cafile loading as well - quick traces look to me like these are
|
look at SSL cafile loading as well - quick traces look to me like these are
|
||||||
done on every request as well, when they should only be necessary once per
|
done on every request as well, when they should only be necessary once per
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
.\" nroff -man curl.1
|
.\" nroff -man curl.1
|
||||||
.\" Written by Daniel Stenberg
|
.\" Written by Daniel Stenberg
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "5 Mar 2004" "Curl 7.11.1" "Curl Manual"
|
.TH curl 1 "25 Mar 2004" "Curl 7.11.2" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -707,6 +707,11 @@ is a plain '-', it is instead written to stdout. This option has no point when
|
|||||||
you're using a shell with decent redirecting capabilities.
|
you're using a shell with decent redirecting capabilities.
|
||||||
|
|
||||||
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 "--tcp-nodelay"
|
||||||
|
Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
|
||||||
|
details about this option. (Added in 7.11.2)
|
||||||
|
|
||||||
|
If this option is used several times, each occurance toggles this on/off.
|
||||||
.IP "-t/--telnet-option <OPT=val>"
|
.IP "-t/--telnet-option <OPT=val>"
|
||||||
Pass options to the telnet protocol. Supported options are:
|
Pass options to the telnet protocol. Supported options are:
|
||||||
|
|
||||||
|
@@ -70,6 +70,8 @@ int main(int argc, char **argv)
|
|||||||
switch(rc) {
|
switch(rc) {
|
||||||
case -1:
|
case -1:
|
||||||
/* select error */
|
/* select error */
|
||||||
|
still_running = 0;
|
||||||
|
printf("select() returns error, this is badness\n");
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
|
@@ -33,8 +33,8 @@ int main(int argc, char *argv[])
|
|||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
|
|
||||||
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:";
|
||||||
|
|
||||||
|
@@ -31,5 +31,4 @@ If this function returns NULL, something went wrong and no valid handle was
|
|||||||
returned.
|
returned.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
|
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
|
||||||
.SH BUGS
|
|
||||||
Surely there are some, you tell me!
|
|
||||||
|
@@ -20,7 +20,7 @@ filled in accordingly and can be relied upon only if the function returns
|
|||||||
CURLE_OK. This function is intended to get used *AFTER* a performed transfer,
|
CURLE_OK. This function is intended to get used *AFTER* a performed transfer,
|
||||||
all results from this function are undefined until the transfer is completed.
|
all results from this function are undefined until the transfer is completed.
|
||||||
.SH AVAILABLE INFORMATION
|
.SH AVAILABLE INFORMATION
|
||||||
These are informations that can be extracted:
|
The following information can be extracted:
|
||||||
.IP CURLINFO_EFFECTIVE_URL
|
.IP CURLINFO_EFFECTIVE_URL
|
||||||
Pass a pointer to a 'char *' to receive the last used effective URL.
|
Pass a pointer to a 'char *' to receive the last used effective URL.
|
||||||
.IP CURLINFO_RESPONSE_CODE
|
.IP CURLINFO_RESPONSE_CODE
|
||||||
@@ -51,7 +51,7 @@ pre-transfer commands and negotiations that are specific to the particular
|
|||||||
protocol(s) involved.
|
protocol(s) involved.
|
||||||
.IP CURLINFO_STARTTRANSFER_TIME
|
.IP CURLINFO_STARTTRANSFER_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 first byte is just about to be transfered. This includes
|
start until the first byte is just about to be transferred. This includes
|
||||||
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
|
||||||
the result.
|
the result.
|
||||||
.IP CURLINFO_REDIRECT_TIME
|
.IP CURLINFO_REDIRECT_TIME
|
||||||
@@ -106,7 +106,7 @@ method(s) available. The meaning of the bits is explained in the
|
|||||||
CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8)
|
CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8)
|
||||||
.IP CURLINFO_PROXYAUTH_AVAIL
|
.IP CURLINFO_PROXYAUTH_AVAIL
|
||||||
Pass a pointer to a long to receive a bitmask indicating the authentication
|
Pass a pointer to a long to receive a bitmask indicating the authentication
|
||||||
method(s) available for your proxy athentication. (Added in 7.10.8)
|
method(s) available for your proxy authentication. (Added in 7.10.8)
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
If the operation was successful, CURLE_OK is returned. Otherwise an
|
If the operation was successful, CURLE_OK is returned. Otherwise an
|
||||||
appropriate error code will be returned.
|
appropriate error code will be returned.
|
||||||
|
@@ -13,7 +13,7 @@ curl_easy_init - Start a libcurl easy session
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function must be the first function to call, and it returns a CURL easy
|
This function must be the first function to call, and it returns a CURL easy
|
||||||
handle that you must use as input to other easy-functions. curl_easy_init
|
handle that you must use as input to other easy-functions. curl_easy_init
|
||||||
intializes 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.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
@@ -21,5 +21,3 @@ If this function returns NULL, something went wrong and you cannot use the
|
|||||||
other curl functions.
|
other curl functions.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR curl_easy_cleanup "(3), " curl_global_init "(3)
|
.BR curl_easy_cleanup "(3), " curl_global_init "(3)
|
||||||
.SH BUGS
|
|
||||||
Surely there are some, you tell me!
|
|
||||||
|
@@ -85,7 +85,7 @@ lookups. It enables nice timeouts for name resolves without signals.
|
|||||||
.IP CURLOPT_WRITEFUNCTION
|
.IP CURLOPT_WRITEFUNCTION
|
||||||
Function pointer that should match the following prototype: \fBsize_t
|
Function pointer that should match the following prototype: \fBsize_t
|
||||||
function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This
|
function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This
|
||||||
function gets called by libcurl as soon as there is data reveiced that needs
|
function gets called by libcurl as soon as there is data received that needs
|
||||||
to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP
|
||||||
multiplied with \fInmemb\fP, it will not be zero terminated. Return the number
|
multiplied with \fInmemb\fP, it will not be zero terminated. Return the number
|
||||||
of bytes actually taken care of. If that amount differs from the amount passed
|
of bytes actually taken care of. If that amount differs from the amount passed
|
||||||
@@ -165,7 +165,7 @@ Function pointer that should match the following prototype: \fIint
|
|||||||
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
||||||
\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
|
\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
|
||||||
\fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information,
|
\fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information,
|
||||||
as specified with the \fBcurl_infotype\fP argument. This funtion must return
|
as specified with the \fBcurl_infotype\fP argument. This function must return
|
||||||
0. The data pointed to by the char * passed to this function WILL NOT be zero
|
0. The data pointed to by the char * passed to this function WILL NOT be zero
|
||||||
terminated, but will be exactly of the size as told by the size_t argument.
|
terminated, but will be exactly of the size as told by the size_t argument.
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ Function pointer that should match the following prototype: \fBCURLcode
|
|||||||
sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called
|
sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called
|
||||||
by libcurl just before the initialization of an SSL connection after having
|
by libcurl just before the initialization of an SSL connection after having
|
||||||
processed all other SSL related options to give a last chance to an
|
processed all other SSL related options to give a last chance to an
|
||||||
application to modify the behaviour of openssl's ssl initilaization. The
|
application to modify the behaviour of openssl's ssl initialization. The
|
||||||
\fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If
|
\fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If
|
||||||
an error is returned no attempt to establish a connection is made and the
|
an error is returned no attempt to establish a connection is made and the
|
||||||
perform operation will return the error code from this callback function. Set
|
perform operation will return the error code from this callback function. Set
|
||||||
@@ -249,8 +249,8 @@ be prefixed with [protocol]:// since any such prefix will be ignored. The
|
|||||||
proxy's port number may optionally be specified with the separate option
|
proxy's port number may optionally be specified with the separate option
|
||||||
\fICURLOPT_PROXYPORT\fP.
|
\fICURLOPT_PROXYPORT\fP.
|
||||||
|
|
||||||
\fBNOTE:\fP when you tell the library to use a HTTP proxy, libcurl will
|
\fBNOTE:\fP when you tell the library to use an HTTP proxy, libcurl will
|
||||||
transparently convert operations to HTTP even if you specify a FTP URL
|
transparently convert operations to HTTP even if you specify an FTP URL
|
||||||
etc. This may have an impact on what other features of the library you can
|
etc. This may have an impact on what other features of the library you can
|
||||||
use, such as \fICURLOPT_QUOTE\fP and similar FTP specifics that don't work
|
use, such as \fICURLOPT_QUOTE\fP and similar FTP specifics that don't work
|
||||||
unless you tunnel through the HTTP proxy. Such tunneling is activated with
|
unless you tunnel through the HTTP proxy. Such tunneling is activated with
|
||||||
@@ -282,19 +282,35 @@ libcurl caches this info for 60 seconds.
|
|||||||
.IP CURLOPT_DNS_USE_GLOBAL_CACHE
|
.IP CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||||
Pass a long. If the value is non-zero, it tells curl to use a global DNS cache
|
Pass a long. If the value is non-zero, it tells curl to use a global DNS cache
|
||||||
that will survive between easy handle creations and deletions. This is not
|
that will survive between easy handle creations and deletions. This is not
|
||||||
thread-safe and this will use a global varible.
|
thread-safe and this will use a global variable.
|
||||||
|
|
||||||
\fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over
|
\fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over
|
||||||
to using the share interface instead! See \fICURLOPT_SHARE\fP and
|
to using the share interface instead! See \fICURLOPT_SHARE\fP and
|
||||||
\fIcurl_share_init(3)\fP.
|
\fIcurl_share_init(3)\fP.
|
||||||
.IP CURLOPT_BUFFERSIZE
|
.IP CURLOPT_BUFFERSIZE
|
||||||
Pass a long specifying your prefered size for the receive buffer in libcurl.
|
Pass a long specifying your preferred size for the receive buffer in libcurl.
|
||||||
The main point of this would be that the write callback gets called more often
|
The main point of this would be that the write callback gets called more often
|
||||||
and with smaller chunks. This is just treated as a request, not an order. You
|
and with smaller chunks. This is just treated as a request, not an order. You
|
||||||
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
cannot be guaranteed to actually get the given size. (Added in 7.10)
|
||||||
.IP CURLOPT_PORT
|
.IP CURLOPT_PORT
|
||||||
Pass a long specifying what remote port number to connect to, instead of the
|
Pass a long specifying what remote port number to connect to, instead of the
|
||||||
one specified in the URL or the default port for the used protocol.
|
one specified in the URL or the default port for the used protocol.
|
||||||
|
.IP CURLOPT_TCP_NODELAY
|
||||||
|
Pass a long specifying whether the TCP_NODELAY option should be set or
|
||||||
|
cleared (1 = set, 0 = clear). The option is cleared by default. This
|
||||||
|
will have no effect after the connection has been established.
|
||||||
|
|
||||||
|
Setting this option will disable TCP's Nagle algorithm. The purpose of
|
||||||
|
this algorithm is to try to minimize the number of small packets on
|
||||||
|
the network (where "small packets" means TCP segments less than the
|
||||||
|
Maximum Segment Size (MSS) for the network).
|
||||||
|
|
||||||
|
Maximizing the amount of data sent per TCP segment is good because it
|
||||||
|
amortizes the overhead of the send. However, in some cases (most
|
||||||
|
notably telnet or rlogin) small segments may need to be sent
|
||||||
|
without delay. This is less efficient than sending larger amounts of
|
||||||
|
data at a time, and can contribute to congestion on the network if
|
||||||
|
overdone.
|
||||||
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
.SH NAMES and PASSWORDS OPTIONS (Authentication)
|
||||||
.IP CURLOPT_NETRC
|
.IP CURLOPT_NETRC
|
||||||
This parameter controls the preference of libcurl between using user names and
|
This parameter controls the preference of libcurl between using user names and
|
||||||
@@ -370,7 +386,7 @@ regular old-fashioned Basic method.
|
|||||||
.IP CURLAUTH_GSSNEGOTIATE
|
.IP CURLAUTH_GSSNEGOTIATE
|
||||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
||||||
"Negotiate") method was designed by Microsoft and is used in their web
|
"Negotiate") method was designed by Microsoft and is used in their web
|
||||||
aplications. It is primarily meant as a support for Kerberos5 authentication
|
applications. It is primarily meant as a support for Kerberos5 authentication
|
||||||
but may be also used along with another authentication methods. For more
|
but may be also used along with another authentication methods. For more
|
||||||
information see IETF draft draft-brezak-spnego-http-04.txt.
|
information see IETF draft draft-brezak-spnego-http-04.txt.
|
||||||
|
|
||||||
@@ -379,17 +395,17 @@ this to work.
|
|||||||
.IP CURLAUTH_NTLM
|
.IP CURLAUTH_NTLM
|
||||||
HTTP NTLM authentication. A proprietary protocol invented and used by
|
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||||
Microsoft. It uses a challenge-response and hash concept similar to Digest, to
|
Microsoft. It uses a challenge-response and hash concept similar to Digest, to
|
||||||
prevent the password from being evesdropped.
|
prevent the password from being eavesdropped.
|
||||||
|
|
||||||
\fBNOTE\fP that you need to build libcurl with SSL support for this option to
|
\fBNOTE\fP that you need to build libcurl with SSL support for this option to
|
||||||
work.
|
work.
|
||||||
.IP CURLAUTH_ANY
|
.IP CURLAUTH_ANY
|
||||||
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
||||||
it finds suitable. libcurl will automaticly select the one it finds most
|
it finds suitable. libcurl will automatically select the one it finds most
|
||||||
secure.
|
secure.
|
||||||
.IP CURLAUTH_ANYSAFE
|
.IP CURLAUTH_ANYSAFE
|
||||||
This is a convenience macro that sets all bits except Basic and thus makes
|
This is a convenience macro that sets all bits except Basic and thus makes
|
||||||
libcurl pick any it finds suitable. libcurl will automaticly select the one it
|
libcurl pick any it finds suitable. libcurl will automatically select the one it
|
||||||
finds most secure.
|
finds most secure.
|
||||||
.RE
|
.RE
|
||||||
.IP CURLOPT_PROXYAUTH
|
.IP CURLOPT_PROXYAUTH
|
||||||
@@ -405,7 +421,7 @@ this writing, only Basic and NTLM work. (Added in 7.10.7)
|
|||||||
.SH HTTP OPTIONS
|
.SH HTTP OPTIONS
|
||||||
.IP CURLOPT_AUTOREFERER
|
.IP CURLOPT_AUTOREFERER
|
||||||
Pass a non-zero parameter to enable this. When enabled, libcurl will
|
Pass a non-zero parameter to enable this. When enabled, libcurl will
|
||||||
automaticly set the Referer: field in requests where it follows a Location:
|
automatically set the Referer: field in requests where it follows a Location:
|
||||||
redirect.
|
redirect.
|
||||||
.IP CURLOPT_ENCODING
|
.IP CURLOPT_ENCODING
|
||||||
Sets the contents of the Accept-Encoding: header sent in an HTTP
|
Sets the contents of the Accept-Encoding: header sent in an HTTP
|
||||||
@@ -422,7 +438,7 @@ encoding done by the server is ignored. See the special file
|
|||||||
lib/README.encoding for details.
|
lib/README.encoding for details.
|
||||||
.IP CURLOPT_FOLLOWLOCATION
|
.IP CURLOPT_FOLLOWLOCATION
|
||||||
A non-zero parameter tells the library to follow any Location: header that the
|
A non-zero parameter tells the library to follow any Location: header that the
|
||||||
server sends as part of a HTTP header.
|
server sends as part of an HTTP header.
|
||||||
|
|
||||||
\fBNOTE:\fP this means that the library will re-send the same request on the
|
\fBNOTE:\fP this means that the library will re-send the same request on the
|
||||||
new location and follow new Location: headers all the way until no more such
|
new location and follow new Location: headers all the way until no more such
|
||||||
@@ -447,7 +463,7 @@ one by HTML forms. See the \fICURLOPT_POSTFIELDS\fP option for how to specify
|
|||||||
the data to post and \fICURLOPT_POSTFIELDSIZE\fP in how to set the data
|
the data to post and \fICURLOPT_POSTFIELDSIZE\fP in how to set the data
|
||||||
size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option.
|
size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option.
|
||||||
.IP CURLOPT_POSTFIELDS
|
.IP CURLOPT_POSTFIELDS
|
||||||
Pass a char * as parameter, which should be the full data to post in a HTTP
|
Pass a char * as parameter, which should be the full data to post in an HTTP
|
||||||
post operation. You need to make sure that the data is formatted the way you
|
post operation. You need to make sure that the data is formatted the way you
|
||||||
want the server to receive it. libcurl will not convert or encode it for
|
want the server to receive it. libcurl will not convert or encode it for
|
||||||
you. Most web servers will assume this data to be url-encoded. Take note.
|
you. Most web servers will assume this data to be url-encoded. Take note.
|
||||||
@@ -529,9 +545,10 @@ set a cookie in the http request. The format of the string should be
|
|||||||
NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie
|
NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie
|
||||||
should contain.
|
should contain.
|
||||||
|
|
||||||
If you need to set mulitple cookies, you need to set them all using a single
|
If you need to set multiple cookies, you need to set them all using a single
|
||||||
option and thus you need to concat them all in one single string. Set multiple
|
option and thus you need to concatenate them all in one single string. Set
|
||||||
cookies in one string like this: "name1=content1; name2=content2;" etc.
|
multiple cookies in one string like this: "name1=content1; name2=content2;"
|
||||||
|
etc.
|
||||||
|
|
||||||
Using this option multiple times will only make the latest string override the
|
Using this option multiple times will only make the latest string override the
|
||||||
previously ones.
|
previously ones.
|
||||||
@@ -622,7 +639,7 @@ only files in their response to NLST; they might not include subdirectories
|
|||||||
and symbolic links.
|
and symbolic links.
|
||||||
.IP CURLOPT_FTPAPPEND
|
.IP CURLOPT_FTPAPPEND
|
||||||
A non-zero parameter tells the library to append to the remote file instead of
|
A non-zero parameter tells the library to append to the remote file instead of
|
||||||
overwrite it. This is only useful when uploading to a ftp site.
|
overwrite it. This is only useful when uploading to an ftp site.
|
||||||
.IP CURLOPT_FTP_USE_EPRT
|
.IP CURLOPT_FTP_USE_EPRT
|
||||||
Pass a long. If the value is non-zero, it tells curl to use the EPRT (and
|
Pass a long. If the value is non-zero, it tells curl to use the EPRT (and
|
||||||
LPRT) command when doing active FTP downloads (which is enabled by
|
LPRT) command when doing active FTP downloads (which is enabled by
|
||||||
@@ -684,7 +701,7 @@ Pass an curl_off_t as parameter. It contains the offset in number of bytes
|
|||||||
that you want the transfer to start from. (Added in 7.11.0)
|
that you want the transfer to start from. (Added in 7.11.0)
|
||||||
.IP CURLOPT_CUSTOMREQUEST
|
.IP CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It will be user
|
Pass a pointer to a zero terminated string as parameter. It will be user
|
||||||
instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST
|
instead of GET or HEAD when doing an HTTP request, or instead of LIST or NLST
|
||||||
when doing an ftp directory listing. This is useful for doing DELETE or other
|
when doing an ftp directory listing. This is useful for doing DELETE or other
|
||||||
more or less obscure HTTP requests. Don't do this at will, make sure your
|
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||||
server supports the command first.
|
server supports the command first.
|
||||||
@@ -863,7 +880,7 @@ key.
|
|||||||
\fBNOTE:\fPIf the crypto device cannot be loaded,
|
\fBNOTE:\fPIf the crypto device cannot be loaded,
|
||||||
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
|
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
|
||||||
.IP CURLOPT_SSLENGINE_DEFAULT
|
.IP CURLOPT_SSLENGINE_DEFAULT
|
||||||
Sets the actual crypto engine as the default for (asymetric) crypto
|
Sets the actual crypto engine as the default for (asymmetric) crypto
|
||||||
operations.
|
operations.
|
||||||
|
|
||||||
\fBNOTE:\fPIf the crypto device cannot be set,
|
\fBNOTE:\fPIf the crypto device cannot be set,
|
||||||
@@ -904,8 +921,8 @@ in the SSL handshake, set 1 to check existence, 2 to ensure that it matches
|
|||||||
the provided hostname. This is by default set to 2. (default changed in 7.10)
|
the provided hostname. This is by default set to 2. (default changed in 7.10)
|
||||||
.IP CURLOPT_SSL_CIPHER_LIST
|
.IP CURLOPT_SSL_CIPHER_LIST
|
||||||
Pass a char *, pointing to a zero terminated string holding the list of
|
Pass a char *, pointing to a zero terminated string holding the list of
|
||||||
ciphers to use for the SSL connection. The list must be syntactly correct, it
|
ciphers to use for the SSL connection. The list must be syntactically correct,
|
||||||
consists of one or more cipher strings separated by colons. Commas or spaces
|
it consists of one or more cipher strings separated by colons. Commas or spaces
|
||||||
are also acceptable separators but colons are normally used, \!, \- and \+ can
|
are also acceptable separators but colons are normally used, \!, \- and \+ can
|
||||||
be used as operators. Valid examples of cipher lists include 'RC4-SHA',
|
be used as operators. Valid examples of cipher lists include 'RC4-SHA',
|
||||||
\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
|
\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
|
||||||
|
@@ -13,7 +13,7 @@ curl_formadd - add a section to a multipart/formdata HTTP POST
|
|||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
curl_formadd() is used to append sections when building a multipart/formdata
|
curl_formadd() is used to append sections when building a multipart/formdata
|
||||||
HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at
|
HTTP POST (sometimes referred to as rfc1867-style posts). Append one section at
|
||||||
a time until you've added all the sections you want included and then you pass
|
a time until you've added all the sections you want included and then you pass
|
||||||
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||||
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
||||||
@@ -81,7 +81,7 @@ internally chosen one.
|
|||||||
|
|
||||||
.B CURLFORM_FILENAME
|
.B CURLFORM_FILENAME
|
||||||
followed by a pointer to a string to a name, will make libcurl use the given
|
followed by a pointer to a string to a name, will make libcurl use the given
|
||||||
name in the file upload part, intead of the actual file name given to
|
name in the file upload part, instead of the actual file name given to
|
||||||
\fICURLFORM_FILE\fP.
|
\fICURLFORM_FILE\fP.
|
||||||
|
|
||||||
.B BCURLFORM_BUFFER
|
.B BCURLFORM_BUFFER
|
||||||
|
@@ -36,7 +36,7 @@ This string specifies the time on a given day. Syntax supported includes:
|
|||||||
.TP
|
.TP
|
||||||
.B time zone items
|
.B time zone items
|
||||||
Specifies international time zone. There are a few acronyms supported, but in
|
Specifies international time zone. There are a few acronyms supported, but in
|
||||||
general you should instead use the specific realtive time compared to
|
general you should instead use the specific relative time compared to
|
||||||
UTC. Supported formats include: -1200, MST, +0100.
|
UTC. Supported formats include: -1200, MST, +0100.
|
||||||
.TP
|
.TP
|
||||||
.B day of the week items
|
.B day of the week items
|
||||||
|
@@ -42,7 +42,7 @@ See this table for notable exceptions.
|
|||||||
Normal printf() clone.
|
Normal printf() clone.
|
||||||
.TP
|
.TP
|
||||||
.B curl_mfprintf()
|
.B curl_mfprintf()
|
||||||
Normal fprinf() clone.
|
Normal fprintf() clone.
|
||||||
.TP
|
.TP
|
||||||
.B curl_msprintf()
|
.B curl_msprintf()
|
||||||
Normal sprintf() clone.
|
Normal sprintf() clone.
|
||||||
|
@@ -14,6 +14,17 @@ this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
|
|||||||
|
|
||||||
When an easy handle has been added to a multi stack, you can not and you must
|
When an easy handle has been added to a multi stack, you can not and you must
|
||||||
not use \fIcurl_easy_perform(3)\fP on that handle!
|
not use \fIcurl_easy_perform(3)\fP on that handle!
|
||||||
|
|
||||||
|
The easy handle will remain added until you remove it again with
|
||||||
|
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
|
||||||
|
multi stack before you terminate first the easy handle and then the multi
|
||||||
|
handle:
|
||||||
|
|
||||||
|
1 - \fIcurl_multi_remove_handle(3)\fP
|
||||||
|
|
||||||
|
2 - \fIcurl_easy_cleanup(3)\fP
|
||||||
|
|
||||||
|
3 - \fIcurl_multi_cleanup(3)\fP
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
CURLMcode type, general libcurl multi interface error code.
|
CURLMcode type, general libcurl multi interface error code.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -11,7 +11,16 @@ curl_multi_cleanup - close down a multi session
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Cleans up and removes a whole multi stack. It does not free or touch any
|
Cleans up and removes a whole multi stack. It does not free or touch any
|
||||||
individual easy handles in any way - they still need to be closed
|
individual easy handles in any way - they still need to be closed
|
||||||
individually, using the usual \fIcurl_easy_cleanup(3)\fP way.
|
individually, using the usual \fIcurl_easy_cleanup(3)\fP way. The order of
|
||||||
|
cleaning up should be:
|
||||||
|
|
||||||
|
1 - \fIcurl_multi_remove_handle(3)\fP before any easy handles are cleaned up
|
||||||
|
|
||||||
|
2 - \fIcurl_easy_cleanup(3)\fP can now be called independently since the easy
|
||||||
|
handle is no longer connected to the multi handle
|
||||||
|
|
||||||
|
3 - \fIcurl_multi_cleanup(3)\fP should be called when all easy handles are
|
||||||
|
removed
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
CURLMcode type, general libcurl multi interface error code.
|
CURLMcode type, general libcurl multi interface error code.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_multi_fdset 3 "3 May 2002" "libcurl 7.9.5" "libcurl Manual"
|
.TH curl_multi_fdset 3 "15 Apr 2004" "libcurl 7.9.5" "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
|
||||||
|
.nf
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||||
@@ -14,15 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
|||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function extracts file descriptor information from a given multi_handle.
|
This function extracts file descriptor information from a given multi_handle.
|
||||||
libcurl returns its fd_set sets. The application can use these to select() or
|
libcurl returns its fd_set sets. The application can use these to select()
|
||||||
poll() on. The curl_multi_perform() function should be called as soon as one
|
on. The \fIcurl_multi_perform(3)\fI function should be called as soon as one
|
||||||
of them are ready to be read from or written to.
|
of them are ready to be read from or written to.
|
||||||
|
|
||||||
NOTE that once this call is made, you must not remove the sets you point to,
|
NOTE that once this call is made, you must not remove the sets you point to,
|
||||||
as libcurl will need to be able to read them. It needs them after select()
|
as libcurl will need to be able to read them. It needs them after select()
|
||||||
calls, to know if certain sockets are readable or writable.
|
calls, to know if certain sockets are readable or writable.
|
||||||
|
|
||||||
|
You should also be aware that when doing select(), you should consider using a
|
||||||
|
rather small (single-digit number of seconds) timeout and call
|
||||||
|
\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
|
||||||
|
you'd think.
|
||||||
.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)"
|
||||||
|
@@ -23,7 +23,7 @@ remaining messages after this function was called.
|
|||||||
The data the returned pointer points to will not survive calling
|
The data the returned pointer points to will not survive calling
|
||||||
\fIcurl_multi_cleanup(3)\fP.
|
\fIcurl_multi_cleanup(3)\fP.
|
||||||
|
|
||||||
The 'CURLMsg' struct is very simple and only contain very basic informations.
|
The 'CURLMsg' struct is very simple and only contain very basic information.
|
||||||
If more involved information is wanted, the particular "easy handle" in
|
If more involved information is wanted, the particular "easy handle" in
|
||||||
present in that struct and can thus be used in subsequent regular
|
present in that struct and can thus be used in subsequent regular
|
||||||
\fIcurl_easy_getinfo(3)\fP calls (or similar):
|
\fIcurl_easy_getinfo(3)\fP calls (or similar):
|
||||||
|
@@ -10,7 +10,7 @@ curl_multi_init - create a multi handle
|
|||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function returns a CURLM handle to be used as input to all the other
|
This function returns a CURLM handle to be used as input to all the other
|
||||||
multi-functions, sometimes refered to as a multi handle on some places in the
|
multi-functions, sometimes referred to as a multi handle on some places in the
|
||||||
documentation. This init call MUST have a corresponding call to
|
documentation. This init call MUST have a corresponding call to
|
||||||
\fIcurl_multi_cleanup(3)\fP when the operation is complete.
|
\fIcurl_multi_cleanup(3)\fP when the operation is complete.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
@@ -19,14 +19,14 @@ integer-pointer.
|
|||||||
.SH "RETURN VALUE"
|
.SH "RETURN VALUE"
|
||||||
CURLMcode type, general libcurl multi interface error code.
|
CURLMcode type, general libcurl multi interface error code.
|
||||||
|
|
||||||
If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basicly means that you
|
If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you
|
||||||
should call \fIcurl_multi_perform\fP again, before you select() on more
|
should call \fIcurl_multi_perform\fP again, before you select() on more
|
||||||
actions. You don't have to do it immediately, but the return code means that
|
actions. 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
|
libcurl may have more data available to return or that there may be more data
|
||||||
to send off before it is "satisfied".
|
to send off before it is "satisfied".
|
||||||
|
|
||||||
NOTE that this only returns errors etc regarding the whole multi stack. There
|
NOTE that this only returns errors etc regarding the whole multi stack. There
|
||||||
might still have occurred problems on invidual 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 application will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
||||||
|
@@ -10,7 +10,7 @@ curl_share_init - Create a shared object
|
|||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function returns a CURLSH handle to be used as input to all the other
|
This function returns a CURLSH handle to be used as input to all the other
|
||||||
share-functions, sometimes refered to as a share handle on some places in the
|
share-functions, sometimes referred to as a share handle on some places in the
|
||||||
documentation. This init call MUST have a corresponding call to
|
documentation. This init call MUST have a corresponding call to
|
||||||
\fIcurl_share_cleanup\fP when all operations using the share are complete.
|
\fIcurl_share_cleanup\fP when all operations using the share are complete.
|
||||||
|
|
||||||
|
@@ -1 +1 @@
|
|||||||
.so curl_strequal.3
|
.so man3/curl_strequal.3
|
||||||
|
@@ -23,7 +23,7 @@ return until it is done (successfully or not).
|
|||||||
|
|
||||||
After the transfer has been made, you can set new options and make another
|
After the transfer has been made, you can set new options and make another
|
||||||
transfer, or if you're done, cleanup the session by calling
|
transfer, or if you're done, cleanup the session by calling
|
||||||
\fIcurl_easy_cleanup(3)\fP. If you want persistant connections, you don't
|
\fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't
|
||||||
cleanup immediately, but instead run ahead and perform other transfers using
|
cleanup immediately, but instead run ahead and perform other transfers using
|
||||||
the same easy handle.
|
the same easy handle.
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ 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 a FTP server, libcurl expects to get a certain reply back.
|
After connecting to an FTP server, libcurl expects to get a certain reply back.
|
||||||
This error code implies that it god a strange or bad reply. The given remote
|
This error code implies that it god a strange or bad reply. The given remote
|
||||||
server is probably not an OK FTP server.
|
server is probably not an OK FTP server.
|
||||||
.IP "CURLE_FTP_ACCESS_DENIED (9)"
|
.IP "CURLE_FTP_ACCESS_DENIED (9)"
|
||||||
@@ -93,7 +93,7 @@ There was a problem reading a local file or an error returned by the read
|
|||||||
callback.
|
callback.
|
||||||
.IP "CURLE_OUT_OF_MEMORY (27)"
|
.IP "CURLE_OUT_OF_MEMORY (27)"
|
||||||
Out of memory. A memory allocation request failed. This is serious badness and
|
Out of memory. A memory allocation request failed. This is serious badness and
|
||||||
things are severly screwed up if this ever occur.
|
things are severely screwed up if this ever occur.
|
||||||
.IP "CURLE_OPERATION_TIMEOUTED (28)"
|
.IP "CURLE_OPERATION_TIMEOUTED (28)"
|
||||||
Operation timeout. The specified time-out period was reached according to the
|
Operation timeout. The specified time-out period was reached according to the
|
||||||
conditions.
|
conditions.
|
||||||
@@ -106,14 +106,14 @@ specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP.
|
|||||||
The FTP REST command returned error. This should never happen if the server is
|
The FTP REST command returned error. This should never happen if the server is
|
||||||
sane.
|
sane.
|
||||||
.IP "CURLE_FTP_COULDNT_GET_SIZE (32)"
|
.IP "CURLE_FTP_COULDNT_GET_SIZE (32)"
|
||||||
The FTP SIZE command returned errror. SIZE is not a kosher FTP command, it is
|
The FTP SIZE command returned error. SIZE is not a kosher FTP command, it is
|
||||||
an extension and not all servers support it. This is not a surprising error.
|
an extension and not all servers support it. This is not a surprising error.
|
||||||
.IP "CURLE_HTTP_RANGE_ERROR (33)"
|
.IP "CURLE_HTTP_RANGE_ERROR (33)"
|
||||||
The HTTP server does not support or accept range requests.
|
The HTTP server does not support or accept range requests.
|
||||||
.IP "CURLE_HTTP_POST_ERROR (34)"
|
.IP "CURLE_HTTP_POST_ERROR (34)"
|
||||||
This is an odd error that mainly occurs due to internal confusion.
|
This is an odd error that mainly occurs due to internal confusion.
|
||||||
.IP "CURLE_SSL_CONNECT_ERROR (35)"
|
.IP "CURLE_SSL_CONNECT_ERROR (35)"
|
||||||
A problem occured somewhere in the SSL/TLS handshake. You really want the
|
A problem occurred somewhere in the SSL/TLS handshake. You really want the
|
||||||
error buffer and read the message there as it pinpoints the problem slightly
|
error buffer and read the message there as it pinpoints the problem slightly
|
||||||
more. Could be certificates (file formats, paths, permissions), passwords, and
|
more. Could be certificates (file formats, paths, permissions), passwords, and
|
||||||
others.
|
others.
|
||||||
@@ -187,8 +187,19 @@ Requested FTP SSL level failed
|
|||||||
.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.
|
interface.
|
||||||
|
.IP "CURLM_CALL_MULTI_PERFORM (-1)"
|
||||||
This is left to be documented.
|
This is not really an error. It means you should call
|
||||||
|
\fIcurl_multi_perform(3)\fP again without doing select() or similar in between.
|
||||||
|
.IP "CURLM_OK (0)"
|
||||||
|
Things are fine.
|
||||||
|
.IP "CURLM_BAD_HANDLE (1)"
|
||||||
|
The passed-in handle is not a valid CURLM handle.
|
||||||
|
.IP "CURLM_BAD_EASY_HANDLE (2)"
|
||||||
|
An easy handle was not good/valid.
|
||||||
|
.IP "CURLM_OUT_OF_MEMORY (3)"
|
||||||
|
You are doomed.
|
||||||
|
.IP "CURLM_INTERNAL_ERROR (4)"
|
||||||
|
This can only be returned if libcurl bugs. Please report it to us!
|
||||||
.SH "CURLSHcode"
|
.SH "CURLSHcode"
|
||||||
The "share" interface will return a CURLSHcode to indicate when an
|
The "share" interface will return a CURLSHcode to indicate when an
|
||||||
error has occurred.
|
error has occurred.
|
||||||
|
@@ -71,7 +71,7 @@ timeout every now and then, should you want that.
|
|||||||
|
|
||||||
A little note here about the return codes from the multi functions, and
|
A little note here about the return codes from the multi functions, and
|
||||||
especially the \fIcurl_multi_perform(3)\fP: if you receive
|
especially the \fIcurl_multi_perform(3)\fP: if you receive
|
||||||
\fICURLM_CALL_MULTI_PERFORM\fP, this basicly means that you should call
|
\fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you should call
|
||||||
\fIcurl_multi_perform(3)\fP again, before you select() on more actions. You
|
\fIcurl_multi_perform(3)\fP again, before you select() on more actions. You
|
||||||
don't have to do it immediately, but the return code means that libcurl may
|
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
|
have more data available to return or that there may be more data to send off
|
||||||
@@ -97,4 +97,4 @@ to clean them up properly.
|
|||||||
|
|
||||||
If you want to re-use an easy handle that was added to the multi handle for
|
If you want to re-use an easy handle that was added to the multi handle for
|
||||||
transfer, you must first remove it from the multi stack and then re-add it
|
transfer, you must first remove it from the multi stack and then re-add it
|
||||||
again (possbily after having altered some options at your own choice).
|
again (possibly after having altered some options at your own choice).
|
||||||
|
@@ -21,8 +21,8 @@ libcurl is complete, it \fBmust\fP call \fIcurl_global_cleanup(3)\fP. In
|
|||||||
between those two calls, you can use libcurl as described below.
|
between those two calls, you can use libcurl as described below.
|
||||||
|
|
||||||
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) transfered you have the
|
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
|
||||||
option of using the "easy" interface, or the "multi" interface.
|
the option of using the "easy" interface, or the "multi" interface.
|
||||||
|
|
||||||
The easy interface is a synchronous interface with which you call
|
The easy interface is a synchronous interface with which you call
|
||||||
\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
|
\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
|
||||||
@@ -30,7 +30,7 @@ completed, the function return and you can continue. More details are found in
|
|||||||
the \fIlibcurl-easy(3)\fP man page.
|
the \fIlibcurl-easy(3)\fP man page.
|
||||||
|
|
||||||
The multi interface on the other hand is an asynchronous interface, that you
|
The multi interface on the other hand is an asynchronous interface, that you
|
||||||
call and that performs only a little piece of the tranfer on each invoke. It
|
call and that performs only a little piece of the transfer on each invoke. It
|
||||||
is perfect if you want to do things while the transfer is in progress, or
|
is perfect if you want to do things while the transfer is in progress, or
|
||||||
similar. The multi interface allows you to select() on libcurl action, and
|
similar. The multi interface allows you to select() on libcurl action, and
|
||||||
even to easily download multiple files simultaneously using a single thread.
|
even to easily download multiple files simultaneously using a single thread.
|
||||||
@@ -56,7 +56,7 @@ portable environment variable reader
|
|||||||
get information about a performed transfer
|
get information about a performed transfer
|
||||||
.TP
|
.TP
|
||||||
.B curl_formadd()
|
.B curl_formadd()
|
||||||
helps building a HTTP form POST
|
helps building an HTTP form POST
|
||||||
.TP
|
.TP
|
||||||
.B curl_formfree()
|
.B curl_formfree()
|
||||||
free a list built with \fIcurl_formadd(3)\fP
|
free a list built with \fIcurl_formadd(3)\fP
|
||||||
|
@@ -1,8 +1,5 @@
|
|||||||
pkginclude_HEADERS = \
|
pkginclude_HEADERS = \
|
||||||
curl.h \
|
curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h
|
||||||
easy.h \
|
|
||||||
mprintf.h \
|
|
||||||
stdcheaders.h \
|
|
||||||
types.h \
|
|
||||||
multi.h
|
|
||||||
pkgincludedir= $(includedir)/curl
|
pkgincludedir= $(includedir)/curl
|
||||||
|
|
||||||
|
CLEANFILES = *dist
|
||||||
|
@@ -27,31 +27,7 @@
|
|||||||
http://curl.haxx.se/libcurl/
|
http://curl.haxx.se/libcurl/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
#include "curlver.h" /* the libcurl version defines */
|
||||||
file origins: */
|
|
||||||
#define LIBCURL_VERSION "7.11.0-CVS"
|
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
|
||||||
always follow this syntax:
|
|
||||||
|
|
||||||
0xXXYYZZ
|
|
||||||
|
|
||||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
|
||||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
|
||||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
|
||||||
|
|
||||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
|
||||||
always a greater number in a more recent release. It makes comparisons with
|
|
||||||
greater than and less than work.
|
|
||||||
*/
|
|
||||||
#define LIBCURL_VERSION_NUM 0x070b00
|
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
|
||||||
defines: */
|
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
|
||||||
#define LIBCURL_VERSION_MINOR 11
|
|
||||||
#define LIBCURL_VERSION_PATCH 0
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -786,6 +762,9 @@ typedef enum {
|
|||||||
/* The _LARGE version of the standard POSTFIELDSIZE option */
|
/* The _LARGE version of the standard POSTFIELDSIZE option */
|
||||||
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
|
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
|
||||||
|
|
||||||
|
/* Enable/disable the TCP Nagle algorithm */
|
||||||
|
CINIT(TCP_NODELAY, LONG, 121),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -804,12 +783,12 @@ typedef enum {
|
|||||||
|
|
||||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||||
the obsolete stuff removed! */
|
the obsolete stuff removed! */
|
||||||
#define CURLOPT_HTTPREQUEST 0
|
#define CURLOPT_HTTPREQUEST -1
|
||||||
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
|
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
|
||||||
#define CURLOPT_MUTE 0
|
#define CURLOPT_MUTE -2
|
||||||
#define CURLOPT_PASSWDFUNCTION 0
|
#define CURLOPT_PASSWDFUNCTION -3
|
||||||
#define CURLOPT_PASSWDDATA 0
|
#define CURLOPT_PASSWDDATA -4
|
||||||
#define CURLOPT_CLOSEFUNCTION 0
|
#define CURLOPT_CLOSEFUNCTION -5
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* This is set if CURL_NO_OLDIES is defined at compile-time */
|
/* This is set if CURL_NO_OLDIES is defined at compile-time */
|
||||||
@@ -1090,7 +1069,6 @@ void curl_slist_free_all(struct curl_slist *);
|
|||||||
*/
|
*/
|
||||||
time_t curl_getdate(const char *p, const time_t *now);
|
time_t curl_getdate(const char *p, const time_t *now);
|
||||||
|
|
||||||
|
|
||||||
#define CURLINFO_STRING 0x100000
|
#define CURLINFO_STRING 0x100000
|
||||||
#define CURLINFO_LONG 0x200000
|
#define CURLINFO_LONG 0x200000
|
||||||
#define CURLINFO_DOUBLE 0x300000
|
#define CURLINFO_DOUBLE 0x300000
|
||||||
@@ -1266,6 +1244,28 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
curl_version_info_data *curl_version_info(CURLversion);
|
curl_version_info_data *curl_version_info(CURLversion);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_easy_strerror()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* The curl_easy_strerror function may be used to turn a CURLcode value
|
||||||
|
* into the equivalent human readable error string. This is useful
|
||||||
|
* for printing meaningful error messages.
|
||||||
|
*/
|
||||||
|
const char *curl_easy_strerror(CURLcode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_share_strerror()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* The curl_share_strerror function may be used to turn a CURLSHcode value
|
||||||
|
* into the equivalent human readable error string. This is useful
|
||||||
|
* for printing meaningful error messages.
|
||||||
|
*/
|
||||||
|
const char *curl_share_strerror(CURLSHcode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
55
include/curl/curlver.h
Normal file
55
include/curl/curlver.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef __CURL_CURLVER_H
|
||||||
|
#define __CURL_CURLVER_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2004, 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$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* This header file contains nothing but libcurl version info, generated by
|
||||||
|
a script at release-time. This was made its own header file in 7.11.2 */
|
||||||
|
|
||||||
|
/* This is the version number of the libcurl package from which this header
|
||||||
|
file origins: */
|
||||||
|
#define LIBCURL_VERSION "7.11.2-CVS"
|
||||||
|
|
||||||
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
|
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||||
|
always follow this syntax:
|
||||||
|
|
||||||
|
0xXXYYZZ
|
||||||
|
|
||||||
|
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||||
|
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||||
|
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||||
|
|
||||||
|
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||||
|
always a greater number in a more recent release. It makes comparisons with
|
||||||
|
greater than and less than work.
|
||||||
|
*/
|
||||||
|
#define LIBCURL_VERSION_NUM 0x070b02
|
||||||
|
|
||||||
|
/* The numeric version number is also available "in parts" by using these
|
||||||
|
defines: */
|
||||||
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
|
#define LIBCURL_VERSION_MINOR 11
|
||||||
|
#define LIBCURL_VERSION_PATCH 2
|
||||||
|
|
||||||
|
#endif /* __CURL_CURLVER_H */
|
@@ -203,6 +203,17 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
|||||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
||||||
int *msgs_in_queue);
|
int *msgs_in_queue);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAME curl_multi_strerror()
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* The curl_multi_strerror function may be used to turn a CURLMcode value
|
||||||
|
* into the equivalent human readable error string. This is useful
|
||||||
|
* for printing meaningful error messages.
|
||||||
|
*/
|
||||||
|
const char *curl_multi_strerror(CURLMcode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,17 +1,34 @@
|
|||||||
|
#***************************************************************************
|
||||||
|
# _ _ ____ _
|
||||||
|
# Project ___| | | | _ \| |
|
||||||
|
# / __| | | | |_) | |
|
||||||
|
# | (__| |_| | _ <| |___
|
||||||
|
# \___|\___/|_| \_\_____|
|
||||||
|
#
|
||||||
|
# Copyright (C) 1998 - 2004, 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$
|
# $Id$
|
||||||
#
|
###########################################################################
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||||
|
|
||||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp curllib.dsw \
|
||||||
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
|
||||||
config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
ca-bundle.crt README.encoding README.memoryleak README.ares README.curlx \
|
||||||
README.ares makefile.dj config.dj \
|
makefile.dj config.dj libcurl.framework.make libcurl.plist libcurl.rc \
|
||||||
libcurl.framework.make libcurl.plist libcurl.rc \
|
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
|
||||||
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
|
Makefile.netware nwlib.c libcurl.imp
|
||||||
Makefile.netware nwlib.c libcurl.imp
|
|
||||||
|
|
||||||
lib_LTLIBRARIES = libcurl.la
|
lib_LTLIBRARIES = libcurl.la
|
||||||
|
|
||||||
@@ -38,16 +55,16 @@ VERSION=-version-info 2:2:0
|
|||||||
# that the current interface number gets larger faster.
|
# that the current interface number gets larger faster.
|
||||||
#
|
#
|
||||||
# 3.If the library source code has changed at all since the last update, then
|
# 3.If the library source code has changed at all since the last update, then
|
||||||
# increment revision (c:r:a becomes c:r+1:a).
|
# increment revision (c:r+1:a)
|
||||||
#
|
#
|
||||||
# 4.If any interfaces have been added, removed, or changed since the last
|
# 4.If any interfaces have been added, removed, or changed since the last
|
||||||
# update, increment current, and set revision to 0.
|
# update, increment current, and set revision to 0. (c+1:r=0:a)
|
||||||
#
|
#
|
||||||
# 5.If any interfaces have been added since the last public release, then
|
# 5.If any interfaces have been added since the last public release, then
|
||||||
# increment age.
|
# increment age. (c:r:a+1)
|
||||||
#
|
#
|
||||||
# 6.If any interfaces have been removed since the last public release, then
|
# 6.If any interfaces have been removed since the last public release, then
|
||||||
# set age to 0.
|
# set age to 0. (c:r:a=0)
|
||||||
#
|
#
|
||||||
|
|
||||||
if NO_UNDEFINED
|
if NO_UNDEFINED
|
||||||
@@ -63,20 +80,20 @@ endif
|
|||||||
|
|
||||||
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
|
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
|
||||||
|
|
||||||
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c \
|
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
|
||||||
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c \
|
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||||
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
|
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h \
|
||||||
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \
|
sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \
|
||||||
getdate.c if2ip.h speedcheck.h urldata.h getdate.h ldap.c ssluse.c \
|
getdate.c if2ip.h speedcheck.h urldata.h getdate.h ldap.c ssluse.c \
|
||||||
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c escape.h \
|
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c \
|
||||||
netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
escape.h netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
||||||
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
|
||||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
|
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c \
|
||||||
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
strtok.h connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
||||||
content_encoding.c content_encoding.h share.c share.h http_digest.c \
|
content_encoding.c content_encoding.h share.c share.h http_digest.c \
|
||||||
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
|
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
|
||||||
http_ntlm.c http_ntlm.h ca-bundle.h inet_pton.c inet_pton.h \
|
http_ntlm.c http_ntlm.h ca-bundle.h inet_pton.c inet_pton.h \
|
||||||
strtoofft.c strtoofft.h
|
strtoofft.c strtoofft.h strerror.c strerror.h
|
||||||
|
|
||||||
noinst_HEADERS = setup.h transfer.h
|
noinst_HEADERS = setup.h transfer.h
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ AR = ar
|
|||||||
RM = rm -f
|
RM = rm -f
|
||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
STRIP = strip -g
|
STRIP = strip -g
|
||||||
OPENSSL_PATH = ../../openssl-0.9.7c
|
OPENSSL_PATH = ../../openssl-0.9.7d
|
||||||
ZLIB_PATH = ../../zlib-1.2.1
|
ZLIB_PATH = ../../zlib-1.2.1
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
# files in the "cfg" directory, but then the make file
|
# files in the "cfg" directory, but then the make file
|
||||||
# in \src would need to be changed.
|
# in \src would need to be changed.
|
||||||
#
|
#
|
||||||
|
# $Id: Makefile.vc6,v 1.17 2004/01/13 08:57:01 bagder Exp $
|
||||||
##############################################################
|
##############################################################
|
||||||
# CHANGE LOG
|
# CHANGE LOG
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
@@ -37,12 +38,17 @@ LIB_NAME_DEBUG = libcurld
|
|||||||
OPENSSL_PATH = ../../openssl-0.9.7a
|
OPENSSL_PATH = ../../openssl-0.9.7a
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
!IFNDEF ZLIB_PATH
|
||||||
|
ZLIB_PATH = ../../zlib-1.1.4
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
## Nothing more to do below this line!
|
## Nothing more to do below this line!
|
||||||
|
|
||||||
CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
|
CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
|
||||||
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
|
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
|
||||||
CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||||
|
CFLAGSZLIB = /D "HAVE_ZLIB_H" /D "HAVE_ZLIB" /D "HAVE_LIBZ" /I "$(ZLIB_PATH)"
|
||||||
CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
|
CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
|
||||||
|
|
||||||
LNKDLL = link.exe /DLL /def:libcurl.def
|
LNKDLL = link.exe /DLL /def:libcurl.def
|
||||||
@@ -100,6 +106,19 @@ CFGSET = TRUE
|
|||||||
RESOURCE = $(DIROBJ)\libcurl.res
|
RESOURCE = $(DIROBJ)\libcurl.res
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
######################
|
||||||
|
# release-ssl-zlib
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "release-ssl-zlib"
|
||||||
|
TARGET =$(LIB_NAME).lib
|
||||||
|
DIROBJ =.\$(CFG)
|
||||||
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32"
|
||||||
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
|
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(TARGET)
|
||||||
|
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||||
|
CFGSET = TRUE
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# release-libcurl-ssl-dll
|
# release-libcurl-ssl-dll
|
||||||
!IF "$(CFG)" == "release-libcurl-ssl-dll"
|
!IF "$(CFG)" == "release-libcurl-ssl-dll"
|
||||||
@@ -169,6 +188,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
|||||||
!MESSAGE release - release static library
|
!MESSAGE release - release static library
|
||||||
!MESSAGE release-dll - release dll
|
!MESSAGE release-dll - release dll
|
||||||
!MESSAGE release-ssl - release static library with ssl
|
!MESSAGE release-ssl - release static library with ssl
|
||||||
|
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||||
!MESSAGE release-ssl-dll - release dll library with ssl
|
!MESSAGE release-ssl-dll - release dll library with ssl
|
||||||
!MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl
|
!MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl
|
||||||
!MESSAGE debug - debug static library
|
!MESSAGE debug - debug static library
|
||||||
@@ -222,6 +242,8 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\http_negotiate.obj \
|
$(DIROBJ)\http_negotiate.obj \
|
||||||
$(DIROBJ)\http_ntlm.obj \
|
$(DIROBJ)\http_ntlm.obj \
|
||||||
$(DIROBJ)\md5.obj \
|
$(DIROBJ)\md5.obj \
|
||||||
|
$(DIROBJ)\strerror.obj \
|
||||||
|
$(DIROBJ)\content_encoding.obj \
|
||||||
$(RESOURCE)
|
$(RESOURCE)
|
||||||
|
|
||||||
all : $(TARGET)
|
all : $(TARGET)
|
||||||
|
@@ -5,56 +5,53 @@ $Id$
|
|||||||
| (__| |_| | _ <| |___
|
| (__| |_| | _ <| |___
|
||||||
\___|\___/|_| \_\_____|
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
How To Build libcurl to Use ares For Asynch Name Resolves
|
How To Build libcurl to Use c-ares For Asynch Name Resolves
|
||||||
=========================================================
|
===========================================================
|
||||||
|
|
||||||
ares:
|
c-ares:
|
||||||
ftp://athena-dist.mit.edu/pub/ATHENA/ares/ares-1.1.1.tar.gz
|
http://daniel.haxx.se/projects/c-ares/
|
||||||
http://curl.haxx.se/dev/ares-1.1.1.tar.gz
|
|
||||||
http://curl.sourceforge.net/dev/ares-1.1.1.tar.gz
|
|
||||||
http://curl.planetmirror.com/dev/ares-1.1.1.tar.gz
|
|
||||||
http://curl.tsuren.net/dev/ares-1.1.1.tar.gz
|
|
||||||
|
|
||||||
c-ares: (a patched and improved version of ares)
|
|
||||||
http://curl.haxx.se/beta/arescurl-1.0-pre1.tar.gz
|
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
libcurl works with ares 1.1.1, but several patches and improvements have
|
libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
|
||||||
been put into the c-ares package which has made it more portable and better
|
1.2.0 or alter.
|
||||||
working on several platforms.
|
|
||||||
|
|
||||||
Build ares
|
Once upon the time libcurl built fine with the "original" ares. That is no
|
||||||
==========
|
longer true. You need to use c-ares. c-ares is based on ares but improved.
|
||||||
|
|
||||||
1. unpack the ares archive
|
Build c-ares
|
||||||
2. cd ares-dir
|
============
|
||||||
|
|
||||||
|
1. unpack the c-ares archive
|
||||||
|
2. cd c-ares-dir
|
||||||
3. ./configure
|
3. ./configure
|
||||||
4. make
|
4. make
|
||||||
|
|
||||||
Build libcurl to use ares in the curl source tree
|
Build libcurl to use c-ares in the curl source tree
|
||||||
=================================================
|
===================================================
|
||||||
|
|
||||||
1. name the ares source directory 'ares' in the curl source directory
|
1. name the c-ares source directory 'ares' in the curl source directory
|
||||||
|
(if you have checked out the curl sources from CVS, you will already have
|
||||||
|
c-ares in a directory named ares).
|
||||||
2. ./configure --enable-ares
|
2. ./configure --enable-ares
|
||||||
3. make
|
3. make
|
||||||
|
|
||||||
Build libcurl to use an installed ares
|
Build libcurl to use an installed c-ares
|
||||||
======================================
|
========================================
|
||||||
|
|
||||||
1. ./configure --enable-ares=/path/to/ares/install
|
1. ./configure --enable-ares=/path/to/ares/install
|
||||||
2. make
|
2. make
|
||||||
|
|
||||||
Ares and ipv6
|
c-ares and ipv6
|
||||||
=============
|
===============
|
||||||
|
|
||||||
If the configure script enables IPv6 support you need to explicitly disable
|
If the configure script enables IPv6 support you need to explicitly disable
|
||||||
that (--disable-ipv6) since ares isn't IPv6 compatible (yet).
|
that (--disable-ipv6) since c-ares isn't IPv6 compatible (yet).
|
||||||
|
|
||||||
Ares on win32
|
c-ares on win32
|
||||||
=============
|
===============
|
||||||
(description brought by Dominick Meglio)
|
(description brought by Dominick Meglio)
|
||||||
|
|
||||||
First I compiled curl-ares. I changed the default C runtime library to be the
|
First I compiled c-ares. I changed the default C runtime library to be the
|
||||||
single-threaded rather than the multi-threaded (this seems to be required to
|
single-threaded rather than the multi-threaded (this seems to be required to
|
||||||
prevent linking errors later on). Then I simply build the areslib project (the
|
prevent linking errors later on). Then I simply build the areslib project (the
|
||||||
other projects adig/ahost seem to fail under MSVC).
|
other projects adig/ahost seem to fail under MSVC).
|
||||||
|
43
lib/README.curlx
Normal file
43
lib/README.curlx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
$Id$
|
||||||
|
_ _ ____ _
|
||||||
|
___| | | | _ \| |
|
||||||
|
/ __| | | | |_) | |
|
||||||
|
| (__| |_| | _ <| |___
|
||||||
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
|
Source Code Functions Apps Might Use
|
||||||
|
====================================
|
||||||
|
|
||||||
|
The libcurl source code offers a few functions by source only. They are not
|
||||||
|
part of the official libcurl API, but the source files might be useful for
|
||||||
|
others so apps can optionally compile/build with these sources to gain
|
||||||
|
additional functions.
|
||||||
|
|
||||||
|
|
||||||
|
strtoofft.[ch]
|
||||||
|
==============
|
||||||
|
|
||||||
|
curlx_strtoofft()
|
||||||
|
|
||||||
|
A macro that converts a string containing a number to a curl_off_t number.
|
||||||
|
This might use the curlx_strtoll() function which is provided as source
|
||||||
|
code in strtoofft.c. Note that the function is only provided if no
|
||||||
|
strtoll() (or equivalent) function exist on your platform. If curl_off_t
|
||||||
|
is only a 32 bit number on your platform, this macro uses strtol().
|
||||||
|
|
||||||
|
timeval.[ch]
|
||||||
|
============
|
||||||
|
|
||||||
|
Provides a 'struct timeval' for platforms that don't have one already, and
|
||||||
|
includes the proper include files for those that have one. Using this will
|
||||||
|
make the output require the 'winmm' lib on Windows (unless WITHOUT_MM_LIB
|
||||||
|
is defined at compile-time).
|
||||||
|
|
||||||
|
curlx_tvnow()
|
||||||
|
|
||||||
|
returns a struct timeval for the current time.
|
||||||
|
|
||||||
|
curlx_tvdiff()
|
||||||
|
|
||||||
|
returns the difference between two timeval structs, in number of
|
||||||
|
milliseconds.
|
@@ -25,10 +25,12 @@
|
|||||||
#define HAVE_IO_H 1
|
#define HAVE_IO_H 1
|
||||||
#define HAVE_IOCTLSOCKET 1
|
#define HAVE_IOCTLSOCKET 1
|
||||||
#define HAVE_INET_PTON 1
|
#define HAVE_INET_PTON 1
|
||||||
|
#define HAVE_LONGLONG 1
|
||||||
#define HAVE_MALLOC_H 1
|
#define HAVE_MALLOC_H 1
|
||||||
#define HAVE_MEMORY_H 1
|
#define HAVE_MEMORY_H 1
|
||||||
#define HAVE_NETDB_H 1
|
#define HAVE_NETDB_H 1
|
||||||
#define HAVE_NETINET_IN_H 1
|
#define HAVE_NETINET_IN_H 1
|
||||||
|
#define HAVE_NETINET_TCP_H 1
|
||||||
#define HAVE_NET_IF_H 1
|
#define HAVE_NET_IF_H 1
|
||||||
#define HAVE_PERROR 1
|
#define HAVE_PERROR 1
|
||||||
#define HAVE_SELECT 1
|
#define HAVE_SELECT 1
|
||||||
@@ -38,12 +40,14 @@
|
|||||||
#define HAVE_SIGACTION 1
|
#define HAVE_SIGACTION 1
|
||||||
#define HAVE_SIGSETJMP 1
|
#define HAVE_SIGSETJMP 1
|
||||||
#define HAVE_SOCKET 1
|
#define HAVE_SOCKET 1
|
||||||
|
#define HAVE_SPNEGO 1
|
||||||
#define HAVE_STRCASECMP 1
|
#define HAVE_STRCASECMP 1
|
||||||
#define HAVE_STRDUP 1
|
#define HAVE_STRDUP 1
|
||||||
#define HAVE_STRFTIME 1
|
#define HAVE_STRFTIME 1
|
||||||
#define HAVE_STRICMP 1
|
#define HAVE_STRICMP 1
|
||||||
#define HAVE_STRSTR 1
|
#define HAVE_STRSTR 1
|
||||||
#define HAVE_STRTOLL 1
|
#define HAVE_STRTOLL 1
|
||||||
|
#define HAVE_SYS_IOCTL_H 1
|
||||||
#define HAVE_SYS_SOCKET_H 1
|
#define HAVE_SYS_SOCKET_H 1
|
||||||
#define HAVE_SYS_STAT_H 1
|
#define HAVE_SYS_STAT_H 1
|
||||||
#define HAVE_SYS_TYPES_H 1
|
#define HAVE_SYS_TYPES_H 1
|
||||||
@@ -53,9 +57,13 @@
|
|||||||
#define HAVE_UNISTD_H 1
|
#define HAVE_UNISTD_H 1
|
||||||
#define HAVE_VPRINTF 1
|
#define HAVE_VPRINTF 1
|
||||||
|
|
||||||
|
#if (DJGPP_MINOR >= 4)
|
||||||
|
#define HAVE_STRLCAT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RETSIGTYPE void
|
#define RETSIGTYPE void
|
||||||
#define SIZEOF_LONG_DOUBLE 16
|
#define SIZEOF_LONG_DOUBLE 16
|
||||||
#define SIZEOF_LONG_LONG 8
|
#define SIZEOF_CURL_OFF_T 4 /* no huge file support */
|
||||||
#define STDC_HEADERS 1
|
#define STDC_HEADERS 1
|
||||||
#define TIME_WITH_SYS_TIME 1
|
#define TIME_WITH_SYS_TIME 1
|
||||||
|
|
||||||
|
@@ -32,7 +32,15 @@
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_TCP_H
|
||||||
|
#include <netinet/tcp.h> /* for TCP_NODELAY */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -86,6 +94,7 @@
|
|||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "if2ip.h"
|
#include "if2ip.h"
|
||||||
|
#include "strerror.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
@@ -138,7 +147,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
|||||||
|
|
||||||
#ifdef HAVE_IOCTLSOCKET
|
#ifdef HAVE_IOCTLSOCKET
|
||||||
/* Windows? */
|
/* Windows? */
|
||||||
int flags;
|
unsigned long flags;
|
||||||
flags = nonblock;
|
flags = nonblock;
|
||||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||||
#define SETBLOCK 3
|
#define SETBLOCK 3
|
||||||
@@ -295,10 +304,10 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
data->set.device, strlen(data->set.device)+1) != 0) {
|
data->set.device, strlen(data->set.device)+1) != 0) {
|
||||||
/* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
|
/* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
|
||||||
sockfd, data->set.device, strerror(errno)); */
|
sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */
|
||||||
infof(data, "SO_BINDTODEVICE %s failed\n",
|
infof(data, "SO_BINDTODEVICE %s failed\n",
|
||||||
data->set.device);
|
data->set.device);
|
||||||
/* This is typiclally "errno 1, error: Operation not permitted" if
|
/* This is typically "errno 1, error: Operation not permitted" if
|
||||||
you're not running as root or another suitable privileged user */
|
you're not running as root or another suitable privileged user */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,37 +362,9 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!bindworked) {
|
if(!bindworked) {
|
||||||
switch(errno) {
|
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
|
||||||
case EBADF:
|
|
||||||
failf(data, "Invalid descriptor: %d", errno);
|
|
||||||
break;
|
|
||||||
case EINVAL:
|
|
||||||
failf(data, "Invalid request: %d", errno);
|
|
||||||
break;
|
|
||||||
case EACCES:
|
|
||||||
failf(data, "Address is protected, user not superuser: %d", errno);
|
|
||||||
break;
|
|
||||||
case ENOTSOCK:
|
|
||||||
failf(data,
|
|
||||||
"Argument is a descriptor for a file, not a socket: %d",
|
|
||||||
errno);
|
|
||||||
break;
|
|
||||||
case EFAULT:
|
|
||||||
failf(data, "Inaccessable memory error: %d", errno);
|
|
||||||
break;
|
|
||||||
case ENAMETOOLONG:
|
|
||||||
failf(data, "Address too long: %d", errno);
|
|
||||||
break;
|
|
||||||
case ENOMEM:
|
|
||||||
failf(data, "Insufficient kernel memory was available: %d", errno);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
failf(data, "errno %d", errno);
|
|
||||||
break;
|
|
||||||
} /* end of switch(errno) */
|
|
||||||
|
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
} /* end of else */
|
}
|
||||||
|
|
||||||
} /* end of if h */
|
} /* end of if h */
|
||||||
else {
|
else {
|
||||||
@@ -488,8 +469,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else if(1 != rc) {
|
else if(1 != rc) {
|
||||||
int error = Curl_ourerrno();
|
int error = Curl_ourerrno();
|
||||||
failf(data, "Failed connect to %s:%d, errno: %d",
|
failf(data, "Failed connect to %s:%d; %s",
|
||||||
conn->hostname, conn->port, error);
|
conn->hostname, conn->port, Curl_strerror(conn,error));
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -503,6 +484,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Curl_setNoDelay(struct connectdata *conn,
|
||||||
|
curl_socket_t sockfd)
|
||||||
|
{
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
struct SessionHandle *data= conn->data;
|
||||||
|
socklen_t onoff = (socklen_t) data->set.tcp_nodelay;
|
||||||
|
if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&onoff,
|
||||||
|
sizeof(onoff)) < 0)
|
||||||
|
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||||
|
Curl_strerror(conn, Curl_ourerrno()));
|
||||||
|
else
|
||||||
|
infof(data,"TCP_NODELAY set\n");
|
||||||
|
#else
|
||||||
|
(void)conn;
|
||||||
|
(void)sockfd;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TCP connect to the given host with timeout, proxy or remote doesn't matter.
|
* TCP connect to the given host with timeout, proxy or remote doesn't matter.
|
||||||
@@ -581,6 +579,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
if (sockfd == CURL_SOCKET_BAD)
|
if (sockfd == CURL_SOCKET_BAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
else if(data->set.tcp_nodelay)
|
||||||
|
Curl_setNoDelay(conn, sockfd);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Connecting with old style IPv4-only support
|
* Connecting with old style IPv4-only support
|
||||||
@@ -600,6 +601,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
return CURLE_COULDNT_CONNECT; /* big time error */
|
return CURLE_COULDNT_CONNECT; /* big time error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(data->set.tcp_nodelay)
|
||||||
|
Curl_setNoDelay(conn, sockfd);
|
||||||
|
|
||||||
/* nasty address work before connect can be made */
|
/* nasty address work before connect can be made */
|
||||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||||
memcpy((char *)&(serv_addr.sin_addr),
|
memcpy((char *)&(serv_addr.sin_addr),
|
||||||
@@ -651,8 +655,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unknown error, fallthrough and try another address! */
|
/* unknown error, fallthrough and try another address! */
|
||||||
failf(data, "Failed to connect to %s IP number %d: %d",
|
failf(data, "Failed to connect to %s IP number %d: %s",
|
||||||
hostname, aliasindex+1, error);
|
hostname, aliasindex+1, Curl_strerror(conn,error));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,7 +696,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
if (sockfd == CURL_SOCKET_BAD) {
|
if (sockfd == CURL_SOCKET_BAD) {
|
||||||
/* no good connect was made */
|
/* no good connect was made */
|
||||||
*sockconn = -1;
|
*sockconn = -1;
|
||||||
failf(data, "Connect failed");
|
failf(data, "Connect failed; %s", Curl_strerror(conn,Curl_ourerrno()));
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -43,7 +43,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c
|
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
@@ -70,7 +70,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
|
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
|
||||||
# SUBTRACT CPP /WX /YX
|
# SUBTRACT CPP /WX /YX
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
@@ -271,7 +271,7 @@ CURLcode curl_easy_perform(CURL *curl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!data->hostcache) {
|
if (!data->hostcache) {
|
||||||
data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
data->hostcache = Curl_mk_dnscache();
|
||||||
|
|
||||||
if(!data->hostcache)
|
if(!data->hostcache)
|
||||||
/* While we possibly could survive and do good without a host cache,
|
/* While we possibly could survive and do good without a host cache,
|
||||||
|
@@ -196,7 +196,7 @@ CURLcode Curl_file(struct connectdata *conn)
|
|||||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||||
information. Which for FILE can't be much more than the file size and
|
information. Which for FILE can't be much more than the file size and
|
||||||
date. */
|
date. */
|
||||||
if(data->set.no_body && data->set.include_header && fstated) {
|
if(conn->bits.no_body && data->set.include_header && fstated) {
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
|
sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
|
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
|
||||||
|
115
lib/formdata.c
115
lib/formdata.c
@@ -176,7 +176,7 @@ int FormParse(char *input,
|
|||||||
struct curl_httppost **httppost,
|
struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post)
|
struct curl_httppost **last_post)
|
||||||
{
|
{
|
||||||
/* nextarg MUST be a string in the format 'name=contents' and we'll
|
/* 'input' MUST be a string in the format 'name=contents' and we'll
|
||||||
build a linked list with the info */
|
build a linked list with the info */
|
||||||
char name[256];
|
char name[256];
|
||||||
char *contents;
|
char *contents;
|
||||||
@@ -975,9 +975,13 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* curl_formadd() is a public API to add a section to the multipart formpost.
|
||||||
|
*/
|
||||||
|
|
||||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
struct curl_httppost **last_post,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
CURLFORMcode result;
|
CURLFORMcode result;
|
||||||
@@ -987,6 +991,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AddFormData() adds a chunk of data to the FormData linked list.
|
||||||
|
*/
|
||||||
static size_t AddFormData(struct FormData **formp,
|
static size_t AddFormData(struct FormData **formp,
|
||||||
const void *line,
|
const void *line,
|
||||||
size_t length)
|
size_t length)
|
||||||
@@ -1014,9 +1021,12 @@ static size_t AddFormData(struct FormData **formp,
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AddFormDataf() adds printf()-style formatted data to the formdata chain.
|
||||||
|
*/
|
||||||
|
|
||||||
static size_t AddFormDataf(struct FormData **formp,
|
static size_t AddFormDataf(struct FormData **formp,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char s[4096];
|
char s[4096];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -1027,7 +1037,10 @@ static size_t AddFormDataf(struct FormData **formp,
|
|||||||
return AddFormData(formp, s, 0);
|
return AddFormData(formp, s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_FormBoundary() creates a suitable boundary string and returns an
|
||||||
|
* allocated one.
|
||||||
|
*/
|
||||||
char *Curl_FormBoundary(void)
|
char *Curl_FormBoundary(void)
|
||||||
{
|
{
|
||||||
char *retstring;
|
char *retstring;
|
||||||
@@ -1056,7 +1069,10 @@ char *Curl_FormBoundary(void)
|
|||||||
return retstring;
|
return retstring;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used from http.c, this cleans a built FormData linked list */
|
/*
|
||||||
|
* Curl_formclean() is used from http.c, this cleans a built FormData linked
|
||||||
|
* list
|
||||||
|
*/
|
||||||
void Curl_formclean(struct FormData *form)
|
void Curl_formclean(struct FormData *form)
|
||||||
{
|
{
|
||||||
struct FormData *next;
|
struct FormData *next;
|
||||||
@@ -1069,7 +1085,10 @@ void Curl_formclean(struct FormData *form)
|
|||||||
} while((form=next)); /* continue */
|
} while((form=next)); /* continue */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* external function to free up a whole form post chain */
|
/*
|
||||||
|
* curl_formfree() is an external function to free up a whole form post
|
||||||
|
* chain
|
||||||
|
*/
|
||||||
void curl_formfree(struct curl_httppost *form)
|
void curl_formfree(struct curl_httppost *form)
|
||||||
{
|
{
|
||||||
struct curl_httppost *next;
|
struct curl_httppost *next;
|
||||||
@@ -1098,6 +1117,13 @@ void curl_formfree(struct curl_httppost *form)
|
|||||||
} while((form=next)); /* continue */
|
} while((form=next)); /* continue */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_getFormData() converts a linked list of "meta data" into a complete
|
||||||
|
* (possibly huge) multipart formdata. The input list is in 'post', while the
|
||||||
|
* output resulting linked lists gets stored in '*finalform'. *sizep will get
|
||||||
|
* the total size of the whole POST.
|
||||||
|
*/
|
||||||
|
|
||||||
CURLcode Curl_getFormData(struct FormData **finalform,
|
CURLcode Curl_getFormData(struct FormData **finalform,
|
||||||
struct curl_httppost *post,
|
struct curl_httppost *post,
|
||||||
curl_off_t *sizep)
|
curl_off_t *sizep)
|
||||||
@@ -1218,11 +1244,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
|||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t nread;
|
size_t nread;
|
||||||
|
|
||||||
fileread = strequal("-", file->contents)?stdin:
|
fileread = strequal("-", file->contents)?
|
||||||
/* binary read for win32 crap */
|
stdin:fopen(file->contents, "rb"); /* binary read for win32 */
|
||||||
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */
|
/*
|
||||||
/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */
|
* VMS: This only allows for stream files on VMS. Stream files are
|
||||||
/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
|
* OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
|
||||||
|
* every record needs to have a \n appended & 1 added to SIZE
|
||||||
|
*/
|
||||||
|
|
||||||
if(fileread) {
|
if(fileread) {
|
||||||
while((nread = fread(buffer, 1, 1024, fileread)))
|
while((nread = fread(buffer, 1, 1024, fileread)))
|
||||||
size += AddFormData(&form, buffer, nread);
|
size += AddFormData(&form, buffer, nread);
|
||||||
@@ -1231,10 +1260,6 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
|||||||
fclose(fileread);
|
fclose(fileread);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if 0
|
|
||||||
/* File wasn't found, add a nothing field! */
|
|
||||||
size += AddFormData(&form, "", 0);
|
|
||||||
#endif
|
|
||||||
Curl_formclean(firstform);
|
Curl_formclean(firstform);
|
||||||
free(boundary);
|
free(boundary);
|
||||||
*finalform = NULL;
|
*finalform = NULL;
|
||||||
@@ -1278,6 +1303,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_FormInit() inits the struct 'form' points to with the 'formdata'
|
||||||
|
* and resets the 'sent' counter.
|
||||||
|
*/
|
||||||
int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
||||||
{
|
{
|
||||||
if(!formdata)
|
if(!formdata)
|
||||||
@@ -1289,7 +1318,10 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fread() emulation */
|
/*
|
||||||
|
* Curl_FormReader() is the fread() emulation function that will be used to
|
||||||
|
* deliver the formdata to the transfer loop and then sent away to the peer.
|
||||||
|
*/
|
||||||
size_t Curl_FormReader(char *buffer,
|
size_t Curl_FormReader(char *buffer,
|
||||||
size_t size,
|
size_t size,
|
||||||
size_t nitems,
|
size_t nitems,
|
||||||
@@ -1335,48 +1367,25 @@ size_t Curl_FormReader(char *buffer,
|
|||||||
return gotsize;
|
return gotsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* possible (old) fread() emulation that copies at most one line */
|
/*
|
||||||
size_t Curl_FormReadOneLine(char *buffer,
|
* Curl_formpostheader() returns the first line of the formpost, the
|
||||||
size_t size,
|
* request-header part (which is not part of the request-body like the rest of
|
||||||
size_t nitems,
|
* the post).
|
||||||
FILE *mydata)
|
*/
|
||||||
|
char *Curl_formpostheader(void *formp, size_t *len)
|
||||||
{
|
{
|
||||||
struct Form *form;
|
char *header;
|
||||||
size_t wantedsize;
|
struct Form *form=(struct Form *)formp;
|
||||||
size_t gotsize;
|
|
||||||
|
|
||||||
form=(struct Form *)mydata;
|
|
||||||
|
|
||||||
wantedsize = size * nitems;
|
|
||||||
|
|
||||||
if(!form->data)
|
if(!form->data)
|
||||||
return 0; /* nothing, error, empty */
|
return 0; /* nothing, ERROR! */
|
||||||
|
|
||||||
do {
|
header = form->data->line;
|
||||||
|
*len = form->data->length;
|
||||||
|
|
||||||
if( (form->data->length - form->sent ) > wantedsize ) {
|
form->data = form->data->next; /* advance */
|
||||||
|
|
||||||
memcpy(buffer, form->data->line + form->sent, wantedsize);
|
return header;
|
||||||
|
|
||||||
form->sent += wantedsize;
|
|
||||||
|
|
||||||
return wantedsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer,
|
|
||||||
form->data->line + form->sent,
|
|
||||||
gotsize = (form->data->length - form->sent) );
|
|
||||||
|
|
||||||
form->sent = 0;
|
|
||||||
|
|
||||||
form->data = form->data->next; /* advance */
|
|
||||||
|
|
||||||
} while(!gotsize && form->data);
|
|
||||||
/* If we got an empty line and we have more data, we proceed to the next
|
|
||||||
line immediately to avoid returning zero before we've reached the end.
|
|
||||||
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
|
|
||||||
|
|
||||||
return gotsize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -65,11 +65,12 @@ size_t Curl_FormReader(char *buffer,
|
|||||||
size_t nitems,
|
size_t nitems,
|
||||||
FILE *mydata);
|
FILE *mydata);
|
||||||
|
|
||||||
/* possible (old) fread() emulation that copies at most one line */
|
/*
|
||||||
size_t Curl_FormReadOneLine(char *buffer,
|
* Curl_formpostheader() returns the first line of the formpost, the
|
||||||
size_t size,
|
* request-header part (which is not part of the request-body like the rest of
|
||||||
size_t nitems,
|
* the post).
|
||||||
FILE *mydata);
|
*/
|
||||||
|
char *Curl_formpostheader(void *formp, size_t *len);
|
||||||
|
|
||||||
char *Curl_FormBoundary(void);
|
char *Curl_FormBoundary(void);
|
||||||
|
|
||||||
|
170
lib/ftp.c
170
lib/ftp.c
@@ -91,6 +91,7 @@
|
|||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "ssluse.h"
|
#include "ssluse.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
|
#include "strerror.h"
|
||||||
|
|
||||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||||
#include "inet_ntoa_r.h"
|
#include "inet_ntoa_r.h"
|
||||||
@@ -104,12 +105,19 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_NI_WITHSCOPEID
|
||||||
|
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
|
||||||
|
#else
|
||||||
|
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Local API functions */
|
/* Local API functions */
|
||||||
static CURLcode ftp_sendquote(struct connectdata *conn,
|
static CURLcode ftp_sendquote(struct connectdata *conn,
|
||||||
struct curl_slist *quote);
|
struct curl_slist *quote);
|
||||||
static CURLcode ftp_cwd(struct connectdata *conn, char *path);
|
static CURLcode ftp_cwd(struct connectdata *conn, char *path);
|
||||||
static CURLcode ftp_mkd(struct connectdata *conn, char *path);
|
static CURLcode ftp_mkd(struct connectdata *conn, char *path);
|
||||||
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
|
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
|
||||||
|
static CURLcode ftp_quit(struct connectdata *conn);
|
||||||
|
|
||||||
/* easy-to-use macro: */
|
/* easy-to-use macro: */
|
||||||
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
|
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
|
||||||
@@ -117,9 +125,19 @@ static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
|
|||||||
static void freedirs(struct FTP *ftp)
|
static void freedirs(struct FTP *ftp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; ftp->dirs[i]; i++){
|
if(ftp->dirs) {
|
||||||
free(ftp->dirs[i]);
|
for (i=0; i < ftp->dirdepth; i++){
|
||||||
ftp->dirs[i]=NULL;
|
if(ftp->dirs[i]) {
|
||||||
|
free(ftp->dirs[i]);
|
||||||
|
ftp->dirs[i]=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(ftp->dirs);
|
||||||
|
ftp->dirs = NULL;
|
||||||
|
}
|
||||||
|
if(ftp->file) {
|
||||||
|
free(ftp->file);
|
||||||
|
ftp->file = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,6 +357,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
|||||||
* line */
|
* line */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
conn->headerbytecount += gotbytes;
|
||||||
|
|
||||||
*nreadp += gotbytes;
|
*nreadp += gotbytes;
|
||||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||||
perline++;
|
perline++;
|
||||||
@@ -585,22 +605,22 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
|||||||
infof(data, "We have successfully logged in\n");
|
infof(data, "We have successfully logged in\n");
|
||||||
if (conn->ssl[FIRSTSOCKET].use) {
|
if (conn->ssl[FIRSTSOCKET].use) {
|
||||||
#ifdef HAVE_KRB4
|
#ifdef HAVE_KRB4
|
||||||
/* we are logged in (with Kerberos)
|
/* We are logged in with Kerberos, now set the requested protection
|
||||||
* now set the requested protection level
|
* level
|
||||||
*/
|
*/
|
||||||
if(conn->sec_complete)
|
if(conn->sec_complete)
|
||||||
Curl_sec_set_protection_level(conn);
|
Curl_sec_set_protection_level(conn);
|
||||||
|
|
||||||
/* we may need to issue a KAUTH here to have access to the files
|
/* We may need to issue a KAUTH here to have access to the files
|
||||||
* do it if user supplied a password
|
* do it if user supplied a password
|
||||||
*/
|
*/
|
||||||
if(conn->passwd && *conn->passwd) {
|
if(conn->passwd && *conn->passwd) {
|
||||||
result = Curl_krb_kauth(conn);
|
result = Curl_krb_kauth(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "Odd return code after USER");
|
failf(data, "Odd return code after USER");
|
||||||
@@ -724,14 +744,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
|||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
int ftpcode;
|
int ftpcode;
|
||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
|
bool was_ctl_valid = ftp->ctl_valid;
|
||||||
|
|
||||||
/* free the dir tree parts */
|
/* free the dir tree and file parts */
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
|
|
||||||
if(ftp->file) {
|
ftp->ctl_valid = FALSE;
|
||||||
free(ftp->file);
|
|
||||||
ftp->file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data->set.upload) {
|
if(data->set.upload) {
|
||||||
if((-1 != data->set.infilesize) &&
|
if((-1 != data->set.infilesize) &&
|
||||||
@@ -766,6 +784,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ftp->ctl_valid = was_ctl_valid;
|
||||||
|
|
||||||
#ifdef HAVE_KRB4
|
#ifdef HAVE_KRB4
|
||||||
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
|
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
#endif
|
#endif
|
||||||
@@ -954,7 +974,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
|
|||||||
|
|
||||||
if(ftpcode == 213) {
|
if(ftpcode == 213) {
|
||||||
/* get the size from the ascii string: */
|
/* get the size from the ascii string: */
|
||||||
*size = strtoofft(buf+4, NULL, 0);
|
*size = curlx_strtoofft(buf+4, NULL, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CURLE_FTP_COULDNT_GET_SIZE;
|
return CURLE_FTP_COULDNT_GET_SIZE;
|
||||||
@@ -1073,14 +1093,9 @@ ftp_pasv_verbose(struct connectdata *conn,
|
|||||||
char hbuf[NI_MAXHOST]; /* ~1KB */
|
char hbuf[NI_MAXHOST]; /* ~1KB */
|
||||||
char nbuf[NI_MAXHOST]; /* ~1KB */
|
char nbuf[NI_MAXHOST]; /* ~1KB */
|
||||||
char sbuf[NI_MAXSERV]; /* around 32 */
|
char sbuf[NI_MAXSERV]; /* around 32 */
|
||||||
#ifdef NI_WITHSCOPEID
|
|
||||||
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
|
||||||
#else
|
|
||||||
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
|
||||||
#endif
|
|
||||||
(void)port; /* prevent compiler warning */
|
(void)port; /* prevent compiler warning */
|
||||||
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
||||||
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {
|
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), NIFLAGS)) {
|
||||||
snprintf(nbuf, sizeof(nbuf), "?");
|
snprintf(nbuf, sizeof(nbuf), "?");
|
||||||
snprintf(sbuf, sizeof(sbuf), "?");
|
snprintf(sbuf, sizeof(sbuf), "?");
|
||||||
}
|
}
|
||||||
@@ -1126,11 +1141,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
|
|
||||||
struct sockaddr *sa=(struct sockaddr *)&ss;
|
struct sockaddr *sa=(struct sockaddr *)&ss;
|
||||||
#ifdef NI_WITHSCOPEID
|
|
||||||
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
|
|
||||||
#else
|
|
||||||
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
|
|
||||||
#endif
|
|
||||||
unsigned char *ap;
|
unsigned char *ap;
|
||||||
unsigned char *pp;
|
unsigned char *pp;
|
||||||
char portmsgbuf[4096], tmp[4096];
|
char portmsgbuf[4096], tmp[4096];
|
||||||
@@ -1138,6 +1148,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
|
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
|
||||||
char **modep;
|
char **modep;
|
||||||
int rc;
|
int rc;
|
||||||
|
int error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we should use Curl_if2ip? given pickiness of recent ftpd,
|
* we should use Curl_if2ip? given pickiness of recent ftpd,
|
||||||
@@ -1172,6 +1183,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
portsock = CURL_SOCKET_BAD;
|
portsock = CURL_SOCKET_BAD;
|
||||||
|
error = 0;
|
||||||
for (ai = res; ai; ai = ai->ai_next) {
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
/*
|
/*
|
||||||
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
|
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
|
||||||
@@ -1180,16 +1192,20 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
ai->ai_socktype = hints.ai_socktype;
|
ai->ai_socktype = hints.ai_socktype;
|
||||||
|
|
||||||
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
if (portsock == CURL_SOCKET_BAD)
|
if (portsock == CURL_SOCKET_BAD) {
|
||||||
|
error = Curl_ourerrno();
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
error = Curl_ourerrno();
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
portsock = CURL_SOCKET_BAD;
|
portsock = CURL_SOCKET_BAD;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(portsock, 1) < 0) {
|
if (listen(portsock, 1) < 0) {
|
||||||
|
error = Curl_ourerrno();
|
||||||
sclose(portsock);
|
sclose(portsock);
|
||||||
portsock = CURL_SOCKET_BAD;
|
portsock = CURL_SOCKET_BAD;
|
||||||
continue;
|
continue;
|
||||||
@@ -1199,13 +1215,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
if (portsock == CURL_SOCKET_BAD) {
|
if (portsock == CURL_SOCKET_BAD) {
|
||||||
failf(data, "%s", strerror(errno));
|
failf(data, "%s", Curl_strerror(conn,error));
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sslen = sizeof(ss);
|
sslen = sizeof(ss);
|
||||||
if (getsockname(portsock, sa, &sslen) < 0) {
|
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||||
failf(data, "%s", strerror(errno));
|
failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1248,16 +1264,17 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
/* do not transmit IPv6 scope identifier to the wire */
|
/* do not transmit IPv6 scope identifier to the wire */
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (sa->sa_family == AF_INET6) {
|
||||||
char *q = strchr(portmsgbuf, '%');
|
char *q = strchr(portmsgbuf, '%');
|
||||||
if (q)
|
if (q)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
||||||
portmsgbuf, tmp);
|
portmsgbuf, tmp);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
} else if (strcmp(*modep, "LPRT") == 0 ||
|
}
|
||||||
strcmp(*modep, "PORT") == 0) {
|
else if (strcmp(*modep, "LPRT") == 0 ||
|
||||||
|
strcmp(*modep, "PORT") == 0) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
||||||
@@ -1602,7 +1619,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
|
|||||||
newport = num;
|
newport = num;
|
||||||
|
|
||||||
/* we should use the same host we already are connected to */
|
/* we should use the same host we already are connected to */
|
||||||
newhostp = conn->name;
|
newhostp = conn->hostname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1834,7 +1851,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(!data->set.no_body) {
|
else if(!conn->bits.no_body) {
|
||||||
/* Retrieve file or directory */
|
/* Retrieve file or directory */
|
||||||
bool dirlist=FALSE;
|
bool dirlist=FALSE;
|
||||||
curl_off_t downloadsize=-1;
|
curl_off_t downloadsize=-1;
|
||||||
@@ -1845,10 +1862,10 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
char *ptr;
|
char *ptr;
|
||||||
char *ptr2;
|
char *ptr2;
|
||||||
|
|
||||||
from=strtoofft(conn->range, &ptr, 0);
|
from=curlx_strtoofft(conn->range, &ptr, 0);
|
||||||
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
|
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
|
||||||
ptr++;
|
ptr++;
|
||||||
to=strtoofft(ptr, &ptr2, 0);
|
to=curlx_strtoofft(ptr, &ptr2, 0);
|
||||||
if(ptr == ptr2) {
|
if(ptr == ptr2) {
|
||||||
/* we didn't get any digit */
|
/* we didn't get any digit */
|
||||||
to=-1;
|
to=-1;
|
||||||
@@ -2067,7 +2084,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
/* only if we have nothing but digits: */
|
/* only if we have nothing but digits: */
|
||||||
if(bytes++) {
|
if(bytes++) {
|
||||||
/* get the number! */
|
/* get the number! */
|
||||||
size = strtoofft(bytes, NULL, 0);
|
size = curlx_strtoofft(bytes, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2156,7 +2173,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
|
|
||||||
{
|
{
|
||||||
int i; /* counter for loop */
|
int i; /* counter for loop */
|
||||||
for (i=0; ftp->dirs[i]; i++) {
|
for (i=0; i < ftp->dirdepth; i++) {
|
||||||
/* RFC 1738 says empty components should be respected too, but
|
/* RFC 1738 says empty components should be respected too, but
|
||||||
that is plain stupid since CWD can't be used with an empty argument */
|
that is plain stupid since CWD can't be used with an empty argument */
|
||||||
if ((result = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
|
if ((result = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
|
||||||
@@ -2205,7 +2222,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||||
information. Which in FTP can't be much more than the file size and
|
information. Which in FTP can't be much more than the file size and
|
||||||
date. */
|
date. */
|
||||||
if(data->set.no_body && data->set.include_header && ftp->file) {
|
if(conn->bits.no_body && data->set.include_header && ftp->file) {
|
||||||
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers
|
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers
|
||||||
may not support it! It is however the only way we have to get a file's
|
may not support it! It is however the only way we have to get a file's
|
||||||
size! */
|
size! */
|
||||||
@@ -2268,7 +2285,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.no_body)
|
if(conn->bits.no_body)
|
||||||
/* doesn't really transfer any data */
|
/* doesn't really transfer any data */
|
||||||
ftp->no_transfer = TRUE;
|
ftp->no_transfer = TRUE;
|
||||||
/* Get us a second connection up and connected */
|
/* Get us a second connection up and connected */
|
||||||
@@ -2301,7 +2318,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
* The input argument is already checked for validity.
|
* The input argument is already checked for validity.
|
||||||
*
|
*
|
||||||
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
|
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
|
||||||
* end of the function.
|
* Curl_ftp_done() function without finding any major problem.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_ftp(struct connectdata *conn)
|
CURLcode Curl_ftp(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
@@ -2311,9 +2328,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
|||||||
struct FTP *ftp;
|
struct FTP *ftp;
|
||||||
|
|
||||||
char *slash_pos; /* position of the first '/' char in curpos */
|
char *slash_pos; /* position of the first '/' char in curpos */
|
||||||
char *cur_pos=conn->ppath; /* current position in ppath. point at the begin
|
char *cur_pos=conn->path; /* current position in ppath. point at the begin
|
||||||
of next path component */
|
of next path component */
|
||||||
int path_part=0;/* current path component */
|
|
||||||
|
|
||||||
/* the ftp struct is already inited in ftp_connect() */
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
ftp = conn->proto.ftp;
|
ftp = conn->proto.ftp;
|
||||||
@@ -2325,23 +2341,28 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
|||||||
Curl_pgrsSetUploadSize(data, 0);
|
Curl_pgrsSetUploadSize(data, 0);
|
||||||
Curl_pgrsSetDownloadSize(data, 0);
|
Curl_pgrsSetDownloadSize(data, 0);
|
||||||
|
|
||||||
/* fixed : initialize ftp->dirs[xxx] to NULL !
|
ftp->dirdepth = 0;
|
||||||
is done in Curl_ftp_connect() */
|
ftp->diralloc = 5; /* default dir depth to allocate */
|
||||||
|
ftp->dirs = (char **)malloc(ftp->diralloc * sizeof(ftp->dirs[0]));
|
||||||
|
if(!ftp->dirs)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
ftp->dirs[0] = NULL; /* to start with */
|
||||||
|
|
||||||
/* parse the URL path into separate path components */
|
/* parse the URL path into separate path components */
|
||||||
while((slash_pos=strchr(cur_pos, '/'))) {
|
while((slash_pos=strchr(cur_pos, '/'))) {
|
||||||
/* 1 or 0 to indicate absolute directory */
|
/* 1 or 0 to indicate absolute directory */
|
||||||
bool absolute_dir = (cur_pos - conn->ppath > 0) && (path_part == 0);
|
bool absolute_dir = (cur_pos - conn->path > 0) && (ftp->dirdepth == 0);
|
||||||
|
|
||||||
/* seek out the next path component */
|
/* seek out the next path component */
|
||||||
if (slash_pos-cur_pos) {
|
if (slash_pos-cur_pos) {
|
||||||
/* we skip empty path components, like "x//y" since the FTP command CWD
|
/* we skip empty path components, like "x//y" since the FTP command CWD
|
||||||
requires a parameter and a non-existant parameter a) doesn't work on
|
requires a parameter and a non-existant parameter a) doesn't work on
|
||||||
many servers and b) has no effect on the others. */
|
many servers and b) has no effect on the others. */
|
||||||
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir,
|
ftp->dirs[ftp->dirdepth] = curl_unescape(cur_pos - absolute_dir,
|
||||||
slash_pos - cur_pos + absolute_dir);
|
slash_pos - cur_pos +
|
||||||
|
absolute_dir);
|
||||||
|
|
||||||
if (!ftp->dirs[path_part]) { /* run out of memory ... */
|
if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */
|
||||||
failf(data, "no memory");
|
failf(data, "no memory");
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@@ -2354,12 +2375,16 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
|||||||
|
|
||||||
if(!retcode) {
|
if(!retcode) {
|
||||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||||
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
if(++ftp->dirdepth >= ftp->diralloc) {
|
||||||
/* too deep, we need the last entry to be kept NULL at all
|
/* enlarge array */
|
||||||
times to signal end of list */
|
char *bigger;
|
||||||
failf(data, "too deep dir hierarchy");
|
ftp->diralloc *= 2; /* double the size each time */
|
||||||
freedirs(ftp);
|
bigger = realloc(ftp->dirs, ftp->diralloc * sizeof(ftp->dirs[0]));
|
||||||
return CURLE_URL_MALFORMAT;
|
if(!bigger) {
|
||||||
|
freedirs(ftp);
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
ftp->dirs = (char **)bigger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2400,7 +2425,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
|||||||
else
|
else
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
|
|
||||||
ftp->ctl_valid = TRUE;
|
ftp->ctl_valid = TRUE; /* seems good */
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2455,7 +2481,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
|||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* Curl_ftp_quit()
|
* ftp_quit()
|
||||||
*
|
*
|
||||||
* This should be called before calling sclose() on an ftp control connection
|
* This should be called before calling sclose() on an ftp control connection
|
||||||
* (not data connections). We should then wait for the response from the
|
* (not data connections). We should then wait for the response from the
|
||||||
@@ -2463,7 +2489,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
|||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_ftp_quit(struct connectdata *conn)
|
static CURLcode ftp_quit(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
int ftpcode;
|
int ftpcode;
|
||||||
@@ -2493,13 +2519,13 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
|||||||
bad in any way, sending quit and waiting around here will make the
|
bad in any way, sending quit and waiting around here will make the
|
||||||
disconnect wait in vain and cause more problems than we need to.
|
disconnect wait in vain and cause more problems than we need to.
|
||||||
|
|
||||||
Curl_ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
|
ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
|
||||||
will try to send the QUIT command, otherwise it will just return.
|
will try to send the QUIT command, otherwise it will just return.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The FTP session may or may not have been allocated/setup at this point! */
|
/* The FTP session may or may not have been allocated/setup at this point! */
|
||||||
if(ftp) {
|
if(ftp) {
|
||||||
(void)Curl_ftp_quit(conn); /* ignore errors on the QUIT */
|
(void)ftp_quit(conn); /* ignore errors on the QUIT */
|
||||||
|
|
||||||
if(ftp->entrypath)
|
if(ftp->entrypath)
|
||||||
free(ftp->entrypath);
|
free(ftp->entrypath);
|
||||||
@@ -2507,10 +2533,6 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
|||||||
free(ftp->cache);
|
free(ftp->cache);
|
||||||
ftp->cache = NULL;
|
ftp->cache = NULL;
|
||||||
}
|
}
|
||||||
if(ftp->file) {
|
|
||||||
free(ftp->file);
|
|
||||||
ftp->file = NULL; /* zero */
|
|
||||||
}
|
|
||||||
freedirs(ftp);
|
freedirs(ftp);
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
@@ -32,7 +32,6 @@ CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
|||||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||||
int *ftpcode);
|
int *ftpcode);
|
||||||
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
||||||
CURLcode Curl_ftp_quit(struct connectdata *conn);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -742,16 +742,16 @@ ToYear (int Year)
|
|||||||
static int
|
static int
|
||||||
LookupWord (YYSTYPE *yylval, char *buff)
|
LookupWord (YYSTYPE *yylval, char *buff)
|
||||||
{
|
{
|
||||||
register char *p;
|
char *p;
|
||||||
register char *q;
|
char *q;
|
||||||
register const TABLE *tp;
|
const TABLE *tp;
|
||||||
int i;
|
size_t i;
|
||||||
int abbrev;
|
int abbrev;
|
||||||
|
|
||||||
/* Make it lowercase. */
|
/* Make it lowercase. */
|
||||||
for (p = buff; *p; p++)
|
for (p = buff; *p; p++)
|
||||||
if (ISUPPER ((unsigned char) *p))
|
if (ISUPPER ((unsigned char) *p))
|
||||||
*p = tolower (*p);
|
*p = tolower ((int)*p);
|
||||||
|
|
||||||
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
|
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
|
||||||
{
|
{
|
||||||
|
438
lib/hostip.c
438
lib/hostip.c
@@ -49,6 +49,9 @@
|
|||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
#include <stdlib.h> /* required for free() prototypes */
|
#include <stdlib.h> /* required for free() prototypes */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h> /* for the close() proto */
|
||||||
|
#endif
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
#include <in.h>
|
#include <in.h>
|
||||||
#include <inet.h>
|
#include <inet.h>
|
||||||
@@ -60,6 +63,10 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||||
#undef in_addr_t
|
#undef in_addr_t
|
||||||
#define in_addr_t unsigned long
|
#define in_addr_t unsigned long
|
||||||
@@ -70,6 +77,7 @@
|
|||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "share.h"
|
#include "share.h"
|
||||||
|
#include "strerror.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
@@ -88,19 +96,32 @@
|
|||||||
#define ARES_SUCCESS CURLE_OK
|
#define ARES_SUCCESS CURLE_OK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
||||||
|
many seconds for a name resolve */
|
||||||
|
|
||||||
|
/* These two symbols are for the global DNS cache */
|
||||||
static curl_hash hostname_cache;
|
static curl_hash hostname_cache;
|
||||||
static int host_cache_initialized;
|
static int host_cache_initialized;
|
||||||
|
|
||||||
|
|
||||||
|
static void freednsentry(void *freethis);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* my_getaddrinfo() is the generic low-level name resolve API within this
|
||||||
|
* source file. There exist three versions of this function - for different
|
||||||
|
* name resolve layers (selected at build-time). They all take this same set
|
||||||
|
* of arguments
|
||||||
|
*/
|
||||||
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
int port,
|
int port,
|
||||||
int *waitp);
|
int *waitp);
|
||||||
#ifndef ENABLE_IPV6
|
|
||||||
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
|
#if (!defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
|
||||||
defined(USE_THREADING_GETHOSTBYNAME)
|
defined(USE_THREADING_GETHOSTBYNAME)) && \
|
||||||
|
!defined(ENABLE_IPV6)
|
||||||
static struct hostent* pack_hostent(char** buf, struct hostent* orig);
|
static struct hostent* pack_hostent(char** buf, struct hostent* orig);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||||
#ifdef DEBUG_THREADING_GETHOSTBYNAME
|
#ifdef DEBUG_THREADING_GETHOSTBYNAME
|
||||||
@@ -113,29 +134,40 @@ static void trace_it (const char *fmt, ...);
|
|||||||
#define TRACE(x)
|
#define TRACE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct hostent* pack_hostent (char** buf, struct hostent* orig);
|
|
||||||
static bool init_gethostbyname_thread (struct connectdata *conn,
|
static bool init_gethostbyname_thread (struct connectdata *conn,
|
||||||
const char *hostname, int port);
|
const char *hostname, int port);
|
||||||
struct thread_data {
|
struct thread_data {
|
||||||
HANDLE thread_hnd;
|
HANDLE thread_hnd;
|
||||||
DWORD thread_id;
|
unsigned thread_id;
|
||||||
DWORD thread_status;
|
DWORD thread_status;
|
||||||
|
curl_socket_t dummy_sock; /* dummy for Curl_multi_ares_fdset() */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
|
||||||
|
* Global DNS cache is general badness. Do not use. This will be removed in
|
||||||
|
* a future version. Use the share interface instead!
|
||||||
|
*/
|
||||||
void Curl_global_host_cache_init(void)
|
void Curl_global_host_cache_init(void)
|
||||||
{
|
{
|
||||||
if (!host_cache_initialized) {
|
if (!host_cache_initialized) {
|
||||||
Curl_hash_init(&hostname_cache, 7, Curl_freednsinfo);
|
Curl_hash_init(&hostname_cache, 7, freednsentry);
|
||||||
host_cache_initialized = 1;
|
host_cache_initialized = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to the global cache
|
||||||
|
*/
|
||||||
curl_hash *Curl_global_host_cache_get(void)
|
curl_hash *Curl_global_host_cache_get(void)
|
||||||
{
|
{
|
||||||
return &hostname_cache;
|
return &hostname_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy and cleanup the global DNS cache
|
||||||
|
*/
|
||||||
void Curl_global_host_cache_dtor(void)
|
void Curl_global_host_cache_dtor(void)
|
||||||
{
|
{
|
||||||
if (host_cache_initialized) {
|
if (host_cache_initialized) {
|
||||||
@@ -144,7 +176,10 @@ void Curl_global_host_cache_dtor(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count the number of characters that an integer takes up */
|
/*
|
||||||
|
* Minor utility-function:
|
||||||
|
* Count the number of characters that an integer takes up.
|
||||||
|
*/
|
||||||
static int _num_chars(int i)
|
static int _num_chars(int i)
|
||||||
{
|
{
|
||||||
int chars = 0;
|
int chars = 0;
|
||||||
@@ -165,7 +200,10 @@ static int _num_chars(int i)
|
|||||||
return chars;
|
return chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a hostcache id */
|
/*
|
||||||
|
* Minor utility-function:
|
||||||
|
* Create a hostcache id string for the DNS caching.
|
||||||
|
*/
|
||||||
static char *
|
static char *
|
||||||
create_hostcache_id(char *server, int port, size_t *entry_len)
|
create_hostcache_id(char *server, int port, size_t *entry_len)
|
||||||
{
|
{
|
||||||
@@ -192,6 +230,13 @@ struct hostcache_prune_data {
|
|||||||
time_t now;
|
time_t now;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is set as a callback to be called for every entry in the DNS
|
||||||
|
* cache when we want to prune old unused entries.
|
||||||
|
*
|
||||||
|
* Returning non-zero means remove the entry, return 0 to keep it in the
|
||||||
|
* cache.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
hostcache_timestamp_remove(void *datap, void *hc)
|
hostcache_timestamp_remove(void *datap, void *hc)
|
||||||
{
|
{
|
||||||
@@ -209,6 +254,9 @@ hostcache_timestamp_remove(void *datap, void *hc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prune the DNS cache. This assumes that a lock has already been taken.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
|
hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
|
||||||
{
|
{
|
||||||
@@ -222,6 +270,10 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
|
|||||||
hostcache_timestamp_remove);
|
hostcache_timestamp_remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Library-wide function for pruning the DNS cache. This function takes and
|
||||||
|
* returns the appropriate locks.
|
||||||
|
*/
|
||||||
void Curl_hostcache_prune(struct SessionHandle *data)
|
void Curl_hostcache_prune(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
time_t now;
|
time_t now;
|
||||||
@@ -245,15 +297,22 @@ void Curl_hostcache_prune(struct SessionHandle *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SIGSETJMP
|
#ifdef HAVE_SIGSETJMP
|
||||||
/* Beware this is a global and unique instance */
|
/* Beware this is a global and unique instance. This is used to store the
|
||||||
|
return address that we can jump back to from inside a signal handler. This
|
||||||
|
is not thread-safe stuff. */
|
||||||
sigjmp_buf curl_jmpenv;
|
sigjmp_buf curl_jmpenv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* When calling Curl_resolv() has resulted in a response with a returned
|
/*
|
||||||
address, we call this function to store the information in the dns
|
* cache_resolv_response() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||||
cache etc */
|
*
|
||||||
|
* When calling Curl_resolv() has resulted in a response with a returned
|
||||||
|
* address, we call this function to store the information in the dns
|
||||||
|
* cache etc
|
||||||
|
*
|
||||||
|
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
|
||||||
|
*/
|
||||||
static struct Curl_dns_entry *
|
static struct Curl_dns_entry *
|
||||||
cache_resolv_response(struct SessionHandle *data,
|
cache_resolv_response(struct SessionHandle *data,
|
||||||
Curl_addrinfo *addr,
|
Curl_addrinfo *addr,
|
||||||
@@ -303,15 +362,22 @@ cache_resolv_response(struct SessionHandle *data,
|
|||||||
return dns;
|
return dns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resolve a name and return a pointer in the 'entry' argument if one
|
/*
|
||||||
is available.
|
* Curl_resolv() is the main name resolve function within libcurl. It resolves
|
||||||
|
* a name and returns a pointer to the entry in the 'entry' argument (if one
|
||||||
Return codes:
|
* is provided). This function might return immediately if we're using asynch
|
||||||
|
* resolves. See the return codes.
|
||||||
-1 = error, no pointer
|
*
|
||||||
0 = OK, pointer provided
|
* The cache entry we return will get its 'inuse' counter increased when this
|
||||||
1 = waiting for response, no pointer
|
* function is used. You MUST call Curl_resolv_unlock() later (when you're
|
||||||
*/
|
* done using this struct) to decrease the counter again.
|
||||||
|
*
|
||||||
|
* Return codes:
|
||||||
|
*
|
||||||
|
* -1 = error, no pointer
|
||||||
|
* 0 = OK, pointer provided
|
||||||
|
* 1 = waiting for response, no pointer
|
||||||
|
*/
|
||||||
int Curl_resolv(struct connectdata *conn,
|
int Curl_resolv(struct connectdata *conn,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
int port,
|
int port,
|
||||||
@@ -405,6 +471,11 @@ int Curl_resolv(struct connectdata *conn,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
|
||||||
|
* made, the struct may be destroyed due to pruning. It is important that only
|
||||||
|
* one unlock is made for each Curl_resolv() call.
|
||||||
|
*/
|
||||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||||
{
|
{
|
||||||
if(data->share)
|
if(data->share)
|
||||||
@@ -438,9 +509,9 @@ void Curl_freeaddrinfo(Curl_addrinfo *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free a cache dns entry.
|
* File-internal: free a cache dns entry.
|
||||||
*/
|
*/
|
||||||
void Curl_freednsinfo(void *freethis)
|
static void freednsentry(void *freethis)
|
||||||
{
|
{
|
||||||
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
|
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
|
||||||
|
|
||||||
@@ -449,6 +520,14 @@ void Curl_freednsinfo(void *freethis)
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
|
||||||
|
*/
|
||||||
|
curl_hash *Curl_mk_dnscache(void)
|
||||||
|
{
|
||||||
|
return Curl_hash_alloc(7, freednsentry);
|
||||||
|
}
|
||||||
|
|
||||||
/* --- resolve name or IP-number --- */
|
/* --- resolve name or IP-number --- */
|
||||||
|
|
||||||
/* Allocate enough memory to hold the full name information structs and
|
/* Allocate enough memory to hold the full name information structs and
|
||||||
@@ -460,6 +539,15 @@ void Curl_freednsinfo(void *freethis)
|
|||||||
|
|
||||||
#ifdef USE_ARES
|
#ifdef USE_ARES
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_multi_ares_fdset() is called when someone from the outside world
|
||||||
|
* (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
|
||||||
|
* with ares. The caller must make sure that this function is only called when
|
||||||
|
* we have a working ares channel.
|
||||||
|
*
|
||||||
|
* Returns: CURLE_OK always!
|
||||||
|
*/
|
||||||
|
|
||||||
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
fd_set *read_fd_set,
|
||||||
fd_set *write_fd_set,
|
fd_set *write_fd_set,
|
||||||
@@ -473,25 +561,33 @@ CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called to check if the name is resolved now */
|
/*
|
||||||
|
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||||
|
* request has completed. It should also make sure to time-out if the
|
||||||
|
* operation seems to take too long.
|
||||||
|
*
|
||||||
|
* Returns normal CURLcode errors.
|
||||||
|
*/
|
||||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **dns)
|
struct Curl_dns_entry **dns)
|
||||||
{
|
{
|
||||||
fd_set read_fds, write_fds;
|
fd_set read_fds, write_fds;
|
||||||
static const struct timeval tv={0,0};
|
struct timeval tv={0,0};
|
||||||
int count;
|
int count;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
int nfds;
|
int nfds;
|
||||||
|
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
|
|
||||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||||
|
|
||||||
count = select(nfds, &read_fds, &write_fds, NULL,
|
count = select(nfds, &read_fds, &write_fds, NULL,
|
||||||
(struct timeval *)&tv);
|
(struct timeval *)&tv);
|
||||||
|
|
||||||
if(count)
|
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
above, as otherwise the ares name resolve won't timeout! */
|
||||||
|
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||||
|
|
||||||
*dns = NULL;
|
*dns = NULL;
|
||||||
|
|
||||||
@@ -505,23 +601,21 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a function that locks and waits until the name resolve operation
|
/*
|
||||||
has completed.
|
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||||
|
* be avoided since using this risk getting the multi interface to "hang".
|
||||||
If 'entry' is non-NULL, make it point to the resolved dns entry
|
*
|
||||||
|
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||||
Return CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
*
|
||||||
CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||||
*/
|
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||||
|
*/
|
||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
CURLcode rc=CURLE_OK;
|
CURLcode rc=CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct timeval now = Curl_tvnow();
|
long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||||
bool timedout = FALSE;
|
|
||||||
long timeout = 300; /* default name resolve timeout in seconds */
|
|
||||||
long elapsed = 0; /* time taken so far */
|
|
||||||
|
|
||||||
/* now, see if there's a connect timeout or a regular timeout to
|
/* now, see if there's a connect timeout or a regular timeout to
|
||||||
use instead of the default one */
|
use instead of the default one */
|
||||||
@@ -530,34 +624,46 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
else if(conn->data->set.timeout)
|
else if(conn->data->set.timeout)
|
||||||
timeout = conn->data->set.timeout;
|
timeout = conn->data->set.timeout;
|
||||||
|
|
||||||
|
/* We convert the number of seconds into number of milliseconds here: */
|
||||||
|
if(timeout < 2147483)
|
||||||
|
/* maximum amount of seconds that can be multiplied with 1000 and
|
||||||
|
still fit within 31 bits */
|
||||||
|
timeout *= 1000;
|
||||||
|
else
|
||||||
|
timeout = 0x7fffffff; /* ridiculous amount of time anyway */
|
||||||
|
|
||||||
/* Wait for the name resolve query to complete. */
|
/* Wait for the name resolve query to complete. */
|
||||||
while (1) {
|
while (1) {
|
||||||
int nfds=0;
|
int nfds=0;
|
||||||
fd_set read_fds, write_fds;
|
fd_set read_fds, write_fds;
|
||||||
struct timeval *tvp, tv, store;
|
struct timeval *tvp, tv, store;
|
||||||
int count;
|
int count;
|
||||||
|
struct timeval now = Curl_tvnow();
|
||||||
|
long timediff;
|
||||||
|
|
||||||
store.tv_sec = (int)(timeout - elapsed);
|
store.tv_sec = (int)timeout/1000;
|
||||||
store.tv_usec = 0;
|
store.tv_usec = (timeout%1000)*1000;
|
||||||
|
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||||
if (nfds == 0)
|
if (nfds == 0)
|
||||||
|
/* no file descriptors means we're done waiting */
|
||||||
break;
|
break;
|
||||||
tvp = ares_timeout(data->state.areschannel,
|
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
||||||
&store, &tv);
|
|
||||||
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||||
if (count < 0 && errno != EINVAL)
|
if (count < 0 && errno != EINVAL)
|
||||||
break;
|
break;
|
||||||
else if(!count) {
|
|
||||||
/* timeout */
|
|
||||||
timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||||
|
|
||||||
elapsed = Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
|
timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
|
||||||
|
timeout -= timediff?timediff:1; /* always deduct at least 1 */
|
||||||
|
if (timeout < 0) {
|
||||||
|
/* our timeout, so we cancel the ares operation */
|
||||||
|
ares_cancel(data->state.areschannel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operation complete, if the lookup was successful we now have the entry
|
/* Operation complete, if the lookup was successful we now have the entry
|
||||||
@@ -568,12 +674,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!conn->async.dns) {
|
if(!conn->async.dns) {
|
||||||
/* a name was not resolved */
|
/* a name was not resolved */
|
||||||
if(timedout || (conn->async.status == ARES_ETIMEOUT)) {
|
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
|
||||||
failf(data, "Resolving host timed out: %s", conn->name);
|
failf(data, "Resolving host timed out: %s", conn->hostname);
|
||||||
rc = CURLE_OPERATION_TIMEDOUT;
|
rc = CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
else if(conn->async.done) {
|
else if(conn->async.done) {
|
||||||
failf(data, "Could not resolve host: %s (%s)", conn->name,
|
failf(data, "Could not resolve host: %s (%s)", conn->hostname,
|
||||||
ares_strerror(conn->async.status));
|
ares_strerror(conn->async.status));
|
||||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
@@ -591,8 +697,16 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
|
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
|
||||||
|
|
||||||
/* this function gets called by ares/gethostbyname_thread() when we got
|
/*
|
||||||
the name resolved or not */
|
* host_callback() gets called by ares/gethostbyname_thread() when we got the
|
||||||
|
* name resolved (or not!).
|
||||||
|
*
|
||||||
|
* If the status argument is ARES_SUCCESS, we must copy the hostent field
|
||||||
|
* since ares will free it when this function returns. This operation stores
|
||||||
|
* the resolved data in the DNS cache.
|
||||||
|
*
|
||||||
|
* The storage operation locks and unlocks the DNS cache.
|
||||||
|
*/
|
||||||
static void host_callback(void *arg, /* "struct connectdata *" */
|
static void host_callback(void *arg, /* "struct connectdata *" */
|
||||||
int status,
|
int status,
|
||||||
struct hostent *hostent)
|
struct hostent *hostent)
|
||||||
@@ -633,9 +747,11 @@ static void host_callback(void *arg, /* "struct connectdata *" */
|
|||||||
|
|
||||||
#ifdef USE_ARES
|
#ifdef USE_ARES
|
||||||
/*
|
/*
|
||||||
* Return name information about the given hostname and port number. If
|
* my_getaddrinfo() when using ares for name resolves.
|
||||||
|
*
|
||||||
|
* Returns name information about the given hostname and port number. If
|
||||||
* successful, the 'hostent' is returned and the forth argument will point to
|
* successful, the 'hostent' is returned and the forth argument will point to
|
||||||
* memory we need to free after use. That meory *MUST* be freed with
|
* memory we need to free after use. That memory *MUST* be freed with
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
* Curl_freeaddrinfo(), nothing else.
|
||||||
*/
|
*/
|
||||||
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||||
@@ -648,6 +764,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
*waitp = FALSE;
|
*waitp = FALSE;
|
||||||
|
|
||||||
|
if(data->set.ip_version == CURL_IPRESOLVE_V6)
|
||||||
|
/* an ipv6 address was requested and we can't get/use one */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
bufp = strdup(hostname);
|
bufp = strdup(hostname);
|
||||||
|
|
||||||
if(bufp) {
|
if(bufp) {
|
||||||
@@ -670,9 +790,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
#if !defined(USE_ARES) && !defined(USE_THREADING_GETHOSTBYNAME)
|
#if !defined(USE_ARES) && !defined(USE_THREADING_GETHOSTBYNAME)
|
||||||
|
|
||||||
/* For builds without ARES and threaded gethostbyname, Curl_resolv() can never
|
/*
|
||||||
return wait==TRUE, so this function will never be called. If it still gets
|
* Curl_wait_for_resolv() for builds without ARES and threaded gethostbyname,
|
||||||
called, we return failure at once. */
|
* Curl_resolv() can never return wait==TRUE, so this function will never be
|
||||||
|
* called. If it still gets called, we return failure at once.
|
||||||
|
*
|
||||||
|
* We provide this function only to allow multi.c to remain unaware if we are
|
||||||
|
* doing asynch resolves or not.
|
||||||
|
*/
|
||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
@@ -681,6 +806,13 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function will never be called when built with ares or threaded
|
||||||
|
* resolves. If it still gets called, we return failure at once.
|
||||||
|
*
|
||||||
|
* We provide this function only to allow multi.c to remain unaware if we are
|
||||||
|
* doing asynch resolves or not.
|
||||||
|
*/
|
||||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **dns)
|
struct Curl_dns_entry **dns)
|
||||||
{
|
{
|
||||||
@@ -692,18 +824,32 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ARES)
|
#if !defined(USE_ARES)
|
||||||
|
/*
|
||||||
|
* Non-ares build. If we are using threading gethostbyname, then this must
|
||||||
|
* set the fd_set for the threaded resolve socket. If not, we just return OK.
|
||||||
|
*/
|
||||||
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
fd_set *read_fd_set,
|
||||||
fd_set *write_fd_set,
|
fd_set *write_fd_set,
|
||||||
int *max_fdp)
|
int *max_fdp)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||||
|
const struct thread_data *td =
|
||||||
|
(const struct thread_data *) conn->async.os_specific;
|
||||||
|
|
||||||
|
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
||||||
|
FD_SET(td->dummy_sock,write_fd_set);
|
||||||
|
*max_fdp = td->dummy_sock;
|
||||||
|
}
|
||||||
|
#else /* if not USE_THREADING_GETHOSTBYNAME */
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)read_fd_set;
|
(void)read_fd_set;
|
||||||
(void)write_fd_set;
|
(void)write_fd_set;
|
||||||
(void)max_fdp;
|
(void)max_fdp;
|
||||||
|
#endif
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* !USE_ARES */
|
||||||
|
|
||||||
#if defined(ENABLE_IPV6) && !defined(USE_ARES)
|
#if defined(ENABLE_IPV6) && !defined(USE_ARES)
|
||||||
|
|
||||||
@@ -745,9 +891,11 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return name information about the given hostname and port number. If
|
* my_getaddrinfo() when built ipv6-enabled.
|
||||||
|
*
|
||||||
|
* Returns name information about the given hostname and port number. If
|
||||||
* successful, the 'addrinfo' is returned and the forth argument will point to
|
* successful, the 'addrinfo' is returned and the forth argument will point to
|
||||||
* memory we need to free after use. That meory *MUST* be freed with
|
* memory we need to free after use. That memory *MUST* be freed with
|
||||||
* Curl_freeaddrinfo(), nothing else.
|
* Curl_freeaddrinfo(), nothing else.
|
||||||
*/
|
*/
|
||||||
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||||
@@ -765,11 +913,17 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
/* see if we have an IPv6 stack */
|
/* see if we have an IPv6 stack */
|
||||||
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||||
if (s < 0)
|
if (s < 0) {
|
||||||
/* Some non-IPv6 stacks have been found to make very slow name resolves
|
/* Some non-IPv6 stacks have been found to make very slow name resolves
|
||||||
* when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
|
* when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
|
||||||
* the stack seems to be a non-ipv6 one. */
|
* the stack seems to be a non-ipv6 one. */
|
||||||
|
|
||||||
|
if(data->set.ip_version == CURL_IPRESOLVE_V6)
|
||||||
|
/* an ipv6 address was requested and we can't get/use one */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
|
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
|
||||||
* possible checks. And close the socket again.
|
* possible checks. And close the socket again.
|
||||||
@@ -807,11 +961,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
#else /* following code is IPv4-only */
|
#else /* following code is IPv4-only */
|
||||||
|
|
||||||
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
|
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
|
||||||
|
defined(USE_THREADING_GETHOSTBYNAME)
|
||||||
static void hostcache_fixoffset(struct hostent *h, long offset);
|
static void hostcache_fixoffset(struct hostent *h, long offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
|
* pack_hostent() is a file-local function that performs a "deep" copy of a
|
||||||
* copy). Make absolutely sure the destination buffer is big enough!
|
* hostent into a buffer (returns a pointer to the copy). Make absolutely sure
|
||||||
|
* the destination buffer is big enough!
|
||||||
*/
|
*/
|
||||||
static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
||||||
{
|
{
|
||||||
@@ -887,11 +1044,11 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
|||||||
|
|
||||||
/* now, shrink the allocated buffer to the size we actually need, which
|
/* now, shrink the allocated buffer to the size we actually need, which
|
||||||
most often is only a fraction of the original alloc */
|
most often is only a fraction of the original alloc */
|
||||||
newbuf=(char *)realloc(*buf, (long)bufptr-(long)(*buf));
|
newbuf=(char *)realloc(*buf, (long)(bufptr-*buf));
|
||||||
|
|
||||||
/* if the alloc moved, we need to adjust things again */
|
/* if the alloc moved, we need to adjust things again */
|
||||||
if(newbuf != *buf)
|
if(newbuf != *buf)
|
||||||
hostcache_fixoffset((struct hostent*)newbuf, (long)newbuf-(long)*buf);
|
hostcache_fixoffset((struct hostent*)newbuf, (long)(newbuf-*buf));
|
||||||
|
|
||||||
/* setup the return */
|
/* setup the return */
|
||||||
*buf = newbuf;
|
*buf = newbuf;
|
||||||
@@ -901,6 +1058,12 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hostcache_fixoffset() is a utility-function that corrects all pointers in
|
||||||
|
* the given hostent struct according to the offset. This is typically used
|
||||||
|
* when a hostent has been reallocated and needs to be setup properly on the
|
||||||
|
* new address.
|
||||||
|
*/
|
||||||
static void hostcache_fixoffset(struct hostent *h, long offset)
|
static void hostcache_fixoffset(struct hostent *h, long offset)
|
||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
@@ -925,6 +1088,11 @@ static void hostcache_fixoffset(struct hostent *h, long offset)
|
|||||||
|
|
||||||
#ifndef USE_ARES
|
#ifndef USE_ARES
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MakeIP() converts the input binary ipv4-address to an ascii string in the
|
||||||
|
* dotted numerical format. 'addr' is a pointer to a buffer that is 'addr_len'
|
||||||
|
* bytes big. 'num' is the 32 bit IP number.
|
||||||
|
*/
|
||||||
static char *MakeIP(unsigned long num, char *addr, int addr_len)
|
static char *MakeIP(unsigned long num, char *addr, int addr_len)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
|
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
|
||||||
@@ -946,9 +1114,13 @@ static char *MakeIP(unsigned long num, char *addr, int addr_len)
|
|||||||
return (addr);
|
return (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The original code to this function was once stolen from the Dancer source
|
/*
|
||||||
code, written by Bjorn Reese, it has since been patched and modified
|
* my_getaddrinfo() - the ipv4 "traditional" version.
|
||||||
considerably. */
|
*
|
||||||
|
* The original code to this function was once stolen from the Dancer source
|
||||||
|
* code, written by Bjorn Reese, it has since been patched and modified
|
||||||
|
* considerably.
|
||||||
|
*/
|
||||||
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
int port,
|
int port,
|
||||||
@@ -961,6 +1133,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
*waitp = 0; /* don't wait, we act synchronously */
|
*waitp = 0; /* don't wait, we act synchronously */
|
||||||
|
|
||||||
|
if(data->set.ip_version == CURL_IPRESOLVE_V6)
|
||||||
|
/* an ipv6 address was requested and we can't get/use one */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
in=inet_addr(hostname);
|
in=inet_addr(hostname);
|
||||||
if (in != CURL_INADDR_NONE) {
|
if (in != CURL_INADDR_NONE) {
|
||||||
struct in_addr *addrentry;
|
struct in_addr *addrentry;
|
||||||
@@ -1148,9 +1324,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||||
|
/* fire up a new resolver thread! */
|
||||||
if (init_gethostbyname_thread(conn,hostname,port)) {
|
if (init_gethostbyname_thread(conn,hostname,port)) {
|
||||||
*waitp = TRUE; /* please wait for the response */
|
*waitp = TRUE; /* please wait for the response */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
infof(data, "init_gethostbyname_thread() failed for %s; code %lu\n",
|
infof(data, "init_gethostbyname_thread() failed for %s; code %lu\n",
|
||||||
hostname, GetLastError());
|
hostname, GetLastError());
|
||||||
@@ -1183,20 +1360,26 @@ static void trace_it (const char *fmt, ...)
|
|||||||
static int do_trace = -1;
|
static int do_trace = -1;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
if (do_trace == -1)
|
if (do_trace == -1) {
|
||||||
do_trace = getenv("CURL_TRACE") ? 1 : 0;
|
const char *env = getenv("CURL_TRACE");
|
||||||
|
do_trace = (env && atoi(env) > 0);
|
||||||
|
}
|
||||||
if (!do_trace)
|
if (!do_trace)
|
||||||
return;
|
return;
|
||||||
va_start (args, fmt);
|
va_start (args, fmt);
|
||||||
vfprintf (stderr, fmt, args);
|
vfprintf (stderr, fmt, args);
|
||||||
fflush (stderr);
|
/*fflush (stderr); */ /* seems a bad idea in a multi-threaded app */
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For builds without ARES/USE_IPV6, create a resolver thread and wait on it.
|
/*
|
||||||
|
* gethostbyname_thread() resolves a name, calls the host_callback and then
|
||||||
|
* exits.
|
||||||
|
*
|
||||||
|
* For builds without ARES/USE_IPV6, create a resolver thread and wait on it.
|
||||||
*/
|
*/
|
||||||
static DWORD WINAPI gethostbyname_thread (void *arg)
|
static unsigned __stdcall gethostbyname_thread (void *arg)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = (struct connectdata*) arg;
|
struct connectdata *conn = (struct connectdata*) arg;
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
@@ -1215,32 +1398,43 @@ static DWORD WINAPI gethostbyname_thread (void *arg)
|
|||||||
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
|
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
|
||||||
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
|
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
|
||||||
return (rc);
|
return (rc);
|
||||||
/* An implicit ExitThread() here */
|
/* An implicit _endthreadex() here */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* complementary of ares_destroy
|
/*
|
||||||
|
* destroy_thread_data() cleans up async resolver data.
|
||||||
|
* Complementary of ares_destroy.
|
||||||
*/
|
*/
|
||||||
static void destroy_thread_data (struct connectdata *conn)
|
static void destroy_thread_data (struct Curl_async *async)
|
||||||
{
|
{
|
||||||
if (conn->async.hostname)
|
if (async->hostname)
|
||||||
free(conn->async.hostname);
|
free(async->hostname);
|
||||||
if (conn->async.os_specific)
|
|
||||||
free(conn->async.os_specific);
|
if (async->os_specific) {
|
||||||
conn->async.hostname = NULL;
|
curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock;
|
||||||
conn->async.os_specific = NULL;
|
|
||||||
|
if (sock != CURL_SOCKET_BAD)
|
||||||
|
sclose(sock);
|
||||||
|
free(async->os_specific);
|
||||||
|
}
|
||||||
|
async->hostname = NULL;
|
||||||
|
async->os_specific = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_gethostbyname_thread() starts a new thread that performs
|
||||||
|
* the actual resolve. This function returns before the resolve is done.
|
||||||
|
*/
|
||||||
static bool init_gethostbyname_thread (struct connectdata *conn,
|
static bool init_gethostbyname_thread (struct connectdata *conn,
|
||||||
const char *hostname, int port)
|
const char *hostname, int port)
|
||||||
{
|
{
|
||||||
struct thread_data *td = malloc(sizeof(*td));
|
struct thread_data *td = calloc(sizeof(*td), 1);
|
||||||
|
|
||||||
if (!td) {
|
if (!td) {
|
||||||
SetLastError(ENOMEM);
|
SetLastError(ENOMEM);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (td, 0, sizeof(*td));
|
|
||||||
Curl_safefree(conn->async.hostname);
|
Curl_safefree(conn->async.hostname);
|
||||||
conn->async.hostname = strdup(hostname);
|
conn->async.hostname = strdup(hostname);
|
||||||
if (!conn->async.hostname) {
|
if (!conn->async.hostname) {
|
||||||
@@ -1255,17 +1449,31 @@ static bool init_gethostbyname_thread (struct connectdata *conn,
|
|||||||
conn->async.dns = NULL;
|
conn->async.dns = NULL;
|
||||||
conn->async.os_specific = (void*) td;
|
conn->async.os_specific = (void*) td;
|
||||||
|
|
||||||
td->thread_hnd = CreateThread(NULL, 0, gethostbyname_thread,
|
td->dummy_sock = CURL_SOCKET_BAD;
|
||||||
|
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, gethostbyname_thread,
|
||||||
conn, 0, &td->thread_id);
|
conn, 0, &td->thread_id);
|
||||||
if (!td->thread_hnd) {
|
if (!td->thread_hnd) {
|
||||||
TRACE(("CreateThread() failed; %lu\n", GetLastError()));
|
SetLastError(errno);
|
||||||
destroy_thread_data(conn);
|
TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
|
||||||
|
destroy_thread_data(&conn->async);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
/* This socket is only to keep Curl_multi_ares_fdset() and select() happy;
|
||||||
|
* should never become signalled for read/write since it's unbound but
|
||||||
|
* Windows needs atleast 1 socket in select().
|
||||||
|
*/
|
||||||
|
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called to check if the name is resolved now */
|
/*
|
||||||
|
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
|
||||||
|
* be avoided since using this risk getting the multi interface to "hang".
|
||||||
|
*
|
||||||
|
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||||
|
*
|
||||||
|
* This is the version for resolves-in-a-thread.
|
||||||
|
*/
|
||||||
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
@@ -1279,26 +1487,31 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
/* now, see if there's a connect timeout or a regular timeout to
|
/* now, see if there's a connect timeout or a regular timeout to
|
||||||
use instead of the default one */
|
use instead of the default one */
|
||||||
timeout = conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
timeout =
|
||||||
conn->data->set.timeout ? conn->data->set.timeout :
|
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
||||||
300; /* default name resolve timeout in seconds */
|
conn->data->set.timeout ? conn->data->set.timeout :
|
||||||
|
CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||||
ticks = GetTickCount();
|
ticks = GetTickCount();
|
||||||
|
|
||||||
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
|
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
|
||||||
if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
|
if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
|
||||||
/* Thread finished before timeout; propagate Winsock error to this thread */
|
/* Thread finished before timeout; propagate Winsock error to this thread.
|
||||||
|
* 'conn->async.done = TRUE' is set in host_callback().
|
||||||
|
*/
|
||||||
WSASetLastError(conn->async.status);
|
WSASetLastError(conn->async.status);
|
||||||
GetExitCodeThread(td->thread_hnd, &td->thread_status);
|
GetExitCodeThread(td->thread_hnd, &td->thread_status);
|
||||||
TRACE(("status %lu, thread-status %08lX\n", status, td->thread_status));
|
TRACE(("gethostbyname_thread() status %lu, thread retval %lu, ",
|
||||||
|
status, td->thread_status));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn->async.done = TRUE;
|
conn->async.done = TRUE;
|
||||||
TerminateThread(td->thread_hnd, (DWORD)-1);
|
|
||||||
td->thread_status = (DWORD)-1;
|
td->thread_status = (DWORD)-1;
|
||||||
|
TRACE(("gethostbyname_thread() timeout, "));
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n",
|
TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
|
||||||
td->thread_status, GetTickCount()-ticks));
|
|
||||||
|
CloseHandle(td->thread_hnd);
|
||||||
|
|
||||||
if(entry)
|
if(entry)
|
||||||
*entry = conn->async.dns;
|
*entry = conn->async.dns;
|
||||||
@@ -1308,24 +1521,33 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
if (!conn->async.dns) {
|
if (!conn->async.dns) {
|
||||||
/* a name was not resolved */
|
/* a name was not resolved */
|
||||||
if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
|
if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
|
||||||
failf(data, "Resolving host timed out: %s", conn->name);
|
failf(data, "Resolving host timed out: %s", conn->hostname);
|
||||||
rc = CURLE_OPERATION_TIMEDOUT;
|
rc = CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
else if(conn->async.done) {
|
else if(conn->async.done) {
|
||||||
failf(data, "Could not resolve host: %s (code %lu)", conn->name, conn->async.status);
|
failf(data, "Could not resolve host: %s; %s",
|
||||||
|
conn->hostname, Curl_strerror(conn,conn->async.status));
|
||||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = CURLE_OPERATION_TIMEDOUT;
|
rc = CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
destroy_thread_data(conn);
|
destroy_thread_data(&conn->async);
|
||||||
|
|
||||||
|
if (CURLE_OK != rc)
|
||||||
/* close the connection, since we can't return failure here without
|
/* close the connection, since we can't return failure here without
|
||||||
cleaning up this connection properly */
|
cleaning up this connection properly */
|
||||||
Curl_disconnect(conn);
|
Curl_disconnect(conn);
|
||||||
}
|
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
|
||||||
|
* request has completed. It should also make sure to time-out if the
|
||||||
|
* operation seems to take too long.
|
||||||
|
*/
|
||||||
CURLcode Curl_is_resolved(struct connectdata *conn,
|
CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||||
struct Curl_dns_entry **entry)
|
struct Curl_dns_entry **entry)
|
||||||
{
|
{
|
||||||
@@ -1333,7 +1555,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
|||||||
|
|
||||||
if (conn->async.done) {
|
if (conn->async.done) {
|
||||||
/* we're done */
|
/* we're done */
|
||||||
destroy_thread_data(conn);
|
destroy_thread_data(&conn->async);
|
||||||
if (!conn->async.dns) {
|
if (!conn->async.dns) {
|
||||||
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
|
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
|
@@ -74,8 +74,8 @@ void Curl_scan_cache_used(void *user, void *ptr);
|
|||||||
/* free name info */
|
/* free name info */
|
||||||
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
||||||
|
|
||||||
/* free cached name info */
|
/* make a new dns cache and return the handle */
|
||||||
void Curl_freednsinfo(void *freethis);
|
curl_hash *Curl_mk_dnscache(void);
|
||||||
|
|
||||||
/* prune old entries from the DNS cache */
|
/* prune old entries from the DNS cache */
|
||||||
void Curl_hostcache_prune(struct SessionHandle *data);
|
void Curl_hostcache_prune(struct SessionHandle *data);
|
||||||
|
349
lib/http.c
349
lib/http.c
@@ -105,8 +105,10 @@
|
|||||||
static CURLcode Curl_output_basic_proxy(struct connectdata *conn);
|
static CURLcode Curl_output_basic_proxy(struct connectdata *conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks the linked list of custom HTTP headers for a particular
|
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||||
* header (prefix).
|
* particular header (prefix).
|
||||||
|
*
|
||||||
|
* Returns a pointer to the first matching header or NULL if none matched.
|
||||||
*/
|
*/
|
||||||
static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||||
{
|
{
|
||||||
@@ -120,6 +122,12 @@ static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_output_basic() sets up an Authorization: header for HTTP Basic
|
||||||
|
* authentication. It uses the conn->user, conn->passwd fields for it.
|
||||||
|
*
|
||||||
|
* Returns CURLcode.
|
||||||
|
*/
|
||||||
static CURLcode Curl_output_basic(struct connectdata *conn)
|
static CURLcode Curl_output_basic(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
char *authorization;
|
char *authorization;
|
||||||
@@ -139,6 +147,13 @@ static CURLcode Curl_output_basic(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_output_basic_proxy() sets up a proxy-Authorization: header for HTTP
|
||||||
|
* Basic proxy authentication. It uses the conn->proxyuser and
|
||||||
|
* conn->proxypasswd fields for it.
|
||||||
|
*
|
||||||
|
* Returns CURLcode.
|
||||||
|
*/
|
||||||
static CURLcode Curl_output_basic_proxy(struct connectdata *conn)
|
static CURLcode Curl_output_basic_proxy(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
char *authorization;
|
char *authorization;
|
||||||
@@ -186,33 +201,49 @@ void Curl_http_auth_act(struct connectdata *conn)
|
|||||||
conn->newurl = strdup(data->change.url); /* clone URL */
|
conn->newurl = strdup(data->change.url); /* clone URL */
|
||||||
data->state.authavail = CURLAUTH_NONE; /* clear it here */
|
data->state.authavail = CURLAUTH_NONE; /* clear it here */
|
||||||
}
|
}
|
||||||
|
else if(!data->state.authdone && (data->info.httpcode < 400)) {
|
||||||
|
/* no (known) authentication available,
|
||||||
|
authentication is not "done" yet and
|
||||||
|
no authentication seems to be required and
|
||||||
|
we didn't try HEAD or GET */
|
||||||
|
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||||
|
(data->set.httpreq != HTTPREQ_HEAD)) {
|
||||||
|
conn->newurl = strdup(data->change.url); /* clone URL */
|
||||||
|
data->state.authdone = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Setup the authentication headers for the host/proxy and the correct
|
* http_auth_headers() setups the authentication headers for the host/proxy
|
||||||
* authentication method.
|
* and the correct authentication method. conn->data->state.authdone is set to
|
||||||
|
* TRUE when authentication is done.
|
||||||
|
*
|
||||||
|
* @param conn all information about the current connection
|
||||||
|
*
|
||||||
|
* Returns CURLcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static CURLcode http_auth_headers(struct connectdata *conn,
|
static CURLcode http_auth_headers(struct connectdata *conn,
|
||||||
char *request,
|
char *request,
|
||||||
char *path,
|
char *path)
|
||||||
bool *ready) /* set TRUE when the auth phase
|
|
||||||
is done and ready to do the *actual*
|
|
||||||
request */
|
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *auth=NULL;
|
char *auth=NULL;
|
||||||
|
|
||||||
*ready = FALSE; /* default is no */
|
curlassert(data);
|
||||||
|
|
||||||
if(!data->state.authstage) {
|
if(!data->state.authstage) {
|
||||||
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd)
|
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) {
|
||||||
|
data->state.authdone = FALSE;
|
||||||
Curl_http_auth_stage(data, 407);
|
Curl_http_auth_stage(data, 407);
|
||||||
else if(conn->bits.user_passwd)
|
}
|
||||||
|
else if(conn->bits.user_passwd) {
|
||||||
|
data->state.authdone = FALSE;
|
||||||
Curl_http_auth_stage(data, 401);
|
Curl_http_auth_stage(data, 401);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
return CURLE_OK; /* no authentication with no user or password */
|
return CURLE_OK; /* no authentication with no user or password */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +260,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, TRUE, ready);
|
result = Curl_output_ntlm(conn, TRUE);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -244,7 +275,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
/* Switch to web authentication after proxy authentication is done */
|
||||||
Curl_http_auth_stage(data, 401);
|
Curl_http_auth_stage(data, 401);
|
||||||
}
|
}
|
||||||
@@ -262,14 +293,14 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
result = Curl_output_negotiate(conn);
|
result = Curl_output_negotiate(conn);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, FALSE, ready);
|
result = Curl_output_ntlm(conn, FALSE);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -284,7 +315,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
(unsigned char *)path);
|
(unsigned char *)path);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
}
|
}
|
||||||
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
|
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
|
||||||
if(conn->bits.user_passwd &&
|
if(conn->bits.user_passwd &&
|
||||||
@@ -295,7 +326,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* basic is always ready */
|
/* basic is always ready */
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(auth)
|
if(auth)
|
||||||
@@ -304,7 +335,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*ready = TRUE;
|
data->state.authdone = TRUE;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -365,8 +396,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
||||||
/* if exactly this is wanted, go */
|
/* if exactly this is wanted, go */
|
||||||
int neg = Curl_input_negotiate(conn, start);
|
int neg = Curl_input_negotiate(conn, start);
|
||||||
if (neg == 0)
|
if (neg == 0) {
|
||||||
conn->newurl = strdup(data->change.url);
|
conn->newurl = strdup(data->change.url);
|
||||||
|
data->state.authproblem = (conn->newurl == NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
||||||
@@ -383,10 +420,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
CURLntlm ntlm =
|
CURLntlm ntlm =
|
||||||
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
||||||
|
|
||||||
if(CURLNTLM_BAD != ntlm)
|
if(CURLNTLM_BAD != ntlm) {
|
||||||
conn->newurl = strdup(data->change.url); /* clone string */
|
conn->newurl = strdup(data->change.url); /* clone string */
|
||||||
else
|
data->state.authproblem = (conn->newurl == NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(data->state.authwant & CURLAUTH_NTLM)
|
if(data->state.authwant & CURLAUTH_NTLM)
|
||||||
@@ -398,17 +439,18 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
*availp |= CURLAUTH_DIGEST;
|
*availp |= CURLAUTH_DIGEST;
|
||||||
if(data->state.authwant == CURLAUTH_DIGEST) {
|
if(data->state.authwant == CURLAUTH_DIGEST) {
|
||||||
/* Digest authentication is activated */
|
/* Digest authentication is activated */
|
||||||
CURLdigest dig = CURLDIGEST_BAD;
|
CURLdigest dig = Curl_input_digest(conn, start);
|
||||||
|
|
||||||
if(data->state.digest.nonce)
|
if(CURLDIGEST_FINE == dig) {
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
|
||||||
else
|
|
||||||
dig = Curl_input_digest(conn, start);
|
|
||||||
|
|
||||||
if(CURLDIGEST_FINE == dig)
|
|
||||||
/* We act on it. Store our new url, which happens to be
|
/* We act on it. Store our new url, which happens to be
|
||||||
the same one we already use! */
|
the same one we already use! */
|
||||||
conn->newurl = strdup(data->change.url); /* clone string */
|
conn->newurl = strdup(data->change.url); /* clone string */
|
||||||
|
data->state.authproblem = (conn->newurl == NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(data->state.authwant & CURLAUTH_DIGEST) {
|
if(data->state.authwant & CURLAUTH_DIGEST) {
|
||||||
@@ -430,16 +472,114 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
|||||||
valid. */
|
valid. */
|
||||||
data->state.authavail = CURLAUTH_NONE;
|
data->state.authavail = CURLAUTH_NONE;
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
else if(data->state.authwant & CURLAUTH_BASIC) {
|
else if(data->state.authwant & CURLAUTH_BASIC) {
|
||||||
data->state.authavail |= CURLAUTH_BASIC;
|
data->state.authavail |= CURLAUTH_BASIC;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
** We asked for something besides basic but got
|
||||||
|
** Basic anyway. This is no good.
|
||||||
|
*/
|
||||||
|
infof(data, "Server expects Basic auth, but we're doing something else.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Curl_http_should_fail() determines whether an HTTP response has gotten us
|
||||||
|
* into an error state or not.
|
||||||
|
*
|
||||||
|
* @param conn all information about the current connection
|
||||||
|
*
|
||||||
|
* @retval 0 communications should continue
|
||||||
|
*
|
||||||
|
* @retval 1 communications should not continue
|
||||||
|
*/
|
||||||
|
int Curl_http_should_fail(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data;
|
||||||
|
struct Curl_transfer_keeper *k;
|
||||||
|
|
||||||
/* fread() emulation to provide POST and/or request data */
|
curlassert(conn);
|
||||||
|
data = conn->data;
|
||||||
|
curlassert(data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** For readability
|
||||||
|
*/
|
||||||
|
k = &conn->keep;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If we haven't been asked to fail on error,
|
||||||
|
** don't fail.
|
||||||
|
*/
|
||||||
|
if (!data->set.http_fail_on_error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Any code < 400 is never terminal.
|
||||||
|
*/
|
||||||
|
if (k->httpcode < 400)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Any code >= 400 that's not 401 or 407 is always
|
||||||
|
** a terminal error
|
||||||
|
*/
|
||||||
|
if ((k->httpcode != 401) &&
|
||||||
|
(k->httpcode != 407))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** All we have left to deal with is 401 and 407
|
||||||
|
*/
|
||||||
|
curlassert((k->httpcode == 401) || (k->httpcode == 407));
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Examine the current authentication state to see if this
|
||||||
|
** is an error. The idea is for this function to get
|
||||||
|
** called after processing all the headers in a response
|
||||||
|
** message. So, if we've been to asked to authenticate a
|
||||||
|
** particular stage, and we've done it, we're OK. But, if
|
||||||
|
** we're already completely authenticated, it's not OK to
|
||||||
|
** get another 401 or 407.
|
||||||
|
**
|
||||||
|
** It is possible for authentication to go stale such that
|
||||||
|
** the client needs to reauthenticate. Once that info is
|
||||||
|
** available, use it here.
|
||||||
|
*/
|
||||||
|
#if 0 /* set to 1 when debugging this functionality */
|
||||||
|
infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage);
|
||||||
|
infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant);
|
||||||
|
infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail);
|
||||||
|
infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode);
|
||||||
|
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
|
||||||
|
infof(data,"%s: newurl = %s\n",__FUNCTION__,conn->newurl ? conn->newurl : "(null)");
|
||||||
|
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (data->state.authstage &&
|
||||||
|
(data->state.authstage == k->httpcode))
|
||||||
|
return (data->state.authdone || data->state.authproblem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Either we're not authenticating, or we're supposed to
|
||||||
|
** be authenticating something else. This is an error.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readmoredata() is a "fread() emulation" to provide POST and/or request
|
||||||
|
* data. It is used when a huge POST is to be made and the entire chunk wasn't
|
||||||
|
* sent in the first send(). This function will then be called from the
|
||||||
|
* transfer.c loop when more data is to be sent to the peer.
|
||||||
|
*
|
||||||
|
* Returns the amount of bytes it filled the buffer with.
|
||||||
|
*/
|
||||||
static size_t readmoredata(char *buffer,
|
static size_t readmoredata(char *buffer,
|
||||||
size_t size,
|
size_t size,
|
||||||
size_t nitems,
|
size_t nitems,
|
||||||
@@ -502,7 +642,7 @@ static CURLcode
|
|||||||
add_buffer(send_buffer *in, const void *inptr, size_t size);
|
add_buffer(send_buffer *in, const void *inptr, size_t size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add_buffer_init() returns a fine buffer struct
|
* add_buffer_init() sets up and returns a fine buffer struct
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
send_buffer *add_buffer_init(void)
|
send_buffer *add_buffer_init(void)
|
||||||
@@ -518,6 +658,8 @@ send_buffer *add_buffer_init(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* add_buffer_send() sends a buffer and frees all associated memory.
|
* add_buffer_send() sends a buffer and frees all associated memory.
|
||||||
|
*
|
||||||
|
* Returns CURLcode
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
CURLcode add_buffer_send(send_buffer *in,
|
CURLcode add_buffer_send(send_buffer *in,
|
||||||
@@ -608,7 +750,7 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add_bufferf() builds a buffer from the formatted input
|
* add_bufferf() add the formatted input to the buffer.
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
|
CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
|
||||||
@@ -633,7 +775,7 @@ CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add_buffer() appends a memory chunk to the existing one
|
* add_buffer() appends a memory chunk to the existing buffer
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
|
CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
|
||||||
@@ -760,9 +902,6 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bool auth; /* we don't really have to know when the auth phase is done,
|
|
||||||
but this variable will be set to true then */
|
|
||||||
|
|
||||||
if(conn->newurl) {
|
if(conn->newurl) {
|
||||||
/* This only happens if we've looped here due to authentication reasons,
|
/* This only happens if we've looped here due to authentication reasons,
|
||||||
and we don't really use the newly cloned URL here then. Just free()
|
and we don't really use the newly cloned URL here then. Just free()
|
||||||
@@ -776,7 +915,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Setup the proxy-authorization header, if any */
|
/* Setup the proxy-authorization header, if any */
|
||||||
result = http_auth_headers(conn, (char *)"CONNECT", host_port, &auth);
|
result = http_auth_headers(conn, (char *)"CONNECT", host_port);
|
||||||
if(CURLE_OK == result) {
|
if(CURLE_OK == result) {
|
||||||
|
|
||||||
/* OK, now send the connect request to the proxy */
|
/* OK, now send the connect request to the proxy */
|
||||||
@@ -877,7 +1016,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
|
|
||||||
/* send the header to the callback */
|
/* send the header to the callback */
|
||||||
writetype = CLIENTWRITE_HEADER;
|
writetype = CLIENTWRITE_HEADER;
|
||||||
if(data->set.http_include_header)
|
if(data->set.include_header)
|
||||||
writetype |= CLIENTWRITE_BODY;
|
writetype |= CLIENTWRITE_BODY;
|
||||||
|
|
||||||
result = Curl_client_write(data, writetype, line_start, perline);
|
result = Curl_client_write(data, writetype, line_start, perline);
|
||||||
@@ -951,7 +1090,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HTTP stuff to do at connect-time.
|
* Curl_http_connect() performs HTTP stuff to do at connect-time, called from
|
||||||
|
* the generic Curl_connect().
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_http_connect(struct connectdata *conn)
|
CURLcode Curl_http_connect(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
@@ -997,6 +1137,11 @@ CURLcode Curl_http_connect(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
||||||
|
* has been performed.
|
||||||
|
*/
|
||||||
|
|
||||||
CURLcode Curl_http_done(struct connectdata *conn)
|
CURLcode Curl_http_done(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data;
|
struct SessionHandle *data;
|
||||||
@@ -1029,10 +1174,12 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
conn->bytecount = http->readbytecount + http->writebytecount;
|
conn->bytecount = http->readbytecount + http->writebytecount;
|
||||||
|
|
||||||
if(!conn->bits.retry &&
|
if(!conn->bits.retry &&
|
||||||
!(http->readbytecount + conn->headerbytecount)) {
|
((http->readbytecount +
|
||||||
|
conn->headerbytecount -
|
||||||
|
conn->deductheadercount)) <= 0) {
|
||||||
/* If this connection isn't simply closed to be retried, AND nothing was
|
/* If this connection isn't simply closed to be retried, AND nothing was
|
||||||
read from the HTTP server, this can't be right so we return an error
|
read from the HTTP server (that counts), this can't be right so we
|
||||||
here */
|
return an error here */
|
||||||
failf(data, "Empty reply from server");
|
failf(data, "Empty reply from server");
|
||||||
return CURLE_GOT_NOTHING;
|
return CURLE_GOT_NOTHING;
|
||||||
}
|
}
|
||||||
@@ -1040,6 +1187,10 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_http_auth_stage() sets the "authentication stage" - which is 407 for
|
||||||
|
* proxy authentication or 401 for host authentication.
|
||||||
|
*/
|
||||||
void Curl_http_auth_stage(struct SessionHandle *data,
|
void Curl_http_auth_stage(struct SessionHandle *data,
|
||||||
int stage)
|
int stage)
|
||||||
{
|
{
|
||||||
@@ -1054,6 +1205,11 @@ void Curl_http_auth_stage(struct SessionHandle *data,
|
|||||||
data->state.authavail = CURLAUTH_NONE; /* no type available yet */
|
data->state.authavail = CURLAUTH_NONE; /* no type available yet */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
||||||
|
* request is to be performed. This creates and sends a propperly constructed
|
||||||
|
* HTTP request.
|
||||||
|
*/
|
||||||
CURLcode Curl_http(struct connectdata *conn)
|
CURLcode Curl_http(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
@@ -1061,12 +1217,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
struct HTTP *http;
|
struct HTTP *http;
|
||||||
struct Cookie *co=NULL; /* no cookies from start */
|
struct Cookie *co=NULL; /* no cookies from start */
|
||||||
char *ppath = conn->ppath; /* three previous function arguments */
|
char *ppath = conn->path;
|
||||||
char *host = conn->name;
|
char *host = conn->hostname;
|
||||||
const char *te = ""; /* tranfer-encoding */
|
const char *te = ""; /* tranfer-encoding */
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *request;
|
char *request;
|
||||||
bool authdone=TRUE; /* if the authentication phase is done */
|
Curl_HttpReq httpreq = data->set.httpreq;
|
||||||
|
|
||||||
if(!conn->proto.http) {
|
if(!conn->proto.http) {
|
||||||
/* Only allocate this struct if we don't already have it! */
|
/* Only allocate this struct if we don't already have it! */
|
||||||
@@ -1085,19 +1241,40 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
|
|
||||||
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
|
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
|
||||||
data->set.upload) {
|
data->set.upload) {
|
||||||
data->set.httpreq = HTTPREQ_PUT;
|
httpreq = HTTPREQ_PUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
request = data->set.customrequest?
|
/* Now set the 'request' pointer to the proper request string */
|
||||||
data->set.customrequest:
|
if(data->set.customrequest)
|
||||||
(data->set.no_body?(char *)"HEAD":
|
request = data->set.customrequest;
|
||||||
((HTTPREQ_POST == data->set.httpreq) ||
|
else {
|
||||||
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
|
if(conn->bits.no_body)
|
||||||
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
|
request = (char *)"HEAD";
|
||||||
|
else {
|
||||||
|
curlassert((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
|
||||||
|
switch(httpreq) {
|
||||||
|
case HTTPREQ_POST:
|
||||||
|
case HTTPREQ_POST_FORM:
|
||||||
|
request = (char *)"POST";
|
||||||
|
break;
|
||||||
|
case HTTPREQ_PUT:
|
||||||
|
request = (char *)"PUT";
|
||||||
|
break;
|
||||||
|
case HTTPREQ_GET:
|
||||||
|
request = (char *)"GET";
|
||||||
|
break;
|
||||||
|
case HTTPREQ_HEAD:
|
||||||
|
request = (char *)"HEAD";
|
||||||
|
break;
|
||||||
|
default: /* this should never happen */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The User-Agent string has been built in url.c already, because it might
|
/* The User-Agent string might have been allocated in url.c already, because
|
||||||
have been used in the proxy connect, but if we have got a header with
|
it might have been used in the proxy connect, but if we have got a header
|
||||||
the user-agent string specified, we erase the previously made string
|
with the user-agent string specified, we erase the previously made string
|
||||||
here. */
|
here. */
|
||||||
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
||||||
free(conn->allocptr.uagent);
|
free(conn->allocptr.uagent);
|
||||||
@@ -1105,10 +1282,20 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup the authentication headers */
|
/* setup the authentication headers */
|
||||||
result = http_auth_headers(conn, request, ppath, &authdone);
|
result = http_auth_headers(conn, request, ppath);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
if(!data->state.authdone && (httpreq != HTTPREQ_GET)) {
|
||||||
|
/* Until we are authenticated, we switch over to HEAD. Unless its a GET
|
||||||
|
we want to do. The explanation for this is rather long and boring, but
|
||||||
|
the point is that it can't be done otherwise without risking having to
|
||||||
|
send the POST or PUT data multiple times. */
|
||||||
|
httpreq = HTTPREQ_HEAD;
|
||||||
|
request = (char *)"HEAD";
|
||||||
|
conn->bits.no_body = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
Curl_safefree(conn->allocptr.ref);
|
Curl_safefree(conn->allocptr.ref);
|
||||||
if(data->change.referer && !checkheaders(data, "Referer:"))
|
if(data->change.referer && !checkheaders(data, "Referer:"))
|
||||||
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
|
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
|
||||||
@@ -1121,7 +1308,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
else
|
else
|
||||||
conn->allocptr.cookie = NULL;
|
conn->allocptr.cookie = NULL;
|
||||||
|
|
||||||
if(!conn->bits.upload_chunky && (data->set.httpreq != HTTPREQ_GET)) {
|
if(!conn->bits.upload_chunky && (httpreq != HTTPREQ_GET)) {
|
||||||
/* not a chunky transfer yet, but data is to be sent */
|
/* not a chunky transfer yet, but data is to be sent */
|
||||||
ptr = checkheaders(data, "Transfer-Encoding:");
|
ptr = checkheaders(data, "Transfer-Encoding:");
|
||||||
if(ptr) {
|
if(ptr) {
|
||||||
@@ -1212,7 +1399,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* The path sent to the proxy is in fact the entire URL */
|
/* The path sent to the proxy is in fact the entire URL */
|
||||||
ppath = data->change.url;
|
ppath = data->change.url;
|
||||||
}
|
}
|
||||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
if(HTTPREQ_POST_FORM == httpreq) {
|
||||||
/* we must build the whole darned post sequence first, so that we have
|
/* we must build the whole darned post sequence first, so that we have
|
||||||
a size of the whole shebang before we start to send it */
|
a size of the whole shebang before we start to send it */
|
||||||
result = Curl_getFormData(&http->sendit, data->set.httppost,
|
result = Curl_getFormData(&http->sendit, data->set.httppost,
|
||||||
@@ -1231,9 +1418,9 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
if(!checkheaders(data, "Accept:"))
|
if(!checkheaders(data, "Accept:"))
|
||||||
http->p_accept = "Accept: */*\r\n";
|
http->p_accept = "Accept: */*\r\n";
|
||||||
|
|
||||||
if(( (HTTPREQ_POST == data->set.httpreq) ||
|
if(( (HTTPREQ_POST == httpreq) ||
|
||||||
(HTTPREQ_POST_FORM == data->set.httpreq) ||
|
(HTTPREQ_POST_FORM == httpreq) ||
|
||||||
(HTTPREQ_PUT == data->set.httpreq) ) &&
|
(HTTPREQ_PUT == httpreq) ) &&
|
||||||
conn->resume_from) {
|
conn->resume_from) {
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Resuming upload in HTTP means that we PUT or POST and that we have
|
* Resuming upload in HTTP means that we PUT or POST and that we have
|
||||||
@@ -1296,14 +1483,14 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
* or uploading and we always let customized headers override our internal
|
* or uploading and we always let customized headers override our internal
|
||||||
* ones if any such are specified.
|
* ones if any such are specified.
|
||||||
*/
|
*/
|
||||||
if((data->set.httpreq == HTTPREQ_GET) &&
|
if((httpreq == HTTPREQ_GET) &&
|
||||||
!checkheaders(data, "Range:")) {
|
!checkheaders(data, "Range:")) {
|
||||||
/* if a line like this was already allocated, free the previous one */
|
/* if a line like this was already allocated, free the previous one */
|
||||||
if(conn->allocptr.rangeline)
|
if(conn->allocptr.rangeline)
|
||||||
free(conn->allocptr.rangeline);
|
free(conn->allocptr.rangeline);
|
||||||
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
|
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
|
||||||
}
|
}
|
||||||
else if((data->set.httpreq != HTTPREQ_GET) &&
|
else if((httpreq != HTTPREQ_GET) &&
|
||||||
!checkheaders(data, "Content-Range:")) {
|
!checkheaders(data, "Content-Range:")) {
|
||||||
|
|
||||||
if(conn->resume_from) {
|
if(conn->resume_from) {
|
||||||
@@ -1466,11 +1653,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
http->postdata = NULL; /* nothing to post at this point */
|
http->postdata = NULL; /* nothing to post at this point */
|
||||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||||
|
|
||||||
/* If 'authdone' is still FALSE, we must not set the write socket index to
|
/* If 'authdone' is FALSE, we must not set the write socket index to the
|
||||||
the Curl_transfer() call below, as we're not ready to actually upload
|
Curl_transfer() call below, as we're not ready to actually upload any
|
||||||
any data yet. */
|
data yet. */
|
||||||
|
|
||||||
switch(data->set.httpreq) {
|
switch(httpreq) {
|
||||||
|
|
||||||
case HTTPREQ_POST_FORM:
|
case HTTPREQ_POST_FORM:
|
||||||
if(Curl_FormInit(&http->form, http->sendit)) {
|
if(Curl_FormInit(&http->form, http->sendit)) {
|
||||||
@@ -1499,7 +1686,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!checkheaders(data, "Content-Type:")) {
|
if(!checkheaders(data, "Content-Type:")) {
|
||||||
/* Get Content-Type: line from Curl_FormReadOneLine, which happens
|
/* Get Content-Type: line from Curl_formpostheader, which happens
|
||||||
to always be the first line. We can know this for sure since
|
to always be the first line. We can know this for sure since
|
||||||
we always build the formpost linked list the same way!
|
we always build the formpost linked list the same way!
|
||||||
|
|
||||||
@@ -1507,13 +1694,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
string etc why disabling this header is likely to not make things
|
string etc why disabling this header is likely to not make things
|
||||||
work, but we support it anyway.
|
work, but we support it anyway.
|
||||||
*/
|
*/
|
||||||
char contentType[256];
|
char *contentType;
|
||||||
size_t linelength=0;
|
size_t linelength=0;
|
||||||
linelength = Curl_FormReadOneLine(contentType,
|
contentType = Curl_formpostheader((void *)&http->form,
|
||||||
sizeof(contentType),
|
&linelength);
|
||||||
1,
|
if(!contentType) {
|
||||||
(FILE *)&http->form);
|
|
||||||
if(!linelength) {
|
|
||||||
failf(data, "Could not get Content-Type header line!");
|
failf(data, "Could not get Content-Type header line!");
|
||||||
return CURLE_HTTP_POST_ERROR;
|
return CURLE_HTTP_POST_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1535,8 +1720,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* setup variables for the upcoming transfer */
|
/* setup variables for the upcoming transfer */
|
||||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
authdone?FIRSTSOCKET:-1,
|
data->state.authdone?FIRSTSOCKET:-1,
|
||||||
authdone?&http->writebytecount:NULL);
|
data->state.authdone?&http->writebytecount:NULL);
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_formclean(http->sendit); /* free that whole lot */
|
Curl_formclean(http->sendit); /* free that whole lot */
|
||||||
return result;
|
return result;
|
||||||
@@ -1574,8 +1759,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* prepare for transfer */
|
/* prepare for transfer */
|
||||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||||
&http->readbytecount,
|
&http->readbytecount,
|
||||||
authdone?FIRSTSOCKET:-1,
|
data->state.authdone?FIRSTSOCKET:-1,
|
||||||
authdone?&http->writebytecount:NULL);
|
data->state.authdone?&http->writebytecount:NULL);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
break;
|
break;
|
||||||
@@ -1606,7 +1791,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
|
|
||||||
if(data->set.postfields) {
|
if(data->set.postfields) {
|
||||||
|
|
||||||
if(authdone && (postsize < (100*1024))) {
|
if(data->state.authdone && (postsize < (100*1024))) {
|
||||||
/* If we're not done with the authentication phase, we don't expect
|
/* If we're not done with the authentication phase, we don't expect
|
||||||
to actually send off any data yet. Hence, we delay the sending of
|
to actually send off any data yet. Hence, we delay the sending of
|
||||||
the body until we receive that friendly 100-continue response */
|
the body until we receive that friendly 100-continue response */
|
||||||
@@ -1642,7 +1827,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||||
|
|
||||||
if(!authdone && !checkheaders(data, "Expect:")) {
|
if(!data->state.authdone && !checkheaders(data, "Expect:")) {
|
||||||
/* if not disabled explicitly we add a Expect: 100-continue to the
|
/* if not disabled explicitly we add a Expect: 100-continue to the
|
||||||
headers which actually speeds up post operations (as there is
|
headers which actually speeds up post operations (as there is
|
||||||
one packet coming back from the web server) */
|
one packet coming back from the web server) */
|
||||||
|
@@ -42,9 +42,13 @@ CURLcode Curl_http_connect(struct connectdata *conn);
|
|||||||
void Curl_httpchunk_init(struct connectdata *conn);
|
void Curl_httpchunk_init(struct connectdata *conn);
|
||||||
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||||
ssize_t length, ssize_t *wrote);
|
ssize_t length, ssize_t *wrote);
|
||||||
|
|
||||||
|
/* These functions are in http.c */
|
||||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||||
CURLcode Curl_http_auth(struct connectdata *conn,
|
CURLcode Curl_http_auth(struct connectdata *conn,
|
||||||
int httpcode, char *header);
|
int httpcode, char *header);
|
||||||
void Curl_http_auth_act(struct connectdata *conn);
|
void Curl_http_auth_act(struct connectdata *conn);
|
||||||
|
|
||||||
|
int Curl_http_should_fail(struct connectdata *conn);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "http_digest.h"
|
#include "http_digest.h"
|
||||||
|
#include "url.h" /* for Curl_safefree() */
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -57,6 +58,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
bool more = TRUE;
|
bool more = TRUE;
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
|
bool before = FALSE; /* got a nonce before */
|
||||||
|
struct digestdata *d = &data->state.digest;
|
||||||
|
|
||||||
/* skip initial whitespaces */
|
/* skip initial whitespaces */
|
||||||
while(*header && isspace((int)*header))
|
while(*header && isspace((int)*header))
|
||||||
@@ -65,6 +68,10 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
if(checkprefix("Digest", header)) {
|
if(checkprefix("Digest", header)) {
|
||||||
header += strlen("Digest");
|
header += strlen("Digest");
|
||||||
|
|
||||||
|
/* If we already have received a nonce, keep that in mind */
|
||||||
|
if(d->nonce)
|
||||||
|
before = TRUE;
|
||||||
|
|
||||||
/* clear off any former leftovers and init to defaults */
|
/* clear off any former leftovers and init to defaults */
|
||||||
Curl_digest_cleanup(data);
|
Curl_digest_cleanup(data);
|
||||||
|
|
||||||
@@ -77,21 +84,32 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
header++;
|
header++;
|
||||||
|
|
||||||
/* how big can these strings be? */
|
/* how big can these strings be? */
|
||||||
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||||
value, content)) {
|
value, content)) ||
|
||||||
|
/* try the same scan but without quotes around the content but don't
|
||||||
|
include the possibly trailing comma */
|
||||||
|
(2 == sscanf(header, "%31[^=]=%127[^,]",
|
||||||
|
value, content)) ) {
|
||||||
if(strequal(value, "nonce")) {
|
if(strequal(value, "nonce")) {
|
||||||
data->state.digest.nonce = strdup(content);
|
d->nonce = strdup(content);
|
||||||
|
}
|
||||||
|
else if(strequal(value, "stale")) {
|
||||||
|
if(strequal(content, "true"))
|
||||||
|
d->stale = TRUE;
|
||||||
}
|
}
|
||||||
else if(strequal(value, "cnonce")) {
|
else if(strequal(value, "cnonce")) {
|
||||||
data->state.digest.cnonce = strdup(content);
|
d->cnonce = strdup(content);
|
||||||
}
|
}
|
||||||
else if(strequal(value, "realm")) {
|
else if(strequal(value, "realm")) {
|
||||||
data->state.digest.realm = strdup(content);
|
d->realm = strdup(content);
|
||||||
}
|
}
|
||||||
else if(strequal(value, "algorithm")) {
|
else if(strequal(value, "algorithm")) {
|
||||||
if(strequal(content, "MD5-sess"))
|
if(strequal(content, "MD5-sess"))
|
||||||
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
|
d->algo = CURLDIGESTALGO_MD5SESS;
|
||||||
/* else, remain using the default md5 */
|
else if(strequal(content, "MD5"))
|
||||||
|
d->algo = CURLDIGESTALGO_MD5;
|
||||||
|
else
|
||||||
|
return CURLDIGEST_BADALGO;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* unknown specifier, ignore it! */
|
/* unknown specifier, ignore it! */
|
||||||
@@ -106,8 +124,15 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
/* allow the list to be comma-separated */
|
/* allow the list to be comma-separated */
|
||||||
header++;
|
header++;
|
||||||
}
|
}
|
||||||
|
/* We had a nonce since before, and we got another one now without
|
||||||
|
'stale=true'. This means we provided bad credentials in the previous
|
||||||
|
request */
|
||||||
|
|
||||||
if(!data->state.digest.nonce)
|
if(before && !d->stale)
|
||||||
|
return CURLDIGEST_BAD;
|
||||||
|
|
||||||
|
/* We got this header without a nonce, that's a bad Digest line! */
|
||||||
|
if(!d->nonce)
|
||||||
return CURLDIGEST_BAD;
|
return CURLDIGEST_BAD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -140,6 +165,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
unsigned char *md5this;
|
unsigned char *md5this;
|
||||||
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct digestdata *d = &data->state.digest;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
||||||
@@ -151,20 +177,20 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||||
":" unq(nonce-value) ":" unq(cnonce-value)
|
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||||
*/
|
*/
|
||||||
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
|
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||||
md5this = (unsigned char *)
|
md5this = (unsigned char *)
|
||||||
aprintf("%s:%s:%s:%s:%s",
|
aprintf("%s:%s:%s:%s:%s",
|
||||||
conn->user,
|
conn->user,
|
||||||
data->state.digest.realm,
|
d->realm,
|
||||||
conn->passwd,
|
conn->passwd,
|
||||||
data->state.digest.nonce,
|
d->nonce,
|
||||||
data->state.digest.cnonce);
|
d->cnonce);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
md5this = (unsigned char *)
|
md5this = (unsigned char *)
|
||||||
aprintf("%s:%s:%s",
|
aprintf("%s:%s:%s",
|
||||||
conn->user,
|
conn->user,
|
||||||
data->state.digest.realm,
|
d->realm,
|
||||||
conn->passwd);
|
conn->passwd);
|
||||||
}
|
}
|
||||||
Curl_md5it(md5buf, md5this);
|
Curl_md5it(md5buf, md5this);
|
||||||
@@ -183,7 +209,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
free(md5this); /* free this again */
|
free(md5this); /* free this again */
|
||||||
md5_to_ascii(md5buf, ha2);
|
md5_to_ascii(md5buf, ha2);
|
||||||
|
|
||||||
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, data->state.digest.nonce,
|
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, d->nonce,
|
||||||
ha2);
|
ha2);
|
||||||
Curl_md5it(md5buf, md5this);
|
Curl_md5it(md5buf, md5this);
|
||||||
free(md5this); /* free this again */
|
free(md5this); /* free this again */
|
||||||
@@ -195,6 +221,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Curl_safefree(conn->allocptr.userpwd);
|
||||||
conn->allocptr.userpwd =
|
conn->allocptr.userpwd =
|
||||||
aprintf( "Authorization: Digest "
|
aprintf( "Authorization: Digest "
|
||||||
"username=\"%s\", "
|
"username=\"%s\", "
|
||||||
@@ -203,8 +230,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
"uri=\"%s\", "
|
"uri=\"%s\", "
|
||||||
"response=\"%s\"\r\n",
|
"response=\"%s\"\r\n",
|
||||||
conn->user,
|
conn->user,
|
||||||
data->state.digest.realm,
|
d->realm,
|
||||||
data->state.digest.nonce,
|
d->nonce,
|
||||||
uripath, /* this is the PATH part of the URL */
|
uripath, /* this is the PATH part of the URL */
|
||||||
request_digest );
|
request_digest );
|
||||||
|
|
||||||
@@ -213,19 +240,23 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
|
|
||||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
if(data->state.digest.nonce)
|
struct digestdata *d = &data->state.digest;
|
||||||
free(data->state.digest.nonce);
|
|
||||||
data->state.digest.nonce = NULL;
|
|
||||||
|
|
||||||
if(data->state.digest.cnonce)
|
if(d->nonce)
|
||||||
free(data->state.digest.cnonce);
|
free(d->nonce);
|
||||||
data->state.digest.cnonce = NULL;
|
d->nonce = NULL;
|
||||||
|
|
||||||
if(data->state.digest.realm)
|
if(d->cnonce)
|
||||||
free(data->state.digest.realm);
|
free(d->cnonce);
|
||||||
data->state.digest.realm = NULL;
|
d->cnonce = NULL;
|
||||||
|
|
||||||
data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
if(d->realm)
|
||||||
|
free(d->realm);
|
||||||
|
d->realm = NULL;
|
||||||
|
|
||||||
|
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||||
|
|
||||||
|
d->stale = FALSE; /* default means normal, not stale */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
CURLDIGEST_NONE, /* not a digest */
|
CURLDIGEST_NONE, /* not a digest */
|
||||||
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||||
|
CURLDIGEST_BADALGO, /* unsupported algorithm requested */
|
||||||
CURLDIGEST_FINE, /* a digest we act on */
|
CURLDIGEST_FINE, /* a digest we act on */
|
||||||
|
|
||||||
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||||
|
@@ -77,7 +77,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define this to make the type-3 message include the NT response message */
|
/* Define this to make the type-3 message include the NT response message */
|
||||||
#undef USE_NTRESPONSES
|
#define USE_NTRESPONSES 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
||||||
@@ -277,8 +277,7 @@ static void mkhash(char *password,
|
|||||||
|
|
||||||
/* this is for creating ntlm header output */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||||
bool proxy,
|
bool proxy)
|
||||||
bool *ready)
|
|
||||||
{
|
{
|
||||||
const char *domain=""; /* empty */
|
const char *domain=""; /* empty */
|
||||||
const char *host=""; /* empty */
|
const char *host=""; /* empty */
|
||||||
@@ -300,7 +299,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
/* point to the correct struct with this */
|
/* point to the correct struct with this */
|
||||||
struct ntlmdata *ntlm;
|
struct ntlmdata *ntlm;
|
||||||
|
|
||||||
*ready = FALSE;
|
curlassert(conn);
|
||||||
|
curlassert(conn->data);
|
||||||
|
conn->data->state.authdone = FALSE;
|
||||||
|
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||||
@@ -562,7 +563,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||||
|
|
||||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||||
*ready = TRUE;
|
conn->data->state.authdone = TRUE;
|
||||||
|
|
||||||
/* Switch to web authentication after proxy authentication is done */
|
/* Switch to web authentication after proxy authentication is done */
|
||||||
if (proxy)
|
if (proxy)
|
||||||
@@ -577,7 +578,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
free(*allocuserpwd);
|
free(*allocuserpwd);
|
||||||
*allocuserpwd=NULL;
|
*allocuserpwd=NULL;
|
||||||
}
|
}
|
||||||
*ready = TRUE;
|
conn->data->state.authdone = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ typedef enum {
|
|||||||
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||||
|
|
||||||
/* this is for creating ntlm header output */
|
/* this is for creating ntlm header output */
|
||||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy, bool *ready);
|
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||||
|
|
||||||
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
void Curl_ntlm_cleanup(struct SessionHandle *data);
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#include <winver.h>
|
#include <winver.h>
|
||||||
#include "../include/curl/curl.h"
|
#include "../include/curl/curlver.h"
|
||||||
|
|
||||||
LANGUAGE 0x09,0x01
|
LANGUAGE 0x09,0x01
|
||||||
|
|
||||||
|
236
lib/makefile.dj
236
lib/makefile.dj
@@ -14,13 +14,14 @@ endif
|
|||||||
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
|
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
|
||||||
easy.c escape.c file.c formdata.c ftp.c \
|
easy.c escape.c file.c formdata.c ftp.c \
|
||||||
getdate.c getenv.c getinfo.c hash.c hostip.c \
|
getdate.c getenv.c getinfo.c hash.c hostip.c \
|
||||||
http.c http_chu.c http_dig.c http_neg.c http_ntl.c \
|
|
||||||
if2ip.c krb4.c md5.c ldap.c llist.c \
|
if2ip.c krb4.c md5.c ldap.c llist.c \
|
||||||
memdebug.c mprintf.c multi.c netrc.c progress.c \
|
memdebug.c mprintf.c multi.c netrc.c progress.c \
|
||||||
security.c sendf.c share.c speedche.c ssluse.c \
|
security.c sendf.c share.c speedche.c ssluse.c \
|
||||||
strequal.c strtok.c telnet.c timeval.c transfer.c \
|
strequal.c strtok.c telnet.c timeval.c transfer.c \
|
||||||
url.c version.c
|
strerror.c strtoofft.c url.c version.c http.c \
|
||||||
|
http_chunks.c http_digest.c http_negotiate.c http_ntlm.c
|
||||||
|
|
||||||
|
SOURCES := $(strip $(SOURCES))
|
||||||
OBJECTS = $(SOURCES:.c=.o)
|
OBJECTS = $(SOURCES:.c=.o)
|
||||||
CURL_LIB = libcurl.a
|
CURL_LIB = libcurl.a
|
||||||
|
|
||||||
@@ -46,130 +47,155 @@ realclean vclean: clean
|
|||||||
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
|
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
|
||||||
base64.h
|
base64.h
|
||||||
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
|
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h sendf.h if2ip.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
if2ip.h strerror.h connect.h
|
||||||
content_.o: content_.c setup.h config.h config.dj
|
content_.o: content_.c setup.h config.h config.dj
|
||||||
cookie.o: cookie.c setup.h config.h config.dj urldata.h cookie.h \
|
cookie.o: cookie.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h getdate.h strequal.h strtok.h sendf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h getdate.h \
|
||||||
|
strequal.h strtok.h sendf.h
|
||||||
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
|
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
|
||||||
../include/curl/mprintf.h
|
sendf.h progress.h strequal.h dict.h ../include/curl/mprintf.h
|
||||||
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
|
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h transfer.h ssluse.h url.h getinfo.h share.h \
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
|
||||||
../include/curl/mprintf.h
|
ssluse.h url.h getinfo.h share.h ../include/curl/mprintf.h
|
||||||
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
|
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
|
../include/curl/easy.h ../include/curl/multi.h
|
||||||
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
|
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h progress.h sendf.h escape.h ../include/curl/mprintf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h progress.h \
|
||||||
|
sendf.h escape.h file.h speedcheck.h getinfo.h transfer.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
|
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
formdata.h strequal.h
|
../include/curl/easy.h ../include/curl/multi.h formdata.h strequal.h
|
||||||
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
|
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
strequal.h ssluse.h connect.h ../include/curl/mprintf.h
|
if2ip.h progress.h transfer.h escape.h http.h ftp.h strtoofft.h \
|
||||||
|
strequal.h ssluse.h connect.h strerror.h ../include/curl/mprintf.h
|
||||||
getdate.o: getdate.c setup.h config.h config.dj getdate.h
|
getdate.o: getdate.c setup.h config.h config.dj getdate.h
|
||||||
getenv.o: getenv.c setup.h config.h config.dj
|
getenv.o: getenv.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
|
../include/curl/easy.h ../include/curl/multi.h
|
||||||
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
|
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h getinfo.h
|
||||||
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
|
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
|
||||||
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
|
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h sendf.h share.h url.h ../include/curl/mprintf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
|
share.h url.h ../include/curl/mprintf.h
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
if2ip.o: if2ip.c setup.h config.h config.dj if2ip.h
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h transfer.h sendf.h progress.h base64.h strequal.h \
|
|
||||||
ssluse.h http_digest.h http_ntlm.h http_negotiate.h url.h share.h \
|
|
||||||
http.h ../include/curl/mprintf.h
|
|
||||||
http_chu.o: http_chu.c setup.h config.h config.dj urldata.h cookie.h \
|
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h sendf.h content_encoding.h ../include/curl/mprintf.h
|
|
||||||
http_dig.o: http_dig.c setup.h config.h config.dj urldata.h cookie.h \
|
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h sendf.h strequal.h md5.h http_digest.h \
|
|
||||||
../include/curl/mprintf.h
|
|
||||||
http_neg.o: http_neg.c setup.h config.h config.dj
|
|
||||||
http_ntl.o: http_ntl.c setup.h config.h config.dj
|
|
||||||
if2ip.o: if2ip.c setup.h config.h config.dj
|
|
||||||
krb4.o: krb4.c setup.h config.h config.dj
|
krb4.o: krb4.c setup.h config.h config.dj
|
||||||
md5.o: md5.c setup.h config.h config.dj
|
md5.o: md5.c setup.h config.h config.dj md5.h
|
||||||
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
|
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
hash.h llist.h sendf.h escape.h transfer.h ../include/curl/mprintf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
escape.h transfer.h ldap.h ../include/curl/mprintf.h
|
||||||
llist.o: llist.c setup.h config.h config.dj llist.h
|
llist.o: llist.c setup.h config.h config.dj llist.h
|
||||||
memdebug.o: memdebug.c setup.h config.h config.dj ../include/curl/curl.h \
|
memdebug.o: memdebug.c
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
mprintf.o: mprintf.c setup.h config.h config.dj ../include/curl/mprintf.h
|
||||||
../include/curl/mprintf.h urldata.h cookie.h formdata.h timeval.h \
|
|
||||||
http_chunks.h hostip.h hash.h llist.h
|
|
||||||
mprintf.o: mprintf.c setup.h config.h config.dj
|
|
||||||
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
|
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h transfer.h url.h connect.h progress.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
|
||||||
|
url.h connect.h progress.h
|
||||||
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
|
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
strequal.h strtok.h ../include/curl/mprintf.h
|
../include/curl/easy.h ../include/curl/multi.h netrc.h strequal.h \
|
||||||
|
strtok.h ../include/curl/mprintf.h
|
||||||
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
|
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h sendf.h progress.h ../include/curl/mprintf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
progress.h ../include/curl/mprintf.h
|
||||||
security.o: security.c setup.h config.h config.dj
|
security.o: security.c setup.h config.h config.dj
|
||||||
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
|
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h sendf.h connect.h ../include/curl/mprintf.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
connect.h ../include/curl/mprintf.h
|
||||||
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
|
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h share.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h share.h
|
||||||
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
|
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
llist.h sendf.h speedcheck.h
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
speedcheck.h
|
||||||
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
|
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h sendf.h url.h inet_pton.h
|
|
||||||
strequal.o: strequal.c setup.h config.h config.dj
|
|
||||||
strtok.o: strtok.c setup.h config.h config.dj
|
|
||||||
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
|
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h transfer.h sendf.h ../include/curl/mprintf.h \
|
|
||||||
arpa_telnet.h
|
|
||||||
timeval.o: timeval.c timeval.h setup.h config.h config.dj
|
|
||||||
transfer.o: transfer.c setup.h config.h config.dj strequal.h urldata.h \
|
|
||||||
cookie.h ../include/curl/curl.h ../include/curl/types.h \
|
|
||||||
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
|
|
||||||
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
|
|
||||||
transfer.h sendf.h speedcheck.h progress.h getdate.h http.h url.h \
|
|
||||||
getinfo.h ssluse.h http_digest.h http_ntlm.h http_negotiate.h share.h \
|
|
||||||
../include/curl/mprintf.h
|
|
||||||
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
|
|
||||||
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
|
|
||||||
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
|
||||||
hash.h llist.h netrc.h base64.h ssluse.h if2ip.h transfer.h sendf.h \
|
|
||||||
progress.h strequal.h escape.h strtok.h share.h content_encoding.h \
|
|
||||||
http_digest.h http_negotiate.h ftp.h dict.h telnet.h http.h file.h \
|
|
||||||
ldap.h url.h connect.h ca-bundle.h ../include/curl/mprintf.h
|
|
||||||
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
|
|
||||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
llist.h
|
url.h inet_pton.h ssluse.h connect.h
|
||||||
|
strequal.o: strequal.c setup.h config.h config.dj strequal.h
|
||||||
|
strtok.o: strtok.c setup.h config.h config.dj strtok.h
|
||||||
|
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
|
||||||
|
sendf.h telnet.h ../include/curl/mprintf.h arpa_telnet.h
|
||||||
|
timeval.o: timeval.c timeval.h setup.h config.h config.dj
|
||||||
|
transfer.o: transfer.c setup.h config.h config.dj strtoofft.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
strequal.h urldata.h cookie.h formdata.h timeval.h http_chunks.h \
|
||||||
|
hostip.h hash.h llist.h netrc.h content_encoding.h transfer.h sendf.h \
|
||||||
|
speedcheck.h progress.h getdate.h http.h url.h getinfo.h ssluse.h \
|
||||||
|
http_digest.h http_ntlm.h http_negotiate.h share.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
|
strerror.o: strerror.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
|
../include/curl/easy.h ../include/curl/multi.h strerror.h urldata.h \
|
||||||
|
cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
|
strtoofft.o: strtoofft.c setup.h config.h config.dj strtoofft.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
|
||||||
|
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h netrc.h \
|
||||||
|
base64.h ssluse.h if2ip.h transfer.h sendf.h progress.h strequal.h \
|
||||||
|
escape.h strtok.h share.h content_encoding.h http_digest.h \
|
||||||
|
http_negotiate.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h \
|
||||||
|
connect.h ca-bundle.h ../include/curl/mprintf.h
|
||||||
|
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
|
||||||
|
../include/curl/curlver.h ../include/curl/types.h \
|
||||||
|
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h
|
||||||
|
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
|
||||||
|
sendf.h progress.h base64.h strequal.h ssluse.h http_digest.h \
|
||||||
|
http_ntlm.h http_negotiate.h url.h share.h http.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
|
http_chunks.o: http_chunks.c setup.h config.h config.dj urldata.h \
|
||||||
|
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
content_encoding.h http.h ../include/curl/mprintf.h
|
||||||
|
http_digest.o: http_digest.c setup.h config.h config.dj urldata.h \
|
||||||
|
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
|
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
|
||||||
|
strequal.h md5.h http_digest.h ../include/curl/mprintf.h
|
||||||
|
http_negotiate.o: http_negotiate.c setup.h config.h config.dj
|
||||||
|
http_ntlm.o: http_ntlm.c setup.h config.h config.dj
|
||||||
|
@@ -122,8 +122,8 @@ enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
FormatType type;
|
FormatType type;
|
||||||
int flags;
|
int flags;
|
||||||
int width; /* width OR width parameter number */
|
long width; /* width OR width parameter number */
|
||||||
int precision; /* precision OR precision parameter number */
|
long precision; /* precision OR precision parameter number */
|
||||||
union {
|
union {
|
||||||
char *str;
|
char *str;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@@ -281,7 +281,8 @@ int dprintf_Pass1Report(va_stack_t *vto, int max)
|
|||||||
*
|
*
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
static int dprintf_Pass1(char *format, va_stack_t *vto, char **endpos, va_list arglist)
|
static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
||||||
|
va_list arglist)
|
||||||
{
|
{
|
||||||
char *fmt = format;
|
char *fmt = format;
|
||||||
int param_num = 0;
|
int param_num = 0;
|
||||||
@@ -681,7 +682,7 @@ static int dprintf_formatf(
|
|||||||
else
|
else
|
||||||
prec = -1;
|
prec = -1;
|
||||||
|
|
||||||
alt = p->flags & FLAGS_ALT;
|
alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case FORMAT_INT:
|
case FORMAT_INT:
|
||||||
@@ -1042,7 +1043,7 @@ static int alloc_addbyter(int output, FILE *data)
|
|||||||
infop->alloc *= 2;
|
infop->alloc *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
infop->buffer[ infop->len ] = output;
|
infop->buffer[ infop->len ] = (char)output;
|
||||||
|
|
||||||
infop->len++;
|
infop->len++;
|
||||||
|
|
||||||
|
@@ -122,7 +122,7 @@ CURLM *curl_multi_init(void)
|
|||||||
multi->type = CURL_MULTI_HANDLE;
|
multi->type = CURL_MULTI_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
multi->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
multi->hostcache = Curl_mk_dnscache();
|
||||||
if(!multi->hostcache) {
|
if(!multi->hostcache) {
|
||||||
/* failure, free mem and bail out */
|
/* failure, free mem and bail out */
|
||||||
free(multi);
|
free(multi);
|
||||||
@@ -380,7 +380,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
case CURLM_STATE_WAITRESOLVE:
|
case CURLM_STATE_WAITRESOLVE:
|
||||||
/* awaiting an asynch name resolve to complete */
|
/* awaiting an asynch name resolve to complete */
|
||||||
{
|
{
|
||||||
struct Curl_dns_entry *dns;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
|
|
||||||
/* check if we have the name resolved by now */
|
/* check if we have the name resolved by now */
|
||||||
easy->result = Curl_is_resolved(easy->easy_conn, &dns);
|
easy->result = Curl_is_resolved(easy->easy_conn, &dns);
|
||||||
|
@@ -91,7 +91,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
|
|
||||||
char state_login=0; /* Found a login keyword */
|
char state_login=0; /* Found a login keyword */
|
||||||
char state_password=0; /* Found a password keyword */
|
char state_password=0; /* Found a password keyword */
|
||||||
char state_our_login=0; /* With specific_login, found *our* login name */
|
int state_our_login=FALSE; /* With specific_login, found *our* login name */
|
||||||
|
|
||||||
#define NETRC DOT_CHAR "netrc"
|
#define NETRC DOT_CHAR "netrc"
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
else if(strequal("machine", tok)) {
|
else if(strequal("machine", tok)) {
|
||||||
/* ok, there's machine here go => */
|
/* ok, there's machine here go => */
|
||||||
state = HOSTFOUND;
|
state = HOSTFOUND;
|
||||||
state_our_login = 0;
|
state_our_login = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} /* switch (state) */
|
} /* switch (state) */
|
||||||
|
150
lib/progress.c
150
lib/progress.c
@@ -26,9 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* 20000318 mgs
|
|
||||||
* later we use _scrsize to determine the screen width, this emx library
|
|
||||||
* function needs stdlib.h to be included */
|
|
||||||
#if defined(__EMX__)
|
#if defined(__EMX__)
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -36,19 +33,34 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
|
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
|
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||||
static void time2str(char *r, int t)
|
byte) */
|
||||||
|
static void time2str(char *r, long t)
|
||||||
{
|
{
|
||||||
int h = (t/3600);
|
long h;
|
||||||
int m = (t-(h*3600))/60;
|
if(!t) {
|
||||||
int s = (t-(h*3600)-(m*60));
|
strcpy(r, "--:--:--");
|
||||||
sprintf(r,"%2d:%02d:%02d",h,m,s);
|
return;
|
||||||
|
}
|
||||||
|
h = (t/3600);
|
||||||
|
if(h <= 99) {
|
||||||
|
long m = (t-(h*3600))/60;
|
||||||
|
long s = (t-(h*3600)-(m*60));
|
||||||
|
sprintf(r, "%2ld:%02ld:%02ld",h,m,s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* this equals to more than 99 hours, switch to a more suitable output
|
||||||
|
format to fit within the limits. */
|
||||||
|
if(h/24 <= 999)
|
||||||
|
sprintf(r, "%3ldd %02ldh", h/24, h-(h/24)*24);
|
||||||
|
else
|
||||||
|
sprintf(r, "%7ldd", h/24);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The point of this function would be to return a string of the input data,
|
/* The point of this function would be to return a string of the input data,
|
||||||
@@ -105,13 +117,12 @@ static char *max5data(curl_off_t bytes, char *max5)
|
|||||||
void Curl_pgrsDone(struct connectdata *conn)
|
void Curl_pgrsDone(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
if(!(data->progress.flags & PGRS_HIDE)) {
|
data->progress.lastshow=0;
|
||||||
data->progress.lastshow=0;
|
Curl_pgrsUpdate(conn); /* the final (forced) update */
|
||||||
Curl_pgrsUpdate(conn); /* the final (forced) update */
|
if(!(data->progress.flags & PGRS_HIDE) &&
|
||||||
if(!data->progress.callback)
|
!data->progress.callback)
|
||||||
/* only output if we don't use progress callback */
|
/* only output if we don't use a progress callback and we're not hidden */
|
||||||
fprintf(data->set.err, "\n");
|
fprintf(data->set.err, "\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset all times except redirect */
|
/* reset all times except redirect */
|
||||||
@@ -137,26 +148,26 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
|
|||||||
|
|
||||||
case TIMER_NAMELOOKUP:
|
case TIMER_NAMELOOKUP:
|
||||||
data->progress.t_nslookup =
|
data->progress.t_nslookup =
|
||||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
break;
|
break;
|
||||||
case TIMER_CONNECT:
|
case TIMER_CONNECT:
|
||||||
data->progress.t_connect =
|
data->progress.t_connect =
|
||||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
break;
|
break;
|
||||||
case TIMER_PRETRANSFER:
|
case TIMER_PRETRANSFER:
|
||||||
data->progress.t_pretransfer =
|
data->progress.t_pretransfer =
|
||||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
break;
|
break;
|
||||||
case TIMER_STARTTRANSFER:
|
case TIMER_STARTTRANSFER:
|
||||||
data->progress.t_starttransfer =
|
data->progress.t_starttransfer =
|
||||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
|
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
break;
|
break;
|
||||||
case TIMER_POSTRANSFER:
|
case TIMER_POSTRANSFER:
|
||||||
/* this is the normal end-of-transfer thing */
|
/* this is the normal end-of-transfer thing */
|
||||||
break;
|
break;
|
||||||
case TIMER_REDIRECT:
|
case TIMER_REDIRECT:
|
||||||
data->progress.t_redirect =
|
data->progress.t_redirect =
|
||||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.start)/1000.0;
|
Curl_tvdiff_secs(Curl_tvnow(), data->progress.start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,44 +206,27 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
|
|||||||
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
|
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EXAMPLE OUTPUT to follow:
|
|
||||||
|
|
||||||
% Total % Received % Xferd Average Speed Time Curr.
|
|
||||||
Dload Upload Total Current Left Speed
|
|
||||||
100 12345 100 12345 100 12345 12345 12345 12:12:12 12:12:12 12:12:12 12345
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Curl_pgrsUpdate(struct connectdata *conn)
|
int Curl_pgrsUpdate(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
char max5[6][10];
|
char max5[6][10];
|
||||||
double dlpercen=0;
|
int dlpercen=0;
|
||||||
double ulpercen=0;
|
int ulpercen=0;
|
||||||
double total_percen=0;
|
int total_percen=0;
|
||||||
|
|
||||||
curl_off_t total_transfer;
|
curl_off_t total_transfer;
|
||||||
curl_off_t total_expected_transfer;
|
curl_off_t total_expected_transfer;
|
||||||
double timespent;
|
long timespent;
|
||||||
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
int nowindex = data->progress.speeder_c% CURR_TIME;
|
int nowindex = data->progress.speeder_c% CURR_TIME;
|
||||||
int checkindex;
|
int checkindex;
|
||||||
|
|
||||||
int countindex; /* amount of seconds stored in the speeder array */
|
int countindex; /* amount of seconds stored in the speeder array */
|
||||||
|
|
||||||
char time_left[10];
|
char time_left[10];
|
||||||
char time_total[10];
|
char time_total[10];
|
||||||
char time_current[10];
|
char time_spent[10];
|
||||||
|
long ulestimate=0;
|
||||||
double ulestimate=0;
|
long dlestimate=0;
|
||||||
double dlestimate=0;
|
long total_estimate;
|
||||||
|
|
||||||
double total_estimate;
|
|
||||||
|
|
||||||
|
|
||||||
if(data->progress.flags & PGRS_HIDE)
|
if(data->progress.flags & PGRS_HIDE)
|
||||||
; /* We do enter this function even if we don't wanna see anything, since
|
; /* We do enter this function even if we don't wanna see anything, since
|
||||||
@@ -246,26 +240,25 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
|||||||
"\n",
|
"\n",
|
||||||
conn->resume_from);
|
conn->resume_from);
|
||||||
fprintf(data->set.err,
|
fprintf(data->set.err,
|
||||||
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
|
" %% Total %% Received %% Xferd Average Speed Time Time Time Current\n"
|
||||||
" Dload Upload Total Current Left Speed\n");
|
" Dload Upload Total Spent Left Speed\n");
|
||||||
}
|
}
|
||||||
data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
|
data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
|
||||||
}
|
}
|
||||||
|
|
||||||
now = Curl_tvnow(); /* what time is it */
|
now = Curl_tvnow(); /* what time is it */
|
||||||
|
|
||||||
/* The exact time spent so far (from the start) */
|
/* The time spent so far (from the start) */
|
||||||
timespent = (double)Curl_tvdiff (now, data->progress.start)/1000;
|
data->progress.timespent = Curl_tvdiff_secs(now, data->progress.start);
|
||||||
|
timespent = (long)data->progress.timespent;
|
||||||
data->progress.timespent = timespent;
|
|
||||||
|
|
||||||
/* The average download speed this far */
|
/* The average download speed this far */
|
||||||
data->progress.dlspeed =
|
data->progress.dlspeed =
|
||||||
data->progress.downloaded/(timespent>0.01?timespent:1);
|
data->progress.downloaded/(timespent?timespent:1);
|
||||||
|
|
||||||
/* The average upload speed this far */
|
/* The average upload speed this far */
|
||||||
data->progress.ulspeed =
|
data->progress.ulspeed =
|
||||||
data->progress.uploaded/(timespent>0.01?timespent:1);
|
data->progress.uploaded/(timespent?timespent:1);
|
||||||
|
|
||||||
if(data->progress.lastshow == Curl_tvlong(now))
|
if(data->progress.lastshow == Curl_tvlong(now))
|
||||||
return 0; /* never update this more than once a second if the end isn't
|
return 0; /* never update this more than once a second if the end isn't
|
||||||
@@ -309,7 +302,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
|||||||
span_ms=1; /* at least one millisecond MUST have passed */
|
span_ms=1; /* at least one millisecond MUST have passed */
|
||||||
|
|
||||||
/* Calculate the average speed the last 'countindex' seconds */
|
/* Calculate the average speed the last 'countindex' seconds */
|
||||||
data->progress.current_speed =
|
data->progress.current_speed = (curl_off_t)
|
||||||
(data->progress.speeder[nowindex]-
|
(data->progress.speeder[nowindex]-
|
||||||
data->progress.speeder[checkindex])/((double)span_ms/1000);
|
data->progress.speeder[checkindex])/((double)span_ms/1000);
|
||||||
}
|
}
|
||||||
@@ -338,35 +331,25 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
|||||||
/* Figure out the estimated time of arrival for the upload */
|
/* Figure out the estimated time of arrival for the upload */
|
||||||
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
|
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
|
||||||
(data->progress.ulspeed > 0)) {
|
(data->progress.ulspeed > 0)) {
|
||||||
ulestimate = (double)data->progress.size_ul / data->progress.ulspeed;
|
ulestimate = (long)(data->progress.size_ul / data->progress.ulspeed);
|
||||||
ulpercen = ((double)data->progress.uploaded / data->progress.size_ul)*100;
|
ulpercen = (long)(data->progress.uploaded / data->progress.size_ul)*100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... and the download */
|
/* ... and the download */
|
||||||
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
|
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
|
||||||
(data->progress.dlspeed > 0)) {
|
(data->progress.dlspeed > 0)) {
|
||||||
dlestimate = (double)data->progress.size_dl / data->progress.dlspeed;
|
dlestimate = (long)(data->progress.size_dl / data->progress.dlspeed);
|
||||||
dlpercen = ((double)data->progress.downloaded / data->progress.size_dl)*100;
|
dlpercen = (long)(data->progress.downloaded / data->progress.size_dl)*100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now figure out which of them that is slower and use for the for
|
/* Now figure out which of them that is slower and use for the for
|
||||||
total estimate! */
|
total estimate! */
|
||||||
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
||||||
|
|
||||||
|
/* create the three time strings */
|
||||||
/* If we have a total estimate, we can display that and the expected
|
time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
|
||||||
time left */
|
time2str(time_total, total_estimate);
|
||||||
if(total_estimate > 0) {
|
time2str(time_spent, timespent);
|
||||||
time2str(time_left, (int)(total_estimate - data->progress.timespent));
|
|
||||||
time2str(time_total, (int)total_estimate);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* otherwise we blank those times */
|
|
||||||
strcpy(time_left, "--:--:--");
|
|
||||||
strcpy(time_total, "--:--:--");
|
|
||||||
}
|
|
||||||
/* The time spent so far is always known */
|
|
||||||
time2str(time_current, (int)data->progress.timespent);
|
|
||||||
|
|
||||||
/* Get the total amount of data expected to get transfered */
|
/* Get the total amount of data expected to get transfered */
|
||||||
total_expected_transfer =
|
total_expected_transfer =
|
||||||
@@ -380,22 +363,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
|||||||
|
|
||||||
/* Get the percentage of data transfered so far */
|
/* Get the percentage of data transfered so far */
|
||||||
if(total_expected_transfer > 0)
|
if(total_expected_transfer > 0)
|
||||||
total_percen=((double)total_transfer/total_expected_transfer)*100;
|
total_percen=(int)(total_transfer/total_expected_transfer)*100;
|
||||||
|
|
||||||
fprintf(data->set.err,
|
fprintf(data->set.err,
|
||||||
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
|
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
|
||||||
(int)total_percen, /* total % */
|
total_percen, /* 3 letters */ /* total % */
|
||||||
max5data(total_expected_transfer, max5[2]), /* total size */
|
max5data(total_expected_transfer, max5[2]), /* total size */
|
||||||
(int)dlpercen, /* rcvd % */
|
dlpercen, /* 3 letters */ /* rcvd % */
|
||||||
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
|
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
|
||||||
(int)ulpercen, /* xfer % */
|
ulpercen, /* 3 letters */ /* xfer % */
|
||||||
max5data(data->progress.uploaded, max5[1]), /* xfer size */
|
max5data(data->progress.uploaded, max5[1]), /* xfer size */
|
||||||
|
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
|
||||||
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
|
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
||||||
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
time_total, /* 8 letters */ /* total time */
|
||||||
time_total, /* total time */
|
time_spent, /* 8 letters */ /* time spent */
|
||||||
time_current, /* current time */
|
time_left, /* 8 letters */ /* time left */
|
||||||
time_left, /* time left */
|
|
||||||
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -417,7 +417,6 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
|
|
||||||
if(-1 == nread) {
|
if(-1 == nread) {
|
||||||
int err = Curl_ourerrno();
|
int err = Curl_ourerrno();
|
||||||
conn->sockerror = err;
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(WSAEWOULDBLOCK == err)
|
if(WSAEWOULDBLOCK == err)
|
||||||
#else
|
#else
|
||||||
@@ -425,8 +424,6 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
conn->sockerror = 0; /* no error */
|
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
}
|
}
|
||||||
|
24
lib/setup.h
24
lib/setup.h
@@ -46,10 +46,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VMS
|
|
||||||
/* hand-modified VMS config.h! */
|
|
||||||
#include "config-vms.h"
|
|
||||||
#endif
|
|
||||||
#ifdef NETWARE
|
#ifdef NETWARE
|
||||||
/* hand-modified NetWare config.h! */
|
/* hand-modified NetWare config.h! */
|
||||||
#include "config-netware.h"
|
#include "config-netware.h"
|
||||||
@@ -134,15 +130,10 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||||
#ifdef VMS
|
|
||||||
#include "../include/curl/stdcheaders.h"
|
|
||||||
#else
|
|
||||||
#include <curl/stdcheaders.h>
|
#include <curl/stdcheaders.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
|
#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
|
||||||
#define NDEBUG
|
|
||||||
#define curlassert(x) assert(x)
|
#define curlassert(x) assert(x)
|
||||||
#else
|
#else
|
||||||
/* does nothing without CURLDEBUG defined */
|
/* does nothing without CURLDEBUG defined */
|
||||||
@@ -174,6 +165,17 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
|||||||
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
|
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(ENABLE_IPV6) || defined(CURLDEBUG)) && defined(_MSC_VER) && \
|
||||||
|
(!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500)
|
||||||
|
/*
|
||||||
|
* Needed to pull in the real getaddrinfo() and not the inline version
|
||||||
|
* in <wspiAPI.H> which doesn't support IPv6 (IPv4 only). <wspiAPI.H> is
|
||||||
|
* included from <ws2tcpip.h> for <= 0x0500 SDKs.
|
||||||
|
*/
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <winsock2.h> /* required by telnet.c */
|
#include <winsock2.h> /* required by telnet.c */
|
||||||
|
|
||||||
#if defined(ENABLE_IPV6) || defined(USE_SSLEAY)
|
#if defined(ENABLE_IPV6) || defined(USE_SSLEAY)
|
||||||
@@ -276,10 +278,6 @@ typedef struct hostent Curl_addrinfo;
|
|||||||
typedef struct in_addr Curl_ipconnect;
|
typedef struct in_addr Curl_ipconnect;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VMS
|
|
||||||
#define IOCTL_3_ARGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef mpeix
|
#ifdef mpeix
|
||||||
#define IOCTL_3_ARGS
|
#define IOCTL_3_ARGS
|
||||||
#endif
|
#endif
|
||||||
|
@@ -73,7 +73,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
|||||||
{
|
{
|
||||||
case CURL_LOCK_DATA_DNS:
|
case CURL_LOCK_DATA_DNS:
|
||||||
if (!share->hostcache) {
|
if (!share->hostcache) {
|
||||||
share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
share->hostcache = Curl_mk_dnscache();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
27
lib/ssluse.c
27
lib/ssluse.c
@@ -94,7 +94,7 @@ static int passwd_callback(char *buf, int num, int verify
|
|||||||
else {
|
else {
|
||||||
if(num > (int)strlen((char *)global_passwd)) {
|
if(num > (int)strlen((char *)global_passwd)) {
|
||||||
strcpy(buf, global_passwd);
|
strcpy(buf, global_passwd);
|
||||||
return strlen(buf);
|
return (int)strlen(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -185,7 +185,7 @@ int random_the_seed(struct SessionHandle *data)
|
|||||||
if(!area)
|
if(!area)
|
||||||
return 3; /* out of memory */
|
return 3; /* out of memory */
|
||||||
|
|
||||||
len = strlen(area);
|
len = (int)strlen(area);
|
||||||
RAND_add(area, len, (len >> 1));
|
RAND_add(area, len, (len >> 1));
|
||||||
|
|
||||||
free(area); /* now remove the random junk */
|
free(area); /* now remove the random junk */
|
||||||
@@ -544,7 +544,7 @@ static int Get_SSL_Session(struct connectdata *conn,
|
|||||||
if(!check->sessionid)
|
if(!check->sessionid)
|
||||||
/* not session ID means blank entry */
|
/* not session ID means blank entry */
|
||||||
continue;
|
continue;
|
||||||
if(curl_strequal(conn->name, check->name) &&
|
if(curl_strequal(conn->hostname, check->name) &&
|
||||||
(conn->remote_port == check->remote_port) &&
|
(conn->remote_port == check->remote_port) &&
|
||||||
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
|
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
|
||||||
/* yes, we have a session ID! */
|
/* yes, we have a session ID! */
|
||||||
@@ -662,7 +662,7 @@ static int Store_SSL_Session(struct connectdata *conn,
|
|||||||
/* now init the session struct wisely */
|
/* now init the session struct wisely */
|
||||||
store->sessionid = ssl_sessionid;
|
store->sessionid = ssl_sessionid;
|
||||||
store->age = data->state.sessionage; /* set current age */
|
store->age = data->state.sessionage; /* set current age */
|
||||||
store->name = strdup(conn->name); /* clone host name */
|
store->name = strdup(conn->hostname); /* clone host name */
|
||||||
store->remote_port = conn->remote_port; /* port number */
|
store->remote_port = conn->remote_port; /* port number */
|
||||||
|
|
||||||
Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config);
|
Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config);
|
||||||
@@ -818,10 +818,10 @@ static CURLcode verifyhost(struct connectdata *conn,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(GEN_DNS == target) {
|
if(GEN_DNS == target) {
|
||||||
hostlen = strlen(conn->hostname);
|
hostlen = (int)strlen(conn->hostname);
|
||||||
domain = strchr(conn->hostname, '.');
|
domain = strchr(conn->hostname, '.');
|
||||||
if(domain)
|
if(domain)
|
||||||
domainlen = strlen(domain);
|
domainlen = (int)strlen(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get amount of alternatives, RFC2459 claims there MUST be at least
|
/* get amount of alternatives, RFC2459 claims there MUST be at least
|
||||||
@@ -1070,7 +1070,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
and then how much time that has elapsed to know how much time we
|
and then how much time that has elapsed to know how much time we
|
||||||
allow for the connect call */
|
allow for the connect call */
|
||||||
if(data->set.timeout || data->set.connecttimeout) {
|
if(data->set.timeout || data->set.connecttimeout) {
|
||||||
double has_passed;
|
long has_passed;
|
||||||
|
|
||||||
/* Evaluate in milliseconds how much time that has passed */
|
/* Evaluate in milliseconds how much time that has passed */
|
||||||
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
|
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
|
||||||
@@ -1087,7 +1087,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
timeout_ms = data->set.connecttimeout*1000;
|
timeout_ms = data->set.connecttimeout*1000;
|
||||||
|
|
||||||
/* subtract the passed time */
|
/* subtract the passed time */
|
||||||
timeout_ms -= (long)has_passed;
|
timeout_ms -= has_passed;
|
||||||
|
|
||||||
if(timeout_ms < 0) {
|
if(timeout_ms < 0) {
|
||||||
/* a precaution, no need to continue if time already is up */
|
/* a precaution, no need to continue if time already is up */
|
||||||
@@ -1117,14 +1117,15 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
FD_SET(sockfd, &writefd);
|
FD_SET(sockfd, &writefd);
|
||||||
else {
|
else {
|
||||||
/* untreated error */
|
/* untreated error */
|
||||||
|
unsigned long errdetail;
|
||||||
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||||
120 bytes long. */
|
120 bytes long. */
|
||||||
|
|
||||||
detail = ERR_get_error(); /* Gets the earliest error code from the
|
errdetail = ERR_get_error(); /* Gets the earliest error code from the
|
||||||
thread's error queue and removes the
|
thread's error queue and removes the
|
||||||
entry. */
|
entry. */
|
||||||
|
|
||||||
switch(detail) {
|
switch(errdetail) {
|
||||||
case 0x1407E086:
|
case 0x1407E086:
|
||||||
/* 1407E086:
|
/* 1407E086:
|
||||||
SSL routines:
|
SSL routines:
|
||||||
@@ -1140,7 +1141,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
return CURLE_SSL_CACERT;
|
return CURLE_SSL_CACERT;
|
||||||
default:
|
default:
|
||||||
/* detail is already set to the SSL error above */
|
/* detail is already set to the SSL error above */
|
||||||
failf(data, "SSL: %s", ERR_error_string(detail, error_buffer));
|
failf(data, "SSL: %s", ERR_error_string(errdetail, error_buffer));
|
||||||
/* OpenSSL 0.9.6 and later has a function named
|
/* OpenSSL 0.9.6 and later has a function named
|
||||||
ERRO_error_string_n() that takes the size of the buffer as a third
|
ERRO_error_string_n() that takes the size of the buffer as a third
|
||||||
argument, and we should possibly switch to using that one in the
|
argument, and we should possibly switch to using that one in the
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user