Compare commits
316 Commits
cares-1_1_
...
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 | ||
|
|
a5b206f398 | ||
|
|
306a05f9ff | ||
|
|
81f8350616 | ||
|
|
760ca6adc4 | ||
|
|
ffb35ff5c3 | ||
|
|
8eda06131b | ||
|
|
5b55f9ecb3 | ||
|
|
3417e0b0fc | ||
|
|
79ed144b0f | ||
|
|
8e5cf6589c | ||
|
|
fc67cca882 | ||
|
|
eea2287068 | ||
|
|
5fe5de7511 | ||
|
|
4a6b9972dd | ||
|
|
256a16a8a3 | ||
|
|
30e0891d3d | ||
|
|
8147ccdf76 | ||
|
|
26ab286630 | ||
|
|
738807883e | ||
|
|
03a0988ce8 | ||
|
|
7de892eeb4 | ||
|
|
8c4e91a653 | ||
|
|
8f77030473 | ||
|
|
546d0bd3d1 | ||
|
|
5d53b544d3 | ||
|
|
6dc8fac122 | ||
|
|
8114f8562b | ||
|
|
c79fa187b9 | ||
|
|
237ec68b0e | ||
|
|
4ebf4f6e55 | ||
|
|
4d86593f3c | ||
|
|
ec050ccbc4 | ||
|
|
f19cade50f | ||
|
|
a2f35aaf67 | ||
|
|
e5c4b6b345 | ||
|
|
bad978feb2 | ||
|
|
bea9152aa8 | ||
|
|
f788f988ea | ||
|
|
d04ffd258b | ||
|
|
24cfa7f1bb | ||
|
|
94a1d09ac7 | ||
|
|
230a75091b | ||
|
|
4ad68ec305 | ||
|
|
ef776ab893 | ||
|
|
f8ff0f6bef | ||
|
|
bc7122f6e2 | ||
|
|
e5963dae48 | ||
|
|
1ebda8fa0e | ||
|
|
9af532e662 | ||
|
|
9d064a3927 | ||
|
|
d6edcfb486 | ||
|
|
1d5a914c1c | ||
|
|
666bc9ee4e | ||
|
|
e545e33d5f | ||
|
|
326e8b9fc1 | ||
|
|
0d1fc73f21 | ||
|
|
50a1853560 | ||
|
|
35e158d80b | ||
|
|
7225b14002 | ||
|
|
85838a8966 | ||
|
|
d29590f583 | ||
|
|
467c3e3a1f |
1572
CHANGES.2003
Normal file
1572
CHANGES.2003
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,8 +24,7 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
|
||||
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh \
|
||||
RELEASE-NOTES
|
||||
curl-config.in curl-style.el sample.emacs testcurl.sh RELEASE-NOTES
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
|
||||
@@ -81,7 +81,9 @@ amiga:
|
||||
cd ./lib && make -f makefile.amiga
|
||||
cd ./src && make -f makefile.amiga
|
||||
|
||||
|
||||
netware:
|
||||
cd lib && make -f Makefile.netware
|
||||
cd src && make -f Makefile.netware
|
||||
|
||||
unix: all
|
||||
|
||||
|
||||
17
README
17
README
@@ -32,25 +32,30 @@ WEB SITE
|
||||
|
||||
Sweden -- http://curl.haxx.se/
|
||||
Australia -- http://curl.planetmirror.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 (TX) -- http://curl.cyberservers.net/
|
||||
US -- http://curl.signal42.com/
|
||||
|
||||
DOWNLOAD
|
||||
|
||||
The official download mirror sites are:
|
||||
|
||||
Australia -- http://curl.planetmirror.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/
|
||||
US (TX) -- http://curl.cyberservers.net/download/
|
||||
Thailand -- http://curl.siamu.ac.th/download.html
|
||||
US (CA) -- http://curl.mirror.redwire.net/download.html
|
||||
|
||||
CVS
|
||||
|
||||
|
||||
125
RELEASE-NOTES
125
RELEASE-NOTES
@@ -1,85 +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: 111
|
||||
Available curl_easy_setopt() options: 113
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
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 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.0.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
|
||||
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)
|
||||
|
||||
40
TODO-RELEASE
40
TODO-RELEASE
@@ -3,31 +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)
|
||||
|
||||
To get fixed in 7.12.0 (no date)
|
||||
======================
|
||||
|
||||
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
|
||||
25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
|
||||
Code already in CVS. Messages need overview/improvements.
|
||||
Medium prio.
|
||||
|
||||
10. Anton Fedorov's "dumpcert" patch (only mailed to me privately) UNASSIGNED
|
||||
26. i18n of error messages?
|
||||
Low prio. Nobody has volunteered. Subject for removal.
|
||||
|
||||
14. Evaluate/apply Gertjan van Wingerde's SSL patches, UNASSIGNED
|
||||
33. Add a function to replace the malloc-calls within libcurl.
|
||||
Low prio. Seshubabu Pasam works on this.
|
||||
|
||||
23. Peter Sylvester's "Most Significant Common Name" patch. Feedback welcome.
|
||||
At least the UTF8 conversion and comparison should be done. Patch?
|
||||
UNASSIGNED
|
||||
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.
|
||||
|
||||
24. Make the progress meter use one digit more for the hour time fields.
|
||||
Accomplish this by removing one of the times displayed.
|
||||
36. Add support for a threaded getaddrinfo() on Windows and IPv6 enabled
|
||||
libcurl.
|
||||
|
||||
To get fixed in 7.12.0
|
||||
======================
|
||||
37. Configure option "--with-libidn" to support IDNA (Internationalising
|
||||
Domain Names in Applications). Translate to/from ACE encoded domain
|
||||
names as needed.
|
||||
|
||||
25. curl_strerror()
|
||||
|
||||
26. i18n of error messages
|
||||
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.
|
||||
|
||||
@@ -5,3 +5,4 @@ adig
|
||||
ahost
|
||||
config.log
|
||||
config.status
|
||||
aclocal.m4
|
||||
|
||||
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.
@@ -1,69 +0,0 @@
|
||||
$!
|
||||
$
|
||||
$ on control_y then goto Common_Exit!
|
||||
$ orig = f$environment("DEFAULT")
|
||||
$ loc = f$environment("PROCEDURE")
|
||||
$ def = f$parse("X.X;1",loc) - "X.X;1"
|
||||
$
|
||||
$ set def 'def'
|
||||
$ cc_qual = "/define=HAVE_CONFIG_H=1/include=(""../include/"",""../"",""../../openssl-0_9_7/include/"")"
|
||||
$ if p1 .eqs. "LISTING" then cc_qual = cc_qual + "/LIST/MACHINE"
|
||||
$ if p1 .eqs. "DEBUG" then cc_qual = cc_qual + "/LIST/MACHINE/DEBUG"
|
||||
$ msg_qual = ""
|
||||
$ call build "[.lib]" "*.c"
|
||||
$ call build "[.src]" "*.c"
|
||||
$ call build "[.src]" "*.msg"
|
||||
$ link /exe=curl.exe [.src]curl/lib/include=main,[.lib]curl/lib, -
|
||||
[-.openssl-0_9_7.axp.exe.ssl]libssl/lib, -
|
||||
[-.openssl-0_9_7.axp.exe.crypto]libcrypto/lib
|
||||
$
|
||||
$
|
||||
$ goto Common_Exit
|
||||
$build: subroutine
|
||||
$ set noon
|
||||
$ set default 'p1'
|
||||
$ search = p2
|
||||
$ reset = f$search("reset")
|
||||
$ if f$search("CURL.OLB") .eqs. ""
|
||||
$ then
|
||||
$ LIB/CREATE/OBJECT CURL.OLB
|
||||
$ endif
|
||||
$ reset = f$search("reset",1)
|
||||
$Loop:
|
||||
$ file = f$search(search,1)
|
||||
$ if file .eqs. "" then goto EndLoop
|
||||
$ obj = f$search(f$parse(".OBJ;",file),2)
|
||||
$ if (obj .nes. "")
|
||||
$ then
|
||||
$ if (f$cvtime(f$file(file,"rdt")) .gts. f$cvtime(f$file(obj,"rdt")))
|
||||
$ then
|
||||
$ call compile 'file'
|
||||
$ lib/object curl.OLB 'f$parse(".obj;",file)'
|
||||
$ else
|
||||
$! write sys$output "File: ''file' is up to date"
|
||||
$ endif
|
||||
$ else
|
||||
$! write sys$output "Object for file: ''file' does not exist"
|
||||
$ call compile 'file'
|
||||
$ lib/object curl.OLB 'f$parse(".obj;",file)'
|
||||
$ endif
|
||||
$ goto Loop
|
||||
$EndLoop:
|
||||
$ purge
|
||||
$ set def 'def'
|
||||
$ endsubroutine ! Build
|
||||
$
|
||||
$compile: subroutine
|
||||
$ set noon
|
||||
$ file = p1
|
||||
$ qual = p2+p3+p4+p5+p6+p7+p8
|
||||
$ typ = f$parse(file,,,"TYPE") - "."
|
||||
$ cmd_c = "CC "+cc_qual
|
||||
$ cmd_msg = "MESSAGE "+msg_qual
|
||||
$ x = cmd_'typ'
|
||||
$ 'x' 'file'
|
||||
$ ENDSUBROUTINE ! Compile
|
||||
$
|
||||
$Common_Exit:
|
||||
$ set default 'orig'
|
||||
$ exit
|
||||
20
buildconf
20
buildconf
@@ -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."
|
||||
@@ -138,6 +138,20 @@ fi
|
||||
|
||||
echo "buildconf: libtool version $lt_version (ok)"
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# m4 check
|
||||
#
|
||||
m4=`${M4:-m4} --version 2>/dev/null|head -1`;
|
||||
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
|
||||
|
||||
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
|
||||
echo "buildconf: GNU m4 version $m4_version (ok)"
|
||||
else
|
||||
echo "buildconf: m4 version $m4 found. You need a GNU m4 installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
|
||||
# run the correct scripts now
|
||||
@@ -145,7 +159,7 @@ echo "buildconf: libtool version $lt_version (ok)"
|
||||
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"
|
||||
@@ -156,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 ..
|
||||
|
||||
75
configure.ac
75
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 **********************************************************************
|
||||
@@ -490,8 +492,8 @@ AC_HELP_STRING([--with-krb4=DIR],[where to look for Kerberos4]),[
|
||||
OPT_KRB4="$withval"
|
||||
if test X"$OPT_KRB4" != Xyes
|
||||
then
|
||||
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib"
|
||||
KRB4LIB="$OPT_KRB4/lib"
|
||||
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib$libsuff"
|
||||
KRB4LIB="$OPT_KRB4/lib$libsuff"
|
||||
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
|
||||
KRB4INC="$OPT_KRB4/include"
|
||||
fi
|
||||
@@ -627,7 +629,7 @@ if test x"$want_gss" = xyes; then
|
||||
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||
LDFLAGS="$LDFLAGS $gss_ldflags"
|
||||
else
|
||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib -lgssapi"
|
||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff -lgssapi"
|
||||
fi
|
||||
else
|
||||
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
|
||||
@@ -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.
|
||||
@@ -710,7 +712,7 @@ else
|
||||
*)
|
||||
dnl check the given spot right away!
|
||||
EXTRA_SSL=$OPT_SSL
|
||||
LDFLAGS="$LDFLAGS -L$EXTRA_SSL/lib"
|
||||
LDFLAGS="$LDFLAGS -L$EXTRA_SSL/lib$libsuff"
|
||||
CPPFLAGS="$CPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
|
||||
;;
|
||||
esac
|
||||
@@ -720,7 +722,7 @@ else
|
||||
],[
|
||||
OLDLDFLAGS="$LDFLAGS"
|
||||
OLDCPPFLAGS="$CPPFLAGS"
|
||||
LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib"
|
||||
LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib$libsuff"
|
||||
CPPFLAGS="$CLEANCPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
|
||||
AC_CHECK_LIB(crypto, CRYPTO_add_lock,[
|
||||
HAVECRYPTO="yes" ], [
|
||||
@@ -852,7 +854,7 @@ case "$OPT_ZLIB" in
|
||||
dnl if no lib found, try to add the given library
|
||||
[if test -d "$OPT_ZLIB"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include"
|
||||
LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib"
|
||||
LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff"
|
||||
fi])
|
||||
|
||||
AC_CHECK_HEADER(zlib.h,
|
||||
@@ -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)
|
||||
@@ -1268,6 +1322,7 @@ AC_CONFIG_FILES([Makefile \
|
||||
packages/DOS/Makefile \
|
||||
packages/EPM/curl.list \
|
||||
packages/EPM/Makefile \
|
||||
packages/vms/Makefile \
|
||||
curl-config
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -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 ...
|
||||
|
||||
43
docs/FAQ
43
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: December 22, 2003 (http://curl.haxx.se/docs/faq.html)
|
||||
Updated: March 16, 2004 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -90,7 +90,7 @@ FAQ
|
||||
with URL spelled in uppercase to make it obvious it deals with URLs. The
|
||||
fact it can also be pronounced 'see URL' also helped, it works as an
|
||||
abbrivation for "Client URL Request Library" or why not the recursive
|
||||
version: "Curl is a URL Request Library".
|
||||
version: "Curl URL Request Library".
|
||||
|
||||
Curl supports a range of common Internet protocols, currently including
|
||||
HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE.
|
||||
@@ -101,7 +101,7 @@ FAQ
|
||||
NOTE: there are numerous sub-projects and related projects that also use the
|
||||
word curl in the project names in various combinations, but you should take
|
||||
notice that this FAQ is directed at the command-line tool named curl (and
|
||||
libcurl the library), and may therefore not be valid for other curl
|
||||
libcurl the library), and may therefore not be valid for other curl-related
|
||||
projects.
|
||||
|
||||
1.2 What is libcurl?
|
||||
@@ -109,16 +109,16 @@ FAQ
|
||||
libcurl is a reliable and portable library which provides you with an easy
|
||||
interface to a range of common Internet protocols.
|
||||
|
||||
You can use libcurl for free in your application even if it is commercial
|
||||
or closed-source.
|
||||
You can use libcurl for free in your application, be it open source,
|
||||
commercial or closed-source.
|
||||
|
||||
1.3 What is cURL not?
|
||||
|
||||
Curl is *not* a wget clone even though that is a very common misconception.
|
||||
Never, during curl's development, have we intended curl to replace wget or
|
||||
compete on its market. Curl is targeted at single-shot file transfers.
|
||||
Curl is *not* a wget clone. That is a common misconception. Never, during
|
||||
curl's development, have we intended curl to replace wget or compete on its
|
||||
market. Curl is targeted at single-shot file transfers.
|
||||
|
||||
Curl is not a web site mirroring program. If you wanna use curl to mirror
|
||||
Curl is not a web site mirroring program. If you want to use curl to mirror
|
||||
something: fine, go ahead and write a script that wraps around curl to make
|
||||
it reality (like curlmirror.pl does).
|
||||
|
||||
@@ -181,9 +181,8 @@ FAQ
|
||||
curl. We do this voluntarily on our spare time.
|
||||
|
||||
We get some help from companies. Contactor Data hosts the curl web site,
|
||||
Haxx owns the curl web site's domain and sourceforge.net hosts several
|
||||
project services we take advantage from, like the bug tracker, mailing lists
|
||||
and more.
|
||||
Haxx owns the curl web site's domain and sourceforge.net hosts project
|
||||
services we take advantage from, like the bug tracker.
|
||||
|
||||
If you want to support our project with a donation or similar, one way of
|
||||
doing that would be to buy "gift certificates" at useful online shopping
|
||||
@@ -281,8 +280,7 @@ FAQ
|
||||
|
||||
2.4. Does cURL support Socks (RFC 1928) ?
|
||||
|
||||
There is limited support for SOCKS5 for curl built with IPv6 support
|
||||
disabled.
|
||||
Yes, SOCKS5 is supported when curl is built with IPv6 support disabled.
|
||||
|
||||
|
||||
3. Usage problems
|
||||
@@ -478,7 +476,7 @@ FAQ
|
||||
requests properly. To correct this problem, tell curl to select SSLv2 from
|
||||
the command line (-2/--sslv2).
|
||||
|
||||
There has also been examples where the remote server didn't like the SSLv2
|
||||
There have also been examples where the remote server didn't like the SSLv2
|
||||
request and instead you had to force curl to use SSLv3 with -3/--sslv3.
|
||||
|
||||
4.2. Why do I get problems when I use & or % in the URL?
|
||||
@@ -577,21 +575,26 @@ FAQ
|
||||
|
||||
The first part is to avoid having clear-text passwords in the command line
|
||||
so that they don't appear in 'ps' outputs and similar. That is easily
|
||||
avoided by using the "-K" option to tell curl to read parameters from a
|
||||
file or stdin to which you can pass the secret info.
|
||||
avoided by using the "-K" option to tell curl to read parameters from a file
|
||||
or stdin to which you can pass the secret info. curl itself will also
|
||||
attempt to "hide" the given password by blanking out the option - this
|
||||
doesn't work on all platforms.
|
||||
|
||||
To keep the passwords in your account secret from the rest of the world is
|
||||
not a task that curl addresses. You could of course encrypt them somehow to
|
||||
at least hide them from being read by human eyes, but that is not what
|
||||
anyone would call security.
|
||||
|
||||
Also note that regular HTTP and FTP passwords are sent in clear across the
|
||||
network. All it takes for anyone to fetch them is to listen on the network.
|
||||
Eavesdropping is very easy.
|
||||
Also note that regular HTTP (using Basic authentication) and FTP passwords
|
||||
are sent in clear across the network. All it takes for anyone to fetch them
|
||||
is to listen on the network. Eavesdropping is very easy. Use more secure
|
||||
authentication methods (like Digest, Negotiate or even NTLM) or consider the
|
||||
SSL-based alternatives HTTPS and FTPS.
|
||||
|
||||
4.8 I found a bug!
|
||||
|
||||
It is not a bug if the behavior is documented. Read the docs first.
|
||||
Especially check out the KNOWN_BUGS file, it may be a documented bug!
|
||||
|
||||
If it is a problem with a binary you've downloaded or a package for your
|
||||
particular platform, try contacting the person who built the package/archive
|
||||
|
||||
@@ -511,6 +511,7 @@ PORTS
|
||||
- i386 HURD
|
||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
||||
- i386 NetBSD
|
||||
- i386 Novell NetWare
|
||||
- i386 OS/2
|
||||
- i386 OpenBSD
|
||||
- i386 SCO unix
|
||||
|
||||
@@ -3,6 +3,10 @@ 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!
|
||||
|
||||
* --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
|
||||
manually for HTTP PUT resume to work, and then '-C [index]'.
|
||||
@@ -19,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:
|
||||
@@ -35,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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Peer SSL Certificate Verification
|
||||
=================================
|
||||
|
||||
Starting in 7.10, libcurl performs peer SSL certificate verification by
|
||||
Since version 7.10, libcurl performs peer SSL certificate verification by
|
||||
default. This is done by installing a default CA cert bundle on 'make install'
|
||||
(or similar), that CA bundle package is used by default on operations against
|
||||
SSL servers.
|
||||
@@ -11,9 +11,11 @@ by CAs present in the bundle, you will not notice any changed behavior and you
|
||||
will seamlessly get a higher security level on your SSL connections since you
|
||||
can be sure that the remote server really is the one it claims to be.
|
||||
|
||||
If the remote server uses a self-signed certificate, or if you don't install
|
||||
curl's CA cert bundle or if it uses a certificate signed by a CA that isn't
|
||||
included in the bundle, then you need to do one of the following:
|
||||
If the remote server uses a self-signed certificate, if you don't install
|
||||
curl's CA cert bundle, if the server uses a certificate signed by a CA that
|
||||
isn't included in the bundle or if the remoste host is an imposter
|
||||
impersonating your favourite site, and you want to transfer files from this
|
||||
server, do one of the following:
|
||||
|
||||
1. Tell libcurl to *not* verify the peer. With libcurl you disable with with
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
@@ -26,6 +28,12 @@ included in the bundle, then you need to 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")
|
||||
@@ -37,3 +45,4 @@ trouble for some users, since it adds security to a majority of the SSL
|
||||
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.
|
||||
|
||||
|
||||
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!
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_easy_setopt 3 "27 Feb 2004" "libcurl 7.11.1" "libcurl Manual"
|
||||
.TH curl_easy_setopt 3 "12 Mar 2004" "libcurl 7.11.1" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_easy_setopt - set options for a curl easy handle
|
||||
.SH SYNOPSIS
|
||||
@@ -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.
|
||||
@@ -464,6 +480,11 @@ If you want to post data to the server without letting libcurl do a strlen()
|
||||
to measure the data size, this option must be used. When this option is used
|
||||
you can post fully binary data, which otherwise is likely to fail. If this
|
||||
size is set to zero, the library will use strlen() to get the size.
|
||||
.IP CURLOPT_POSTFIELDSIZE_LARGE
|
||||
Pass a curl_off_t as parameter. Use this to set the size of the
|
||||
\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the
|
||||
data to figure out the size. This is the large file version of the
|
||||
\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1)
|
||||
.IP CURLOPT_HTTPPOST
|
||||
Tells libcurl you want a multipart/formdata HTTP POST to be made and you
|
||||
instruct what data to pass on to the server. Pass a pointer to a linked list
|
||||
@@ -524,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.
|
||||
@@ -617,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
|
||||
@@ -679,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.
|
||||
@@ -858,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,
|
||||
@@ -899,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.
|
||||
|
||||
@@ -9,11 +9,22 @@ curl_multi_add_handle - add an easy handle to a multi session
|
||||
CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
Adds a standard easy handle to the multi stack. This will make this multi
|
||||
handle control the specified easy handle.
|
||||
Adds a standard easy handle to the multi stack. This function call will make
|
||||
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 curl_easy_perform() on that handle!
|
||||
not use \fIcurl_easy_perform(3)\fP on that handle!
|
||||
|
||||
The easy handle will remain added until you remove it again with
|
||||
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
|
||||
multi stack before you terminate first the easy handle and then the multi
|
||||
handle:
|
||||
|
||||
1 - \fIcurl_multi_remove_handle(3)\fP
|
||||
|
||||
2 - \fIcurl_easy_cleanup(3)\fP
|
||||
|
||||
3 - \fIcurl_multi_cleanup(3)\fP
|
||||
.SH RETURN VALUE
|
||||
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 curl_easy_cleanup() 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,14 +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.
|
||||
CURLMcode type, general libcurl multi interface error code. See
|
||||
\fIlibcurl-errors(3)\fP
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)"
|
||||
|
||||
@@ -21,13 +21,14 @@ integer pointed to with \fImsgs_in_queue\fP will contain the number of
|
||||
remaining messages after this function was called.
|
||||
|
||||
The data the returned pointer points to will not survive calling
|
||||
curl_multi_cleanup().
|
||||
\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
|
||||
curl_easy_getinfo() calls (or similar):
|
||||
\fIcurl_easy_getinfo(3)\fP calls (or similar):
|
||||
|
||||
.NF
|
||||
struct CURLMsg {
|
||||
CURLMSG msg; /* what this message means */
|
||||
CURL *easy_handle; /* the handle it concerns */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.\"
|
||||
.TH curl_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_multi_init - Start a multi session
|
||||
curl_multi_init - create a multi handle
|
||||
.SH SYNOPSIS
|
||||
.B #include <curl/curl.h>
|
||||
.sp
|
||||
@@ -10,13 +10,12 @@ curl_multi_init - Start a multi session
|
||||
.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\fP when the operation is complete.
|
||||
\fIcurl_multi_cleanup(3)\fP when the operation is complete.
|
||||
.SH RETURN VALUE
|
||||
If this function returns NULL, something went wrong and you cannot use the
|
||||
other curl functions.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)"
|
||||
.SH BUGS
|
||||
Surely there are some, you tell me!
|
||||
|
||||
|
||||
@@ -19,18 +19,19 @@ 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\fP to get the multi_handle's
|
||||
Most application will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
||||
file descriptors, then it'll wait for action on them using select() and as
|
||||
soon as one or more of them are ready, \fIcurl_multi_perform\fP gets called.
|
||||
soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
|
||||
called.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)"
|
||||
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)," curl_multi_fdset "(3)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,21 +9,21 @@ libcurl-easy \- easy interface overview
|
||||
When using libcurl's "easy" interface you init your session and get a handle
|
||||
(often referred to as an "easy handle" in various docs and sources), which you
|
||||
use as input to the easy interface functions you use. Use
|
||||
\fIcurl_easy_init()\fP to get the handle.
|
||||
\fIcurl_easy_init(3)\fP to get the handle.
|
||||
|
||||
You continue by setting all the options you want in the upcoming transfer, the
|
||||
most important among them is the URL itself (you can't transfer anything
|
||||
without a specified URL as you may have figured out yourself). You might want
|
||||
to set some callbacks as well that will be called from the library when data
|
||||
is available etc. \fIcurl_easy_setopt()\fP is used for all this.
|
||||
is available etc. \fIcurl_easy_setopt(3)\fP is used for all this.
|
||||
|
||||
When all is setup, you tell libcurl to perform the transfer using
|
||||
\fIcurl_easy_perform()\fP. It will then do the entire operation and won't
|
||||
\fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't
|
||||
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()\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.
|
||||
|
||||
@@ -32,7 +32,7 @@ complicated for the application.
|
||||
file descriptors simultaneous easily.
|
||||
.SH "ONE MULTI HANDLE MANY EASY HANDLES"
|
||||
To use the multi interface, you must first create a 'multi handle' with
|
||||
\fIcurl_multi_init\fP. This handle is then used as input to all further
|
||||
\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
|
||||
curl_multi_* functions.
|
||||
|
||||
Each single transfer is built up with an easy handle. You must create them,
|
||||
@@ -40,29 +40,29 @@ and setup the appropriate options for each easy handle, as outlined in the
|
||||
\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
|
||||
|
||||
When the easy handle is setup for a transfer, then instead of using
|
||||
\fIcurl_easy_perform\fP (as when using the easy interface for transfers), you
|
||||
should instead add the easy handle to the multi handle using
|
||||
\fIcurl_easy_add_handl\fP. The multi handle is sometimes referred to as a
|
||||
\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers),
|
||||
you should instead add the easy handle to the multi handle using
|
||||
\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
|
||||
\'multi stack\' because of the fact that it may hold a large amount of easy
|
||||
handles.
|
||||
|
||||
Should you change your mind, the easy handle is again removed from the multi
|
||||
stack using \fIcurl_multi_remove_handle\fP. Once removed from the multi
|
||||
stack using \fIcurl_multi_remove_handle(3)\fP. Once removed from the multi
|
||||
handle, you can again use other easy interface functions like
|
||||
\fIcurl_easy_perform\fP on the handle or whatever you think is necessary.
|
||||
\fIcurl_easy_perform(3)\fP on the handle or whatever you think is necessary.
|
||||
|
||||
Adding the easy handle to the multi handle does not start the transfer.
|
||||
Remember that one of the main ideas with this interface is to let your
|
||||
application drive. You drive the transfers by invoking
|
||||
\fIcurl_multi_perform\fP. libcurl will then transfer data if there is anything
|
||||
available to transfer. It'll use the callbacks and everything else you have
|
||||
setup in the individual easy handles. It'll transfer data on all current
|
||||
transfers in the multi stack that are ready to transfer anything. It may be
|
||||
all, it may be none.
|
||||
\fIcurl_multi_perform(3)\fP. libcurl will then transfer data if there is
|
||||
anything available to transfer. It'll use the callbacks and everything else
|
||||
you have setup in the individual easy handles. It'll transfer data on all
|
||||
current transfers in the multi stack that are ready to transfer anything. It
|
||||
may be all, it may be none.
|
||||
|
||||
Your application can acquire knowledge from libcurl when it would like to get
|
||||
invoked to transfer data, so that you don't have to busy-loop and call that
|
||||
\fIcurl_multi_perform\fP like crazy. \fIcurl_multi_fdset\fP offers an
|
||||
\fIcurl_multi_perform(3)\fP like crazy. \fIcurl_multi_fdset(3)\fP offers an
|
||||
interface using which you can extract fd_sets from libcurl to use in select()
|
||||
or poll() calls in order to get to know when the transfers in the multi stack
|
||||
might need attention. This also makes it very easy for your program to wait
|
||||
@@ -70,31 +70,31 @@ for input on your own private file descriptors at the same time or perhaps
|
||||
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\fP: if you receive
|
||||
\fICURLM_CALL_MULTI_PERFORM\fP, this basicly 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
|
||||
especially the \fIcurl_multi_perform(3)\fP: if you receive
|
||||
\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
|
||||
before it is "satisfied".
|
||||
|
||||
\fIcurl_multi_perform\fP stores the number of still running transfers in one
|
||||
of its input arguments, and by reading that you can figure out when all the
|
||||
transfers in the multi handles are done. 'done' does not mean successful. One
|
||||
or more of the transfers may have failed. Tracking when this number changes,
|
||||
you know when one or more transfers are done.
|
||||
\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
|
||||
one of its input arguments, and by reading that you can figure out when all
|
||||
the transfers in the multi handles are done. 'done' does not mean
|
||||
successful. One or more of the transfers may have failed. Tracking when this
|
||||
number changes, you know when one or more transfers are done.
|
||||
|
||||
To get information about completed transfers, to figure out success or not and
|
||||
similar, \fIcurl_multi_info_read\fP should be called. It can return a message
|
||||
about a current or previous transfer. Repeated invokes of the function get
|
||||
more messages until the message queue is empty. The information you receive
|
||||
there includes an easy handle pointer which you may use to identify which easy
|
||||
handle the information regards.
|
||||
similar, \fIcurl_multi_info_read(3)\fP should be called. It can return a
|
||||
message about a current or previous transfer. Repeated invokes of the function
|
||||
get more messages until the message queue is empty. The information you
|
||||
receive there includes an easy handle pointer which you may use to identify
|
||||
which easy handle the information regards.
|
||||
|
||||
When all transfers in the multi stack are done, cleanup the multi handle with
|
||||
\fIcurl_multi_cleanup\fP. Be careful and please note that you \fBMUST\fP
|
||||
invoke separate \fIcurl_easy_cleanup\fP calls on every single easy handle to
|
||||
clean them up properly.
|
||||
\fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP
|
||||
invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle
|
||||
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).
|
||||
|
||||
@@ -20,27 +20,27 @@ You can have multiple easy handles share data between them. Have them update
|
||||
and use the \fBsame\fP cookie database or DNS cache! This way, each single
|
||||
transfer will take advantage from data updates made by the other transfer(s).
|
||||
.SH "SHARE OBJECT"
|
||||
You create a shared object with \fIcurl_share_init()\fP. It returns a handle
|
||||
You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
|
||||
for a newly created one.
|
||||
|
||||
You tell the shared object what data you want it to share by using
|
||||
\fIcurl_share_setopt()\fP. Currently you can only share DNS and/or COOKIE
|
||||
\fIcurl_share_setopt(3)\fP. Currently you can only share DNS and/or COOKIE
|
||||
data.
|
||||
|
||||
Since you can use this share from multiple threads, and libcurl has no
|
||||
internal thread synchronization, you must provide mutex callbacks if you're
|
||||
using this multi-threaded. You set lock and unlock functions with
|
||||
\fIcurl_share_setopt()\fP too.
|
||||
\fIcurl_share_setopt(3)\fP too.
|
||||
|
||||
Then, you make an easy handle to use this share, you set the CURLOPT_SHARE
|
||||
option with \fIcurl_easy_setopt\fP, and pass in share handle. You can make any
|
||||
number of easy handles share the same share handle.
|
||||
Then, you make an easy handle to use this share, you set the
|
||||
\fICURLOPT_SHARE\fP option with \fIcurl_easy_setopt(3)\fP, and pass in share
|
||||
handle. You can make any number of easy handles share the same share handle.
|
||||
|
||||
To make an easy handle stop using that particular share, you set CURLOPT_SHARE
|
||||
to NULL for that easy handle. To make a handle stop sharing a particular data,
|
||||
you can CURLSHOPT_UNSHARE it.
|
||||
To make an easy handle stop using that particular share, you set
|
||||
\fICURLOPT_SHARE\fP to NULL for that easy handle. To make a handle stop
|
||||
sharing a particular data, you can \fICURLSHOPT_UNSHARE\fP it.
|
||||
|
||||
When you're done using the share, make sure that no easy handle is still using
|
||||
it, and call \fIcurl_share_cleanup()\fP on the handle.
|
||||
it, and call \fIcurl_share_cleanup(3)\fP on the handle.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_share_init "(3), " curl_share_setopt "(3), " curl_share_cleanup "(3)"
|
||||
|
||||
@@ -8,37 +8,36 @@ libcurl \- client-side URL transfers
|
||||
.SH DESCRIPTION
|
||||
This is an overview on how to use libcurl in your C programs. There are
|
||||
specific man pages for each function mentioned in here. There are also the
|
||||
\fIlibcurl-easy\fP man page, the \fIlibcurl-multi\fP man page, the
|
||||
\fIlibcurl-share\fP man page and the \fIlibcurl-the-guide\fP document for
|
||||
\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
|
||||
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-the-guide\fP document for
|
||||
further reading on how to do programming with libcurl.
|
||||
|
||||
There exist more than a dozen custom bindings that bring libcurl access to
|
||||
your favourite language. Look elsewhere for documentation on those.
|
||||
|
||||
All applications that use libcurl should call \fIcurl_global_init()\fP exactly
|
||||
once before any libcurl function can be used. After all usage of libcurl is
|
||||
complete, it \fBmust\fP call \fIcurl_global_cleanup()\fP. In between those two
|
||||
calls, you can use libcurl as described below.
|
||||
All applications that use libcurl should call \fIcurl_global_init(3)\fP
|
||||
exactly once before any libcurl function can be used. After all usage of
|
||||
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()\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\fP and let it perform the transfer. When it is completed,
|
||||
the function return and you can continue. More details are found in the
|
||||
.BR "libcurl-easy (3)"
|
||||
man page.
|
||||
\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
|
||||
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.
|
||||
|
||||
You can have multiple easy handles share certain data, even if they are used
|
||||
in different threads. This magic is setup using the share interface, as
|
||||
described in the \fIlibcurl-share\fP man page.
|
||||
described in the \fIlibcurl-share(3)\fP man page.
|
||||
|
||||
There is also a series of other helpful functions to use. They are:
|
||||
|
||||
@@ -57,10 +56,10 @@ 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 curl_formparse()/curl_formadd()
|
||||
free a list built with \fIcurl_formadd(3)\fP
|
||||
.TP
|
||||
.B curl_slist_append()
|
||||
builds a linked list
|
||||
@@ -102,20 +101,20 @@ Never ever call curl-functions simultaneously using the same handle from
|
||||
several threads. libcurl is thread-safe and can be used in any number of
|
||||
threads, but you must use separate curl handles if you want to use libcurl in
|
||||
more than one thread simultaneously.
|
||||
.SH "PERSISTANT CONNECTIONS"
|
||||
.SH "PERSISTENT CONNECTIONS"
|
||||
Persistent connections means that libcurl can re-use the same connection for
|
||||
several transfers, if the conditions are right.
|
||||
|
||||
libcurl will *always* attempt to use persistent connections. Whenever you use
|
||||
\fIcurl_easy_perform()\fP or \fIcurl_multi_perform()\fP, libcurl will attempt
|
||||
to use an existing connection to do the transfer, and if none exists it'll
|
||||
open a new one that will be subject for re-use on a possible following call to
|
||||
\fIcurl_easy_perform()\fP or \fIcurl_multi_perform()\fP.
|
||||
libcurl will \fBalways\fP attempt to use persistent connections. Whenever you
|
||||
use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP, libcurl will
|
||||
attempt to use an existing connection to do the transfer, and if none exists
|
||||
it'll open a new one that will be subject for re-use on a possible following
|
||||
call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
|
||||
|
||||
To allow libcurl to take full advantage of persistent connections, you should
|
||||
do as many of your file transfers as possible using the same curl handle. When
|
||||
you call \fIcurl_easy_cleanup()\fP, all the possibly open connections held by
|
||||
you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
|
||||
libcurl will be closed and forgotten.
|
||||
|
||||
Note that the options set with \fIcurl_easy_setopt()\fP will be used in on
|
||||
every repeated \fIcurl_easy_perform()\fP call.
|
||||
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used in on
|
||||
every repeated \fIcurl_easy_perform(3)\fP call.
|
||||
|
||||
@@ -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>
|
||||
@@ -783,6 +759,12 @@ typedef enum {
|
||||
*/
|
||||
CINIT(FTP_SSL, LONG, 119),
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -801,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 */
|
||||
@@ -1087,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
|
||||
@@ -1263,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 */
|
||||
@@ -55,10 +55,10 @@
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
|
||||
#ifdef _AIX
|
||||
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||
libc5-based Linux systems. Only include it on system that are known to
|
||||
require it! */
|
||||
#if defined(_AIX) || defined(NETWARE)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
@@ -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,16 +1,34 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
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 \
|
||||
config-amigaos.h amigaos.c amigaos.h makefile.amiga
|
||||
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 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
|
||||
|
||||
lib_LTLIBRARIES = libcurl.la
|
||||
|
||||
@@ -37,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
|
||||
@@ -62,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 \
|
||||
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 \
|
||||
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 \
|
||||
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
|
||||
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 \
|
||||
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 \
|
||||
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 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
|
||||
|
||||
########################################################
|
||||
|
||||
277
lib/Makefile.netware
Normal file
277
lib/Makefile.netware
Normal file
@@ -0,0 +1,277 @@
|
||||
#################################################################
|
||||
#
|
||||
## Makefile for building libcurl.nlm (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
#
|
||||
#################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Novell NDK.
|
||||
BASE = c:/novell
|
||||
INSTDIR = s:/libcurl
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ZLIB_PATH = ../../../cw/zlib-src-1.1.4
|
||||
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = libcurl
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (c) 1996 - 2004, Daniel Stenberg, <daniel@haxx.se>
|
||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
SCREEN = none
|
||||
#MODULES = libz.nlm
|
||||
EXPORTS = @libcurl.imp
|
||||
|
||||
# Edit the var below to point to your lib architecture.
|
||||
ifndef LIBARCH
|
||||
LIBARCH = LIBC
|
||||
endif
|
||||
|
||||
# must be equal to DEBUG or NDEBUG
|
||||
DB = NDEBUG
|
||||
# DB = DEBUG
|
||||
# Optimization: -O<n> or debugging: -g
|
||||
ifeq ($(DB),NDEBUG)
|
||||
OPT = -O2
|
||||
OBJDIR = release
|
||||
else
|
||||
OPT = -g
|
||||
OBJDIR = debug
|
||||
endif
|
||||
|
||||
# Include the version info retrieved from jk_version.h
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# The following line defines your compiler.
|
||||
ifdef METROWERKS
|
||||
CC = mwccnlm
|
||||
else
|
||||
CC = gcc
|
||||
endif
|
||||
# RM = rm -f
|
||||
# CP = cp -fv
|
||||
# if you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.de/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
|
||||
#CFLAGS += -DHAVE_LIBZ
|
||||
|
||||
ifeq ($(CC),mwccnlm)
|
||||
LD = mwldnlm
|
||||
LDFLAGS = -nostdlib $(PRELUDE) $(OBJDIR)/*.o -o $(OBJDIR)/$(TARGET).nlm -commandfile
|
||||
CFLAGS += -gccinc -inline off -opt nointrinsics
|
||||
CFLAGS += -relax_pointers
|
||||
#CFLAGS += -w on
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
|
||||
CFLAGS += -align 4 -inst mmx -proc 686
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
# CFLAGS += -D__ANSIC__
|
||||
else
|
||||
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
|
||||
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
|
||||
CFLAGS += -align 1 -proc 586
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||
CFLAGS += -D_POSIX_SOURCE
|
||||
# CFLAGS += -D__ANSIC__
|
||||
else
|
||||
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
|
||||
CFLAGS += -include $(BASE)/nlmconv/genlm.h
|
||||
endif
|
||||
endif
|
||||
|
||||
LDLIBS =
|
||||
|
||||
NDK_ROOT = $(BASE)/ndk
|
||||
SDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
SDK_LIBC = $(NDK_ROOT)/libc
|
||||
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
|
||||
CURL_INC = ../include
|
||||
|
||||
INCLUDES = -I$(CURL_INC)
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
|
||||
INCLUDES += -I$(SDK_LIBC)/include/winsock
|
||||
INCLUDES += -I$(SDK_LDAP)/libc/inc
|
||||
else
|
||||
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
|
||||
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
|
||||
INCLUDES += -I$(SDK_LDAP)/clib/inc
|
||||
CFLAGS += -DNETDB_USE_INTERNET
|
||||
endif
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
ifeq ($(MTSAFE),YES)
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(OSTYPE),linux)
|
||||
DL = '
|
||||
-include $(BASE)/nlmconv/ncpfs.inc
|
||||
endif
|
||||
|
||||
OBJS = \
|
||||
$(OBJDIR)/file.o \
|
||||
$(OBJDIR)/timeval.o \
|
||||
$(OBJDIR)/base64.o \
|
||||
$(OBJDIR)/hostip.o \
|
||||
$(OBJDIR)/progress.o \
|
||||
$(OBJDIR)/formdata.o \
|
||||
$(OBJDIR)/cookie.o \
|
||||
$(OBJDIR)/http.o \
|
||||
$(OBJDIR)/sendf.o \
|
||||
$(OBJDIR)/ftp.o \
|
||||
$(OBJDIR)/url.o \
|
||||
$(OBJDIR)/dict.o \
|
||||
$(OBJDIR)/if2ip.o \
|
||||
$(OBJDIR)/speedcheck.o \
|
||||
$(OBJDIR)/getdate.o \
|
||||
$(OBJDIR)/transfer.o \
|
||||
$(OBJDIR)/ldap.o \
|
||||
$(OBJDIR)/ssluse.o \
|
||||
$(OBJDIR)/version.o \
|
||||
$(OBJDIR)/getenv.o \
|
||||
$(OBJDIR)/escape.o \
|
||||
$(OBJDIR)/mprintf.o \
|
||||
$(OBJDIR)/telnet.o \
|
||||
$(OBJDIR)/netrc.o \
|
||||
$(OBJDIR)/getinfo.o \
|
||||
$(OBJDIR)/strequal.o \
|
||||
$(OBJDIR)/easy.o \
|
||||
$(OBJDIR)/security.o \
|
||||
$(OBJDIR)/krb4.o \
|
||||
$(OBJDIR)/memdebug.o \
|
||||
$(OBJDIR)/http_chunks.o \
|
||||
$(OBJDIR)/strtok.o \
|
||||
$(OBJDIR)/connect.o \
|
||||
$(OBJDIR)/hash.o \
|
||||
$(OBJDIR)/llist.o \
|
||||
$(OBJDIR)/multi.o \
|
||||
$(OBJDIR)/share.o \
|
||||
$(OBJDIR)/content_encoding.o \
|
||||
$(OBJDIR)/http_digest.o \
|
||||
$(OBJDIR)/http_negotiate.o \
|
||||
$(OBJDIR)/http_ntlm.o \
|
||||
$(OBJDIR)/md5.o \
|
||||
$(OBJDIR)/strtoofft.o \
|
||||
$(OBJDIR)/nwlib.o
|
||||
|
||||
|
||||
all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
@echo Compiling $<
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curl.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@awk -f ../packages/netware/get_ver.awk $< > $@
|
||||
|
||||
dist: all
|
||||
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
|
||||
-$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA)
|
||||
# -$(CP) ../changes.txt $(OBJDIR)/
|
||||
|
||||
install: all
|
||||
@[ -d $(INSTDIR) ] || mkdir $(INSTDIR)
|
||||
@$(CP) $(TARGET).nlm $(INSTDIR)
|
||||
|
||||
clean:
|
||||
-$(RM) -r $(OBJDIR)
|
||||
|
||||
$(OBJDIR):
|
||||
@mkdir $(OBJDIR)
|
||||
|
||||
$(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)#$(DL) >> $@
|
||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
||||
@echo $(DL)description "$(DESCR)"$(DL) >> $@
|
||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||
ifdef NLMTYPE
|
||||
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
|
||||
endif
|
||||
ifdef STACK
|
||||
@echo $(DL)stack $(STACK)$(DL) >> $@
|
||||
endif
|
||||
ifdef SCREEN
|
||||
@echo $(DL)screenname "$(SCREEN)"$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(DB),DEBUG)
|
||||
@echo $(DL)debug$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@
|
||||
ifdef XDCDATA
|
||||
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)start _Prelude$(DL) >> $@
|
||||
@echo $(DL)exit _Stop$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module clib$(DL) >> $@
|
||||
else
|
||||
ifeq ($(LD),nlmconv)
|
||||
@echo $(DL)flag_on 64$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)autounload$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)pseudopreemption$(DL) >> $@
|
||||
@echo $(DL)start _LibCPrelude$(DL) >> $@
|
||||
@echo $(DL)exit _LibCPostlude$(DL) >> $@
|
||||
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
|
||||
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
|
||||
@echo $(DL)module libc$(DL) >> $@
|
||||
endif
|
||||
ifdef MODULES
|
||||
@echo $(DL)module $(MODULES)$(DL) >> $@
|
||||
endif
|
||||
ifdef EXPORTS
|
||||
@echo $(DL)export $(EXPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifdef IMPORTS
|
||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||
endif
|
||||
ifeq ($(LD),nlmconv)
|
||||
@echo $(DL)input $(OBJS)$(DL) >> $@
|
||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
||||
endif
|
||||
|
||||
@@ -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.
|
||||
485
lib/config-netware.h
Normal file
485
lib/config-netware.h
Normal file
@@ -0,0 +1,485 @@
|
||||
/* lib/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* to disable DICT */
|
||||
#undef CURL_DISABLE_DICT
|
||||
|
||||
/* to disable FILE */
|
||||
#undef CURL_DISABLE_FILE
|
||||
|
||||
/* to disable FTP */
|
||||
#undef CURL_DISABLE_FTP
|
||||
|
||||
/* to disable GOPHER */
|
||||
#undef CURL_DISABLE_GOPHER
|
||||
|
||||
/* to disable HTTP */
|
||||
#undef CURL_DISABLE_HTTP
|
||||
|
||||
/* to disable LDAP */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
/* to disable TELNET */
|
||||
#undef CURL_DISABLE_TELNET
|
||||
|
||||
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||
#undef DISABLED_THREADSAFE
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
#undef EGD_SOCKET
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#undef ENABLE_IPV6
|
||||
|
||||
/* Define to 1 if you have the <alloca.h> header file. */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
#undef HAVE_CLOSESOCKET
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
#undef HAVE_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
#undef HAVE_DES_H
|
||||
|
||||
/* disabled non-blocking sockets */
|
||||
#undef HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* XXX: #undef HAVE_DLFCN_H */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `dlopen' function. */
|
||||
#define HAVE_DLOPEN 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* use FIONBIO for non-blocking sockets */
|
||||
/* XXX: #undef HAVE_FIONBIO */
|
||||
#define HAVE_FIONBIO 1
|
||||
|
||||
/* Define if getaddrinfo exists and works */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr' function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the `gethostbyaddr_r' function. */
|
||||
#undef HAVE_GETHOSTBYADDR_R
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_5
|
||||
|
||||
/* gethostbyaddr_r() takes 7 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_7
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#undef HAVE_GETHOSTBYADDR_R_8
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
/* gethostbyname_r() takes 3 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_3
|
||||
|
||||
/* gethostbyname_r() takes 5 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_5
|
||||
|
||||
/* gethostbyname_r() takes 6 args */
|
||||
#undef HAVE_GETHOSTBYNAME_R_6
|
||||
|
||||
/* Define to 1 if you have the `getpass_r' function. */
|
||||
#undef HAVE_GETPASS_R
|
||||
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#undef HAVE_GETPWUID
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* if you have the gssapi libraries */
|
||||
#undef HAVE_GSSAPI
|
||||
|
||||
/* if you have the Heimdal gssapi libraries */
|
||||
#undef HAVE_GSSHEIMDAL
|
||||
|
||||
/* if you have the MIT gssapi libraries */
|
||||
#undef HAVE_GSSMIT
|
||||
|
||||
/* Define to 1 if you have the `inet_addr' function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||
#define HAVE_INET_NTOA 1
|
||||
|
||||
/* Define to 1 if you have the `inet_ntoa_r' function. */
|
||||
#undef HAVE_INET_NTOA_R
|
||||
|
||||
/* inet_ntoa_r() is declared */
|
||||
#undef HAVE_INET_NTOA_R_DECL
|
||||
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* use ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET
|
||||
|
||||
/* use Ioctlsocket() for non-blocking sockets */
|
||||
#undef HAVE_IOCTLSOCKET_CASE
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||
#undef HAVE_KRB4
|
||||
|
||||
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
||||
|
||||
/* Define to 1 if you have the <krb.h> header file. */
|
||||
#undef HAVE_KRB_H
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#undef HAVE_LIBCRYPTO
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define to 1 if you have the `nsl' library (-lnsl). */
|
||||
#undef HAVE_LIBNSL
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
#undef HAVE_LIBRESOLV
|
||||
|
||||
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||
#undef HAVE_LIBRESOLVE
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||
#undef HAVE_LIBSSL
|
||||
|
||||
/* If zlib is available */
|
||||
#undef HAVE_LIBZ
|
||||
//#define HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* if your compiler supports 'long long' */
|
||||
#define HAVE_LONGLONG 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||
#undef HAVE_OPENSSL_CRYPTO_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/pem.h> header file. */
|
||||
#undef HAVE_OPENSSL_PEM_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||
#undef HAVE_OPENSSL_X509_H
|
||||
|
||||
/* use O_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_O_NONBLOCK
|
||||
|
||||
/* Define to 1 if you have the <pem.h> header file. */
|
||||
#undef HAVE_PEM_H
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#undef HAVE_PERROR
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define to 1 if you have the `RAND_egd' function. */
|
||||
#undef HAVE_RAND_EGD
|
||||
|
||||
/* Define to 1 if you have the `RAND_screen' function. */
|
||||
#undef HAVE_RAND_SCREEN
|
||||
|
||||
/* Define to 1 if you have the `RAND_status' function. */
|
||||
#undef HAVE_RAND_STATUS
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
#undef HAVE_RSA_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#define HAVE_SETJMP_H 1
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#undef HAVE_SGTTY_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `siginterrupt' function. */
|
||||
#undef HAVE_SIGINTERRUPT
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* If you have sigsetjmp */
|
||||
#undef HAVE_SIGSETJMP
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* use SO_NONBLOCK for non-blocking sockets */
|
||||
#undef HAVE_SO_NONBLOCK
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
#undef HAVE_SPNEGO
|
||||
|
||||
/* Define to 1 if you have the <ssl.h> header file. */
|
||||
#undef HAVE_SSL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strcmpi' function. */
|
||||
#undef HAVE_STRCMPI
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the `stricmp' function. */
|
||||
#undef HAVE_STRICMP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strlcat' function. */
|
||||
#define HAVE_STRLCAT 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#define HAVE_STRLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the `strtok_r' function. */
|
||||
#undef HAVE_STRTOK_R
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#undef HAVE_STRTOLL
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||
#undef HAVE_SYS_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the `tcgetattr' function. */
|
||||
#undef HAVE_TCGETATTR
|
||||
|
||||
/* Define to 1 if you have the `tcsetattr' function. */
|
||||
#undef HAVE_TCSETATTR
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the <winsock.h> header file. */
|
||||
#undef HAVE_WINSOCK_H
|
||||
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
#undef HAVE_WRITABLE_ARGV
|
||||
|
||||
/* Define to 1 if you have the <x509.h> header file. */
|
||||
#undef HAVE_X509_H
|
||||
|
||||
/* if you have the zlib.h header file */
|
||||
#define HAVE_ZLIB_H 1
|
||||
|
||||
/* need REENTRANT defined */
|
||||
#undef NEED_REENTRANT
|
||||
|
||||
/* cpu-machine-OS */
|
||||
#define OS "i386-pc-NetWare"
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* a suitable file to read random data from */
|
||||
#undef RANDOM_FILE
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
#undef SELECT_TYPE_ARG1
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
#undef SELECT_TYPE_ARG234
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
#undef SELECT_TYPE_ARG5
|
||||
|
||||
/* The size of a `curl_off_t', as computed by sizeof. */
|
||||
#define SIZEOF_CURL_OFF_T 4
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* XXX: #undef STDC_HEADERS */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if you want to enable ares support */
|
||||
#undef USE_ARES
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* type to use in place of in_addr_t if not defined */
|
||||
#undef in_addr_t
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* type to use in place of socklen_t if not defined */
|
||||
#define socklen_t int
|
||||
|
||||
/* the signed version of size_t */
|
||||
#undef ssize_t
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -52,6 +60,13 @@
|
||||
#include <stdlib.h> /* required for free() prototype, without it, this crashes
|
||||
on macos 68K */
|
||||
#endif
|
||||
#if (defined(HAVE_FIONBIO) && defined(__NOVELL_LIBC__))
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
#ifdef VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
@@ -79,6 +94,7 @@
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
@@ -131,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
|
||||
@@ -288,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 */
|
||||
}
|
||||
}
|
||||
@@ -346,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 {
|
||||
@@ -417,6 +405,7 @@ static bool verifyconnect(curl_socket_t sockfd)
|
||||
/* This wasn't a successful connect */
|
||||
return FALSE;
|
||||
#else
|
||||
(void)sockfd;
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
@@ -480,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;
|
||||
}
|
||||
/*
|
||||
@@ -495,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.
|
||||
@@ -571,8 +577,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
*/
|
||||
for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (sockfd < 0)
|
||||
if (sockfd == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
|
||||
else if(data->set.tcp_nodelay)
|
||||
Curl_setNoDelay(conn, sockfd);
|
||||
#else
|
||||
/*
|
||||
* Connecting with old style IPv4-only support
|
||||
@@ -592,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),
|
||||
@@ -643,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;
|
||||
}
|
||||
}
|
||||
@@ -681,10 +693,10 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
before = after;
|
||||
}
|
||||
if (sockfd < 0) {
|
||||
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
|
||||
@@ -387,6 +387,22 @@ SOURCE=.\http_digest.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_ntlm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\http_ntlm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inet_pton.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\inet_pton.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\md5.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
10
lib/easy.c
10
lib/easy.c
@@ -198,8 +198,12 @@ CURL *curl_easy_init(void)
|
||||
struct SessionHandle *data;
|
||||
|
||||
/* Make sure we inited the global SSL stuff */
|
||||
if (!initialized)
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if (!initialized) {
|
||||
res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if(res)
|
||||
/* something in the global init failed, return nothing */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We use curl_open() with undefined URL so far */
|
||||
res = Curl_open(&data);
|
||||
@@ -267,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);
|
||||
@@ -242,7 +242,7 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
it avoids problems with select() and recv() on file descriptors
|
||||
in Winsock */
|
||||
if(fstated)
|
||||
Curl_pgrsSetDownloadSize(data, (double)expected_size);
|
||||
Curl_pgrsSetDownloadSize(data, expected_size);
|
||||
|
||||
if(conn->resume_from)
|
||||
lseek(fd, conn->resume_from, SEEK_SET);
|
||||
@@ -268,7 +268,7 @@ CURLcode Curl_file(struct connectdata *conn)
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
Curl_pgrsSetDownloadCounter(data, (double)bytecount);
|
||||
Curl_pgrsSetDownloadCounter(data, bytecount);
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
117
lib/formdata.c
117
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,9 +975,13 @@ 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,
|
||||
...)
|
||||
struct curl_httppost **last_post,
|
||||
...)
|
||||
{
|
||||
va_list arg;
|
||||
CURLFORMcode result;
|
||||
@@ -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,9 +1021,12 @@ 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, ...)
|
||||
const char *fmt, ...)
|
||||
{
|
||||
char s[4096];
|
||||
va_list ap;
|
||||
@@ -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,9 +1117,16 @@ 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,
|
||||
size_t *sizep)
|
||||
curl_off_t *sizep)
|
||||
{
|
||||
struct FormData *form = NULL;
|
||||
struct FormData *firstform;
|
||||
@@ -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 {
|
||||
header = form->data->line;
|
||||
*len = form->data->length;
|
||||
|
||||
if( (form->data->length - form->sent ) > wantedsize ) {
|
||||
form->data = form->data->next; /* advance */
|
||||
|
||||
memcpy(buffer, form->data->line + form->sent, wantedsize);
|
||||
|
||||
form->sent += wantedsize;
|
||||
|
||||
return wantedsize;
|
||||
}
|
||||
|
||||
memcpy(buffer,
|
||||
form->data->line + form->sent,
|
||||
gotsize = (form->data->length - form->sent) );
|
||||
|
||||
form->sent = 0;
|
||||
|
||||
form->data = form->data->next; /* advance */
|
||||
|
||||
} while(!gotsize && form->data);
|
||||
/* If we got an empty line and we have more data, we proceed to the next
|
||||
line immediately to avoid returning zero before we've reached the end.
|
||||
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
|
||||
|
||||
return gotsize;
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata );
|
||||
CURLcode
|
||||
Curl_getFormData(struct FormData **,
|
||||
struct curl_httppost *post,
|
||||
size_t *size);
|
||||
curl_off_t *size);
|
||||
|
||||
/* fread() emulation */
|
||||
size_t Curl_FormReader(char *buffer,
|
||||
@@ -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);
|
||||
|
||||
|
||||
192
lib/ftp.c
192
lib/ftp.c
@@ -65,6 +65,11 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
#undef in_addr_t
|
||||
#define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -86,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"
|
||||
@@ -99,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
|
||||
@@ -112,9 +125,19 @@ 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++){
|
||||
free(ftp->dirs[i]);
|
||||
ftp->dirs[i]=NULL;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +189,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
default:
|
||||
/* we have received data here */
|
||||
{
|
||||
int s;
|
||||
curl_socket_t s;
|
||||
size_t size = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in add;
|
||||
|
||||
@@ -175,7 +198,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
|
||||
sclose(sock); /* close the first socket */
|
||||
|
||||
if (-1 == s) {
|
||||
if (CURL_SOCKET_BAD == s) {
|
||||
/* DIE! */
|
||||
failf(data, "Error accept()ing server connect");
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
@@ -334,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++;
|
||||
@@ -580,22 +605,22 @@ 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
|
||||
*/
|
||||
if(conn->sec_complete)
|
||||
Curl_sec_set_protection_level(conn);
|
||||
/* 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
|
||||
* do it if user supplied a password
|
||||
*/
|
||||
if(conn->passwd && *conn->passwd) {
|
||||
result = Curl_krb_kauth(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
/* 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) {
|
||||
result = Curl_krb_kauth(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
failf(data, "Odd return code after USER");
|
||||
@@ -719,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) &&
|
||||
@@ -761,12 +784,14 @@ 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
|
||||
/* shut down the socket to inform the server we're done */
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = -1;
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
|
||||
if(!ftp->no_transfer) {
|
||||
/* Let's see what the server says about the transfer we just performed,
|
||||
@@ -949,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;
|
||||
@@ -1068,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), "?");
|
||||
}
|
||||
@@ -1121,11 +1141,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
char hbuf[NI_MAXHOST];
|
||||
|
||||
struct sockaddr *sa=(struct sockaddr *)&ss;
|
||||
#ifdef NI_WITHSCOPEID
|
||||
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
||||
#else
|
||||
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||
#endif
|
||||
unsigned char *ap;
|
||||
unsigned char *pp;
|
||||
char portmsgbuf[4096], tmp[4096];
|
||||
@@ -1133,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,
|
||||
@@ -1146,7 +1162,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
}
|
||||
|
||||
rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
|
||||
niflags);
|
||||
NIFLAGS);
|
||||
if(rc) {
|
||||
failf(data, "getnameinfo() returned %d\n", rc);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
@@ -1167,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):
|
||||
@@ -1175,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;
|
||||
@@ -1194,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;
|
||||
}
|
||||
|
||||
@@ -1236,22 +1257,24 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
||||
if (eprtaf < 0)
|
||||
continue;
|
||||
if (getnameinfo((struct sockaddr *)&ss, sslen,
|
||||
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))
|
||||
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp),
|
||||
NIFLAGS))
|
||||
continue;
|
||||
|
||||
/* do not transmit IPv6 scope identifier to the wire */
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
char *q = strchr(portmsgbuf, '%');
|
||||
if (q)
|
||||
*q = '\0';
|
||||
if (q)
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
||||
portmsgbuf, tmp);
|
||||
if(result)
|
||||
return result;
|
||||
} else if (strcmp(*modep, "LPRT") == 0 ||
|
||||
strcmp(*modep, "PORT") == 0) {
|
||||
}
|
||||
else if (strcmp(*modep, "LPRT") == 0 ||
|
||||
strcmp(*modep, "PORT") == 0) {
|
||||
int i;
|
||||
|
||||
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
||||
@@ -1596,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
|
||||
@@ -1820,7 +1843,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
/* When we know we're uploading a specified file, we can get the file
|
||||
size prior to the actual upload. */
|
||||
|
||||
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize);
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
|
||||
result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
|
||||
SECONDARYSOCKET, bytecountp);
|
||||
@@ -1828,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;
|
||||
@@ -1839,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;
|
||||
@@ -2061,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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2150,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)
|
||||
@@ -2199,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! */
|
||||
@@ -2262,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 */
|
||||
@@ -2295,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)
|
||||
{
|
||||
@@ -2305,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
|
||||
of next path component */
|
||||
int path_part=0;/* current path component */
|
||||
char *cur_pos=conn->path; /* current position in ppath. point at the begin
|
||||
of next path component */
|
||||
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
ftp = conn->proto.ftp;
|
||||
@@ -2319,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;
|
||||
@@ -2348,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");
|
||||
freedirs(ftp);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
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_OUT_OF_MEMORY;
|
||||
}
|
||||
ftp->dirs = (char **)bigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2378,10 +2409,10 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
if(connected)
|
||||
retcode = Curl_ftp_nextconnect(conn);
|
||||
|
||||
if(retcode && (conn->sock[SECONDARYSOCKET] >= 0)) {
|
||||
if(retcode && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
|
||||
/* Failure detected, close the second socket if it was created already */
|
||||
sclose(conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = -1;
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
if(ftp->no_transfer)
|
||||
@@ -2394,7 +2425,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
|
||||
else
|
||||
freedirs(ftp);
|
||||
|
||||
ftp->ctl_valid = TRUE;
|
||||
ftp->ctl_valid = TRUE; /* seems good */
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
@@ -2449,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
|
||||
@@ -2457,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;
|
||||
@@ -2487,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);
|
||||
@@ -2501,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)
|
||||
{
|
||||
|
||||
@@ -135,25 +135,25 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
*param_doublep = data->progress.t_starttransfer;
|
||||
break;
|
||||
case CURLINFO_SIZE_UPLOAD:
|
||||
*param_doublep = data->progress.uploaded;
|
||||
*param_doublep = (double)data->progress.uploaded;
|
||||
break;
|
||||
case CURLINFO_SIZE_DOWNLOAD:
|
||||
*param_doublep = data->progress.downloaded;
|
||||
*param_doublep = (double)data->progress.downloaded;
|
||||
break;
|
||||
case CURLINFO_SPEED_DOWNLOAD:
|
||||
*param_doublep = data->progress.dlspeed;
|
||||
*param_doublep = (double)data->progress.dlspeed;
|
||||
break;
|
||||
case CURLINFO_SPEED_UPLOAD:
|
||||
*param_doublep = data->progress.ulspeed;
|
||||
*param_doublep = (double)data->progress.ulspeed;
|
||||
break;
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
|
||||
*param_doublep = data->progress.size_dl;
|
||||
*param_doublep = (double)data->progress.size_dl;
|
||||
break;
|
||||
case CURLINFO_CONTENT_LENGTH_UPLOAD:
|
||||
*param_doublep = data->progress.size_ul;
|
||||
*param_doublep = (double)data->progress.size_ul;
|
||||
break;
|
||||
case CURLINFO_REDIRECT_TIME:
|
||||
*param_doublep = data->progress.t_redirect;
|
||||
|
||||
443
lib/hostip.c
443
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,11 +63,21 @@
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
@@ -83,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
|
||||
@@ -108,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) {
|
||||
@@ -139,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;
|
||||
@@ -160,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)
|
||||
{
|
||||
@@ -187,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)
|
||||
{
|
||||
@@ -204,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)
|
||||
{
|
||||
@@ -217,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;
|
||||
@@ -240,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,
|
||||
@@ -298,15 +362,22 @@ 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,
|
||||
int port,
|
||||
@@ -400,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)
|
||||
@@ -433,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;
|
||||
|
||||
@@ -444,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
|
||||
@@ -455,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,
|
||||
@@ -468,25 +561,33 @@ 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)
|
||||
ares_process(data->state.areschannel, &read_fds, &write_fds);
|
||||
/* 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;
|
||||
|
||||
@@ -500,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 */
|
||||
@@ -525,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
|
||||
@@ -563,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;
|
||||
}
|
||||
@@ -586,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)
|
||||
@@ -628,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,
|
||||
@@ -643,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) {
|
||||
@@ -665,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)
|
||||
{
|
||||
@@ -676,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)
|
||||
{
|
||||
@@ -687,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)
|
||||
|
||||
@@ -740,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,
|
||||
@@ -760,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.
|
||||
@@ -802,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)
|
||||
{
|
||||
@@ -882,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;
|
||||
@@ -896,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;
|
||||
@@ -920,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)
|
||||
@@ -941,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,
|
||||
@@ -956,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;
|
||||
@@ -1143,9 +1324,10 @@ 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;
|
||||
*waitp = TRUE; /* please wait for the response */
|
||||
return NULL;
|
||||
}
|
||||
infof(data, "init_gethostbyname_thread() failed for %s; code %lu\n",
|
||||
hostname, GetLastError());
|
||||
@@ -1178,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;
|
||||
@@ -1210,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) {
|
||||
@@ -1250,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)
|
||||
{
|
||||
@@ -1274,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 :
|
||||
conn->data->set.timeout ? conn->data->set.timeout :
|
||||
300; /* default name resolve timeout in seconds */
|
||||
timeout =
|
||||
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
|
||||
conn->data->set.timeout ? conn->data->set.timeout :
|
||||
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;
|
||||
@@ -1303,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)
|
||||
{
|
||||
@@ -1328,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);
|
||||
|
||||
376
lib/http.c
376
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,
|
||||
@@ -456,9 +596,9 @@ static size_t readmoredata(char *buffer,
|
||||
/* make sure that a HTTP request is never sent away chunked! */
|
||||
conn->bits.forbidchunk= (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
|
||||
|
||||
if(http->postsize <= fullsize) {
|
||||
memcpy(buffer, http->postdata, http->postsize);
|
||||
fullsize = http->postsize;
|
||||
if(http->postsize <= (curl_off_t)fullsize) {
|
||||
memcpy(buffer, http->postdata, (size_t)http->postsize);
|
||||
fullsize = (size_t)http->postsize;
|
||||
|
||||
if(http->backup.postsize) {
|
||||
/* move backup data into focus and continue on that */
|
||||
@@ -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)
|
||||
@@ -750,7 +892,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||
fd_set readfd;
|
||||
char *line_start;
|
||||
char *host_port;
|
||||
int tunnelsocket = conn->sock[sockindex];
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@@ -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) {
|
||||
@@ -1333,7 +1520,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
|
||||
send_buffer *req_buffer;
|
||||
struct curl_slist *headers=data->set.headers;
|
||||
size_t postsize;
|
||||
curl_off_t postsize; /* off_t type to be able to hold a large file size */
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = add_buffer_init();
|
||||
@@ -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)) {
|
||||
@@ -1487,7 +1674,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
if(!conn->bits.upload_chunky)
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
add_bufferf(req_buffer,
|
||||
"Content-Length: %d\r\n", http->postsize);
|
||||
"Content-Length: %" FORMAT_OFF_T "\r\n", http->postsize);
|
||||
|
||||
if(!checkheaders(data, "Expect:")) {
|
||||
/* if not disabled explicitly we add a Expect: 100-continue
|
||||
@@ -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;
|
||||
@@ -1563,7 +1748,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
add_buffer(req_buffer, "\r\n", 2); /* end of headers */
|
||||
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize);
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
|
||||
/* this sends the buffer and frees all the buffer resources */
|
||||
result = add_buffer_send(req_buffer, conn,
|
||||
@@ -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;
|
||||
@@ -1586,7 +1771,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
/* store the size of the postfields */
|
||||
postsize = data->set.postfieldsize?
|
||||
data->set.postfieldsize:
|
||||
(data->set.postfields?strlen(data->set.postfields):0);
|
||||
(data->set.postfields?(curl_off_t)strlen(data->set.postfields):0);
|
||||
|
||||
if(!conn->bits.upload_chunky) {
|
||||
/* We only set Content-Length and allow a custom Content-Length if
|
||||
@@ -1596,7 +1781,8 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
if(!checkheaders(data, "Content-Length:"))
|
||||
/* we allow replacing this header, although it isn't very wise to
|
||||
actually set your own */
|
||||
add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize);
|
||||
add_bufferf(req_buffer, "Content-Length: %" FORMAT_OFF_T"\r\n",
|
||||
postsize);
|
||||
}
|
||||
|
||||
if(!checkheaders(data, "Content-Type:"))
|
||||
@@ -1605,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 */
|
||||
@@ -1619,11 +1805,11 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
if(!conn->bits.upload_chunky)
|
||||
/* We're not sending it 'chunked', append it to the request
|
||||
already now to reduce the number if send() calls */
|
||||
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||
add_buffer(req_buffer, data->set.postfields, (size_t)postsize);
|
||||
else {
|
||||
/* Append the POST data chunky-style */
|
||||
add_bufferf(req_buffer, "%x\r\n", postsize);
|
||||
add_buffer(req_buffer, data->set.postfields, postsize);
|
||||
add_bufferf(req_buffer, "%x\r\n", (int)postsize);
|
||||
add_buffer(req_buffer, data->set.postfields, (size_t)postsize);
|
||||
add_buffer(req_buffer, "\r\n0\r\n\r\n", 7); /* end of a chunked
|
||||
transfer stream */
|
||||
}
|
||||
@@ -1641,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) */
|
||||
@@ -1657,7 +1843,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
||||
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
|
||||
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize);
|
||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||
|
||||
/* set the pointer to mark that we will send the post body using
|
||||
the read callback */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
|
||||
!defined(__riscos__) && !defined(__INTERIX)
|
||||
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE)
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
@@ -125,5 +125,8 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
|
||||
/* -- end of if2ip() -- */
|
||||
#else
|
||||
#define if2ip(x) NULL
|
||||
char *Curl_if2ip(char *interface, char *buf, int buf_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user