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
17
README
17
README
@@ -32,25 +32,30 @@ WEB SITE
|
||||
|
||||
Sweden -- http://curl.haxx.se/
|
||||
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.netmirror.org/
|
||||
Russia -- http://curl.tsuren.net/
|
||||
Thailand -- http://curl.siamu.ac.th/
|
||||
US (CA) -- http://curl.mirror.redwire.net/
|
||||
US -- http://curl.signal42.com/
|
||||
|
||||
DOWNLOAD
|
||||
|
||||
The official download mirror sites are:
|
||||
|
||||
Australia -- http://curl.planetmirror.com/download/
|
||||
Estonia -- http://curl.dope-brothers.com/download/
|
||||
Australia -- http://curl.planetmirror.com/download.html
|
||||
Estonia -- http://curl.wildyou.net/download.html
|
||||
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/
|
||||
Russia -- http://curl.tsuren.net/download/
|
||||
Russia -- http://curl.tsuren.net/download.html
|
||||
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||
Sweden -- http://cool.haxx.se/curl/
|
||||
Thailand -- http://curl.siamu.ac.th/download/
|
||||
US (CA) -- http://curl.mirror.redwire.net/download/
|
||||
Thailand -- http://curl.siamu.ac.th/download.html
|
||||
US (CA) -- http://curl.mirror.redwire.net/download.html
|
||||
|
||||
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
|
||||
Releases counted from the very beginning: 106
|
||||
Public curl release number: 80
|
||||
Releases counted from the very beginning: 107
|
||||
Available command line options: 94
|
||||
Available curl_easy_setopt() options: 112
|
||||
Available curl_easy_setopt() options: 113
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o CURLOPT_POSTFIELDSIZE_LARGE added to offer POSTs larger than 2GB
|
||||
o CURL_VERSION_LARGEFILE is a feature bit returned by libcurls that feature
|
||||
large file support
|
||||
o libcurl only requires winsock 1.1 on windows now
|
||||
o when doing FTP, curl now sends QUIT before disconnecting
|
||||
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
|
||||
o removed maximum user+password+hostname size limit
|
||||
o removed maximum dir depth limit for FTP
|
||||
o the ares build now requires c-ares 1.2.0 or later
|
||||
o --tcp-nodelay and CURLOPT_TCP_NODELAY were added
|
||||
o curl/curlver.h contains the libcurl version info now
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o builds and runs on Novell NetWare
|
||||
o Windows builds now report OS as "i386-pc-win32"
|
||||
o received signals during SSL connect is handled better
|
||||
o improved PUT/POST with NTLM/Digest authentication
|
||||
o following redirects and doing NTLM/Digest (where the first connection gets
|
||||
closed) with the multi interface work better now
|
||||
o file: progress meter and getinfo variables work now
|
||||
o CURLOPT_FRESH_CONNECT and CURLAUTH_NTLM now work when set together
|
||||
o share interface usage without (un)lock functions segfaulted
|
||||
o --limit-rate no longer cripples the --speed-limit feature
|
||||
o fixed verbose output problem with ipv6-enabled re-used connections
|
||||
o fixed the socks5 code to check version in the socks response properly
|
||||
o dns cache bug - fixed the 'inuse' counter
|
||||
o large file fix for Content-Length
|
||||
o better docs for the share interface
|
||||
o several configure fixes for mingw/msys
|
||||
o setting a Host: header is no longer affecting the Host: header used when
|
||||
libcurl follows a Location:
|
||||
o fixed numerous compiler warnings on several operating systems and compilers
|
||||
o PUTing from stdin couldn't disable chunked transfer-encoding
|
||||
o corrected the mingw makefiles
|
||||
o improved the configure libz detection
|
||||
o fixed EPRT/PORT use when doing FTP on ipv6-enabled AIX hosts
|
||||
o *nroff commands that only support -mandoc and not -man are now supported
|
||||
(for the built-in manual text in the command line tool)
|
||||
o fixed the unconditional #include of config.h in hugehelp.c
|
||||
o builds fine on MPE/iX
|
||||
o upload using chunked transfer-encoding now sends the last chunk properly
|
||||
teriminated with an extra CRLF
|
||||
o Fixed the progress meter display for files >2GB
|
||||
o persistant connections over a proxy messed up the proxy name/password
|
||||
o the socks5 code segfaulted if no username/password was set
|
||||
o the *_LARGE options now take curl_off_t types as parameters and this will
|
||||
make it possible to handle large files on windows too
|
||||
o builds with large file support even on systems without strtoll()
|
||||
o configure --disable-manual works better
|
||||
o removed a memory leak when doing a windows threaded resolve and it failed
|
||||
o --proxy-ntlm now checks if libcurl supports NTLM before using it
|
||||
o minor --fail with authentication bugfix
|
||||
o CURLOPT_IPRESOLVE set to CURL_IPRESOLVE_V6 will now cause a returned error
|
||||
if the host only can resolve ipv4 addresses
|
||||
o curl -4/-6 now actually sets the requested option in libcurl
|
||||
o multi interface on Windows without ares works again
|
||||
o improved resolution for the CURLINFO_*_TIME info variables
|
||||
o getting only a 100 Continue response and nothing else, when talking HTTP,
|
||||
is now treated as an error by libcurl
|
||||
o fixed minor memory leak in libcurl for Windows when statically linked
|
||||
o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better
|
||||
o --limit-rate with high speed rates is a lot more accurate now, and supports
|
||||
limiting to speeds >2GB/sec on systems with Large File support.
|
||||
o curl_strnqual.3 "refer-to" man page fix
|
||||
o fixed a minor very old progress meter final update bug
|
||||
o added checks for a working NI_WITHSCOPEID before that is used
|
||||
o fixed a flaw that prevented ares name resolve timeouts to occur
|
||||
o getting user name from http_proxy env variable works now
|
||||
o fixed too early name resolve timeouts with ares
|
||||
o HTTP Digest "re-negotiation" works now
|
||||
o CURLOPT_FAILONERROR (-f/--fail) works with all kinds of authentication
|
||||
o better thread-safety thanks to the internal strerror() replacement
|
||||
o better thread-safety on AIX thanks to better function detection
|
||||
o minor ipv6 build fix for windows
|
||||
o the test suite runs fine with mingw-built curl
|
||||
o the postit2.c example works now
|
||||
o better error message when --interface fails on windows
|
||||
o the progress meter now displays very long times better
|
||||
o CURLINFO_CONTENT_LENGTH_DOWNLOAD with CURLOPT_NOBODY set TRUE now works
|
||||
o passwords longer than 14 letters work with NTLM
|
||||
o 'make netware' in the root dir works now
|
||||
o builds fine on VMS again and even nicer than before
|
||||
|
||||
Other curl-related news since the previous public release:
|
||||
|
||||
o Many platforms are being used to autobuild and autotest curl on a daily
|
||||
basis. Please join in and test curl on your systems:
|
||||
http://curl.haxx.se/auto/
|
||||
o the curl mailing lists moved, (re-)subscribe to the new ones from here:
|
||||
http://curl.haxx.se/mail/
|
||||
o c-ares 1.1.0 was relased: http://daniel.haxx.se/projects/c-ares/
|
||||
o TclCurl 0.11.0 was released:
|
||||
http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||
o PycURL 7.11.0 was released: http://pycurl.sourceforge.net/
|
||||
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/
|
||||
o PycURL 7.11.1 was released: http://pycurl.sf.net/
|
||||
o CURLHandle 1.9 was released: http://curlhandle.sourceforge.net/
|
||||
o A curl module for the Q language was announced:
|
||||
http://q-lang.sourceforge.net/
|
||||
o c-ares 1.2.0 was released: http://daniel.haxx.se/projects/c-ares/
|
||||
o New curl web mirrors:
|
||||
Germany http://curl.netmirror.org/
|
||||
USA http://curl.signal42.com/
|
||||
Denmark http://curl.cofman.dk/
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Gisle Vanem, Vincent Bronner, Richard Bramante, Dirk Manske, Dan Fandrich,
|
||||
Ken Hirsch, Stadler Stephan, Domenico Andreoli, Patrick Smith, Tor Arntsen,
|
||||
Andr<64>s Garc<72>a, Tim Baker, Len Krause, Gilad, Ken Rastatter, P R Schaffner,
|
||||
Greg Hewgill, Ben Greear, Jeff Lawson, Grigory Entin, Doug Porter, David
|
||||
Byron, Andy Serpa, Joe Halpin, Christopher R. Palmer, G<>nter Knauf
|
||||
Thomas Schwinge, Marty Kuhrt, G<>nter Knauf, Kevin Roth, Glen Nakamura, Gisle
|
||||
Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz
|
||||
Wark, Andr<64>s Garc<72>a, Robin Kay, Alan Pinstein, David Byron, Nathan
|
||||
O'Sullivan, Erwin Authried
|
||||
|
||||
|
||||
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.
|
||||
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
|
||||
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
|
||||
To get fixed in 7.12.0 (no date)
|
||||
======================
|
||||
|
||||
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 */
|
||||
int socket;
|
||||
int flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
|
||||
],[
|
||||
dnl ioctlsocket test was good
|
||||
nonblock="ioctlsocket"
|
||||
@@ -245,7 +245,8 @@ AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
void main(void) {
|
||||
int main(void)
|
||||
{
|
||||
struct addrinfo hints, *ai;
|
||||
int error;
|
||||
|
||||
@@ -254,11 +255,9 @@ void main(void) {
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||
if (error) {
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
exit(0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
],[
|
||||
ac_cv_working_getaddrinfo="yes"
|
||||
@@ -276,10 +275,72 @@ if test "$ac_cv_working_getaddrinfo" = "yes"; then
|
||||
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],
|
||||
[
|
||||
dnl check for a few thread-safe functions
|
||||
dnl check for localtime_r
|
||||
AC_CHECK_FUNCS(localtime_r,[
|
||||
AC_MSG_CHECKING(whether localtime_r is declared)
|
||||
AC_EGREP_CPP(localtime_r,[
|
||||
@@ -295,6 +356,92 @@ AC_DEFUN([CURL_CHECK_LOCALTIME_R],
|
||||
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],
|
||||
[
|
||||
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
|
||||
- Gisle Vanem improved build on Windows.
|
||||
|
||||
@@ -74,3 +98,5 @@ Version 1.0-pre1 (8 October 2003)
|
||||
- Daniel Stenberg adjusted the 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.plg
|
||||
vc/vc.dsw
|
||||
vc/vc.ncb
|
||||
vc/vc.opt
|
||||
vc/ahost/ahost.dep
|
||||
vc/ahost/ahost.dsp
|
||||
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_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_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}
|
||||
ar cru $@ ${OBJS}
|
||||
@@ -60,31 +68,9 @@ install:
|
||||
chmod u-w ${DESTDIR}${libdir}/$(LIB)
|
||||
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
|
||||
${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir}
|
||||
${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3
|
||||
${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3
|
||||
${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3
|
||||
${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
|
||||
(for man in $(MANPAGES); do \
|
||||
${INSTALL} -m 444 ${srcdir}/$${man} ${DESTDIR}${mandir}/man3; \
|
||||
done)
|
||||
|
||||
clean:
|
||||
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
|
||||
put together and release my own ares archives since the ares maintainer
|
||||
doesn't want these improvements.
|
||||
This package is based on ares 1.1.1 (written by Greg Hudson). I decided to
|
||||
fork and release a separate project since the ares author didn't want the
|
||||
improvements that were vital for our use of it.
|
||||
|
||||
The package is thus dubbed 'c-ares' since I (Daniel Stenberg) want this for
|
||||
use within the curl project (hence the letter C) and it makes a nice
|
||||
pun. Also, c-ares will not remain API compatible with the original ares, so
|
||||
picking a new name makes it more obvious to the public.
|
||||
This package is dubbed 'c-ares' since I (Daniel Stenberg) wanted this for use
|
||||
within the curl project (hence the letter C) and it makes a nice pun. Also,
|
||||
c-ares is not API compatible with ares: a new name makes that more obvious to
|
||||
the public.
|
||||
|
||||
The full source code is available in the 'c-ares' release archives, and in the
|
||||
'ares' subdir of the curl CVS source repostitory.
|
||||
|
||||
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
|
||||
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
|
||||
original ares.
|
||||
|
@@ -55,6 +55,7 @@
|
||||
#define ARES_EFILE 14
|
||||
#define ARES_ENOMEM 15
|
||||
#define ARES_EDESTRUCTION 16
|
||||
#define ARES_EBADSTR 17
|
||||
|
||||
/* Flag values */
|
||||
#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 optmask);
|
||||
void ares_destroy(ares_channel channel);
|
||||
|
||||
void ares_cancel(ares_channel channel);
|
||||
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
||||
ares_callback callback, void *arg);
|
||||
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 ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
|
||||
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,
|
||||
struct hostent **host);
|
||||
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
|
||||
might have been stored in their arguments.
|
||||
.SH SEE ALSO
|
||||
.BR ares_init (3)
|
||||
.BR ares_init (3),
|
||||
.BR ares_cancel (3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
.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
|
||||
function frees a
|
||||
.B struct hostent
|
||||
allocated by one of the functions
|
||||
.I ares_parse_a_reply
|
||||
or
|
||||
.IR ares_parse_ptr_reply .
|
||||
allocated by one of the functions \fIares_parse_a_reply(3)\fP or
|
||||
\fIares_parse_ptr_reply(3)\fP.
|
||||
.SH NOTES
|
||||
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
|
||||
.BR ares_parse_a_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
|
||||
Greg Hudson, MIT Information Systems
|
||||
.br
|
||||
|
@@ -26,11 +26,10 @@ ares_free_string \- Free strings allocated by ares functions
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I ares_free_string
|
||||
function frees a string allocated by the
|
||||
.I ares_mkquery
|
||||
function.
|
||||
function frees a string allocated by an ares function.
|
||||
.SH SEE ALSO
|
||||
.BR ares_mkquery (3)
|
||||
.BR ares_expand_string (3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
.br
|
||||
|
@@ -40,14 +40,10 @@ and
|
||||
.I addrlen
|
||||
give the address as a series of bytes, and
|
||||
.I family
|
||||
gives the type of address. When the query is complete or has failed,
|
||||
the ares library will invoke
|
||||
.IR callback .
|
||||
Completion or failure of the query may happen immediately, or may
|
||||
happen during a later call to
|
||||
.BR ares_process (3)
|
||||
or
|
||||
.BR ares_destroy (3).
|
||||
gives the type of address. When the query is complete or has failed, the ares
|
||||
library will invoke \fIcallback\fP. Completion or failure of the query may
|
||||
happen immediately, or may happen during a later call to
|
||||
\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.
|
||||
.PP
|
||||
The callback argument
|
||||
.I arg
|
||||
@@ -93,7 +89,8 @@ did not complete successfully,
|
||||
will be
|
||||
.BR NULL .
|
||||
.SH SEE ALSO
|
||||
.BR ares_process (3)
|
||||
.BR ares_process (3),
|
||||
.BR ares_gethostbyname (3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
.br
|
||||
|
@@ -87,10 +87,10 @@ static void next_lookup(struct addr_query *aquery)
|
||||
{
|
||||
case 'b':
|
||||
addr = ntohl(aquery->addr.s_addr);
|
||||
a1 = (int)(addr >> 24) & 0xff;
|
||||
a2 = (int)(addr >> 16) & 0xff;
|
||||
a3 = (int)(addr >> 8) & 0xff;
|
||||
a4 = (int)addr & 0xff;
|
||||
a1 = (int)((addr >> 24) & 0xff);
|
||||
a2 = (int)((addr >> 16) & 0xff);
|
||||
a3 = (int)((addr >> 8) & 0xff);
|
||||
a4 = (int)(addr & 0xff);
|
||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
|
||||
aquery->remaining_lookups = p + 1;
|
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||
|
@@ -37,14 +37,11 @@ The parameter
|
||||
.I name
|
||||
gives the hostname as a NUL-terminated C string, and
|
||||
.I family
|
||||
gives the desired type of address for the resulting host entry. When
|
||||
the query is complete or has failed, the ares library will invoke
|
||||
.IR callback .
|
||||
Completion or failure of the query may happen immediately, or may
|
||||
happen during a later call to
|
||||
.BR ares_process (3)
|
||||
or
|
||||
.BR ares_destroy (3).
|
||||
gives the desired type of address for the resulting host entry. When the
|
||||
query is complete or has failed, the ares library will invoke \fIcallback\fP.
|
||||
Completion or failure of the query may happen immediately, or may happen
|
||||
during a later call to \fIares_process(3)\fP, \fIares_destroy(3)\fP or
|
||||
\fIares_cancel(3)\fP.
|
||||
.PP
|
||||
The callback argument
|
||||
.I arg
|
||||
@@ -96,7 +93,8 @@ did not complete successfully,
|
||||
will be
|
||||
.BR NULL .
|
||||
.SH SEE ALSO
|
||||
.BR ares_process (3)
|
||||
.BR ares_process (3),
|
||||
.BR ares_gethostbyaddr (3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
.br
|
||||
|
@@ -21,11 +21,9 @@ ares_mkquery \- Compose a single-question DNS query buffer
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B
|
||||
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
|
||||
.B
|
||||
unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
|
||||
int *\fIbuflen\fP)
|
||||
.B 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 int *\fIbuflen\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
.IR buflen .
|
||||
It is the caller's responsibility to free this buffer using
|
||||
.B ares_free_string
|
||||
when it is no longer needed.
|
||||
\fIares_free_string(3)\fP when it is no longer needed.
|
||||
.SH RETURN VALUES
|
||||
.B ares_mkquery
|
||||
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
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B
|
||||
int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB,
|
||||
.B struct hostent **\fIhost\fB);
|
||||
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||
.B struct hostent **\fIhost\fP);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
|
@@ -21,11 +21,9 @@ ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent
|
||||
.nf
|
||||
.B #include <ares.h>
|
||||
.PP
|
||||
.B
|
||||
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 struct hostent **\fIhost\fB);
|
||||
.B int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||
.B const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
|
||||
.B struct hostent **\fIhost\fP);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
|
@@ -35,13 +35,10 @@ The file descriptor sets pointed to by
|
||||
and
|
||||
.I write_fds
|
||||
should have file descriptors set in them according to whether the file
|
||||
descriptors specified by
|
||||
.BR ares_fds (3)
|
||||
are ready for reading and writing. (The easiest way to determine this
|
||||
information is to invoke
|
||||
descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
|
||||
(The easiest way to determine this information is to invoke
|
||||
.B select
|
||||
with a timeout no greater than the timeout given by
|
||||
.BR ares_timeout (3)).
|
||||
with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ).
|
||||
.PP
|
||||
The
|
||||
.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 unsigned char *\fIabuf\fP, int \fIalen\fP)
|
||||
.PP
|
||||
.B
|
||||
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
||||
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
||||
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
|
@@ -35,7 +35,9 @@ const char *ares_strerror(int code)
|
||||
"Timeout while contacting DNS servers",
|
||||
"End of 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)));
|
||||
|
@@ -27,10 +27,8 @@ ares_fds \- Get file descriptors to select on for name service
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B ares_timeout
|
||||
function determines the maximum time for which the caller should wait
|
||||
before invoking
|
||||
.BR ares_process (3)
|
||||
to process timeouts. The parameter
|
||||
function determines the maximum time for which the caller should wait before
|
||||
invoking \fIares_process(3)\fP to process timeouts. The parameter
|
||||
.I maxtv
|
||||
specifies a existing maximum timeout, or
|
||||
.B NULL
|
||||
|
@@ -4,12 +4,12 @@
|
||||
#define ARES__VERSION_H
|
||||
|
||||
#define ARES_VERSION_MAJOR 1
|
||||
#define ARES_VERSION_MINOR 0
|
||||
#define ARES_VERSION_MINOR 2
|
||||
#define ARES_VERSION_PATCH 0
|
||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||
(ARES_VERSION_MINOR<<8)|\
|
||||
(ARES_VERSION_PATCH))
|
||||
#define ARES_VERSION_STR "1.0.0"
|
||||
#define ARES_VERSION_STR "1.2.0"
|
||||
|
||||
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`;
|
||||
# remove the dir
|
||||
`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
|
||||
#
|
||||
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
|
||||
echo "buildconf: automake not found."
|
||||
echo " You need automake version $need_automake or newer installed."
|
||||
@@ -159,7 +159,7 @@ fi
|
||||
echo "buildconf: running libtoolize"
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
|
||||
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"
|
||||
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
||||
echo "buildconf: running autoheader"
|
||||
@@ -170,7 +170,7 @@ ${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||
if test -d ares; then
|
||||
cd ares
|
||||
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"
|
||||
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
|
||||
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)
|
||||
|
||||
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)
|
||||
AC_MSG_CHECKING([curl version])
|
||||
AC_MSG_RESULT($VERSION)
|
||||
|
||||
dnl
|
||||
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)
|
||||
|
||||
dnl Solaris pkgadd support definitions
|
||||
@@ -384,6 +384,8 @@ main()
|
||||
|
||||
if test "$ipv6" = "yes"; then
|
||||
CURL_CHECK_WORKING_GETADDRINFO
|
||||
|
||||
CURL_CHECK_NI_WITHSCOPEID
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
@@ -693,7 +695,7 @@ AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||
|
||||
if test X"$OPT_SSL" = Xno
|
||||
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
|
||||
|
||||
dnl Check for and handle argument to --with-ssl.
|
||||
@@ -915,6 +917,7 @@ printf("just fine");
|
||||
#endif
|
||||
],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
RECENTAIX=yes
|
||||
OPT_THREAD=off ],
|
||||
[ AC_MSG_RESULT([no]) ]
|
||||
)
|
||||
@@ -952,10 +955,31 @@ else
|
||||
dnl is there a 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
|
||||
|
||||
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 Back to "normal" configuring
|
||||
dnl **********************************************************************
|
||||
@@ -979,6 +1003,7 @@ AC_CHECK_HEADERS(
|
||||
arpa/inet.h \
|
||||
net/if.h \
|
||||
netinet/in.h \
|
||||
netinet/tcp.h \
|
||||
netdb.h \
|
||||
sys/sockio.h \
|
||||
sys/stat.h \
|
||||
@@ -1015,6 +1040,9 @@ dnl default includes
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#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.
|
||||
if test "x$enableval" = "xyes" ; then
|
||||
if test -d "$srcdir/ares"; then
|
||||
aresembedded="yes"
|
||||
AC_CONFIG_SUBDIRS(ares)
|
||||
aresinc=`cd $srcdir/ares && pwd`
|
||||
CPPFLAGS="$CPPFLAGS -I$aresinc"
|
||||
@@ -1240,6 +1269,31 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
|
||||
CPPFLAGS="$CPPFLAGS -I$enableval/include"
|
||||
LDFLAGS="$LDFLAGS -L$enableval/lib"
|
||||
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 ],
|
||||
AC_MSG_RESULT(no)
|
||||
|
@@ -2,17 +2,8 @@
|
||||
;;;; $Id$
|
||||
|
||||
;;; The curl hacker's C conventions.
|
||||
|
||||
;;; After loading this file and added the mode-hook you can in C
|
||||
;;; files, put something like this to use the curl style
|
||||
;;; automatically:
|
||||
;;
|
||||
;; /* -----------------------------------------------------------------
|
||||
;; * local variables:
|
||||
;; * eval: (set c-file-style "curl")
|
||||
;; * end:
|
||||
;; */
|
||||
;;
|
||||
;;; See the sample.emacs file on how this file can be made to take
|
||||
;;; effect automatically when editing curl source files.
|
||||
|
||||
(defconst curl-c-style
|
||||
'((c-basic-offset . 2)
|
||||
@@ -37,7 +28,7 @@
|
||||
(setq tab-width 8
|
||||
indent-tabs-mode nil ; Use spaces. Not tabs.
|
||||
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
|
||||
;; 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
|
||||
may have been fixed since this was written!
|
||||
|
||||
* NTLM authentication with passwords longer than 14 letters fail. There is
|
||||
a known fix for this, planned to come in curl 7.11.2
|
||||
* --limit-rate using -d or -F does not work. This is because the limit logic
|
||||
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
|
||||
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
|
||||
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
|
||||
it seems HTTP servers send the *uncompressed* length in that header and
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
FTPS
|
||||
|
||||
It is just like for FTP, but you may also want to specify and use
|
||||
SSL-specific options for certificates etc.
|
||||
|
||||
HTTP
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
style when using Curl via a proxy. You _must_ use the -u style fetch
|
||||
during such circumstances.
|
||||
|
@@ -28,6 +28,12 @@ server, do one of the following:
|
||||
|
||||
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
|
||||
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")
|
||||
@@ -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
|
||||
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
|
||||
|
||||
* 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
|
||||
allegedly from ncftp:
|
||||
http://curl.haxx.se/mail/archive-2003-04/0126.html
|
||||
@@ -91,6 +98,15 @@ TODO
|
||||
|
||||
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
|
||||
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
|
||||
|
@@ -2,7 +2,7 @@
|
||||
.\" nroff -man curl.1
|
||||
.\" 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
|
||||
curl \- transfer a URL
|
||||
.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.
|
||||
|
||||
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>"
|
||||
Pass options to the telnet protocol. Supported options are:
|
||||
|
||||
|
@@ -70,6 +70,8 @@ int main(int argc, char **argv)
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
still_running = 0;
|
||||
printf("select() returns error, this is badness\n");
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
|
@@ -33,8 +33,8 @@ int main(int argc, char *argv[])
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct HttpPost *formpost=NULL;
|
||||
struct HttpPost *lastptr=NULL;
|
||||
struct curl_httppost *formpost=NULL;
|
||||
struct curl_httppost *lastptr=NULL;
|
||||
struct curl_slist *headerlist=NULL;
|
||||
char buf[] = "Expect:";
|
||||
|
||||
|
@@ -31,5 +31,4 @@ If this function returns NULL, something went wrong and no valid handle was
|
||||
returned.
|
||||
.SH "SEE ALSO"
|
||||
.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,
|
||||
all results from this function are undefined until the transfer is completed.
|
||||
.SH AVAILABLE INFORMATION
|
||||
These are informations that can be extracted:
|
||||
The following information can be extracted:
|
||||
.IP CURLINFO_EFFECTIVE_URL
|
||||
Pass a pointer to a 'char *' to receive the last used effective URL.
|
||||
.IP CURLINFO_RESPONSE_CODE
|
||||
@@ -51,7 +51,7 @@ pre-transfer commands and negotiations that are specific to the particular
|
||||
protocol(s) involved.
|
||||
.IP CURLINFO_STARTTRANSFER_TIME
|
||||
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
|
||||
the result.
|
||||
.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)
|
||||
.IP CURLINFO_PROXYAUTH_AVAIL
|
||||
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
|
||||
If the operation was successful, CURLE_OK is returned. Otherwise an
|
||||
appropriate error code will be returned.
|
||||
|
@@ -13,7 +13,7 @@ curl_easy_init - Start a libcurl easy session
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
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.
|
||||
|
||||
.SH RETURN VALUE
|
||||
@@ -21,5 +21,3 @@ If this function returns NULL, something went wrong and you cannot use the
|
||||
other curl functions.
|
||||
.SH "SEE ALSO"
|
||||
.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
|
||||
Function pointer that should match the following prototype: \fBsize_t
|
||||
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
|
||||
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
|
||||
@@ -165,7 +165,7 @@ Function pointer that should match the following prototype: \fIint
|
||||
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
|
||||
\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
|
||||
\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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
\fICURLOPT_PROXYPORT\fP.
|
||||
|
||||
\fBNOTE:\fP when you tell the library to use a HTTP proxy, libcurl will
|
||||
transparently convert operations to HTTP even if you specify a FTP URL
|
||||
\fBNOTE:\fP when you tell the library to use an HTTP proxy, libcurl will
|
||||
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
|
||||
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
|
||||
@@ -282,19 +282,35 @@ libcurl caches this info for 60 seconds.
|
||||
.IP CURLOPT_DNS_USE_GLOBAL_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
|
||||
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
|
||||
to using the share interface instead! See \fICURLOPT_SHARE\fP and
|
||||
\fIcurl_share_init(3)\fP.
|
||||
.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
|
||||
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)
|
||||
.IP CURLOPT_PORT
|
||||
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.
|
||||
.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)
|
||||
.IP CURLOPT_NETRC
|
||||
This parameter controls the preference of libcurl between using user names and
|
||||
@@ -370,7 +386,7 @@ regular old-fashioned Basic method.
|
||||
.IP CURLAUTH_GSSNEGOTIATE
|
||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
||||
"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
|
||||
information see IETF draft draft-brezak-spnego-http-04.txt.
|
||||
|
||||
@@ -379,17 +395,17 @@ this to work.
|
||||
.IP CURLAUTH_NTLM
|
||||
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||
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
|
||||
work.
|
||||
.IP CURLAUTH_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.
|
||||
.IP CURLAUTH_ANYSAFE
|
||||
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.
|
||||
.RE
|
||||
.IP CURLOPT_PROXYAUTH
|
||||
@@ -405,7 +421,7 @@ this writing, only Basic and NTLM work. (Added in 7.10.7)
|
||||
.SH HTTP OPTIONS
|
||||
.IP CURLOPT_AUTOREFERER
|
||||
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.
|
||||
.IP CURLOPT_ENCODING
|
||||
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.
|
||||
.IP CURLOPT_FOLLOWLOCATION
|
||||
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
|
||||
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
|
||||
size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option.
|
||||
.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
|
||||
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.
|
||||
@@ -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
|
||||
should contain.
|
||||
|
||||
If you need to set mulitple 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
|
||||
cookies in one string like this: "name1=content1; name2=content2;" etc.
|
||||
If you need to set multiple cookies, you need to set them all using a single
|
||||
option and thus you need to concatenate them all in one single string. Set
|
||||
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
|
||||
previously ones.
|
||||
@@ -622,7 +639,7 @@ only files in their response to NLST; they might not include subdirectories
|
||||
and symbolic links.
|
||||
.IP CURLOPT_FTPAPPEND
|
||||
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
|
||||
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
|
||||
@@ -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)
|
||||
.IP CURLOPT_CUSTOMREQUEST
|
||||
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
|
||||
more or less obscure HTTP requests. Don't do this at will, make sure your
|
||||
server supports the command first.
|
||||
@@ -863,7 +880,7 @@ key.
|
||||
\fBNOTE:\fPIf the crypto device cannot be loaded,
|
||||
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
|
||||
.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.
|
||||
|
||||
\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)
|
||||
.IP CURLOPT_SSL_CIPHER_LIST
|
||||
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
|
||||
consists of one or more cipher strings separated by colons. Commas or spaces
|
||||
ciphers to use for the SSL connection. The list must be syntactically correct,
|
||||
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
|
||||
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
|
||||
|
@@ -13,7 +13,7 @@ curl_formadd - add a section to a multipart/formdata HTTP POST
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
|
||||
\fIlastitem\fP is set after each call and on repeated invokes it should be
|
||||
@@ -81,7 +81,7 @@ internally chosen one.
|
||||
|
||||
.B CURLFORM_FILENAME
|
||||
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.
|
||||
|
||||
.B BCURLFORM_BUFFER
|
||||
|
@@ -36,7 +36,7 @@ This string specifies the time on a given day. Syntax supported includes:
|
||||
.TP
|
||||
.B time zone items
|
||||
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.
|
||||
.TP
|
||||
.B day of the week items
|
||||
|
@@ -42,7 +42,7 @@ See this table for notable exceptions.
|
||||
Normal printf() clone.
|
||||
.TP
|
||||
.B curl_mfprintf()
|
||||
Normal fprinf() clone.
|
||||
Normal fprintf() clone.
|
||||
.TP
|
||||
.B curl_msprintf()
|
||||
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
|
||||
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
|
||||
CURLMcode type, general libcurl multi interface error code.
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -11,7 +11,16 @@ curl_multi_cleanup - close down a multi session
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
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
|
||||
CURLMcode type, general libcurl multi interface error code.
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -1,9 +1,10 @@
|
||||
.\" $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
|
||||
curl_multi_fdset - extracts file descriptor information from a multi handle
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
@@ -14,15 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
poll() on. The curl_multi_perform() function should be called as soon as one
|
||||
libcurl returns its fd_set sets. The application can use these to select()
|
||||
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.
|
||||
|
||||
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()
|
||||
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
|
||||
CURLMcode type, general libcurl multi interface error code. See
|
||||
\fIlibcurl-errors.3\fP
|
||||
\fIlibcurl-errors(3)\fP
|
||||
.SH "SEE ALSO"
|
||||
.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
|
||||
\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
|
||||
present in that struct and can thus be used in subsequent regular
|
||||
\fIcurl_easy_getinfo(3)\fP calls (or similar):
|
||||
|
@@ -10,7 +10,7 @@ curl_multi_init - create a multi handle
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
\fIcurl_multi_cleanup(3)\fP when the operation is complete.
|
||||
.SH RETURN VALUE
|
||||
|
@@ -19,14 +19,14 @@ integer-pointer.
|
||||
.SH "RETURN VALUE"
|
||||
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
|
||||
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
|
||||
to send off before it is "satisfied".
|
||||
|
||||
NOTE that this only returns errors etc regarding the whole multi stack. There
|
||||
might still have occurred problems on invidual transfers even when this
|
||||
might still have occurred problems on individual transfers even when this
|
||||
function returns OK.
|
||||
.SH "TYPICAL USAGE"
|
||||
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
|
||||
.SH DESCRIPTION
|
||||
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
|
||||
\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
|
||||
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
|
||||
the same easy handle.
|
||||
|
||||
|
@@ -36,7 +36,7 @@ Couldn't resolve host. The given remote host was not resolved.
|
||||
.IP "CURLE_COULDNT_CONNECT (7)"
|
||||
Failed to connect() to host or proxy.
|
||||
.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
|
||||
server is probably not an OK FTP server.
|
||||
.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.
|
||||
.IP "CURLE_OUT_OF_MEMORY (27)"
|
||||
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)"
|
||||
Operation timeout. The specified time-out period was reached according to the
|
||||
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
|
||||
sane.
|
||||
.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.
|
||||
.IP "CURLE_HTTP_RANGE_ERROR (33)"
|
||||
The HTTP server does not support or accept range requests.
|
||||
.IP "CURLE_HTTP_POST_ERROR (34)"
|
||||
This is an odd error that mainly occurs due to internal confusion.
|
||||
.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
|
||||
more. Could be certificates (file formats, paths, permissions), passwords, and
|
||||
others.
|
||||
@@ -187,8 +187,19 @@ Requested FTP SSL level failed
|
||||
.SH "CURLMcode"
|
||||
This is the generic return code used by functions in the libcurl multi
|
||||
interface.
|
||||
|
||||
This is left to be documented.
|
||||
.IP "CURLM_CALL_MULTI_PERFORM (-1)"
|
||||
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"
|
||||
The "share" interface will return a CURLSHcode to indicate when an
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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.
|
||||
|
||||
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
|
||||
option of using the "easy" interface, or the "multi" interface.
|
||||
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
|
||||
the option of using the "easy" interface, or the "multi" interface.
|
||||
|
||||
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
|
||||
@@ -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 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
|
||||
similar. The multi interface allows you to select() on libcurl action, and
|
||||
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
|
||||
.TP
|
||||
.B curl_formadd()
|
||||
helps building a HTTP form POST
|
||||
helps building an HTTP form POST
|
||||
.TP
|
||||
.B curl_formfree()
|
||||
free a list built with \fIcurl_formadd(3)\fP
|
||||
|
@@ -1,8 +1,5 @@
|
||||
pkginclude_HEADERS = \
|
||||
curl.h \
|
||||
easy.h \
|
||||
mprintf.h \
|
||||
stdcheaders.h \
|
||||
types.h \
|
||||
multi.h
|
||||
curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h
|
||||
pkgincludedir= $(includedir)/curl
|
||||
|
||||
CLEANFILES = *dist
|
||||
|
@@ -27,31 +27,7 @@
|
||||
http://curl.haxx.se/libcurl/
|
||||
*/
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
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 "curlver.h" /* the libcurl version defines */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
@@ -786,6 +762,9 @@ typedef enum {
|
||||
/* The _LARGE version of the standard POSTFIELDSIZE option */
|
||||
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
|
||||
|
||||
/* Enable/disable the TCP Nagle algorithm */
|
||||
CINIT(TCP_NODELAY, LONG, 121),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -804,12 +783,12 @@ typedef enum {
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
#define CURLOPT_HTTPREQUEST 0
|
||||
#define CURLOPT_HTTPREQUEST -1
|
||||
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
|
||||
#define CURLOPT_MUTE 0
|
||||
#define CURLOPT_PASSWDFUNCTION 0
|
||||
#define CURLOPT_PASSWDDATA 0
|
||||
#define CURLOPT_CLOSEFUNCTION 0
|
||||
#define CURLOPT_MUTE -2
|
||||
#define CURLOPT_PASSWDFUNCTION -3
|
||||
#define CURLOPT_PASSWDDATA -4
|
||||
#define CURLOPT_CLOSEFUNCTION -5
|
||||
|
||||
#else
|
||||
/* 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);
|
||||
|
||||
|
||||
#define CURLINFO_STRING 0x100000
|
||||
#define CURLINFO_LONG 0x200000
|
||||
#define CURLINFO_DOUBLE 0x300000
|
||||
@@ -1266,6 +1244,28 @@ typedef struct {
|
||||
*/
|
||||
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
|
||||
}
|
||||
#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,
|
||||
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
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
@@ -1,15 +1,32 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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$
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
|
||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
|
||||
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
|
||||
config.h.in ca-bundle.crt README.encoding README.memoryleak \
|
||||
README.ares makefile.dj config.dj \
|
||||
libcurl.framework.make libcurl.plist libcurl.rc \
|
||||
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp curllib.dsw \
|
||||
config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
|
||||
ca-bundle.crt README.encoding README.memoryleak README.ares README.curlx \
|
||||
makefile.dj config.dj libcurl.framework.make libcurl.plist libcurl.rc \
|
||||
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
|
||||
Makefile.netware nwlib.c libcurl.imp
|
||||
|
||||
@@ -38,16 +55,16 @@ VERSION=-version-info 2:2:0
|
||||
# that the current interface number gets larger faster.
|
||||
#
|
||||
# 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
|
||||
# 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
|
||||
# increment age.
|
||||
# increment age. (c:r:a+1)
|
||||
#
|
||||
# 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
|
||||
@@ -63,20 +80,20 @@ endif
|
||||
|
||||
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
|
||||
|
||||
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c \
|
||||
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c \
|
||||
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
|
||||
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \
|
||||
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
|
||||
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
|
||||
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.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 \
|
||||
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c escape.h \
|
||||
netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
|
||||
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.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 \
|
||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
|
||||
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
|
||||
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.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 \
|
||||
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 \
|
||||
strtoofft.c strtoofft.h
|
||||
strtoofft.c strtoofft.h strerror.c strerror.h
|
||||
|
||||
noinst_HEADERS = setup.h transfer.h
|
||||
|
||||
|
@@ -12,7 +12,7 @@ AR = ar
|
||||
RM = rm -f
|
||||
RANLIB = ranlib
|
||||
STRIP = strip -g
|
||||
OPENSSL_PATH = ../../openssl-0.9.7c
|
||||
OPENSSL_PATH = ../../openssl-0.9.7d
|
||||
ZLIB_PATH = ../../zlib-1.2.1
|
||||
|
||||
########################################################
|
||||
|
@@ -19,6 +19,7 @@
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
# $Id: Makefile.vc6,v 1.17 2004/01/13 08:57:01 bagder Exp $
|
||||
##############################################################
|
||||
# CHANGE LOG
|
||||
# ------------------------------------------------------------
|
||||
@@ -37,12 +38,17 @@ LIB_NAME_DEBUG = libcurld
|
||||
OPENSSL_PATH = ../../openssl-0.9.7a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.1.4
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
|
||||
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
|
||||
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"
|
||||
|
||||
LNKDLL = link.exe /DLL /def:libcurl.def
|
||||
@@ -100,6 +106,19 @@ CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!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
|
||||
!IF "$(CFG)" == "release-libcurl-ssl-dll"
|
||||
@@ -169,6 +188,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-dll - release dll
|
||||
!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-libcurl-ssl-dll - static libcurl with shared ssl
|
||||
!MESSAGE debug - debug static library
|
||||
@@ -222,6 +242,8 @@ X_OBJS= \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
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:
|
||||
ftp://athena-dist.mit.edu/pub/ATHENA/ares/ares-1.1.1.tar.gz
|
||||
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
|
||||
c-ares:
|
||||
http://daniel.haxx.se/projects/c-ares/
|
||||
|
||||
NOTE
|
||||
libcurl works with ares 1.1.1, but several patches and improvements have
|
||||
been put into the c-ares package which has made it more portable and better
|
||||
working on several platforms.
|
||||
libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
|
||||
1.2.0 or alter.
|
||||
|
||||
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
|
||||
2. cd ares-dir
|
||||
Build c-ares
|
||||
============
|
||||
|
||||
1. unpack the c-ares archive
|
||||
2. cd c-ares-dir
|
||||
3. ./configure
|
||||
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
|
||||
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
|
||||
2. make
|
||||
|
||||
Ares and ipv6
|
||||
=============
|
||||
c-ares and ipv6
|
||||
===============
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
prevent linking errors later on). Then I simply build the areslib project (the
|
||||
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_IOCTLSOCKET 1
|
||||
#define HAVE_INET_PTON 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_MALLOC_H 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
#define HAVE_NET_IF_H 1
|
||||
#define HAVE_PERROR 1
|
||||
#define HAVE_SELECT 1
|
||||
@@ -38,12 +40,14 @@
|
||||
#define HAVE_SIGACTION 1
|
||||
#define HAVE_SIGSETJMP 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_SPNEGO 1
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRFTIME 1
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRSTR 1
|
||||
#define HAVE_STRTOLL 1
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
@@ -53,9 +57,13 @@
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
#if (DJGPP_MINOR >= 4)
|
||||
#define HAVE_STRLCAT 1
|
||||
#endif
|
||||
|
||||
#define RETSIGTYPE void
|
||||
#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 TIME_WITH_SYS_TIME 1
|
||||
|
||||
|
@@ -32,7 +32,15 @@
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#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>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -86,6 +94,7 @@
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
@@ -138,7 +147,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET
|
||||
/* Windows? */
|
||||
int flags;
|
||||
unsigned long flags;
|
||||
flags = nonblock;
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
#define SETBLOCK 3
|
||||
@@ -295,10 +304,10 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
data->set.device, strlen(data->set.device)+1) != 0) {
|
||||
/* 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",
|
||||
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 */
|
||||
}
|
||||
}
|
||||
@@ -353,37 +362,9 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
if(!bindworked) {
|
||||
switch(errno) {
|
||||
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) */
|
||||
|
||||
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
|
||||
return CURLE_HTTP_PORT_FAILED;
|
||||
} /* end of else */
|
||||
}
|
||||
|
||||
} /* end of if h */
|
||||
else {
|
||||
@@ -488,8 +469,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
}
|
||||
else if(1 != rc) {
|
||||
int error = Curl_ourerrno();
|
||||
failf(data, "Failed connect to %s:%d, errno: %d",
|
||||
conn->hostname, conn->port, error);
|
||||
failf(data, "Failed connect to %s:%d; %s",
|
||||
conn->hostname, conn->port, Curl_strerror(conn,error));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
/*
|
||||
@@ -503,6 +484,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
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.
|
||||
@@ -581,6 +579,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (sockfd == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
|
||||
else if(data->set.tcp_nodelay)
|
||||
Curl_setNoDelay(conn, sockfd);
|
||||
#else
|
||||
/*
|
||||
* 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 */
|
||||
}
|
||||
|
||||
else if(data->set.tcp_nodelay)
|
||||
Curl_setNoDelay(conn, sockfd);
|
||||
|
||||
/* nasty address work before connect can be made */
|
||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||
memcpy((char *)&(serv_addr.sin_addr),
|
||||
@@ -651,8 +655,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
break;
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
failf(data, "Failed to connect to %s IP number %d: %d",
|
||||
hostname, aliasindex+1, error);
|
||||
failf(data, "Failed to connect to %s IP number %d: %s",
|
||||
hostname, aliasindex+1, Curl_strerror(conn,error));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -692,7 +696,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
if (sockfd == CURL_SOCKET_BAD) {
|
||||
/* no good connect was made */
|
||||
*sockconn = -1;
|
||||
failf(data, "Connect failed");
|
||||
failf(data, "Connect failed; %s", Curl_strerror(conn,Curl_ourerrno()));
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# 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 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
|
||||
# ADD BASE 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 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 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
|
||||
# ADD BASE 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) {
|
||||
data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
||||
data->hostcache = Curl_mk_dnscache();
|
||||
|
||||
if(!data->hostcache)
|
||||
/* 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
|
||||
information. Which for FILE can't be much more than the file size and
|
||||
date. */
|
||||
if(data->set.no_body && data->set.include_header && fstated) {
|
||||
if(conn->bits.no_body && data->set.include_header && fstated) {
|
||||
CURLcode result;
|
||||
sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
|
||||
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
|
||||
|
107
lib/formdata.c
107
lib/formdata.c
@@ -176,7 +176,7 @@ int FormParse(char *input,
|
||||
struct curl_httppost **httppost,
|
||||
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 */
|
||||
char name[256];
|
||||
char *contents;
|
||||
@@ -975,6 +975,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_formadd() is a public API to add a section to the multipart formpost.
|
||||
*/
|
||||
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...)
|
||||
@@ -987,6 +991,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* AddFormData() adds a chunk of data to the FormData linked list.
|
||||
*/
|
||||
static size_t AddFormData(struct FormData **formp,
|
||||
const void *line,
|
||||
size_t length)
|
||||
@@ -1014,6 +1021,9 @@ static size_t AddFormData(struct FormData **formp,
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* AddFormDataf() adds printf()-style formatted data to the formdata chain.
|
||||
*/
|
||||
|
||||
static size_t AddFormDataf(struct FormData **formp,
|
||||
const char *fmt, ...)
|
||||
@@ -1027,7 +1037,10 @@ static size_t AddFormDataf(struct FormData **formp,
|
||||
return AddFormData(formp, s, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_FormBoundary() creates a suitable boundary string and returns an
|
||||
* allocated one.
|
||||
*/
|
||||
char *Curl_FormBoundary(void)
|
||||
{
|
||||
char *retstring;
|
||||
@@ -1056,7 +1069,10 @@ char *Curl_FormBoundary(void)
|
||||
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)
|
||||
{
|
||||
struct FormData *next;
|
||||
@@ -1069,7 +1085,10 @@ void Curl_formclean(struct FormData *form)
|
||||
} 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)
|
||||
{
|
||||
struct curl_httppost *next;
|
||||
@@ -1098,6 +1117,13 @@ void curl_formfree(struct curl_httppost *form)
|
||||
} 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,
|
||||
struct curl_httppost *post,
|
||||
curl_off_t *sizep)
|
||||
@@ -1218,11 +1244,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
char buffer[1024];
|
||||
size_t nread;
|
||||
|
||||
fileread = strequal("-", file->contents)?stdin:
|
||||
/* binary read for win32 crap */
|
||||
/*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?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */
|
||||
fileread = strequal("-", file->contents)?
|
||||
stdin:fopen(file->contents, "rb"); /* binary read for win32 */
|
||||
/*
|
||||
* VMS: This only allows for stream files on VMS. Stream files are
|
||||
* 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) {
|
||||
while((nread = fread(buffer, 1, 1024, fileread)))
|
||||
size += AddFormData(&form, buffer, nread);
|
||||
@@ -1231,10 +1260,6 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
fclose(fileread);
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
/* File wasn't found, add a nothing field! */
|
||||
size += AddFormData(&form, "", 0);
|
||||
#endif
|
||||
Curl_formclean(firstform);
|
||||
free(boundary);
|
||||
*finalform = NULL;
|
||||
@@ -1278,6 +1303,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
|
||||
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 )
|
||||
{
|
||||
if(!formdata)
|
||||
@@ -1289,7 +1318,10 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
|
||||
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 size,
|
||||
size_t nitems,
|
||||
@@ -1335,48 +1367,25 @@ size_t Curl_FormReader(char *buffer,
|
||||
return gotsize;
|
||||
}
|
||||
|
||||
/* possible (old) fread() emulation that copies at most one line */
|
||||
size_t Curl_FormReadOneLine(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *mydata)
|
||||
/*
|
||||
* Curl_formpostheader() returns the first line of the formpost, the
|
||||
* request-header part (which is not part of the request-body like the rest of
|
||||
* the post).
|
||||
*/
|
||||
char *Curl_formpostheader(void *formp, size_t *len)
|
||||
{
|
||||
struct Form *form;
|
||||
size_t wantedsize;
|
||||
size_t gotsize;
|
||||
|
||||
form=(struct Form *)mydata;
|
||||
|
||||
wantedsize = size * nitems;
|
||||
char *header;
|
||||
struct Form *form=(struct Form *)formp;
|
||||
|
||||
if(!form->data)
|
||||
return 0; /* nothing, error, empty */
|
||||
return 0; /* nothing, ERROR! */
|
||||
|
||||
do {
|
||||
|
||||
if( (form->data->length - form->sent ) > wantedsize ) {
|
||||
|
||||
memcpy(buffer, form->data->line + form->sent, wantedsize);
|
||||
|
||||
form->sent += wantedsize;
|
||||
|
||||
return wantedsize;
|
||||
}
|
||||
|
||||
memcpy(buffer,
|
||||
form->data->line + form->sent,
|
||||
gotsize = (form->data->length - form->sent) );
|
||||
|
||||
form->sent = 0;
|
||||
header = form->data->line;
|
||||
*len = form->data->length;
|
||||
|
||||
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;
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -65,11 +65,12 @@ size_t Curl_FormReader(char *buffer,
|
||||
size_t nitems,
|
||||
FILE *mydata);
|
||||
|
||||
/* possible (old) fread() emulation that copies at most one line */
|
||||
size_t Curl_FormReadOneLine(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
FILE *mydata);
|
||||
/*
|
||||
* Curl_formpostheader() returns the first line of the formpost, the
|
||||
* request-header part (which is not part of the request-body like the rest of
|
||||
* the post).
|
||||
*/
|
||||
char *Curl_formpostheader(void *formp, size_t *len);
|
||||
|
||||
char *Curl_FormBoundary(void);
|
||||
|
||||
|
134
lib/ftp.c
134
lib/ftp.c
@@ -91,6 +91,7 @@
|
||||
#include "strequal.h"
|
||||
#include "ssluse.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
|
||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||
#include "inet_ntoa_r.h"
|
||||
@@ -104,12 +105,19 @@
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NI_WITHSCOPEID
|
||||
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
|
||||
#else
|
||||
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
|
||||
#endif
|
||||
|
||||
/* Local API functions */
|
||||
static CURLcode ftp_sendquote(struct connectdata *conn,
|
||||
struct curl_slist *quote);
|
||||
static CURLcode ftp_cwd(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_quit(struct connectdata *conn);
|
||||
|
||||
/* easy-to-use macro: */
|
||||
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
|
||||
@@ -117,11 +125,21 @@ static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
|
||||
static void freedirs(struct FTP *ftp)
|
||||
{
|
||||
int i;
|
||||
for (i=0; ftp->dirs[i]; i++){
|
||||
if(ftp->dirs) {
|
||||
for (i=0; i < ftp->dirdepth; i++){
|
||||
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 */
|
||||
int i;
|
||||
|
||||
conn->headerbytecount += gotbytes;
|
||||
|
||||
*nreadp += gotbytes;
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
perline++;
|
||||
@@ -585,13 +605,13 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
|
||||
infof(data, "We have successfully logged in\n");
|
||||
if (conn->ssl[FIRSTSOCKET].use) {
|
||||
#ifdef HAVE_KRB4
|
||||
/* we are logged in (with Kerberos)
|
||||
* now set the requested protection level
|
||||
/* We are logged in with Kerberos, now set the requested protection
|
||||
* level
|
||||
*/
|
||||
if(conn->sec_complete)
|
||||
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
|
||||
*/
|
||||
if(conn->passwd && *conn->passwd) {
|
||||
@@ -724,14 +744,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
||||
ssize_t nread;
|
||||
int ftpcode;
|
||||
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);
|
||||
|
||||
if(ftp->file) {
|
||||
free(ftp->file);
|
||||
ftp->file = NULL;
|
||||
}
|
||||
ftp->ctl_valid = FALSE;
|
||||
|
||||
if(data->set.upload) {
|
||||
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
|
||||
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
|
||||
#endif
|
||||
@@ -954,7 +974,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
|
||||
|
||||
if(ftpcode == 213) {
|
||||
/* get the size from the ascii string: */
|
||||
*size = strtoofft(buf+4, NULL, 0);
|
||||
*size = curlx_strtoofft(buf+4, NULL, 0);
|
||||
}
|
||||
else
|
||||
return CURLE_FTP_COULDNT_GET_SIZE;
|
||||
@@ -1073,14 +1093,9 @@ ftp_pasv_verbose(struct connectdata *conn,
|
||||
char hbuf[NI_MAXHOST]; /* ~1KB */
|
||||
char nbuf[NI_MAXHOST]; /* ~1KB */
|
||||
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 */
|
||||
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(sbuf, sizeof(sbuf), "?");
|
||||
}
|
||||
@@ -1126,11 +1141,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
char hbuf[NI_MAXHOST];
|
||||
|
||||
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 *pp;
|
||||
char portmsgbuf[4096], tmp[4096];
|
||||
@@ -1138,6 +1148,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
|
||||
char **modep;
|
||||
int rc;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
error = 0;
|
||||
for (ai = res; ai; ai = ai->ai_next) {
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
error = Curl_ourerrno();
|
||||
sclose(portsock);
|
||||
portsock = CURL_SOCKET_BAD;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (listen(portsock, 1) < 0) {
|
||||
error = Curl_ourerrno();
|
||||
sclose(portsock);
|
||||
portsock = CURL_SOCKET_BAD;
|
||||
continue;
|
||||
@@ -1199,13 +1215,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
if (portsock == CURL_SOCKET_BAD) {
|
||||
failf(data, "%s", strerror(errno));
|
||||
failf(data, "%s", Curl_strerror(conn,error));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||
failf(data, "%s", strerror(errno));
|
||||
failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1256,7 +1272,8 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
portmsgbuf, tmp);
|
||||
if(result)
|
||||
return result;
|
||||
} else if (strcmp(*modep, "LPRT") == 0 ||
|
||||
}
|
||||
else if (strcmp(*modep, "LPRT") == 0 ||
|
||||
strcmp(*modep, "PORT") == 0) {
|
||||
int i;
|
||||
|
||||
@@ -1602,7 +1619,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
|
||||
newport = num;
|
||||
|
||||
/* we should use the same host we already are connected to */
|
||||
newhostp = conn->name;
|
||||
newhostp = conn->hostname;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1834,7 +1851,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
return result;
|
||||
|
||||
}
|
||||
else if(!data->set.no_body) {
|
||||
else if(!conn->bits.no_body) {
|
||||
/* Retrieve file or directory */
|
||||
bool dirlist=FALSE;
|
||||
curl_off_t downloadsize=-1;
|
||||
@@ -1845,10 +1862,10 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
|
||||
from=strtoofft(conn->range, &ptr, 0);
|
||||
from=curlx_strtoofft(conn->range, &ptr, 0);
|
||||
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
|
||||
ptr++;
|
||||
to=strtoofft(ptr, &ptr2, 0);
|
||||
to=curlx_strtoofft(ptr, &ptr2, 0);
|
||||
if(ptr == ptr2) {
|
||||
/* we didn't get any digit */
|
||||
to=-1;
|
||||
@@ -2067,7 +2084,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
/* only if we have nothing but digits: */
|
||||
if(bytes++) {
|
||||
/* 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 */
|
||||
for (i=0; ftp->dirs[i]; i++) {
|
||||
for (i=0; i < ftp->dirdepth; i++) {
|
||||
/* RFC 1738 says empty components should be respected too, but
|
||||
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)
|
||||
@@ -2205,7 +2222,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
/* 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
|
||||
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
|
||||
may not support it! It is however the only way we have to get a file's
|
||||
size! */
|
||||
@@ -2268,7 +2285,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(data->set.no_body)
|
||||
if(conn->bits.no_body)
|
||||
/* doesn't really transfer any data */
|
||||
ftp->no_transfer = TRUE;
|
||||
/* 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.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@@ -2311,9 +2328,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
struct FTP *ftp;
|
||||
|
||||
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 */
|
||||
int path_part=0;/* current path component */
|
||||
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
ftp = conn->proto.ftp;
|
||||
@@ -2325,23 +2341,28 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
|
||||
/* fixed : initialize ftp->dirs[xxx] to NULL !
|
||||
is done in Curl_ftp_connect() */
|
||||
ftp->dirdepth = 0;
|
||||
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 */
|
||||
while((slash_pos=strchr(cur_pos, '/'))) {
|
||||
/* 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 */
|
||||
if (slash_pos-cur_pos) {
|
||||
/* 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
|
||||
many servers and b) has no effect on the others. */
|
||||
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir,
|
||||
slash_pos - cur_pos + absolute_dir);
|
||||
ftp->dirs[ftp->dirdepth] = curl_unescape(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");
|
||||
freedirs(ftp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -2354,12 +2375,16 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
|
||||
if(!retcode) {
|
||||
cur_pos = slash_pos + 1; /* jump to the rest of the string */
|
||||
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) {
|
||||
/* too deep, we need the last entry to be kept NULL at all
|
||||
times to signal end of list */
|
||||
failf(data, "too deep dir hierarchy");
|
||||
if(++ftp->dirdepth >= ftp->diralloc) {
|
||||
/* enlarge array */
|
||||
char *bigger;
|
||||
ftp->diralloc *= 2; /* double the size each time */
|
||||
bigger = realloc(ftp->dirs, ftp->diralloc * sizeof(ftp->dirs[0]));
|
||||
if(!bigger) {
|
||||
freedirs(ftp);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
ftp->dirs = (char **)bigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2400,7 +2425,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
else
|
||||
freedirs(ftp);
|
||||
|
||||
ftp->ctl_valid = TRUE;
|
||||
ftp->ctl_valid = TRUE; /* seems good */
|
||||
|
||||
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
|
||||
* (not data connections). We should then wait for the response from the
|
||||
@@ -2463,7 +2489,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
* connection.
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_ftp_quit(struct connectdata *conn)
|
||||
static CURLcode ftp_quit(struct connectdata *conn)
|
||||
{
|
||||
ssize_t nread;
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
/* The FTP session may or may not have been allocated/setup at this point! */
|
||||
if(ftp) {
|
||||
(void)Curl_ftp_quit(conn); /* ignore errors on the QUIT */
|
||||
(void)ftp_quit(conn); /* ignore errors on the QUIT */
|
||||
|
||||
if(ftp->entrypath)
|
||||
free(ftp->entrypath);
|
||||
@@ -2507,10 +2533,6 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
free(ftp->cache);
|
||||
ftp->cache = NULL;
|
||||
}
|
||||
if(ftp->file) {
|
||||
free(ftp->file);
|
||||
ftp->file = NULL; /* zero */
|
||||
}
|
||||
freedirs(ftp);
|
||||
}
|
||||
return CURLE_OK;
|
||||
|
@@ -32,7 +32,6 @@ CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||
int *ftpcode);
|
||||
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_quit(struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -742,16 +742,16 @@ ToYear (int Year)
|
||||
static int
|
||||
LookupWord (YYSTYPE *yylval, char *buff)
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register const TABLE *tp;
|
||||
int i;
|
||||
char *p;
|
||||
char *q;
|
||||
const TABLE *tp;
|
||||
size_t i;
|
||||
int abbrev;
|
||||
|
||||
/* Make it lowercase. */
|
||||
for (p = buff; *p; p++)
|
||||
if (ISUPPER ((unsigned char) *p))
|
||||
*p = tolower (*p);
|
||||
*p = tolower ((int)*p);
|
||||
|
||||
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
|
||||
{
|
||||
|
426
lib/hostip.c
426
lib/hostip.c
@@ -49,6 +49,9 @@
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
@@ -60,6 +63,10 @@
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
@@ -70,6 +77,7 @@
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
@@ -88,19 +96,32 @@
|
||||
#define ARES_SUCCESS CURLE_OK
|
||||
#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 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,
|
||||
char *hostname,
|
||||
int port,
|
||||
int *waitp);
|
||||
#ifndef ENABLE_IPV6
|
||||
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
|
||||
defined(USE_THREADING_GETHOSTBYNAME)
|
||||
|
||||
#if (!defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
|
||||
defined(USE_THREADING_GETHOSTBYNAME)) && \
|
||||
!defined(ENABLE_IPV6)
|
||||
static struct hostent* pack_hostent(char** buf, struct hostent* orig);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||
#ifdef DEBUG_THREADING_GETHOSTBYNAME
|
||||
@@ -113,29 +134,40 @@ static void trace_it (const char *fmt, ...);
|
||||
#define TRACE(x)
|
||||
#endif
|
||||
|
||||
static struct hostent* pack_hostent (char** buf, struct hostent* orig);
|
||||
static bool init_gethostbyname_thread (struct connectdata *conn,
|
||||
const char *hostname, int port);
|
||||
struct thread_data {
|
||||
HANDLE thread_hnd;
|
||||
DWORD thread_id;
|
||||
unsigned thread_id;
|
||||
DWORD thread_status;
|
||||
curl_socket_t dummy_sock; /* dummy for Curl_multi_ares_fdset() */
|
||||
};
|
||||
#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)
|
||||
{
|
||||
if (!host_cache_initialized) {
|
||||
Curl_hash_init(&hostname_cache, 7, Curl_freednsinfo);
|
||||
Curl_hash_init(&hostname_cache, 7, freednsentry);
|
||||
host_cache_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the global cache
|
||||
*/
|
||||
curl_hash *Curl_global_host_cache_get(void)
|
||||
{
|
||||
return &hostname_cache;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy and cleanup the global DNS cache
|
||||
*/
|
||||
void Curl_global_host_cache_dtor(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int chars = 0;
|
||||
@@ -165,7 +200,10 @@ static int _num_chars(int i)
|
||||
return chars;
|
||||
}
|
||||
|
||||
/* Create a hostcache id */
|
||||
/*
|
||||
* Minor utility-function:
|
||||
* Create a hostcache id string for the DNS caching.
|
||||
*/
|
||||
static char *
|
||||
create_hostcache_id(char *server, int port, size_t *entry_len)
|
||||
{
|
||||
@@ -192,6 +230,13 @@ struct hostcache_prune_data {
|
||||
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
|
||||
hostcache_timestamp_remove(void *datap, void *hc)
|
||||
{
|
||||
@@ -209,6 +254,9 @@ hostcache_timestamp_remove(void *datap, void *hc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prune the DNS cache. This assumes that a lock has already been taken.
|
||||
*/
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Library-wide function for pruning the DNS cache. This function takes and
|
||||
* returns the appropriate locks.
|
||||
*/
|
||||
void Curl_hostcache_prune(struct SessionHandle *data)
|
||||
{
|
||||
time_t now;
|
||||
@@ -245,15 +297,22 @@ void Curl_hostcache_prune(struct SessionHandle *data)
|
||||
}
|
||||
|
||||
#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;
|
||||
#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 etc */
|
||||
|
||||
/*
|
||||
* cache_resolv_response() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
*
|
||||
* 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 *
|
||||
cache_resolv_response(struct SessionHandle *data,
|
||||
Curl_addrinfo *addr,
|
||||
@@ -303,14 +362,21 @@ cache_resolv_response(struct SessionHandle *data,
|
||||
return dns;
|
||||
}
|
||||
|
||||
/* Resolve a name and return a pointer in the 'entry' argument if one
|
||||
is available.
|
||||
|
||||
Return codes:
|
||||
|
||||
-1 = error, no pointer
|
||||
0 = OK, pointer provided
|
||||
1 = waiting for response, no pointer
|
||||
/*
|
||||
* 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
|
||||
* is provided). This function might return immediately if we're using asynch
|
||||
* resolves. See the return codes.
|
||||
*
|
||||
* The cache entry we return will get its 'inuse' counter increased when this
|
||||
* 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,
|
||||
char *hostname,
|
||||
@@ -405,6 +471,11 @@ int Curl_resolv(struct connectdata *conn,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -449,6 +520,14 @@ void Curl_freednsinfo(void *freethis)
|
||||
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 --- */
|
||||
|
||||
/* Allocate enough memory to hold the full name information structs and
|
||||
@@ -460,6 +539,15 @@ void Curl_freednsinfo(void *freethis)
|
||||
|
||||
#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,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
@@ -473,24 +561,32 @@ CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
|
||||
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,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
fd_set read_fds, write_fds;
|
||||
static const struct timeval tv={0,0};
|
||||
struct timeval tv={0,0};
|
||||
int count;
|
||||
struct SessionHandle *data = conn->data;
|
||||
int nfds;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
|
||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||
|
||||
count = select(nfds, &read_fds, &write_fds, NULL,
|
||||
(struct timeval *)&tv);
|
||||
|
||||
if(count)
|
||||
/* Call ares_process() unconditonally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve won't timeout! */
|
||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||
|
||||
*dns = NULL;
|
||||
@@ -505,23 +601,21 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* This is a function that locks and waits until the name resolve operation
|
||||
has completed.
|
||||
|
||||
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.
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode rc=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct timeval now = Curl_tvnow();
|
||||
bool timedout = FALSE;
|
||||
long timeout = 300; /* default name resolve timeout in seconds */
|
||||
long elapsed = 0; /* time taken so far */
|
||||
long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||
|
||||
/* now, see if there's a connect timeout or a regular timeout to
|
||||
use instead of the default one */
|
||||
@@ -530,34 +624,46 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
else if(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. */
|
||||
while (1) {
|
||||
int nfds=0;
|
||||
fd_set read_fds, write_fds;
|
||||
struct timeval *tvp, tv, store;
|
||||
int count;
|
||||
struct timeval now = Curl_tvnow();
|
||||
long timediff;
|
||||
|
||||
store.tv_sec = (int)(timeout - elapsed);
|
||||
store.tv_usec = 0;
|
||||
store.tv_sec = (int)timeout/1000;
|
||||
store.tv_usec = (timeout%1000)*1000;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||
if (nfds == 0)
|
||||
/* no file descriptors means we're done waiting */
|
||||
break;
|
||||
tvp = ares_timeout(data->state.areschannel,
|
||||
&store, &tv);
|
||||
tvp = ares_timeout(data->state.areschannel, &store, &tv);
|
||||
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||
if (count < 0 && errno != EINVAL)
|
||||
break;
|
||||
else if(!count) {
|
||||
/* timeout */
|
||||
timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -568,12 +674,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
|
||||
if(!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
if(timedout || (conn->async.status == ARES_ETIMEOUT)) {
|
||||
failf(data, "Resolving host timed out: %s", conn->name);
|
||||
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
|
||||
failf(data, "Resolving host timed out: %s", conn->hostname);
|
||||
rc = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
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));
|
||||
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)
|
||||
|
||||
/* 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 *" */
|
||||
int status,
|
||||
struct hostent *hostent)
|
||||
@@ -633,9 +747,11 @@ static void host_callback(void *arg, /* "struct connectdata *" */
|
||||
|
||||
#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
|
||||
* 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.
|
||||
*/
|
||||
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||
@@ -648,6 +764,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
*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);
|
||||
|
||||
if(bufp) {
|
||||
@@ -670,9 +790,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
#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
|
||||
called, we return failure at once. */
|
||||
/*
|
||||
* Curl_wait_for_resolv() 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 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,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
@@ -681,6 +806,13 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
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,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
@@ -692,18 +824,32 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
#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,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
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)read_fd_set;
|
||||
(void)write_fd_set;
|
||||
(void)max_fdp;
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
#endif /* !USE_ARES */
|
||||
|
||||
#if defined(ENABLE_IPV6) && !defined(USE_ARES)
|
||||
|
||||
@@ -745,9 +891,11 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
|
||||
#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
|
||||
* 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.
|
||||
*/
|
||||
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 */
|
||||
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
|
||||
* 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. */
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
|
||||
* 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 */
|
||||
|
||||
#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);
|
||||
|
||||
/*
|
||||
* Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
|
||||
* copy). Make absolutely sure the destination buffer is big enough!
|
||||
* pack_hostent() is a file-local function that performs a "deep" copy of a
|
||||
* 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)
|
||||
{
|
||||
@@ -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
|
||||
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(newbuf != *buf)
|
||||
hostcache_fixoffset((struct hostent*)newbuf, (long)newbuf-(long)*buf);
|
||||
hostcache_fixoffset((struct hostent*)newbuf, (long)(newbuf-*buf));
|
||||
|
||||
/* setup the return */
|
||||
*buf = newbuf;
|
||||
@@ -901,6 +1058,12 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
|
||||
}
|
||||
#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)
|
||||
{
|
||||
int i=0;
|
||||
@@ -925,6 +1088,11 @@ static void hostcache_fixoffset(struct hostent *h, long offset)
|
||||
|
||||
#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)
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
/*
|
||||
* my_getaddrinfo() - the ipv4 "traditional" version.
|
||||
*
|
||||
* 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,
|
||||
char *hostname,
|
||||
int port,
|
||||
@@ -961,6 +1133,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
*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);
|
||||
if (in != CURL_INADDR_NONE) {
|
||||
struct in_addr *addrentry;
|
||||
@@ -1148,6 +1324,7 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
|
||||
else {
|
||||
|
||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||
/* fire up a new resolver thread! */
|
||||
if (init_gethostbyname_thread(conn,hostname,port)) {
|
||||
*waitp = TRUE; /* please wait for the response */
|
||||
return NULL;
|
||||
@@ -1183,20 +1360,26 @@ static void trace_it (const char *fmt, ...)
|
||||
static int do_trace = -1;
|
||||
va_list args;
|
||||
|
||||
if (do_trace == -1)
|
||||
do_trace = getenv("CURL_TRACE") ? 1 : 0;
|
||||
if (do_trace == -1) {
|
||||
const char *env = getenv("CURL_TRACE");
|
||||
do_trace = (env && atoi(env) > 0);
|
||||
}
|
||||
if (!do_trace)
|
||||
return;
|
||||
va_start (args, fmt);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fflush (stderr);
|
||||
/*fflush (stderr); */ /* seems a bad idea in a multi-threaded app */
|
||||
va_end (args);
|
||||
}
|
||||
#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 hostent *he;
|
||||
@@ -1215,32 +1398,43 @@ static DWORD WINAPI gethostbyname_thread (void *arg)
|
||||
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
|
||||
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
|
||||
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)
|
||||
free(conn->async.hostname);
|
||||
if (conn->async.os_specific)
|
||||
free(conn->async.os_specific);
|
||||
conn->async.hostname = NULL;
|
||||
conn->async.os_specific = NULL;
|
||||
if (async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if (async->os_specific) {
|
||||
curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock;
|
||||
|
||||
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,
|
||||
const char *hostname, int port)
|
||||
{
|
||||
struct thread_data *td = malloc(sizeof(*td));
|
||||
struct thread_data *td = calloc(sizeof(*td), 1);
|
||||
|
||||
if (!td) {
|
||||
SetLastError(ENOMEM);
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset (td, 0, sizeof(*td));
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = strdup(hostname);
|
||||
if (!conn->async.hostname) {
|
||||
@@ -1255,17 +1449,31 @@ static bool init_gethostbyname_thread (struct connectdata *conn,
|
||||
conn->async.dns = NULL;
|
||||
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);
|
||||
if (!td->thread_hnd) {
|
||||
TRACE(("CreateThread() failed; %lu\n", GetLastError()));
|
||||
destroy_thread_data(conn);
|
||||
SetLastError(errno);
|
||||
TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
|
||||
destroy_thread_data(&conn->async);
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
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
|
||||
use instead of the default one */
|
||||
timeout = conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
||||
timeout =
|
||||
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
||||
conn->data->set.timeout ? conn->data->set.timeout :
|
||||
300; /* default name resolve timeout in seconds */
|
||||
CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
|
||||
ticks = GetTickCount();
|
||||
|
||||
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
|
||||
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);
|
||||
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 {
|
||||
conn->async.done = TRUE;
|
||||
TerminateThread(td->thread_hnd, (DWORD)-1);
|
||||
td->thread_status = (DWORD)-1;
|
||||
TRACE(("gethostbyname_thread() timeout, "));
|
||||
}
|
||||
|
||||
TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n",
|
||||
td->thread_status, GetTickCount()-ticks));
|
||||
TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
|
||||
|
||||
CloseHandle(td->thread_hnd);
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
@@ -1308,24 +1521,33 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
if (!conn->async.dns) {
|
||||
/* a name was not resolved */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else
|
||||
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
|
||||
cleaning up this connection properly */
|
||||
Curl_disconnect(conn);
|
||||
}
|
||||
|
||||
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,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
@@ -1333,7 +1555,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
|
||||
|
||||
if (conn->async.done) {
|
||||
/* we're done */
|
||||
destroy_thread_data(conn);
|
||||
destroy_thread_data(&conn->async);
|
||||
if (!conn->async.dns) {
|
||||
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
|
@@ -74,8 +74,8 @@ void Curl_scan_cache_used(void *user, void *ptr);
|
||||
/* free name info */
|
||||
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
|
||||
|
||||
/* free cached name info */
|
||||
void Curl_freednsinfo(void *freethis);
|
||||
/* make a new dns cache and return the handle */
|
||||
curl_hash *Curl_mk_dnscache(void);
|
||||
|
||||
/* prune old entries from the DNS cache */
|
||||
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);
|
||||
|
||||
/*
|
||||
* This function checks the linked list of custom HTTP headers for a particular
|
||||
* header (prefix).
|
||||
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||
* 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)
|
||||
{
|
||||
@@ -120,6 +122,12 @@ static char *checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||
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)
|
||||
{
|
||||
char *authorization;
|
||||
@@ -139,6 +147,13 @@ static CURLcode Curl_output_basic(struct connectdata *conn)
|
||||
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)
|
||||
{
|
||||
char *authorization;
|
||||
@@ -186,33 +201,49 @@ void Curl_http_auth_act(struct connectdata *conn)
|
||||
conn->newurl = strdup(data->change.url); /* clone URL */
|
||||
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
|
||||
* authentication method.
|
||||
/**
|
||||
* http_auth_headers() setups the authentication headers for the host/proxy
|
||||
* 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,
|
||||
char *request,
|
||||
char *path,
|
||||
bool *ready) /* set TRUE when the auth phase
|
||||
is done and ready to do the *actual*
|
||||
request */
|
||||
char *path)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *auth=NULL;
|
||||
|
||||
*ready = FALSE; /* default is no */
|
||||
curlassert(data);
|
||||
|
||||
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);
|
||||
else if(conn->bits.user_passwd)
|
||||
}
|
||||
else if(conn->bits.user_passwd) {
|
||||
data->state.authdone = FALSE;
|
||||
Curl_http_auth_stage(data, 401);
|
||||
}
|
||||
else {
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
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
|
||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||
auth=(char *)"NTLM";
|
||||
result = Curl_output_ntlm(conn, TRUE, ready);
|
||||
result = Curl_output_ntlm(conn, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -244,7 +275,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
/* Switch to web authentication after proxy authentication is done */
|
||||
Curl_http_auth_stage(data, 401);
|
||||
}
|
||||
@@ -262,14 +293,14 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
||||
result = Curl_output_negotiate(conn);
|
||||
if (result)
|
||||
return result;
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_SSLEAY
|
||||
if(data->state.authwant == CURLAUTH_NTLM) {
|
||||
auth=(char *)"NTLM";
|
||||
result = Curl_output_ntlm(conn, FALSE, ready);
|
||||
result = Curl_output_ntlm(conn, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -284,7 +315,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
||||
(unsigned char *)path);
|
||||
if(result)
|
||||
return result;
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
}
|
||||
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
|
||||
if(conn->bits.user_passwd &&
|
||||
@@ -295,7 +326,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
/* basic is always ready */
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
}
|
||||
}
|
||||
if(auth)
|
||||
@@ -304,7 +335,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else
|
||||
*ready = TRUE;
|
||||
data->state.authdone = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -365,8 +396,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
|
||||
/* if exactly this is wanted, go */
|
||||
int neg = Curl_input_negotiate(conn, start);
|
||||
if (neg == 0)
|
||||
if (neg == 0) {
|
||||
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
|
||||
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
|
||||
@@ -383,10 +420,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
CURLntlm ntlm =
|
||||
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
||||
|
||||
if(CURLNTLM_BAD != ntlm)
|
||||
if(CURLNTLM_BAD != ntlm) {
|
||||
conn->newurl = strdup(data->change.url); /* clone string */
|
||||
else
|
||||
data->state.authproblem = (conn->newurl == NULL);
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(data->state.authwant & CURLAUTH_NTLM)
|
||||
@@ -398,17 +439,18 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
if(data->state.authwant == CURLAUTH_DIGEST) {
|
||||
/* Digest authentication is activated */
|
||||
CURLdigest dig = CURLDIGEST_BAD;
|
||||
CURLdigest dig = Curl_input_digest(conn, start);
|
||||
|
||||
if(data->state.digest.nonce)
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
else
|
||||
dig = Curl_input_digest(conn, start);
|
||||
|
||||
if(CURLDIGEST_FINE == dig)
|
||||
if(CURLDIGEST_FINE == dig) {
|
||||
/* We act on it. Store our new url, which happens to be
|
||||
the same one we already use! */
|
||||
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
|
||||
if(data->state.authwant & CURLAUTH_DIGEST) {
|
||||
@@ -430,16 +472,114 @@ CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
valid. */
|
||||
data->state.authavail = CURLAUTH_NONE;
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else if(data->state.authwant & 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
@@ -502,7 +642,7 @@ static CURLcode
|
||||
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
|
||||
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.
|
||||
*
|
||||
* Returns CURLcode
|
||||
*/
|
||||
static
|
||||
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
|
||||
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
|
||||
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);
|
||||
|
||||
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) {
|
||||
/* 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()
|
||||
@@ -776,7 +915,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* 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) {
|
||||
|
||||
/* 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 */
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.http_include_header)
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -997,6 +1137,11 @@ CURLcode Curl_http_connect(struct connectdata *conn)
|
||||
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)
|
||||
{
|
||||
struct SessionHandle *data;
|
||||
@@ -1029,10 +1174,12 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
conn->bytecount = http->readbytecount + http->writebytecount;
|
||||
|
||||
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
|
||||
read from the HTTP server, this can't be right so we return an error
|
||||
here */
|
||||
read from the HTTP server (that counts), this can't be right so we
|
||||
return an error here */
|
||||
failf(data, "Empty reply from server");
|
||||
return CURLE_GOT_NOTHING;
|
||||
}
|
||||
@@ -1040,6 +1187,10 @@ CURLcode Curl_http_done(struct connectdata *conn)
|
||||
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,
|
||||
int stage)
|
||||
{
|
||||
@@ -1054,6 +1205,11 @@ void Curl_http_auth_stage(struct SessionHandle *data,
|
||||
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)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
@@ -1061,12 +1217,12 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
CURLcode result=CURLE_OK;
|
||||
struct HTTP *http;
|
||||
struct Cookie *co=NULL; /* no cookies from start */
|
||||
char *ppath = conn->ppath; /* three previous function arguments */
|
||||
char *host = conn->name;
|
||||
char *ppath = conn->path;
|
||||
char *host = conn->hostname;
|
||||
const char *te = ""; /* tranfer-encoding */
|
||||
char *ptr;
|
||||
char *request;
|
||||
bool authdone=TRUE; /* if the authentication phase is done */
|
||||
Curl_HttpReq httpreq = data->set.httpreq;
|
||||
|
||||
if(!conn->proto.http) {
|
||||
/* 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)) &&
|
||||
data->set.upload) {
|
||||
data->set.httpreq = HTTPREQ_PUT;
|
||||
httpreq = HTTPREQ_PUT;
|
||||
}
|
||||
|
||||
request = data->set.customrequest?
|
||||
data->set.customrequest:
|
||||
(data->set.no_body?(char *)"HEAD":
|
||||
((HTTPREQ_POST == data->set.httpreq) ||
|
||||
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
|
||||
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
|
||||
/* Now set the 'request' pointer to the proper request string */
|
||||
if(data->set.customrequest)
|
||||
request = data->set.customrequest;
|
||||
else {
|
||||
if(conn->bits.no_body)
|
||||
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
|
||||
have been used in the proxy connect, but if we have got a header with
|
||||
the user-agent string specified, we erase the previously made string
|
||||
/* The User-Agent string might have been allocated in url.c already, because
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
||||
free(conn->allocptr.uagent);
|
||||
@@ -1105,10 +1282,20 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* setup the authentication headers */
|
||||
result = http_auth_headers(conn, request, ppath, &authdone);
|
||||
result = http_auth_headers(conn, request, ppath);
|
||||
if(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);
|
||||
if(data->change.referer && !checkheaders(data, "Referer:"))
|
||||
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
|
||||
@@ -1121,7 +1308,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
else
|
||||
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 */
|
||||
ptr = checkheaders(data, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
@@ -1212,7 +1399,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* The path sent to the proxy is in fact the entire 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
|
||||
a size of the whole shebang before we start to send it */
|
||||
result = Curl_getFormData(&http->sendit, data->set.httppost,
|
||||
@@ -1231,9 +1418,9 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
if(!checkheaders(data, "Accept:"))
|
||||
http->p_accept = "Accept: */*\r\n";
|
||||
|
||||
if(( (HTTPREQ_POST == data->set.httpreq) ||
|
||||
(HTTPREQ_POST_FORM == data->set.httpreq) ||
|
||||
(HTTPREQ_PUT == data->set.httpreq) ) &&
|
||||
if(( (HTTPREQ_POST == httpreq) ||
|
||||
(HTTPREQ_POST_FORM == httpreq) ||
|
||||
(HTTPREQ_PUT == httpreq) ) &&
|
||||
conn->resume_from) {
|
||||
/**********************************************************************
|
||||
* 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
|
||||
* ones if any such are specified.
|
||||
*/
|
||||
if((data->set.httpreq == HTTPREQ_GET) &&
|
||||
if((httpreq == HTTPREQ_GET) &&
|
||||
!checkheaders(data, "Range:")) {
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
if(conn->allocptr.rangeline)
|
||||
free(conn->allocptr.rangeline);
|
||||
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:")) {
|
||||
|
||||
if(conn->resume_from) {
|
||||
@@ -1466,11 +1653,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
http->postdata = NULL; /* nothing to post at this point */
|
||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||
|
||||
/* If 'authdone' is still FALSE, we must not set the write socket index to
|
||||
the Curl_transfer() call below, as we're not ready to actually upload
|
||||
any data yet. */
|
||||
/* If 'authdone' is FALSE, we must not set the write socket index to the
|
||||
Curl_transfer() call below, as we're not ready to actually upload any
|
||||
data yet. */
|
||||
|
||||
switch(data->set.httpreq) {
|
||||
switch(httpreq) {
|
||||
|
||||
case HTTPREQ_POST_FORM:
|
||||
if(Curl_FormInit(&http->form, http->sendit)) {
|
||||
@@ -1499,7 +1686,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
work, but we support it anyway.
|
||||
*/
|
||||
char contentType[256];
|
||||
char *contentType;
|
||||
size_t linelength=0;
|
||||
linelength = Curl_FormReadOneLine(contentType,
|
||||
sizeof(contentType),
|
||||
1,
|
||||
(FILE *)&http->form);
|
||||
if(!linelength) {
|
||||
contentType = Curl_formpostheader((void *)&http->form,
|
||||
&linelength);
|
||||
if(!contentType) {
|
||||
failf(data, "Could not get Content-Type header line!");
|
||||
return CURLE_HTTP_POST_ERROR;
|
||||
}
|
||||
@@ -1535,8 +1720,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* setup variables for the upcoming transfer */
|
||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount,
|
||||
authdone?FIRSTSOCKET:-1,
|
||||
authdone?&http->writebytecount:NULL);
|
||||
data->state.authdone?FIRSTSOCKET:-1,
|
||||
data->state.authdone?&http->writebytecount:NULL);
|
||||
if(result) {
|
||||
Curl_formclean(http->sendit); /* free that whole lot */
|
||||
return result;
|
||||
@@ -1574,8 +1759,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* prepare for transfer */
|
||||
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount,
|
||||
authdone?FIRSTSOCKET:-1,
|
||||
authdone?&http->writebytecount:NULL);
|
||||
data->state.authdone?FIRSTSOCKET:-1,
|
||||
data->state.authdone?&http->writebytecount:NULL);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
@@ -1606,7 +1791,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
|
||||
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
|
||||
to actually send off any data yet. Hence, we delay the sending of
|
||||
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 */
|
||||
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
|
||||
headers which actually speeds up post operations (as there is
|
||||
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);
|
||||
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||
ssize_t length, ssize_t *wrote);
|
||||
|
||||
/* These functions are in http.c */
|
||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||
CURLcode Curl_http_auth(struct connectdata *conn,
|
||||
int httpcode, char *header);
|
||||
void Curl_http_auth_act(struct connectdata *conn);
|
||||
|
||||
int Curl_http_should_fail(struct connectdata *conn);
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "md5.h"
|
||||
#include "http_digest.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -57,6 +58,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
{
|
||||
bool more = TRUE;
|
||||
struct SessionHandle *data=conn->data;
|
||||
bool before = FALSE; /* got a nonce before */
|
||||
struct digestdata *d = &data->state.digest;
|
||||
|
||||
/* skip initial whitespaces */
|
||||
while(*header && isspace((int)*header))
|
||||
@@ -65,6 +68,10 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
if(checkprefix("Digest", header)) {
|
||||
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 */
|
||||
Curl_digest_cleanup(data);
|
||||
|
||||
@@ -77,21 +84,32 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
header++;
|
||||
|
||||
/* how big can these strings be? */
|
||||
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||
value, content)) {
|
||||
if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
|
||||
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")) {
|
||||
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")) {
|
||||
data->state.digest.cnonce = strdup(content);
|
||||
d->cnonce = strdup(content);
|
||||
}
|
||||
else if(strequal(value, "realm")) {
|
||||
data->state.digest.realm = strdup(content);
|
||||
d->realm = strdup(content);
|
||||
}
|
||||
else if(strequal(value, "algorithm")) {
|
||||
if(strequal(content, "MD5-sess"))
|
||||
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
|
||||
/* else, remain using the default md5 */
|
||||
d->algo = CURLDIGESTALGO_MD5SESS;
|
||||
else if(strequal(content, "MD5"))
|
||||
d->algo = CURLDIGESTALGO_MD5;
|
||||
else
|
||||
return CURLDIGEST_BADALGO;
|
||||
}
|
||||
else {
|
||||
/* unknown specifier, ignore it! */
|
||||
@@ -106,8 +124,15 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
/* allow the list to be comma-separated */
|
||||
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;
|
||||
}
|
||||
else
|
||||
@@ -140,6 +165,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
unsigned char *md5this;
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct digestdata *d = &data->state.digest;
|
||||
|
||||
/*
|
||||
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 )
|
||||
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||
*/
|
||||
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
|
||||
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s:%s:%s",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
d->realm,
|
||||
conn->passwd,
|
||||
data->state.digest.nonce,
|
||||
data->state.digest.cnonce);
|
||||
d->nonce,
|
||||
d->cnonce);
|
||||
}
|
||||
else {
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
d->realm,
|
||||
conn->passwd);
|
||||
}
|
||||
Curl_md5it(md5buf, md5this);
|
||||
@@ -183,7 +209,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
free(md5this); /* free this again */
|
||||
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);
|
||||
Curl_md5it(md5buf, md5this);
|
||||
free(md5this); /* free this again */
|
||||
@@ -195,6 +221,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||
*/
|
||||
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd =
|
||||
aprintf( "Authorization: Digest "
|
||||
"username=\"%s\", "
|
||||
@@ -203,8 +230,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
"uri=\"%s\", "
|
||||
"response=\"%s\"\r\n",
|
||||
conn->user,
|
||||
data->state.digest.realm,
|
||||
data->state.digest.nonce,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
uripath, /* this is the PATH part of the URL */
|
||||
request_digest );
|
||||
|
||||
@@ -213,19 +240,23 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
{
|
||||
if(data->state.digest.nonce)
|
||||
free(data->state.digest.nonce);
|
||||
data->state.digest.nonce = NULL;
|
||||
struct digestdata *d = &data->state.digest;
|
||||
|
||||
if(data->state.digest.cnonce)
|
||||
free(data->state.digest.cnonce);
|
||||
data->state.digest.cnonce = NULL;
|
||||
if(d->nonce)
|
||||
free(d->nonce);
|
||||
d->nonce = NULL;
|
||||
|
||||
if(data->state.digest.realm)
|
||||
free(data->state.digest.realm);
|
||||
data->state.digest.realm = NULL;
|
||||
if(d->cnonce)
|
||||
free(d->cnonce);
|
||||
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
|
||||
|
@@ -26,6 +26,7 @@
|
||||
typedef enum {
|
||||
CURLDIGEST_NONE, /* not a digest */
|
||||
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||
CURLDIGEST_BADALGO, /* unsupported algorithm requested */
|
||||
CURLDIGEST_FINE, /* a digest we act on */
|
||||
|
||||
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||
|
@@ -77,7 +77,7 @@
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
@@ -277,8 +277,7 @@ static void mkhash(char *password,
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy,
|
||||
bool *ready)
|
||||
bool proxy)
|
||||
{
|
||||
const char *domain=""; /* empty */
|
||||
const char *host=""; /* empty */
|
||||
@@ -300,7 +299,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
|
||||
*ready = FALSE;
|
||||
curlassert(conn);
|
||||
curlassert(conn->data);
|
||||
conn->data->state.authdone = FALSE;
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
@@ -562,7 +563,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
|
||||
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 */
|
||||
if (proxy)
|
||||
@@ -577,7 +578,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd=NULL;
|
||||
}
|
||||
*ready = TRUE;
|
||||
conn->data->state.authdone = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@ typedef enum {
|
||||
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include <winver.h>
|
||||
#include "../include/curl/curl.h"
|
||||
#include "../include/curl/curlver.h"
|
||||
|
||||
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 \
|
||||
easy.c escape.c file.c formdata.c ftp.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 \
|
||||
memdebug.c mprintf.c multi.c netrc.c progress.c \
|
||||
security.c sendf.c share.c speedche.c ssluse.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)
|
||||
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.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/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h sendf.h if2ip.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 \
|
||||
if2ip.h strerror.h connect.h
|
||||
content_.o: content_.c setup.h config.h config.dj
|
||||
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/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h getdate.h strequal.h strtok.h sendf.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 getdate.h \
|
||||
strequal.h strtok.h sendf.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/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
|
||||
../include/curl/mprintf.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 strequal.h dict.h ../include/curl/mprintf.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/multi.h formdata.h timeval.h http_chunks.h hostip.h \
|
||||
hash.h llist.h transfer.h ssluse.h url.h getinfo.h share.h \
|
||||
../include/curl/mprintf.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 \
|
||||
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 \
|
||||
../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 \
|
||||
../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 progress.h sendf.h escape.h ../include/curl/mprintf.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 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 \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
|
||||
formdata.h strequal.h
|
||||
../include/curl/curlver.h ../include/curl/types.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 \
|
||||
../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 sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
|
||||
strequal.h ssluse.h connect.h ../include/curl/mprintf.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 sendf.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
|
||||
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 \
|
||||
../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
|
||||
../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 getinfo.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 \
|
||||
../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 share.h url.h ../include/curl/mprintf.h
|
||||
http.o: http.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 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
|
||||
../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 \
|
||||
share.h url.h ../include/curl/mprintf.h
|
||||
if2ip.o: if2ip.c setup.h config.h config.dj if2ip.h
|
||||
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 \
|
||||
../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 escape.h transfer.h ../include/curl/mprintf.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 \
|
||||
escape.h transfer.h ldap.h ../include/curl/mprintf.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 \
|
||||
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.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
|
||||
memdebug.o: memdebug.c
|
||||
mprintf.o: mprintf.c setup.h config.h config.dj ../include/curl/mprintf.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 \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h transfer.h url.h connect.h progress.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 transfer.h \
|
||||
url.h connect.h progress.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 \
|
||||
strequal.h strtok.h ../include/curl/mprintf.h
|
||||
../include/curl/curlver.h ../include/curl/types.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 \
|
||||
../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 sendf.h progress.h ../include/curl/mprintf.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 sendf.h \
|
||||
progress.h ../include/curl/mprintf.h
|
||||
security.o: security.c setup.h config.h config.dj
|
||||
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 \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h connect.h ../include/curl/mprintf.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 sendf.h \
|
||||
connect.h ../include/curl/mprintf.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 \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h share.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 share.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 \
|
||||
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
|
||||
llist.h sendf.h speedcheck.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 sendf.h \
|
||||
speedcheck.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/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/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
|
||||
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.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 {
|
||||
FormatType type;
|
||||
int flags;
|
||||
int width; /* width OR width parameter number */
|
||||
int precision; /* precision OR precision parameter number */
|
||||
long width; /* width OR width parameter number */
|
||||
long precision; /* precision OR precision parameter number */
|
||||
union {
|
||||
char *str;
|
||||
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;
|
||||
int param_num = 0;
|
||||
@@ -681,7 +682,7 @@ static int dprintf_formatf(
|
||||
else
|
||||
prec = -1;
|
||||
|
||||
alt = p->flags & FLAGS_ALT;
|
||||
alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
|
||||
|
||||
switch (p->type) {
|
||||
case FORMAT_INT:
|
||||
@@ -1042,7 +1043,7 @@ static int alloc_addbyter(int output, FILE *data)
|
||||
infop->alloc *= 2;
|
||||
}
|
||||
|
||||
infop->buffer[ infop->len ] = output;
|
||||
infop->buffer[ infop->len ] = (char)output;
|
||||
|
||||
infop->len++;
|
||||
|
||||
|
@@ -122,7 +122,7 @@ CURLM *curl_multi_init(void)
|
||||
multi->type = CURL_MULTI_HANDLE;
|
||||
}
|
||||
|
||||
multi->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
||||
multi->hostcache = Curl_mk_dnscache();
|
||||
if(!multi->hostcache) {
|
||||
/* failure, free mem and bail out */
|
||||
free(multi);
|
||||
@@ -380,7 +380,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
case CURLM_STATE_WAITRESOLVE:
|
||||
/* 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 */
|
||||
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_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"
|
||||
|
||||
@@ -210,7 +210,7 @@ int Curl_parsenetrc(char *host,
|
||||
else if(strequal("machine", tok)) {
|
||||
/* ok, there's machine here go => */
|
||||
state = HOSTFOUND;
|
||||
state_our_login = 0;
|
||||
state_our_login = FALSE;
|
||||
}
|
||||
break;
|
||||
} /* switch (state) */
|
||||
|
140
lib/progress.c
140
lib/progress.c
@@ -26,9 +26,6 @@
|
||||
#include <string.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__)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -36,19 +33,34 @@
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "progress.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
|
||||
static void time2str(char *r, int t)
|
||||
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
|
||||
byte) */
|
||||
static void time2str(char *r, long t)
|
||||
{
|
||||
int h = (t/3600);
|
||||
int m = (t-(h*3600))/60;
|
||||
int s = (t-(h*3600)-(m*60));
|
||||
sprintf(r,"%2d:%02d:%02d",h,m,s);
|
||||
long h;
|
||||
if(!t) {
|
||||
strcpy(r, "--:--:--");
|
||||
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,
|
||||
@@ -105,14 +117,13 @@ static char *max5data(curl_off_t bytes, char *max5)
|
||||
void Curl_pgrsDone(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
if(!(data->progress.flags & PGRS_HIDE)) {
|
||||
data->progress.lastshow=0;
|
||||
Curl_pgrsUpdate(conn); /* the final (forced) update */
|
||||
if(!data->progress.callback)
|
||||
/* only output if we don't use progress callback */
|
||||
if(!(data->progress.flags & PGRS_HIDE) &&
|
||||
!data->progress.callback)
|
||||
/* only output if we don't use a progress callback and we're not hidden */
|
||||
fprintf(data->set.err, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* reset all times except redirect */
|
||||
void Curl_pgrsResetTimes(struct SessionHandle *data)
|
||||
@@ -137,26 +148,26 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
|
||||
|
||||
case TIMER_NAMELOOKUP:
|
||||
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;
|
||||
case TIMER_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;
|
||||
case TIMER_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;
|
||||
case TIMER_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;
|
||||
case TIMER_POSTRANSFER:
|
||||
/* this is the normal end-of-transfer thing */
|
||||
break;
|
||||
case TIMER_REDIRECT:
|
||||
data->progress.t_redirect =
|
||||
(double)Curl_tvdiff(Curl_tvnow(), data->progress.start)/1000.0;
|
||||
Curl_tvdiff_secs(Curl_tvnow(), data->progress.start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -195,44 +206,27 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
|
||||
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)
|
||||
{
|
||||
struct timeval now;
|
||||
int result;
|
||||
|
||||
char max5[6][10];
|
||||
double dlpercen=0;
|
||||
double ulpercen=0;
|
||||
double total_percen=0;
|
||||
|
||||
int dlpercen=0;
|
||||
int ulpercen=0;
|
||||
int total_percen=0;
|
||||
curl_off_t total_transfer;
|
||||
curl_off_t total_expected_transfer;
|
||||
double timespent;
|
||||
|
||||
long timespent;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
int nowindex = data->progress.speeder_c% CURR_TIME;
|
||||
int checkindex;
|
||||
|
||||
int countindex; /* amount of seconds stored in the speeder array */
|
||||
|
||||
char time_left[10];
|
||||
char time_total[10];
|
||||
char time_current[10];
|
||||
|
||||
double ulestimate=0;
|
||||
double dlestimate=0;
|
||||
|
||||
double total_estimate;
|
||||
|
||||
char time_spent[10];
|
||||
long ulestimate=0;
|
||||
long dlestimate=0;
|
||||
long total_estimate;
|
||||
|
||||
if(data->progress.flags & PGRS_HIDE)
|
||||
; /* 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",
|
||||
conn->resume_from);
|
||||
fprintf(data->set.err,
|
||||
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
|
||||
" Dload Upload Total Current Left Speed\n");
|
||||
" %% Total %% Received %% Xferd Average Speed Time Time Time Current\n"
|
||||
" Dload Upload Total Spent Left Speed\n");
|
||||
}
|
||||
data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
|
||||
}
|
||||
|
||||
now = Curl_tvnow(); /* what time is it */
|
||||
|
||||
/* The exact time spent so far (from the start) */
|
||||
timespent = (double)Curl_tvdiff (now, data->progress.start)/1000;
|
||||
|
||||
data->progress.timespent = timespent;
|
||||
/* The time spent so far (from the start) */
|
||||
data->progress.timespent = Curl_tvdiff_secs(now, data->progress.start);
|
||||
timespent = (long)data->progress.timespent;
|
||||
|
||||
/* The average download speed this far */
|
||||
data->progress.dlspeed =
|
||||
data->progress.downloaded/(timespent>0.01?timespent:1);
|
||||
data->progress.downloaded/(timespent?timespent:1);
|
||||
|
||||
/* The average upload speed this far */
|
||||
data->progress.ulspeed =
|
||||
data->progress.uploaded/(timespent>0.01?timespent:1);
|
||||
data->progress.uploaded/(timespent?timespent:1);
|
||||
|
||||
if(data->progress.lastshow == Curl_tvlong(now))
|
||||
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 */
|
||||
|
||||
/* 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[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 */
|
||||
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
|
||||
(data->progress.ulspeed > 0)) {
|
||||
ulestimate = (double)data->progress.size_ul / data->progress.ulspeed;
|
||||
ulpercen = ((double)data->progress.uploaded / data->progress.size_ul)*100;
|
||||
ulestimate = (long)(data->progress.size_ul / data->progress.ulspeed);
|
||||
ulpercen = (long)(data->progress.uploaded / data->progress.size_ul)*100;
|
||||
}
|
||||
|
||||
/* ... and the download */
|
||||
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
|
||||
(data->progress.dlspeed > 0)) {
|
||||
dlestimate = (double)data->progress.size_dl / data->progress.dlspeed;
|
||||
dlpercen = ((double)data->progress.downloaded / data->progress.size_dl)*100;
|
||||
dlestimate = (long)(data->progress.size_dl / data->progress.dlspeed);
|
||||
dlpercen = (long)(data->progress.downloaded / data->progress.size_dl)*100;
|
||||
}
|
||||
|
||||
/* Now figure out which of them that is slower and use for the for
|
||||
total estimate! */
|
||||
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
|
||||
|
||||
|
||||
/* If we have a total estimate, we can display that and the expected
|
||||
time left */
|
||||
if(total_estimate > 0) {
|
||||
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);
|
||||
/* create the three time strings */
|
||||
time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
|
||||
time2str(time_total, total_estimate);
|
||||
time2str(time_spent, timespent);
|
||||
|
||||
/* Get the total amount of data expected to get transfered */
|
||||
total_expected_transfer =
|
||||
@@ -380,22 +363,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
||||
|
||||
/* Get the percentage of data transfered so far */
|
||||
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,
|
||||
"\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 */
|
||||
(int)dlpercen, /* rcvd % */
|
||||
dlpercen, /* 3 letters */ /* rcvd % */
|
||||
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.dlspeed, max5[3]), /* avrg dl speed */
|
||||
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
|
||||
time_total, /* total time */
|
||||
time_current, /* current time */
|
||||
time_left, /* time left */
|
||||
time_total, /* 8 letters */ /* total time */
|
||||
time_spent, /* 8 letters */ /* time spent */
|
||||
time_left, /* 8 letters */ /* time left */
|
||||
max5data(data->progress.current_speed, max5[5]) /* current speed */
|
||||
);
|
||||
|
||||
|
@@ -417,7 +417,6 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
||||
|
||||
if(-1 == nread) {
|
||||
int err = Curl_ourerrno();
|
||||
conn->sockerror = err;
|
||||
#ifdef WIN32
|
||||
if(WSAEWOULDBLOCK == err)
|
||||
#else
|
||||
@@ -425,8 +424,6 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
conn->sockerror = 0; /* no error */
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
}
|
||||
|
24
lib/setup.h
24
lib/setup.h
@@ -46,10 +46,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
/* hand-modified VMS config.h! */
|
||||
#include "config-vms.h"
|
||||
#endif
|
||||
#ifdef NETWARE
|
||||
/* hand-modified NetWare config.h! */
|
||||
#include "config-netware.h"
|
||||
@@ -134,15 +130,10 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||
#ifdef VMS
|
||||
#include "../include/curl/stdcheaders.h"
|
||||
#else
|
||||
#include <curl/stdcheaders.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
|
||||
#define NDEBUG
|
||||
#define curlassert(x) assert(x)
|
||||
#else
|
||||
/* 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> */
|
||||
#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 */
|
||||
|
||||
#if defined(ENABLE_IPV6) || defined(USE_SSLEAY)
|
||||
@@ -276,10 +278,6 @@ typedef struct hostent Curl_addrinfo;
|
||||
typedef struct in_addr Curl_ipconnect;
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
#define IOCTL_3_ARGS
|
||||
#endif
|
||||
|
||||
#ifdef mpeix
|
||||
#define IOCTL_3_ARGS
|
||||
#endif
|
||||
|
@@ -73,7 +73,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
|
||||
{
|
||||
case CURL_LOCK_DATA_DNS:
|
||||
if (!share->hostcache) {
|
||||
share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
|
||||
share->hostcache = Curl_mk_dnscache();
|
||||
}
|
||||
break;
|
||||
|
||||
|
23
lib/ssluse.c
23
lib/ssluse.c
@@ -94,7 +94,7 @@ static int passwd_callback(char *buf, int num, int verify
|
||||
else {
|
||||
if(num > (int)strlen((char *)global_passwd)) {
|
||||
strcpy(buf, global_passwd);
|
||||
return strlen(buf);
|
||||
return (int)strlen(buf);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -185,7 +185,7 @@ int random_the_seed(struct SessionHandle *data)
|
||||
if(!area)
|
||||
return 3; /* out of memory */
|
||||
|
||||
len = strlen(area);
|
||||
len = (int)strlen(area);
|
||||
RAND_add(area, len, (len >> 1));
|
||||
|
||||
free(area); /* now remove the random junk */
|
||||
@@ -544,7 +544,7 @@ static int Get_SSL_Session(struct connectdata *conn,
|
||||
if(!check->sessionid)
|
||||
/* not session ID means blank entry */
|
||||
continue;
|
||||
if(curl_strequal(conn->name, check->name) &&
|
||||
if(curl_strequal(conn->hostname, check->name) &&
|
||||
(conn->remote_port == check->remote_port) &&
|
||||
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
|
||||
/* yes, we have a session ID! */
|
||||
@@ -662,7 +662,7 @@ static int Store_SSL_Session(struct connectdata *conn,
|
||||
/* now init the session struct wisely */
|
||||
store->sessionid = ssl_sessionid;
|
||||
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 */
|
||||
|
||||
Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config);
|
||||
@@ -818,10 +818,10 @@ static CURLcode verifyhost(struct connectdata *conn,
|
||||
int i;
|
||||
|
||||
if(GEN_DNS == target) {
|
||||
hostlen = strlen(conn->hostname);
|
||||
hostlen = (int)strlen(conn->hostname);
|
||||
domain = strchr(conn->hostname, '.');
|
||||
if(domain)
|
||||
domainlen = strlen(domain);
|
||||
domainlen = (int)strlen(domain);
|
||||
}
|
||||
|
||||
/* 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
|
||||
allow for the connect call */
|
||||
if(data->set.timeout || data->set.connecttimeout) {
|
||||
double has_passed;
|
||||
long has_passed;
|
||||
|
||||
/* Evaluate in milliseconds how much time that has passed */
|
||||
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
|
||||
@@ -1087,7 +1087,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
||||
timeout_ms = data->set.connecttimeout*1000;
|
||||
|
||||
/* subtract the passed time */
|
||||
timeout_ms -= (long)has_passed;
|
||||
timeout_ms -= has_passed;
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
@@ -1117,14 +1117,15 @@ Curl_SSLConnect(struct connectdata *conn,
|
||||
FD_SET(sockfd, &writefd);
|
||||
else {
|
||||
/* untreated error */
|
||||
unsigned long errdetail;
|
||||
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
||||
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
|
||||
entry. */
|
||||
|
||||
switch(detail) {
|
||||
switch(errdetail) {
|
||||
case 0x1407E086:
|
||||
/* 1407E086:
|
||||
SSL routines:
|
||||
@@ -1140,7 +1141,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
||||
return CURLE_SSL_CACERT;
|
||||
default:
|
||||
/* 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
|
||||
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
|
||||
|
@@ -20,7 +20,17 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "strerror.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
const char *
|
||||
curl_easy_strerror(CURLcode error)
|
||||
@@ -244,8 +254,7 @@ curl_easy_strerror(CURLcode error)
|
||||
const char *
|
||||
curl_multi_strerror(CURLMcode error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
switch (error) {
|
||||
case CURLM_CALL_MULTI_PERFORM:
|
||||
return "please call curl_multi_perform() soon";
|
||||
|
||||
@@ -274,8 +283,7 @@ curl_multi_strerror(CURLMcode error)
|
||||
const char *
|
||||
curl_share_strerror(CURLSHcode error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
switch (error) {
|
||||
case CURLSHE_OK:
|
||||
return "no error";
|
||||
|
||||
@@ -294,3 +302,252 @@ curl_share_strerror(CURLSHcode error)
|
||||
|
||||
return "CURLSH unknown";
|
||||
}
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
/* This function handles most / all (?) Winsock errors cURL is able to produce.
|
||||
*/
|
||||
static const char *
|
||||
get_winsock_error (int err, char *buf, size_t len)
|
||||
{
|
||||
char *p;
|
||||
|
||||
switch (err) {
|
||||
case WSAEINTR:
|
||||
p = "Call interrupted.";
|
||||
break;
|
||||
case WSAEBADF:
|
||||
p = "Bad file";
|
||||
break;
|
||||
case WSAEACCES:
|
||||
p = "Bad access";
|
||||
break;
|
||||
case WSAEFAULT:
|
||||
p = "Bad argument";
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
p = "Invalid arguments";
|
||||
break;
|
||||
case WSAEMFILE:
|
||||
p = "Out of file descriptors";
|
||||
break;
|
||||
case WSAEWOULDBLOCK:
|
||||
p = "Call would block";
|
||||
break;
|
||||
case WSAEINPROGRESS:
|
||||
case WSAEALREADY:
|
||||
p = "Blocking call in progress";
|
||||
break;
|
||||
case WSAENOTSOCK:
|
||||
p = "Descriptor is not a socket.";
|
||||
break;
|
||||
case WSAEDESTADDRREQ:
|
||||
p = "Need destination address";
|
||||
break;
|
||||
case WSAEMSGSIZE:
|
||||
p = "Bad message size";
|
||||
break;
|
||||
case WSAEPROTOTYPE:
|
||||
p = "Bad protocol";
|
||||
break;
|
||||
case WSAENOPROTOOPT:
|
||||
p = "Protocol option is unsupported";
|
||||
break;
|
||||
case WSAEPROTONOSUPPORT:
|
||||
p = "Protocol is unsupported";
|
||||
break;
|
||||
case WSAESOCKTNOSUPPORT:
|
||||
p = "Socket is unsupported";
|
||||
break;
|
||||
case WSAEOPNOTSUPP:
|
||||
p = "Operation not supported";
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
p = "Address family not supported";
|
||||
break;
|
||||
case WSAEPFNOSUPPORT:
|
||||
p = "Protocol family not supported";
|
||||
break;
|
||||
case WSAEADDRINUSE:
|
||||
p = "Address already in use";
|
||||
break;
|
||||
case WSAEADDRNOTAVAIL:
|
||||
p = "Address not available";
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
p = "Network down";
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
p = "Network unreachable";
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
p = "Network has been reset";
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
p = "Connection was aborted";
|
||||
break;
|
||||
case WSAECONNRESET:
|
||||
p = "Connection was reset";
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
p = "No buffer space";
|
||||
break;
|
||||
case WSAEISCONN:
|
||||
p = "Socket is already connected";
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
p = "Socket is not connected";
|
||||
break;
|
||||
case WSAESHUTDOWN:
|
||||
p = "Socket has been shut down";
|
||||
break;
|
||||
case WSAETOOMANYREFS:
|
||||
p = "Too many references";
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
p = "Timed out";
|
||||
break;
|
||||
case WSAECONNREFUSED:
|
||||
p = "Connection refused";
|
||||
break;
|
||||
case WSAELOOP:
|
||||
p = "Loop??";
|
||||
break;
|
||||
case WSAENAMETOOLONG:
|
||||
p = "Name too long";
|
||||
break;
|
||||
case WSAEHOSTDOWN:
|
||||
p = "Host down";
|
||||
break;
|
||||
case WSAEHOSTUNREACH:
|
||||
p = "Host unreachable";
|
||||
break;
|
||||
case WSAENOTEMPTY:
|
||||
p = "Not empty";
|
||||
break;
|
||||
case WSAEPROCLIM:
|
||||
p = "Process limit reached";
|
||||
break;
|
||||
case WSAEUSERS:
|
||||
p = "Too many users";
|
||||
break;
|
||||
case WSAEDQUOT:
|
||||
p = "Bad quota";
|
||||
break;
|
||||
case WSAESTALE:
|
||||
p = "Something is stale";
|
||||
break;
|
||||
case WSAEREMOTE:
|
||||
p = "Remote error";
|
||||
break;
|
||||
case WSAEDISCON:
|
||||
p = "Disconnected";
|
||||
break;
|
||||
|
||||
/* Extended Winsock errors */
|
||||
case WSASYSNOTREADY:
|
||||
p = "Winsock library is not ready";
|
||||
break;
|
||||
case WSANOTINITIALISED:
|
||||
p = "Winsock library not initalised";
|
||||
break;
|
||||
case WSAVERNOTSUPPORTED:
|
||||
p = "Winsock version not supported.";
|
||||
break;
|
||||
|
||||
/* getXbyY() errors (already handled in herrmsg):
|
||||
* Authoritative Answer: Host not found */
|
||||
case WSAHOST_NOT_FOUND:
|
||||
p = "Host not found";
|
||||
break;
|
||||
|
||||
/* Non-Authoritative: Host not found, or SERVERFAIL */
|
||||
case WSATRY_AGAIN:
|
||||
p = "Host not found, try again";
|
||||
break;
|
||||
|
||||
/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
|
||||
case WSANO_RECOVERY:
|
||||
p = "Unrecoverable error in call to nameserver";
|
||||
break;
|
||||
|
||||
/* Valid name, no data record of requested type */
|
||||
case WSANO_DATA:
|
||||
p = "No data record of requested type";
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
strncpy (buf, p, len);
|
||||
buf [len-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
#endif /* WIN32 && !__CYGWIN__ */
|
||||
|
||||
/*
|
||||
* Our thread-safe and smart strerror() replacement.
|
||||
*
|
||||
* The 'err' argument passed in to this function MUST be a true errno number
|
||||
* as reported on this system. We do no range checking on the number before
|
||||
* we pass it to the "number-to-message" convertion function and there might
|
||||
* be systems that don't do proper range checking in there themselves.
|
||||
*
|
||||
* We don't do range checking (on systems other than Windows) since there is
|
||||
* no good reliable and portable way to do it.
|
||||
*/
|
||||
const char *Curl_strerror(struct connectdata *conn, int err)
|
||||
{
|
||||
char *buf, *p;
|
||||
size_t max;
|
||||
|
||||
curlassert(conn);
|
||||
curlassert(err >= 0);
|
||||
|
||||
buf = conn->syserr_buf;
|
||||
max = sizeof(conn->syserr_buf)-1;
|
||||
*buf = '\0';
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
|
||||
if (err >= 0 && err < sys_nerr)
|
||||
strncpy(buf, strerror(err), max);
|
||||
else {
|
||||
if (!get_winsock_error (err, buf, max) &&
|
||||
!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
||||
LANG_NEUTRAL, buf, max, NULL))
|
||||
snprintf(buf, max, "Unknown error %d (%#x)", err, err);
|
||||
}
|
||||
#else /* not native Windows coming up */
|
||||
|
||||
/* These should be atomic and hopefully thread-safe */
|
||||
#ifdef HAVE_STRERROR_R
|
||||
/* There are two different APIs for strerror_r(). The POSIX and the GLIBC
|
||||
versions. */
|
||||
#ifdef HAVE_POSIX_STRERROR_R
|
||||
strerror_r(err, buf, max);
|
||||
/* this may set errno to ERANGE if insufficient storage was supplied via
|
||||
'strerrbuf' and 'buflen' to contain the generated message string, or
|
||||
EINVAL if the value of 'errnum' is not a valid error number.*/
|
||||
#else
|
||||
{
|
||||
/* HAVE_GLIBC_STRERROR_R */
|
||||
char buffer[256];
|
||||
char *msg = strerror_r(err, buffer, sizeof(buffer));
|
||||
strncpy(buf, msg, max);
|
||||
}
|
||||
#endif /* end of HAVE_GLIBC_STRERROR_R */
|
||||
#else /* HAVE_STRERROR_R */
|
||||
strncpy(buf, strerror(err), max);
|
||||
#endif /* end of HAVE_STRERROR_R */
|
||||
#endif /* end of ! Windows */
|
||||
|
||||
buf[max] = '\0'; /* make sure the string is zero terminated */
|
||||
|
||||
/* strip trailing '\r\n' or '\n'. */
|
||||
if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
|
||||
*p = '\0';
|
||||
if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user