Compare commits
240 Commits
curl-7_13_
...
curl-7_14_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
55225106b6 | ||
![]() |
1a31bff9fe | ||
![]() |
4eaa3329ec | ||
![]() |
028d78b993 | ||
![]() |
944af98be6 | ||
![]() |
2789b2b0ad | ||
![]() |
7dded571de | ||
![]() |
95fe8372e8 | ||
![]() |
ecdcb0ef67 | ||
![]() |
6a04a03eb5 | ||
![]() |
0c96056a94 | ||
![]() |
f518a5e231 | ||
![]() |
f581c1062e | ||
![]() |
0b3deceea3 | ||
![]() |
fa4cd8868c | ||
![]() |
8c573ca7f3 | ||
![]() |
5a5cf3a51d | ||
![]() |
3f23e8443e | ||
![]() |
a00f9b093c | ||
![]() |
5f538ce3f8 | ||
![]() |
ebcaa3d579 | ||
![]() |
60e26199a2 | ||
![]() |
11defd180c | ||
![]() |
c82c1691ee | ||
![]() |
364562f209 | ||
![]() |
5d9fc28fa7 | ||
![]() |
e5ec5c284f | ||
![]() |
a90e33ad71 | ||
![]() |
62ab21ce7d | ||
![]() |
cc8e8db1e5 | ||
![]() |
b19cba2016 | ||
![]() |
315a9c95d5 | ||
![]() |
e010ac9706 | ||
![]() |
e4c0a85da0 | ||
![]() |
d3e4cdd5b0 | ||
![]() |
763b812dc7 | ||
![]() |
3269dfb4ab | ||
![]() |
e816bd259f | ||
![]() |
a295408e09 | ||
![]() |
42a34c7cd7 | ||
![]() |
9a72751958 | ||
![]() |
314e6fa80b | ||
![]() |
b2b66f749a | ||
![]() |
708ed6fded | ||
![]() |
5c30fa50d6 | ||
![]() |
fc33c424d9 | ||
![]() |
b04d6dd0b1 | ||
![]() |
9c5f79c56a | ||
![]() |
ef5eea689a | ||
![]() |
fd191deb49 | ||
![]() |
e1da1ff7d3 | ||
![]() |
2b00ed7ef8 | ||
![]() |
d960ea959d | ||
![]() |
274842ec41 | ||
![]() |
c06da7c84a | ||
![]() |
cea117b509 | ||
![]() |
6078c938b2 | ||
![]() |
9e95dd4821 | ||
![]() |
0cc8b57d4f | ||
![]() |
2179e6e797 | ||
![]() |
7dde3d1825 | ||
![]() |
a0fe950b75 | ||
![]() |
44985e8884 | ||
![]() |
f03366bcbf | ||
![]() |
d43ea83033 | ||
![]() |
11bdba0007 | ||
![]() |
07e58aaa79 | ||
![]() |
a31ddd363b | ||
![]() |
ed9e10f2d8 | ||
![]() |
02ae3c2810 | ||
![]() |
669ebb5f71 | ||
![]() |
9a3e0e52cb | ||
![]() |
b0f856213d | ||
![]() |
6f4ff1f2bf | ||
![]() |
d3eea61f1f | ||
![]() |
d59d81fae8 | ||
![]() |
329ca40b6f | ||
![]() |
e71bd416f4 | ||
![]() |
ad66fc6cc2 | ||
![]() |
d12b44204b | ||
![]() |
4be2136de4 | ||
![]() |
c4dbed040b | ||
![]() |
366b62af2d | ||
![]() |
a6955aa486 | ||
![]() |
ad30341fa2 | ||
![]() |
23da55a9f1 | ||
![]() |
41e6292e7b | ||
![]() |
ae1d6f29d9 | ||
![]() |
ccfc1ddbef | ||
![]() |
002de1eae2 | ||
![]() |
63621bae81 | ||
![]() |
85f9e6c4b9 | ||
![]() |
967ec296c0 | ||
![]() |
c6aae9b1d7 | ||
![]() |
913c370c25 | ||
![]() |
e5472bbd21 | ||
![]() |
957c258c6d | ||
![]() |
abee109cd1 | ||
![]() |
502e5ae6e1 | ||
![]() |
b8417be1f2 | ||
![]() |
9e037431b4 | ||
![]() |
f71b3676bb | ||
![]() |
50fe7b5e35 | ||
![]() |
9fb253388b | ||
![]() |
8cf1786296 | ||
![]() |
51b17b299c | ||
![]() |
78882e4642 | ||
![]() |
8465a367a4 | ||
![]() |
3bcfe678ab | ||
![]() |
d5403f3a5b | ||
![]() |
26abb48533 | ||
![]() |
177848ed27 | ||
![]() |
656a2e93d7 | ||
![]() |
6b1220b61d | ||
![]() |
9d7330d879 | ||
![]() |
26a5954fa0 | ||
![]() |
01165e08e0 | ||
![]() |
6e1633a6c5 | ||
![]() |
a8ff0a21bf | ||
![]() |
b8bc6bed97 | ||
![]() |
1a4402038c | ||
![]() |
5ac51cc9b5 | ||
![]() |
c12159ce21 | ||
![]() |
4485503ecc | ||
![]() |
200ac588cc | ||
![]() |
0bb040822d | ||
![]() |
543fbe14ee | ||
![]() |
e02ab66120 | ||
![]() |
76c7c694c5 | ||
![]() |
f0057977b7 | ||
![]() |
e8e43f06af | ||
![]() |
04b35e86d5 | ||
![]() |
64ab85da4f | ||
![]() |
b8d7a13ea3 | ||
![]() |
78a76dc905 | ||
![]() |
5fa5fff0e9 | ||
![]() |
d323b3d816 | ||
![]() |
b685b5672a | ||
![]() |
8f6c2f87c8 | ||
![]() |
f30e8b11eb | ||
![]() |
8bd6d6a4de | ||
![]() |
b3a8f438fc | ||
![]() |
e78ddf0a95 | ||
![]() |
5f0366c2cb | ||
![]() |
779ca09775 | ||
![]() |
313f1a1e83 | ||
![]() |
21337f4776 | ||
![]() |
53a8e5655b | ||
![]() |
2d85585ae1 | ||
![]() |
63d109f7be | ||
![]() |
c904b6b5bf | ||
![]() |
6a27449922 | ||
![]() |
9a9c07f571 | ||
![]() |
4382204e1b | ||
![]() |
6d3114efe2 | ||
![]() |
b62baaed95 | ||
![]() |
9b391e531b | ||
![]() |
a0c7a6d22b | ||
![]() |
14424f7058 | ||
![]() |
6063dff8d0 | ||
![]() |
7fba9ed398 | ||
![]() |
53280a196b | ||
![]() |
0bf9a5704b | ||
![]() |
8182d17ae1 | ||
![]() |
69b1ac7dcd | ||
![]() |
b15507aac3 | ||
![]() |
6c2f583f51 | ||
![]() |
a72eaddda3 | ||
![]() |
dc050e45df | ||
![]() |
2fcbf13920 | ||
![]() |
099ae31523 | ||
![]() |
c2fcdf3a02 | ||
![]() |
2056a538b9 | ||
![]() |
cd1144dc24 | ||
![]() |
e9d068b913 | ||
![]() |
ec2ad57c32 | ||
![]() |
316adac511 | ||
![]() |
d7b11d4c33 | ||
![]() |
c52aa6df33 | ||
![]() |
a19b23b59f | ||
![]() |
4e26b2a65b | ||
![]() |
7c4feac6db | ||
![]() |
e01e364c37 | ||
![]() |
c13a3d7b84 | ||
![]() |
67805b6dc5 | ||
![]() |
0050ab2a3d | ||
![]() |
60e66c6cbf | ||
![]() |
5ad2a253e8 | ||
![]() |
b5d50e9298 | ||
![]() |
37f7362aca | ||
![]() |
bee198def5 | ||
![]() |
f09e479fd6 | ||
![]() |
80fe93bc33 | ||
![]() |
ea03ad3bee | ||
![]() |
feec421744 | ||
![]() |
634982840e | ||
![]() |
fb3c85ab2f | ||
![]() |
a9b7c3531c | ||
![]() |
a7ba0d908d | ||
![]() |
2fc70e2c5d | ||
![]() |
7ae3f0e70c | ||
![]() |
9afaa51e3f | ||
![]() |
c736a719f1 | ||
![]() |
37a547842b | ||
![]() |
b9f1d43921 | ||
![]() |
bec6423c02 | ||
![]() |
241b2b4ae3 | ||
![]() |
14d9b56937 | ||
![]() |
1c3766eb46 | ||
![]() |
70024d61eb | ||
![]() |
2085f133d6 | ||
![]() |
2a045dfceb | ||
![]() |
893cbaaf2f | ||
![]() |
6e61939382 | ||
![]() |
015a618172 | ||
![]() |
2a8b91cdb9 | ||
![]() |
bebd5dbc5a | ||
![]() |
018dbfe058 | ||
![]() |
c6ea597817 | ||
![]() |
175b00c0a2 | ||
![]() |
5ebc6e305e | ||
![]() |
993600761f | ||
![]() |
1d9fff80b7 | ||
![]() |
c712b84dd5 | ||
![]() |
dcf8dd4b5e | ||
![]() |
ba26c3fb22 | ||
![]() |
41563607a8 | ||
![]() |
2d4dcfb740 | ||
![]() |
34854e70cf | ||
![]() |
758d9fe852 | ||
![]() |
6a6c0e7a73 | ||
![]() |
ee44eec3e1 | ||
![]() |
eccd0d8e37 | ||
![]() |
983be0ec60 | ||
![]() |
243a45d840 | ||
![]() |
60ec804047 | ||
![]() |
c53e9ccf4a | ||
![]() |
6e8e0418fc | ||
![]() |
e9eb52305f | ||
![]() |
8501ae748c |
177
CHANGES
177
CHANGES
@@ -7,6 +7,183 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
|
||||||
|
Version 7.14.0 (16 May 2005)
|
||||||
|
|
||||||
|
Daniel (13 May 2005)
|
||||||
|
- Grigory Entin reported that curl's configure detects a fine poll() for Mac
|
||||||
|
OS X 10.4 (while 10.3 or later detected a "bad" one), but the executable
|
||||||
|
doesn't work as good as if built without poll(). I've adjusted the configure
|
||||||
|
to always skip the fine-poll() test on Mac OS X (darwin).
|
||||||
|
|
||||||
|
Daniel (12 May 2005)
|
||||||
|
- When doing a second request (after a disconnect) using the same easy handle,
|
||||||
|
over a proxy that uses NTLM authentication, libcurl failed to use NTLM again
|
||||||
|
properly (the auth method was accidentally reset to the same as had been set
|
||||||
|
for host auth, which defaults to Basic). Bug report #1200661 identified the
|
||||||
|
the problem and the fix.
|
||||||
|
|
||||||
|
- If -z/--time-cond is used with an invalid date syntax, this is no longer
|
||||||
|
silently discarded. Instead a proper warning message is diplayed that
|
||||||
|
informs about it. But it still continues without the condition.
|
||||||
|
|
||||||
|
Version 7.14.0-pre2 (11 May 2005)
|
||||||
|
|
||||||
|
Daniel (11 May 2005)
|
||||||
|
- Starting now, libcurl sends a little different set of headers in its default
|
||||||
|
HTTP requests:
|
||||||
|
|
||||||
|
A) Normal non-proxy HTTP:
|
||||||
|
- no more "Pragma: no-cache" (this only makes sense to proxies)
|
||||||
|
|
||||||
|
B) Non-CONNECT HTTP request over proxy:
|
||||||
|
- "Pragma: no-cache" is used (like before)
|
||||||
|
- "Proxy-Connection: Keep-alive" (for older style 1.0-proxies)
|
||||||
|
|
||||||
|
C) CONNECT HTTP request over proxy:
|
||||||
|
- "Host: [name]:[port]"
|
||||||
|
- "Proxy-Connection: Keep-alive"
|
||||||
|
|
||||||
|
The A) case is mostly to reduce the default header size and remove a
|
||||||
|
pointless header.
|
||||||
|
|
||||||
|
The B) is to address (rare) problems with HTTP 1.0 proxies
|
||||||
|
|
||||||
|
The C) headers are both to address (rare) problems with some proxies. The
|
||||||
|
code in libcurl that deals with CONNECT requests need a rewrite, but it
|
||||||
|
feels like a too big a job for me to do now. Details are added in the code
|
||||||
|
comments for now.
|
||||||
|
|
||||||
|
Updated a large amount of test cases to reflect the news.
|
||||||
|
|
||||||
|
Daniel (10 May 2005)
|
||||||
|
- Half-baked attempt to bail out if select() returns _only_ errorfds when the
|
||||||
|
transfer is in progress. An attempt to fix Allan's problem. See
|
||||||
|
http://curl.haxx.se/mail/lib-2005-05/0073.html and the rest of that thread
|
||||||
|
for details.
|
||||||
|
|
||||||
|
I'm still not sure this is the right fix, but...
|
||||||
|
|
||||||
|
Version 7.14.0-pre1 (9 May 2005)
|
||||||
|
|
||||||
|
Daniel (2 May 2005)
|
||||||
|
- Sort of "fixed" KNOWN_BUGS #4: curl now builds IPv6 enabled on AIX 4.3. At
|
||||||
|
least it should no longer cause a compiler error. However, it does not have
|
||||||
|
AI_NUMERICHOST so we cannot getaddrinfo() any numerical addresses with it
|
||||||
|
(we use that for FTP PORT/EPRT)! So, I modified the configure check that
|
||||||
|
checks if the getaddrinfo() is working, to use AI_NUMERICHOST since then
|
||||||
|
it'll fail on AIX 4.3 and it will automatically build with IPv6 support
|
||||||
|
disabled.
|
||||||
|
|
||||||
|
- Added --trace-time that when used adds a time stamp to each trace line that
|
||||||
|
--trace, --trace-ascii and --verbose output. I also made the '>' display
|
||||||
|
separate each line on the linefeed so that HTTP requests etc look nicer in
|
||||||
|
the -v output.
|
||||||
|
|
||||||
|
- Made curl recognize the environment variables Lynx (and others?) support for
|
||||||
|
pointing out the CA cert path/file: SSL_CERT_DIR and SSL_CERT_FILE. If
|
||||||
|
CURL_CA_BUNDLE is not set, they are checked afterwards.
|
||||||
|
|
||||||
|
Like before: on windows if none of these are set, it checks for the ca cert
|
||||||
|
file like this:
|
||||||
|
|
||||||
|
1. application's directory
|
||||||
|
2. current working directory
|
||||||
|
3. Windows System directory (e.g. C:\windows\system32)
|
||||||
|
4. Windows Directory (e.g. C:\windows)
|
||||||
|
5. all directories along %PATH%
|
||||||
|
|
||||||
|
Daniel (1 May 2005)
|
||||||
|
- The runtests.pl script now starts test servers by doing fork() and exec()
|
||||||
|
instead of the previous approach. This is less complicated and should
|
||||||
|
hopefully lead to less "leaked" servers (servers that aren't stopped
|
||||||
|
properly when the tests are stopped).
|
||||||
|
|
||||||
|
- Alexander Zhuravlev found a case when you did "curl -I [URL]" and it
|
||||||
|
complained on the chunked encoding, even though a HEAD should never return a
|
||||||
|
body and thus it cannot be a chunked-encoding problem!
|
||||||
|
|
||||||
|
Daniel (30 April 2005)
|
||||||
|
- Alexander Zhuravlev found out that (lib)curl SIGSEGVed when using
|
||||||
|
--interface on an address that can't be bound.
|
||||||
|
|
||||||
|
Daniel (28 April 2005)
|
||||||
|
- Working on fixing up test cases to mark sections as 'mode=text' for things
|
||||||
|
that curl writes as text files, since then they can get different line
|
||||||
|
endings depending on OS. Andr<64>s Garc<72>a helps me work this out.
|
||||||
|
|
||||||
|
Did lots of other minor tweaks on the test scripts to work better and more
|
||||||
|
reliably find test servers and also kill test servers.
|
||||||
|
|
||||||
|
- Dan Fandrich pointed out how the runtests.pl script killed the HTTP server
|
||||||
|
instead of the HTTPS server when closing it down.
|
||||||
|
|
||||||
|
Daniel (27 April 2005)
|
||||||
|
- Paul Moore made curl check for the .curlrc file (_curlrc on windows) on two
|
||||||
|
more places. First, CURL_HOME is a new environment variable that is used
|
||||||
|
instead of HOME if it is set, to point out where the default config file
|
||||||
|
lives. If there's no config file in the dir pointed out by one of the
|
||||||
|
environment variables, the Windows version will instead check the same
|
||||||
|
directory the executable curl is located in.
|
||||||
|
|
||||||
|
Daniel (26 April 2005)
|
||||||
|
- Cory Nelson's work on nuking compiler warnings when building on x64 with
|
||||||
|
VS2005.
|
||||||
|
|
||||||
|
Daniel (25 April 2005)
|
||||||
|
- Fred New reported a bug where we used Basic auth and user name and password
|
||||||
|
in .netrc, and when following a Location: the subsequent requests didn't
|
||||||
|
properly use the auth as found in the netrc file. Added test case 257 to
|
||||||
|
verify my fix.
|
||||||
|
|
||||||
|
- Based on feedback from Cory Nelson, I added some preprocessor magic in
|
||||||
|
*/setup.h and */config-win32.h to build fine with VS2005 on x64.
|
||||||
|
|
||||||
|
Daniel (23 April 2005)
|
||||||
|
- Alex Suykov made the curl tool now assume that uploads using HTTP:// or
|
||||||
|
HTTPS:// are the only ones that show output and thus motivates a switched
|
||||||
|
off progress meter if the output is sent to the terminal. This makes FTP
|
||||||
|
uploads without '>', -o or -O show the progress meter.
|
||||||
|
|
||||||
|
Daniel (22 April 2005)
|
||||||
|
- Dave Dribin's MSVC makefile fix: set CURL_STATICLIB when it builds static
|
||||||
|
library variants.
|
||||||
|
|
||||||
|
- Andres Garcia fixed configure to set the proper define when building static
|
||||||
|
libcurl on windows.
|
||||||
|
|
||||||
|
- --retry-delay didn't work.
|
||||||
|
|
||||||
|
Daniel (18 April 2005)
|
||||||
|
- Olivier reported that even though he used CURLOPT_PORT, libcurl clearly
|
||||||
|
still used the default port. He was right. I fixed the problem and added the
|
||||||
|
test cases 521, 522 and 523 to verify the fix.
|
||||||
|
|
||||||
|
- Toshiyuki Maezawa reported that when doing a POST with a read callback,
|
||||||
|
libcurl didn't properly send an Expect: 100-continue header. It does now.
|
||||||
|
|
||||||
|
- I committed by mig change in the test suite's FTP server that moves out all
|
||||||
|
socket/TCP code to a separate C program named sockfilt. And added 4 new
|
||||||
|
test cases for FTP over IPv6.
|
||||||
|
|
||||||
|
Daniel (8 April 2005)
|
||||||
|
- Cory Nelson reported a problem with a HTTP server that responded with a 304
|
||||||
|
response containing an "illegal" Content-Length: header, which was not
|
||||||
|
properly ignored by libcurl. Now it is. Test case 249 verifies.
|
||||||
|
|
||||||
|
Daniel (7 April 2005)
|
||||||
|
- Added ability to build and run with GnuTLS as an alternative to OpenSSL for
|
||||||
|
the secure layer. configure --with-gnutls enables with. Note that the
|
||||||
|
previous OpenSSL check still has preference and if it first detects OpenSSL,
|
||||||
|
it will not check for GnuTLS. You may need to explictly diable OpenSSL with
|
||||||
|
--without-ssl.
|
||||||
|
|
||||||
|
This work has been sponsored by The Written Word.
|
||||||
|
|
||||||
|
Daniel (5 April 2005)
|
||||||
|
- Christophe Legry fixed the post-upload check for FTP to not complain if the
|
||||||
|
upload was skipped due to a time-condition as set with
|
||||||
|
CURLOPT_TIMECONDITION. I added test case 247 and 248 to verify.
|
||||||
|
|
||||||
Version 7.13.2 (5 April 2005)
|
Version 7.13.2 (5 April 2005)
|
||||||
|
|
||||||
Daniel (4 April 2005)
|
Daniel (4 April 2005)
|
||||||
|
@@ -1,57 +1,58 @@
|
|||||||
Curl and libcurl 7.13.2
|
Curl and libcurl 7.14.0
|
||||||
|
|
||||||
Public curl release number: 87
|
Public curl release number: 88
|
||||||
Releases counted from the very beginning: 114
|
Releases counted from the very beginning: 115
|
||||||
Available command line options: 106
|
Available command line options: 107
|
||||||
Available curl_easy_setopt() options: 122
|
Available curl_easy_setopt() options: 122
|
||||||
Number of public functions in libcurl: 46
|
Number of public functions in libcurl: 46
|
||||||
Amount of public web site mirrors: 20
|
Amount of public web site mirrors: 23
|
||||||
Number of known libcurl bindings: 31
|
Number of known libcurl bindings: 31
|
||||||
|
Number of contributors: 437
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o Added --form-string
|
o modified default HTTP request headers
|
||||||
o libcurl can be built with SSPI support. curl_version_info() then returns
|
o curl --trace-time added for time stamping trace logs
|
||||||
a new feature bit: CURL_VERSION_SSPI. configure --enable-sspi added
|
o curl now respects the SSL_CERT_DIR and SSL_CERT_PATH environment variables
|
||||||
o Added --proxy-anyauth
|
o more search paths for curl's default .curlrc config file check
|
||||||
o Added runtests.1 and testcurl.1 man pages
|
o GnuTLS support, use configure --with-gnutls. Work on this was sponsored
|
||||||
|
by The Written Word.
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o the MSVC libcurl Makefile was fixed
|
o uses select() instead of poll() even on Mac OS X 10.4
|
||||||
o libcurl on Windows crash if resolver was active when easy handle was killed
|
o reconnected proxy use with NTLM auth on the same handle
|
||||||
o HTTP POST with auth and an initial 100 response before the 401/407
|
o warns about bad -z date syntax
|
||||||
o configure's SSL-detection for msys/mingw
|
o docs/THANKS now contains all known contributors
|
||||||
o better connection keep-alive when POSTing with HTTP Digest
|
o builds out-of-the-box on (presumably ipv6-enabled) AIX 4.3 hosts
|
||||||
o FTP-SSL
|
o curl --head could wrongly complain on bad chunked-encoding
|
||||||
o reading FTP server response in multiple reads
|
o --interface SIGSEGVed on a bad address
|
||||||
o picking one out of multiple proxy auth methods
|
o kill the HTTPS server better when stopping the test suite
|
||||||
o inet_ntoa_r() when built with uClibc
|
o builds fine with VS2005 on x64
|
||||||
o the so name issue for the LDAP library dynamic load
|
o auth fix for HTTP redirects and .netrc usage
|
||||||
o crash when using SOCKS4 proxy
|
o FTP uploads show the progress meter easier
|
||||||
o a debug printf() was removed
|
o MSVC makefile fixes for static libcurl builds
|
||||||
o CURLOPT_FILETIME when downloading FTP corrupted data
|
o configure fix for static libcurl build on Windows
|
||||||
o FTP upload resume now works even if no file is present on the site
|
o --retry-delay
|
||||||
o SSL seeding no longer attempts to read the whole random file
|
o POST with read callback now uses Expect: 100-continue
|
||||||
|
o CURLOPT_PORT didn't actually use the set port number
|
||||||
|
o HTTP 304 response with Content-Length: header
|
||||||
|
o time-conditioned FTP uploads
|
||||||
|
|
||||||
Other curl-related news since the previous public release:
|
Other curl-related news since the previous public release:
|
||||||
|
|
||||||
o the cURL project is now over 7 years old
|
o http://curl.mirroring.de/ is a new german curl mirror
|
||||||
o daily curl binary builds for Windows fresh from CVS:
|
o pycurl 7.13.2: http://pycurl.sf.net/
|
||||||
http://cool.haxx.se/curl-daily/
|
o TclCurl 0.13.2: http://personal1.iddeo.es/andresgarci/tclcurl/english/
|
||||||
o curl-tracker is a new mailinglist for "tracker" activities:
|
o http://curl.webhosting76.com/ is a new US curl mirror
|
||||||
http://cool.haxx.se/mailman/listinfo/curl-tracker
|
o http://curl.meulie.net/ is a new Canadian curl mirror
|
||||||
o libcurl binding for Common Lisp: http://common-lisp.net/project/cl-curl/
|
|
||||||
o pycurl 7.13.1 http://pycurl.sf.net
|
|
||||||
o http://curl.tolix.org is a new Californian mirror
|
|
||||||
o http://curl.seekmeup.com/ is a new mirror in US Texas
|
|
||||||
|
|
||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Dan Fandrich, Ignacio Vazquez-Abrams, Randy McMurchy, Dominick Meglio,
|
Christophe Legry, Cory Nelson, Gisle Vanem, Dan Fandrich, Toshiyuki Maezawa,
|
||||||
Jean-Marc Ranger, Tor Arntsen, Nodak Sodak, David Houlder, Gisle Vanem,
|
Olivier, Andres Garcia, Dave Dribin, Alex Suykov, Cory Nelson, Fred New,
|
||||||
Christopher R. Palmer, Gwenole Beauchesne, Augustus Saunders, Jesper Jensen,
|
Paul Moore, Alexander Zhuravlev, Bryan Henderson, Jeremy Brown, Allan,
|
||||||
Tom Moers, Andres Garcia, Hardeep Singh, Marcelo Juchem
|
Grigory Entin
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
11
TODO-RELEASE
11
TODO-RELEASE
@@ -1,6 +1,11 @@
|
|||||||
Issues not sorted in any particular order.
|
Issues not sorted in any particular order.
|
||||||
|
|
||||||
To get fixed in 7.13.3 (planned release: June 2005)
|
To get fixed in 7.14.0 (planned release: May/June 2005)
|
||||||
|
======================
|
||||||
|
|
||||||
|
- Make the tests run better on more platforms.
|
||||||
|
|
||||||
|
To get fixed in 7.14.1 (planned release: June 2005)
|
||||||
======================
|
======================
|
||||||
|
|
||||||
58 - Fix KNOWN_BUGS #19: "FTP 3rd party transfers with the multi interface
|
58 - Fix KNOWN_BUGS #19: "FTP 3rd party transfers with the multi interface
|
||||||
@@ -10,7 +15,7 @@ To get fixed in 7.13.3 (planned release: June 2005)
|
|||||||
Awaits OpenSSL support for this, no need to support this in libcurl before
|
Awaits OpenSSL support for this, no need to support this in libcurl before
|
||||||
there's an OpenSSL release that does it.
|
there's an OpenSSL release that does it.
|
||||||
|
|
||||||
To get fixed in 7.14.0
|
To get fixed in 7.15.0
|
||||||
======================
|
======================
|
||||||
|
|
||||||
55 - Add a function to the multi interface that gets file descriptors, as an
|
55 - Add a function to the multi interface that gets file descriptors, as an
|
||||||
@@ -24,7 +29,7 @@ To get fixed in 7.14.0
|
|||||||
internally use and assume the multi interface. The select()-loop should
|
internally use and assume the multi interface. The select()-loop should
|
||||||
use the new function from (55).
|
use the new function from (55).
|
||||||
|
|
||||||
To get fixed in 7.15.0
|
To get fixed in 7.16.0
|
||||||
======================
|
======================
|
||||||
|
|
||||||
57 - Add an interface to libcurl for getting and setting cookies from an easy
|
57 - Add an interface to libcurl for getting and setting cookies from an easy
|
||||||
|
27
acinclude.m4
27
acinclude.m4
@@ -122,6 +122,30 @@ dnl end of non-blocking try-compile test
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl Check for struct sockaddr_storage. Most IPv6-enabled hosts have it, but
|
||||||
|
dnl AIX 4.3 is one known exception.
|
||||||
|
AC_DEFUN([TYPE_SOCKADDR_STORAGE],
|
||||||
|
[
|
||||||
|
AC_CHECK_TYPE([struct sockaddr_storage],
|
||||||
|
AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1,
|
||||||
|
[if struct sockaddr_storage is defined]), ,
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
dnl Check for socklen_t: historically on BSD it is an int, and in
|
dnl Check for socklen_t: historically on BSD it is an int, and in
|
||||||
dnl POSIX 1g it is a type of its own, but some platforms use different
|
dnl POSIX 1g it is a type of its own, but some platforms use different
|
||||||
dnl types for the argument to getsockopt, getpeername, etc. So we
|
dnl types for the argument to getsockopt, getpeername, etc. So we
|
||||||
@@ -234,7 +258,7 @@ exit (h == NULL ? 1 : 0); }],[
|
|||||||
])
|
])
|
||||||
|
|
||||||
dnl ************************************************************
|
dnl ************************************************************
|
||||||
dnl check for working getaddrinfo()
|
dnl check for working getaddrinfo() that works with AI_NUMERICHOST
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
|
AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
|
||||||
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
||||||
@@ -249,6 +273,7 @@ int main(void)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
|
||||||
|
13
ares/AUTHORS
Normal file
13
ares/AUTHORS
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
c-ares is based on ares, and these are the people that have worked on it since
|
||||||
|
the fork was made:
|
||||||
|
|
||||||
|
Daniel Stenberg
|
||||||
|
Dominick Meglio
|
||||||
|
liren at vivisimo.com
|
||||||
|
James Bursa
|
||||||
|
Duncan Wilcox
|
||||||
|
Dirk Manske
|
||||||
|
Dan Fandrich
|
||||||
|
Gisle Vanem
|
||||||
|
Gunter Knauf
|
||||||
|
Henrik Stoerner
|
31
ares/CHANGES
31
ares/CHANGES
@@ -1,5 +1,36 @@
|
|||||||
Changelog for the c-ares project
|
Changelog for the c-ares project
|
||||||
|
|
||||||
|
* May 14
|
||||||
|
|
||||||
|
- Added an inet_ntop function from BIND for systems that do not have it.
|
||||||
|
|
||||||
|
* April 9
|
||||||
|
|
||||||
|
- Made sortlist support IPv6 (this can probably use some testing).
|
||||||
|
|
||||||
|
- Made sortlist support CIDR matching for IPv4.
|
||||||
|
|
||||||
|
* April 8
|
||||||
|
|
||||||
|
- Added preliminary IPv6 support to ares_gethostbyname. Currently, sortlist
|
||||||
|
does not work with IPv6. Also provided an implementation of bitncmp from
|
||||||
|
BIND for systems that do not supply this function. This will be used to add
|
||||||
|
IPv6 support to sortlist.
|
||||||
|
|
||||||
|
- Made ares_gethostbyaddr support IPv6 by specifying AF_INET6 as the family.
|
||||||
|
The function can lookup IPv6 addresses both from files (/etc/hosts) and
|
||||||
|
DNS lookups.
|
||||||
|
|
||||||
|
* April 7
|
||||||
|
|
||||||
|
- Tupone Alfredo fixed includes of arpa/nameser_compat.h to build fine on Mac
|
||||||
|
OS X.
|
||||||
|
|
||||||
|
* April 5
|
||||||
|
|
||||||
|
- Dominick Meglio: Provided implementations of inet_net_pton and inet_pton
|
||||||
|
from BIND for systems that do not include these functions.
|
||||||
|
|
||||||
* March 11, 2005
|
* March 11, 2005
|
||||||
|
|
||||||
- Dominick Meglio added ares_parse_aaaa_reply.c and did various
|
- Dominick Meglio added ares_parse_aaaa_reply.c and did various
|
||||||
|
@@ -12,7 +12,7 @@ MSVCFILES = vc/adig/adig.dep vc/adig/adig.dsp vc/adig/adig.mak \
|
|||||||
# adig and ahost are just sample programs and thus not mentioned with the
|
# adig and ahost are just sample programs and thus not mentioned with the
|
||||||
# regular sources and headers
|
# regular sources and headers
|
||||||
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
|
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
|
||||||
$(MSVCFILES)
|
$(MSVCFILES) AUTHORS
|
||||||
|
|
||||||
|
|
||||||
VER=-version-info 0:0:0
|
VER=-version-info 0:0:0
|
||||||
|
@@ -4,9 +4,10 @@ ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \
|
|||||||
ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \
|
ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \
|
||||||
ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \
|
ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \
|
||||||
windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \
|
windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \
|
||||||
ares_parse_aaaa_reply.c
|
ares_parse_aaaa_reply.c inet_net_pton.c bitncmp.c inet_ntop.c
|
||||||
|
|
||||||
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h
|
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h \
|
||||||
|
inet_net_pton.h ares_ipv6.h bitncmp.h
|
||||||
|
|
||||||
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
||||||
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
|
||||||
|
@@ -126,7 +126,10 @@ DL = '
|
|||||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(wildcard ares_*.c))
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
|
include Makefile.inc
|
||||||
|
|
||||||
|
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(CSOURCES)))
|
||||||
|
|
||||||
.PHONY: lib nlm prebuild dist install clean
|
.PHONY: lib nlm prebuild dist install clean
|
||||||
|
|
||||||
@@ -256,6 +259,7 @@ config.h: Makefile.netware
|
|||||||
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
|
||||||
@echo $(DL)#define PACKAGE_BUGREPORT "curl-bug@haxx.se"$(DL) >> $@
|
@echo $(DL)#define PACKAGE_BUGREPORT "curl-bug@haxx.se"$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||||
|
@echo $(DL)#define HAVE_ARPA_NAMESER_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
|
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
|
||||||
@@ -297,8 +301,11 @@ config.h: Makefile.netware
|
|||||||
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
||||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
|
||||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||||
|
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||||
|
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||||
|
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||||
|
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||||
ifdef NW_WINSOCK
|
ifdef NW_WINSOCK
|
||||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||||
else
|
else
|
||||||
|
@@ -30,12 +30,15 @@
|
|||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
|
||||||
int ares__get_hostent(FILE *fp, struct hostent **host)
|
int ares__get_hostent(FILE *fp, int family, struct hostent **host)
|
||||||
{
|
{
|
||||||
char *line = NULL, *p, *q, *canonical, **alias;
|
char *line = NULL, *p, *q, *canonical, **alias;
|
||||||
int status, linesize, end_at_hostname, naliases;
|
int status, linesize, end_at_hostname, naliases;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
struct in6_addr addr6;
|
||||||
|
int addrlen = sizeof(struct in_addr);
|
||||||
struct hostent *hostent = NULL;
|
struct hostent *hostent = NULL;
|
||||||
|
|
||||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||||
@@ -56,6 +59,17 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
|||||||
*p = 0;
|
*p = 0;
|
||||||
addr.s_addr = inet_addr(line);
|
addr.s_addr = inet_addr(line);
|
||||||
if (addr.s_addr == INADDR_NONE)
|
if (addr.s_addr == INADDR_NONE)
|
||||||
|
{
|
||||||
|
if (ares_inet_pton(AF_INET6, line, &addr6) > 0)
|
||||||
|
{
|
||||||
|
if (family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
addrlen = sizeof(struct in6_addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (family != AF_INET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Get the canonical hostname. */
|
/* Get the canonical hostname. */
|
||||||
@@ -100,7 +114,7 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
|||||||
hostent->h_addr_list = malloc(2 * sizeof(char *));
|
hostent->h_addr_list = malloc(2 * sizeof(char *));
|
||||||
if (!hostent->h_addr_list)
|
if (!hostent->h_addr_list)
|
||||||
break;
|
break;
|
||||||
hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
|
hostent->h_addr_list[0] = malloc(addrlen);
|
||||||
if (!hostent->h_addr_list[0])
|
if (!hostent->h_addr_list[0])
|
||||||
break;
|
break;
|
||||||
hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
|
hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
|
||||||
@@ -134,9 +148,12 @@ int ares__get_hostent(FILE *fp, struct hostent **host)
|
|||||||
}
|
}
|
||||||
hostent->h_aliases[naliases] = NULL;
|
hostent->h_aliases[naliases] = NULL;
|
||||||
|
|
||||||
hostent->h_addrtype = AF_INET;
|
hostent->h_addrtype = family;
|
||||||
hostent->h_length = sizeof(struct in_addr);
|
hostent->h_length = addrlen;
|
||||||
memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
|
if (family == AF_INET)
|
||||||
|
memcpy(hostent->h_addr_list[0], &addr, addrlen);
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
memcpy(hostent->h_addr_list[0], &addr6, addrlen);
|
||||||
hostent->h_addr_list[1] = NULL;
|
hostent->h_addr_list[1] = NULL;
|
||||||
*host = hostent;
|
*host = hostent;
|
||||||
free(line);
|
free(line);
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
* this software for any purpose. It is provided "as is"
|
* this software for any purpose. It is provided "as is"
|
||||||
* without express or implied warranty.
|
* without express or implied warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@@ -23,6 +22,9 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -31,6 +33,7 @@
|
|||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
|
||||||
#ifdef WATT32
|
#ifdef WATT32
|
||||||
#undef WIN32
|
#undef WIN32
|
||||||
@@ -39,7 +42,8 @@
|
|||||||
struct addr_query {
|
struct addr_query {
|
||||||
/* Arguments passed to ares_gethostbyaddr() */
|
/* Arguments passed to ares_gethostbyaddr() */
|
||||||
ares_channel channel;
|
ares_channel channel;
|
||||||
struct in_addr addr;
|
union ares_addr addr;
|
||||||
|
int family;
|
||||||
ares_host_callback callback;
|
ares_host_callback callback;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
@@ -51,14 +55,21 @@ static void addr_callback(void *arg, int status, unsigned char *abuf,
|
|||||||
int alen);
|
int alen);
|
||||||
static void end_aquery(struct addr_query *aquery, int status,
|
static void end_aquery(struct addr_query *aquery, int status,
|
||||||
struct hostent *host);
|
struct hostent *host);
|
||||||
static int file_lookup(struct in_addr *addr, struct hostent **host);
|
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
|
||||||
|
|
||||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||||
int family, ares_host_callback callback, void *arg)
|
int family, ares_host_callback callback, void *arg)
|
||||||
{
|
{
|
||||||
struct addr_query *aquery;
|
struct addr_query *aquery;
|
||||||
|
|
||||||
if (family != AF_INET || addrlen != sizeof(struct in_addr))
|
if (family != AF_INET && family != AF_INET6)
|
||||||
|
{
|
||||||
|
callback(arg, ARES_ENOTIMP, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((family == AF_INET && addrlen != sizeof(struct in_addr)) ||
|
||||||
|
(family == AF_INET6 && addrlen != sizeof(struct in6_addr)))
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL);
|
callback(arg, ARES_ENOTIMP, NULL);
|
||||||
return;
|
return;
|
||||||
@@ -71,7 +82,11 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
aquery->channel = channel;
|
aquery->channel = channel;
|
||||||
memcpy(&aquery->addr, addr, sizeof(aquery->addr));
|
if (family == AF_INET)
|
||||||
|
memcpy(&aquery->addr.addr4, addr, sizeof(struct in_addr));
|
||||||
|
else
|
||||||
|
memcpy(&aquery->addr.addr6, addr, sizeof(struct in6_addr));
|
||||||
|
aquery->family = family;
|
||||||
aquery->callback = callback;
|
aquery->callback = callback;
|
||||||
aquery->arg = arg;
|
aquery->arg = arg;
|
||||||
aquery->remaining_lookups = channel->lookups;
|
aquery->remaining_lookups = channel->lookups;
|
||||||
@@ -82,7 +97,7 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
|||||||
static void next_lookup(struct addr_query *aquery)
|
static void next_lookup(struct addr_query *aquery)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
char name[64];
|
char name[128];
|
||||||
int a1, a2, a3, a4, status;
|
int a1, a2, a3, a4, status;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
@@ -92,7 +107,9 @@ static void next_lookup(struct addr_query *aquery)
|
|||||||
switch (*p)
|
switch (*p)
|
||||||
{
|
{
|
||||||
case 'b':
|
case 'b':
|
||||||
addr = ntohl(aquery->addr.s_addr);
|
if (aquery->family == AF_INET)
|
||||||
|
{
|
||||||
|
addr = ntohl(aquery->addr.addr4.s_addr);
|
||||||
a1 = (int)((addr >> 24) & 0xff);
|
a1 = (int)((addr >> 24) & 0xff);
|
||||||
a2 = (int)((addr >> 16) & 0xff);
|
a2 = (int)((addr >> 16) & 0xff);
|
||||||
a3 = (int)((addr >> 8) & 0xff);
|
a3 = (int)((addr >> 8) & 0xff);
|
||||||
@@ -101,9 +118,27 @@ static void next_lookup(struct addr_query *aquery)
|
|||||||
aquery->remaining_lookups = p + 1;
|
aquery->remaining_lookups = p + 1;
|
||||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||||
aquery);
|
aquery);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char *bytes;
|
||||||
|
bytes = (unsigned char *)&aquery->addr.addr6.s6_addr;
|
||||||
|
sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
||||||
|
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
|
||||||
|
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
|
||||||
|
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
|
||||||
|
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
|
||||||
|
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
|
||||||
|
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
|
||||||
|
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
|
||||||
|
bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4);
|
||||||
|
aquery->remaining_lookups = p + 1;
|
||||||
|
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||||
|
aquery);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 'f':
|
case 'f':
|
||||||
status = file_lookup(&aquery->addr, &host);
|
status = file_lookup(&aquery->addr, aquery->family, &host);
|
||||||
if (status != ARES_ENOTFOUND)
|
if (status != ARES_ENOTFOUND)
|
||||||
{
|
{
|
||||||
end_aquery(aquery, status, host);
|
end_aquery(aquery, status, host);
|
||||||
@@ -122,8 +157,12 @@ static void addr_callback(void *arg, int status, unsigned char *abuf, int alen)
|
|||||||
|
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr,
|
if (aquery->family == AF_INET)
|
||||||
|
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4,
|
||||||
sizeof(struct in_addr), AF_INET, &host);
|
sizeof(struct in_addr), AF_INET, &host);
|
||||||
|
else
|
||||||
|
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr6,
|
||||||
|
sizeof(struct in6_addr), AF_INET6, &host);
|
||||||
end_aquery(aquery, status, host);
|
end_aquery(aquery, status, host);
|
||||||
}
|
}
|
||||||
else if (status == ARES_EDESTRUCTION)
|
else if (status == ARES_EDESTRUCTION)
|
||||||
@@ -141,7 +180,7 @@ static void end_aquery(struct addr_query *aquery, int status,
|
|||||||
free(aquery);
|
free(aquery);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int file_lookup(struct in_addr *addr, struct hostent **host)
|
static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int status;
|
int status;
|
||||||
@@ -178,11 +217,23 @@ static int file_lookup(struct in_addr *addr, struct hostent **host)
|
|||||||
fp = fopen(PATH_HOSTS, "r");
|
fp = fopen(PATH_HOSTS, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return ARES_ENOTFOUND;
|
return ARES_ENOTFOUND;
|
||||||
|
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
|
||||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS)
|
|
||||||
{
|
{
|
||||||
if (memcmp((*host)->h_addr, addr, sizeof(struct in_addr)) == 0)
|
if (family != (*host)->h_addrtype)
|
||||||
|
{
|
||||||
|
ares_free_hostent(*host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (family == AF_INET)
|
||||||
|
{
|
||||||
|
if (memcmp((*host)->h_addr, &addr->addr4, sizeof(struct in_addr)) == 0)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (memcmp((*host)->h_addr, &addr->addr6, sizeof(struct in6_addr)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
ares_free_hostent(*host);
|
ares_free_hostent(*host);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@@ -23,8 +23,13 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -33,6 +38,8 @@
|
|||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
#include "bitncmp.h"
|
||||||
|
|
||||||
#ifdef WATT32
|
#ifdef WATT32
|
||||||
#undef WIN32
|
#undef WIN32
|
||||||
@@ -44,7 +51,7 @@ struct host_query {
|
|||||||
char *name;
|
char *name;
|
||||||
ares_host_callback callback;
|
ares_host_callback callback;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
int family;
|
||||||
const char *remaining_lookups;
|
const char *remaining_lookups;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,13 +60,17 @@ static void host_callback(void *arg, int status, unsigned char *abuf,
|
|||||||
int alen);
|
int alen);
|
||||||
static void end_hquery(struct host_query *hquery, int status,
|
static void end_hquery(struct host_query *hquery, int status,
|
||||||
struct hostent *host);
|
struct hostent *host);
|
||||||
static int fake_hostent(const char *name, ares_host_callback callback,
|
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
||||||
void *arg);
|
void *arg);
|
||||||
static int file_lookup(const char *name, struct hostent **host);
|
static int file_lookup(const char *name, int family, struct hostent **host);
|
||||||
static void sort_addresses(struct hostent *host, struct apattern *sortlist,
|
static void sort_addresses(struct hostent *host, struct apattern *sortlist,
|
||||||
int nsort);
|
int nsort);
|
||||||
|
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
|
||||||
|
int nsort);
|
||||||
static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
||||||
int nsort);
|
int nsort);
|
||||||
|
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
||||||
|
int nsort);
|
||||||
|
|
||||||
void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||||
ares_host_callback callback, void *arg)
|
ares_host_callback callback, void *arg)
|
||||||
@@ -67,13 +78,13 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
struct host_query *hquery;
|
struct host_query *hquery;
|
||||||
|
|
||||||
/* Right now we only know how to look up Internet addresses. */
|
/* Right now we only know how to look up Internet addresses. */
|
||||||
if (family != AF_INET)
|
if (family != AF_INET && family != AF_INET6)
|
||||||
{
|
{
|
||||||
callback(arg, ARES_ENOTIMP, NULL);
|
callback(arg, ARES_ENOTIMP, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fake_hostent(name, callback, arg))
|
if (fake_hostent(name, family, callback, arg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Allocate and fill in the host query structure. */
|
/* Allocate and fill in the host query structure. */
|
||||||
@@ -85,6 +96,7 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
|||||||
}
|
}
|
||||||
hquery->channel = channel;
|
hquery->channel = channel;
|
||||||
hquery->name = strdup(name);
|
hquery->name = strdup(name);
|
||||||
|
hquery->family = family;
|
||||||
if (!hquery->name)
|
if (!hquery->name)
|
||||||
{
|
{
|
||||||
free(hquery);
|
free(hquery);
|
||||||
@@ -112,13 +124,17 @@ static void next_lookup(struct host_query *hquery)
|
|||||||
case 'b':
|
case 'b':
|
||||||
/* DNS lookup */
|
/* DNS lookup */
|
||||||
hquery->remaining_lookups = p + 1;
|
hquery->remaining_lookups = p + 1;
|
||||||
|
if (hquery->family == AF_INET6)
|
||||||
|
ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback,
|
||||||
|
hquery);
|
||||||
|
else
|
||||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||||
hquery);
|
hquery);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
/* Host file lookup */
|
/* Host file lookup */
|
||||||
status = file_lookup(hquery->name, &host);
|
status = file_lookup(hquery->name, hquery->family, &host);
|
||||||
if (status != ARES_ENOTFOUND)
|
if (status != ARES_ENOTFOUND)
|
||||||
{
|
{
|
||||||
end_hquery(hquery, status, host);
|
end_hquery(hquery, status, host);
|
||||||
@@ -137,12 +153,28 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
|
|||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
|
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
|
{
|
||||||
|
if (hquery->family == AF_INET)
|
||||||
{
|
{
|
||||||
status = ares_parse_a_reply(abuf, alen, &host);
|
status = ares_parse_a_reply(abuf, alen, &host);
|
||||||
if (host && channel->nsort)
|
if (host && channel->nsort)
|
||||||
sort_addresses(host, channel->sortlist, channel->nsort);
|
sort_addresses(host, channel->sortlist, channel->nsort);
|
||||||
|
}
|
||||||
|
else if (hquery->family == AF_INET6)
|
||||||
|
{
|
||||||
|
status = ares_parse_aaaa_reply(abuf, alen, &host);
|
||||||
|
if (host && channel->nsort)
|
||||||
|
sort6_addresses(host, channel->sortlist, channel->nsort);
|
||||||
|
}
|
||||||
end_hquery(hquery, status, host);
|
end_hquery(hquery, status, host);
|
||||||
}
|
}
|
||||||
|
else if (status == ARES_ENODATA && hquery->family == AF_INET6)
|
||||||
|
{
|
||||||
|
/* There was no AAAA now lookup an A */
|
||||||
|
hquery->family = AF_INET;
|
||||||
|
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
|
||||||
|
hquery);
|
||||||
|
}
|
||||||
else if (status == ARES_EDESTRUCTION)
|
else if (status == ARES_EDESTRUCTION)
|
||||||
end_hquery(hquery, status, NULL);
|
end_hquery(hquery, status, NULL);
|
||||||
else
|
else
|
||||||
@@ -162,36 +194,34 @@ static void end_hquery(struct host_query *hquery, int status,
|
|||||||
/* If the name looks like an IP address, fake up a host entry, end the
|
/* If the name looks like an IP address, fake up a host entry, end the
|
||||||
* query immediately, and return true. Otherwise return false.
|
* query immediately, and return true. Otherwise return false.
|
||||||
*/
|
*/
|
||||||
static int fake_hostent(const char *name, ares_host_callback callback,
|
static int fake_hostent(const char *name, int family, ares_host_callback callback,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct in_addr addr;
|
|
||||||
struct hostent hostent;
|
struct hostent hostent;
|
||||||
const char *p;
|
|
||||||
char *aliases[1] = { NULL };
|
char *aliases[1] = { NULL };
|
||||||
char *addrs[2];
|
char *addrs[2];
|
||||||
|
int result = 0;
|
||||||
|
struct in_addr in;
|
||||||
|
struct in6_addr in6;
|
||||||
|
|
||||||
/* It only looks like an IP address if it's all numbers and dots. */
|
if (family == AF_INET)
|
||||||
for (p = name; *p; p++)
|
result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
|
||||||
{
|
else if (family == AF_INET6)
|
||||||
if (!isdigit((unsigned char)*p) && *p != '.')
|
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It also only looks like an IP address if it's non-zero-length and
|
if (!result)
|
||||||
* doesn't end with a dot.
|
|
||||||
*/
|
|
||||||
if (p == name || *(p - 1) == '.')
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* It looks like an IP address. Figure out what IP address it is. */
|
if (family == AF_INET)
|
||||||
addr.s_addr = inet_addr(name);
|
|
||||||
if (addr.s_addr == INADDR_NONE)
|
|
||||||
{
|
{
|
||||||
callback(arg, ARES_EBADNAME, NULL);
|
hostent.h_length = sizeof(struct in_addr);
|
||||||
return 1;
|
addrs[0] = (char *)∈
|
||||||
|
}
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
{
|
||||||
|
hostent.h_length = sizeof(struct in6_addr);
|
||||||
|
addrs[0] = (char *)&in6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the name, to avoid a constness violation. */
|
/* Duplicate the name, to avoid a constness violation. */
|
||||||
hostent.h_name = strdup(name);
|
hostent.h_name = strdup(name);
|
||||||
if (!hostent.h_name)
|
if (!hostent.h_name)
|
||||||
@@ -201,11 +231,9 @@ static int fake_hostent(const char *name, ares_host_callback callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in the rest of the host structure and terminate the query. */
|
/* Fill in the rest of the host structure and terminate the query. */
|
||||||
addrs[0] = (char *) &addr;
|
|
||||||
addrs[1] = NULL;
|
addrs[1] = NULL;
|
||||||
hostent.h_aliases = aliases;
|
hostent.h_aliases = aliases;
|
||||||
hostent.h_addrtype = AF_INET;
|
hostent.h_addrtype = family;
|
||||||
hostent.h_length = sizeof(struct in_addr);
|
|
||||||
hostent.h_addr_list = addrs;
|
hostent.h_addr_list = addrs;
|
||||||
callback(arg, ARES_SUCCESS, &hostent);
|
callback(arg, ARES_SUCCESS, &hostent);
|
||||||
|
|
||||||
@@ -213,7 +241,7 @@ static int fake_hostent(const char *name, ares_host_callback callback,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int file_lookup(const char *name, struct hostent **host)
|
static int file_lookup(const char *name, int family, struct hostent **host)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char **alias;
|
char **alias;
|
||||||
@@ -252,7 +280,7 @@ static int file_lookup(const char *name, struct hostent **host)
|
|||||||
if (!fp)
|
if (!fp)
|
||||||
return ARES_ENOTFOUND;
|
return ARES_ENOTFOUND;
|
||||||
|
|
||||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS)
|
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
if (strcasecmp((*host)->h_name, name) == 0)
|
if (strcasecmp((*host)->h_name, name) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -310,8 +338,66 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
|||||||
|
|
||||||
for (i = 0; i < nsort; i++)
|
for (i = 0; i < nsort; i++)
|
||||||
{
|
{
|
||||||
if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr)
|
if (sortlist[i].family != AF_INET)
|
||||||
|
continue;
|
||||||
|
if (sortlist[i].type == PATTERN_MASK)
|
||||||
|
{
|
||||||
|
if ((addr->s_addr & sortlist[i].mask.addr.addr4.s_addr)
|
||||||
|
== sortlist[i].addr.addr4.s_addr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addr.addr4.s_addr,
|
||||||
|
sortlist[i].mask.bits))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
|
||||||
|
int nsort)
|
||||||
|
{
|
||||||
|
struct in6_addr a1, a2;
|
||||||
|
int i1, i2, ind1, ind2;
|
||||||
|
|
||||||
|
/* This is a simple insertion sort, not optimized at all. i1 walks
|
||||||
|
* through the address list, with the loop invariant that everything
|
||||||
|
* to the left of i1 is sorted. In the loop body, the value at i1 is moved
|
||||||
|
* back through the list (via i2) until it is in sorted order.
|
||||||
|
*/
|
||||||
|
for (i1 = 0; host->h_addr_list[i1]; i1++)
|
||||||
|
{
|
||||||
|
memcpy(&a1, host->h_addr_list[i1], sizeof(struct in6_addr));
|
||||||
|
ind1 = get6_address_index(&a1, sortlist, nsort);
|
||||||
|
for (i2 = i1 - 1; i2 >= 0; i2--)
|
||||||
|
{
|
||||||
|
memcpy(&a2, host->h_addr_list[i2], sizeof(struct in6_addr));
|
||||||
|
ind2 = get6_address_index(&a2, sortlist, nsort);
|
||||||
|
if (ind2 <= ind1)
|
||||||
|
break;
|
||||||
|
memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the first entry in sortlist which matches addr. Return nsort
|
||||||
|
* if none of them match.
|
||||||
|
*/
|
||||||
|
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
||||||
|
int nsort)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nsort; i++)
|
||||||
|
{
|
||||||
|
if (sortlist[i].family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addr.addr6.s6_addr, sortlist[i].mask.bits))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,10 +27,17 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -44,6 +51,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
|
||||||
#ifdef WATT32
|
#ifdef WATT32
|
||||||
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
||||||
@@ -61,6 +69,7 @@ static int set_search(ares_channel channel, const char *str);
|
|||||||
static int set_options(ares_channel channel, const char *str);
|
static int set_options(ares_channel channel, const char *str);
|
||||||
static const char *try_option(const char *p, const char *q, const char *opt);
|
static const char *try_option(const char *p, const char *q, const char *opt);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
|
||||||
static int ip_addr(const char *s, int len, struct in_addr *addr);
|
static int ip_addr(const char *s, int len, struct in_addr *addr);
|
||||||
static void natural_mask(struct apattern *pat);
|
static void natural_mask(struct apattern *pat);
|
||||||
static int config_domain(ares_channel channel, char *str);
|
static int config_domain(ares_channel channel, char *str);
|
||||||
@@ -821,36 +830,69 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
|||||||
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||||
const char *str)
|
const char *str)
|
||||||
{
|
{
|
||||||
struct apattern pat, *newsort;
|
struct apattern pat;
|
||||||
const char *q;
|
const char *q;
|
||||||
|
|
||||||
/* Add sortlist entries. */
|
/* Add sortlist entries. */
|
||||||
while (*str && *str != ';')
|
while (*str && *str != ';')
|
||||||
{
|
{
|
||||||
|
int bits;
|
||||||
|
char ipbuf[16], ipbufpfx[32];
|
||||||
|
/* Find just the IP */
|
||||||
q = str;
|
q = str;
|
||||||
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q))
|
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q))
|
||||||
q++;
|
q++;
|
||||||
if (ip_addr(str, (int)(q - str), &pat.addr) == 0)
|
memcpy(ipbuf, str, (int)(q-str));
|
||||||
{
|
ipbuf[(int)(q-str)] = 0;
|
||||||
/* We have a pattern address; now determine the mask. */
|
/* Find the prefix */
|
||||||
if (*q == '/')
|
if (*q == '/')
|
||||||
{
|
{
|
||||||
str = q + 1;
|
const char *str2 = q+1;
|
||||||
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
while (*q && *q != ';' && !isspace((unsigned char)*q))
|
||||||
q++;
|
q++;
|
||||||
if (ip_addr(str, (int)(q - str), &pat.mask) != 0)
|
memcpy(ipbufpfx, str, (int)(q-str));
|
||||||
|
ipbufpfx[(int)(q-str)] = 0;
|
||||||
|
str = str2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ipbufpfx[0] = 0;
|
||||||
|
/* Lets see if it is CIDR */
|
||||||
|
/* First we'll try IPv6 */
|
||||||
|
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx ? ipbufpfx : ipbuf, &pat.addr.addr6,
|
||||||
|
sizeof(pat.addr.addr6))) > 0)
|
||||||
|
{
|
||||||
|
pat.type = PATTERN_CIDR;
|
||||||
|
pat.mask.bits = bits;
|
||||||
|
pat.family = AF_INET6;
|
||||||
|
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
if (ipbufpfx &&
|
||||||
|
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
|
||||||
|
sizeof(pat.addr.addr4))) > 0)
|
||||||
|
{
|
||||||
|
pat.type = PATTERN_CIDR;
|
||||||
|
pat.mask.bits = bits;
|
||||||
|
pat.family = AF_INET;
|
||||||
|
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
/* See if it is just a regular IP */
|
||||||
|
else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
|
||||||
|
{
|
||||||
|
if (ipbufpfx)
|
||||||
|
{
|
||||||
|
memcpy(ipbuf, str, (int)(q-str));
|
||||||
|
ipbuf[(int)(q-str)] = 0;
|
||||||
|
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
|
||||||
natural_mask(&pat);
|
natural_mask(&pat);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
natural_mask(&pat);
|
natural_mask(&pat);
|
||||||
|
pat.family = AF_INET;
|
||||||
/* Add this pattern to our list. */
|
pat.type = PATTERN_MASK;
|
||||||
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
|
if (!sortlist_alloc(sortlist, nsort, &pat))
|
||||||
if (!newsort)
|
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
newsort[*nsort] = pat;
|
|
||||||
*sortlist = newsort;
|
|
||||||
(*nsort)++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -969,15 +1011,24 @@ static const char *try_option(const char *p, const char *q, const char *opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
static int ip_addr(const char *s, int len, struct in_addr *addr)
|
static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat)
|
||||||
|
{
|
||||||
|
struct apattern *newsort;
|
||||||
|
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
|
||||||
|
if (!newsort)
|
||||||
|
return 0;
|
||||||
|
newsort[*nsort] = *pat;
|
||||||
|
*sortlist = newsort;
|
||||||
|
(*nsort)++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
|
||||||
{
|
{
|
||||||
char ipbuf[16];
|
|
||||||
|
|
||||||
/* Four octets and three periods yields at most 15 characters. */
|
/* Four octets and three periods yields at most 15 characters. */
|
||||||
if (len > 15)
|
if (len > 15)
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(ipbuf, s, len);
|
|
||||||
ipbuf[len] = 0;
|
|
||||||
|
|
||||||
addr->s_addr = inet_addr(ipbuf);
|
addr->s_addr = inet_addr(ipbuf);
|
||||||
if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
|
if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
|
||||||
@@ -992,16 +1043,16 @@ static void natural_mask(struct apattern *pat)
|
|||||||
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
|
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
|
||||||
* but portable.
|
* but portable.
|
||||||
*/
|
*/
|
||||||
addr.s_addr = ntohl(pat->addr.s_addr);
|
addr.s_addr = ntohl(pat->addr.addr4.s_addr);
|
||||||
|
|
||||||
/* This is out of date in the CIDR world, but some people might
|
/* This is out of date in the CIDR world, but some people might
|
||||||
* still rely on it.
|
* still rely on it.
|
||||||
*/
|
*/
|
||||||
if (IN_CLASSA(addr.s_addr))
|
if (IN_CLASSA(addr.s_addr))
|
||||||
pat->mask.s_addr = htonl(IN_CLASSA_NET);
|
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSA_NET);
|
||||||
else if (IN_CLASSB(addr.s_addr))
|
else if (IN_CLASSB(addr.s_addr))
|
||||||
pat->mask.s_addr = htonl(IN_CLASSB_NET);
|
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
|
||||||
else
|
else
|
||||||
pat->mask.s_addr = htonl(IN_CLASSC_NET);
|
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
48
ares/ares_ipv6.h
Normal file
48
ares/ares_ipv6.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ARES_IPV6_H
|
||||||
|
#define ARES_IPV6_H
|
||||||
|
|
||||||
|
#ifndef HAVE_PF_INET6
|
||||||
|
#define PF_INET6 AF_INET6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||||
|
struct in6_addr
|
||||||
|
{
|
||||||
|
unsigned char s6_addr[16];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_IN6ADDRSZ
|
||||||
|
#if SIZEOF_STRUCT_IN6_ADDR == 0
|
||||||
|
/* We cannot have it set to zero, so we pick a fixed value here */
|
||||||
|
#define NS_IN6ADDRSZ 16
|
||||||
|
#else
|
||||||
|
#define NS_IN6ADDRSZ SIZEOF_STRUCT_IN6_ADDR
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_INADDRSZ
|
||||||
|
#define NS_INADDRSZ SIZEOF_STRUCT_IN_ADDR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_INT16SZ
|
||||||
|
#define NS_INT16SZ 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ARES_IPV6_H */
|
@@ -21,6 +21,9 @@
|
|||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -24,6 +24,9 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -23,13 +23,19 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_dns.h"
|
#include "ares_dns.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
|
||||||
|
@@ -23,6 +23,9 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -69,6 +69,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "ares_ipv6.h"
|
||||||
|
|
||||||
struct send_request {
|
struct send_request {
|
||||||
/* Remaining data to send */
|
/* Remaining data to send */
|
||||||
const unsigned char *data;
|
const unsigned char *data;
|
||||||
@@ -124,9 +126,23 @@ struct query {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* An IP address pattern; matches an IP address X if X & mask == addr */
|
/* An IP address pattern; matches an IP address X if X & mask == addr */
|
||||||
|
#define PATTERN_MASK 0x1
|
||||||
|
#define PATTERN_CIDR 0x2
|
||||||
|
|
||||||
|
union ares_addr {
|
||||||
|
struct in_addr addr4;
|
||||||
|
struct in6_addr addr6;
|
||||||
|
};
|
||||||
|
|
||||||
struct apattern {
|
struct apattern {
|
||||||
struct in_addr addr;
|
union ares_addr addr;
|
||||||
struct in_addr mask;
|
union
|
||||||
|
{
|
||||||
|
union ares_addr addr;
|
||||||
|
unsigned short bits;
|
||||||
|
} mask;
|
||||||
|
int family;
|
||||||
|
unsigned short type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ares_channeldata {
|
struct ares_channeldata {
|
||||||
@@ -156,7 +172,7 @@ struct ares_channeldata {
|
|||||||
|
|
||||||
void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
void ares__send_query(ares_channel channel, struct query *query, time_t now);
|
||||||
void ares__close_sockets(struct server_state *server);
|
void ares__close_sockets(struct server_state *server);
|
||||||
int ares__get_hostent(FILE *fp, struct hostent **host);
|
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
|
||||||
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
int ares__read_line(FILE *fp, char **buf, int *bufsize);
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
#ifdef CURLDEBUG
|
||||||
|
@@ -27,6 +27,9 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -4,12 +4,12 @@
|
|||||||
#define ARES__VERSION_H
|
#define ARES__VERSION_H
|
||||||
|
|
||||||
#define ARES_VERSION_MAJOR 1
|
#define ARES_VERSION_MAJOR 1
|
||||||
#define ARES_VERSION_MINOR 2
|
#define ARES_VERSION_MINOR 3
|
||||||
#define ARES_VERSION_PATCH 0
|
#define ARES_VERSION_PATCH 0
|
||||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||||
(ARES_VERSION_MINOR<<8)|\
|
(ARES_VERSION_MINOR<<8)|\
|
||||||
(ARES_VERSION_PATCH))
|
(ARES_VERSION_PATCH))
|
||||||
#define ARES_VERSION_STR "1.2.0"
|
#define ARES_VERSION_STR "1.3.0"
|
||||||
|
|
||||||
const char *ares_version(int *version);
|
const char *ares_version(int *version);
|
||||||
|
|
||||||
|
60
ares/bitncmp.c
Normal file
60
ares/bitncmp.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_BITNCMP
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "bitncmp.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int
|
||||||
|
* bitncmp(l, r, n)
|
||||||
|
* compare bit masks l and r, for n bits.
|
||||||
|
* return:
|
||||||
|
* -1, 1, or 0 in the libc tradition.
|
||||||
|
* note:
|
||||||
|
* network byte order assumed. this means 192.5.5.240/28 has
|
||||||
|
* 0x11110000 in its fourth octet.
|
||||||
|
* author:
|
||||||
|
* Paul Vixie (ISC), June 1996
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ares_bitncmp(const void *l, const void *r, int n) {
|
||||||
|
unsigned int lb, rb;
|
||||||
|
int x, b;
|
||||||
|
|
||||||
|
b = n / 8;
|
||||||
|
x = memcmp(l, r, b);
|
||||||
|
if (x)
|
||||||
|
return (x);
|
||||||
|
|
||||||
|
lb = ((const unsigned char *)l)[b];
|
||||||
|
rb = ((const unsigned char *)r)[b];
|
||||||
|
for (b = n % 8; b > 0; b--) {
|
||||||
|
if ((lb & 0x80) != (rb & 0x80)) {
|
||||||
|
if (lb & 0x80)
|
||||||
|
return (1);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
lb <<= 1;
|
||||||
|
rb <<= 1;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
#endif
|
26
ares/bitncmp.h
Normal file
26
ares/bitncmp.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BITNCMP_H
|
||||||
|
#define BITNCMP_H
|
||||||
|
|
||||||
|
#ifndef HAVE_BITNCMP
|
||||||
|
int ares_bitncmp(const void *l, const void *r, int n);
|
||||||
|
#else
|
||||||
|
#define ares_bitncmp(x,y,z) bitncmp(x,y,z)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BITNCMP_H */
|
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
libtoolize --copy --automake --force
|
${LIBTOOLIZE:-libtoolize} --copy --automake --force
|
||||||
aclocal
|
${ACLOCAL:-aclocal}
|
||||||
autoheader
|
${AUTOHEADER:-autoheader}
|
||||||
autoconf
|
${AUTOCONF:-autoconf}
|
||||||
automake --add-missing
|
${AUTOMAKE:-automake} --add-missing
|
||||||
|
@@ -67,6 +67,20 @@ AC_CHECK_HEADERS(
|
|||||||
sys/socket.h \
|
sys/socket.h \
|
||||||
winsock.h \
|
winsock.h \
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
|
arpa/nameser.h \
|
||||||
|
arpa/nameser_compat.h \
|
||||||
|
arpa/inet.h, , ,
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
dnl We do this default-include simply to make sure that the nameser_compat.h
|
||||||
|
dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1
|
||||||
|
dnl (and others?) is not designed to allow this.
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#endif
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl check for AF_INET6
|
dnl check for AF_INET6
|
||||||
@@ -120,4 +134,141 @@ CARES_CHECK_STRUCT(
|
|||||||
AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
|
AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dnl check for inet_pton
|
||||||
|
AC_CHECK_FUNCS(inet_pton)
|
||||||
|
dnl Some systems have it, but not IPv6
|
||||||
|
if test "$ac_cv_func_inet_pton" = "yes" ; then
|
||||||
|
AC_MSG_CHECKING(if inet_pton supports IPv6)
|
||||||
|
AC_TRY_RUN(
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
struct in6_addr addr6;
|
||||||
|
if (inet_pton(AF_INET6, "::1", &addr6) < 1)
|
||||||
|
exit(1);
|
||||||
|
else
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.])
|
||||||
|
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||||
|
fi
|
||||||
|
dnl Check for inet_net_pton
|
||||||
|
AC_CHECK_FUNCS(inet_net_pton)
|
||||||
|
dnl Again, some systems have it, but not IPv6
|
||||||
|
if test "$ac_cv_func_inet_net_pton" = "yes" ; then
|
||||||
|
AC_MSG_CHECKING(if inet_net_pton supports IPv6)
|
||||||
|
AC_TRY_RUN(
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
struct in6_addr addr6;
|
||||||
|
if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1)
|
||||||
|
exit(1);
|
||||||
|
else
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.])
|
||||||
|
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for inet_ntop
|
||||||
|
AC_CHECK_FUNCS(inet_ntop)
|
||||||
|
dnl Again, some systems have it, but not IPv6
|
||||||
|
if test "$ac_cv_func_inet_ntop" = "yes" ; then
|
||||||
|
AC_MSG_CHECKING(if inet_ntop supports IPv6)
|
||||||
|
AC_TRY_RUN(
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
struct in6_addr addr6;
|
||||||
|
char buf[128];
|
||||||
|
if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)
|
||||||
|
exit(1);
|
||||||
|
else
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.])
|
||||||
|
], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(struct in6_addr, ,
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
]
|
||||||
|
)
|
||||||
|
AC_CHECK_SIZEOF(struct in_addr, ,
|
||||||
|
[
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK_H
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS(bitncmp)
|
||||||
|
|
||||||
|
|
||||||
AC_OUTPUT(Makefile)
|
AC_OUTPUT(Makefile)
|
||||||
|
439
ares/inet_net_pton.c
Normal file
439
ares/inet_net_pton.c
Normal file
@@ -0,0 +1,439 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(WATT32)
|
||||||
|
#include "nameser.h"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ares_ipv6.h"
|
||||||
|
#include "inet_net_pton.h"
|
||||||
|
|
||||||
|
#if !defined(HAVE_INET_NET_PTON) || !defined(HAVE_INET_NET_PTON_IPV6) || \
|
||||||
|
!defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* static int
|
||||||
|
* inet_net_pton_ipv4(src, dst, size)
|
||||||
|
* convert IPv4 network number from presentation to network format.
|
||||||
|
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||||
|
* "size" is in bytes and describes "dst".
|
||||||
|
* return:
|
||||||
|
* number of bits, either imputed classfully or specified with /CIDR,
|
||||||
|
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||||
|
* not an IPv4 network specification.
|
||||||
|
* note:
|
||||||
|
* network byte order assumed. this means 192.5.5.240/28 has
|
||||||
|
* 0b11110000 in its fourth octet.
|
||||||
|
* author:
|
||||||
|
* Paul Vixie (ISC), June 1996
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
|
||||||
|
{
|
||||||
|
static const char xdigits[] = "0123456789abcdef";
|
||||||
|
static const char digits[] = "0123456789";
|
||||||
|
int n, ch, tmp = 0, dirty, bits;
|
||||||
|
const unsigned char *odst = dst;
|
||||||
|
|
||||||
|
ch = *src++;
|
||||||
|
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||||
|
&& isascii((unsigned char)(src[1]))
|
||||||
|
&& isxdigit((unsigned char)(src[1]))) {
|
||||||
|
/* Hexadecimal: Eat nybble string. */
|
||||||
|
if (size <= 0U)
|
||||||
|
goto emsgsize;
|
||||||
|
dirty = 0;
|
||||||
|
src++; /* skip x or X. */
|
||||||
|
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
|
||||||
|
if (isupper(ch))
|
||||||
|
ch = tolower(ch);
|
||||||
|
n = (int)(strchr(xdigits, ch) - xdigits);
|
||||||
|
if (dirty == 0)
|
||||||
|
tmp = n;
|
||||||
|
else
|
||||||
|
tmp = (tmp << 4) | n;
|
||||||
|
if (++dirty == 2) {
|
||||||
|
if (size-- <= 0U)
|
||||||
|
goto emsgsize;
|
||||||
|
*dst++ = (unsigned char) tmp;
|
||||||
|
dirty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dirty) { /* Odd trailing nybble? */
|
||||||
|
if (size-- <= 0U)
|
||||||
|
goto emsgsize;
|
||||||
|
*dst++ = (unsigned char) (tmp << 4);
|
||||||
|
}
|
||||||
|
} else if (isascii(ch) && isdigit(ch)) {
|
||||||
|
/* Decimal: eat dotted digit string. */
|
||||||
|
for (;;) {
|
||||||
|
tmp = 0;
|
||||||
|
do {
|
||||||
|
n = (int)(strchr(digits, ch) - digits);
|
||||||
|
tmp *= 10;
|
||||||
|
tmp += n;
|
||||||
|
if (tmp > 255)
|
||||||
|
goto enoent;
|
||||||
|
} while ((ch = *src++) != '\0' &&
|
||||||
|
isascii(ch) && isdigit(ch));
|
||||||
|
if (size-- <= 0U)
|
||||||
|
goto emsgsize;
|
||||||
|
*dst++ = (unsigned char) tmp;
|
||||||
|
if (ch == '\0' || ch == '/')
|
||||||
|
break;
|
||||||
|
if (ch != '.')
|
||||||
|
goto enoent;
|
||||||
|
ch = *src++;
|
||||||
|
if (!isascii(ch) || !isdigit(ch))
|
||||||
|
goto enoent;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
goto enoent;
|
||||||
|
|
||||||
|
bits = -1;
|
||||||
|
if (ch == '/' && isascii((unsigned char)(src[0])) &&
|
||||||
|
isdigit((unsigned char)(src[0])) && dst > odst) {
|
||||||
|
/* CIDR width specifier. Nothing can follow it. */
|
||||||
|
ch = *src++; /* Skip over the /. */
|
||||||
|
bits = 0;
|
||||||
|
do {
|
||||||
|
n = (int)(strchr(digits, ch) - digits);
|
||||||
|
bits *= 10;
|
||||||
|
bits += n;
|
||||||
|
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||||
|
if (ch != '\0')
|
||||||
|
goto enoent;
|
||||||
|
if (bits > 32)
|
||||||
|
goto emsgsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Firey death and destruction unless we prefetched EOS. */
|
||||||
|
if (ch != '\0')
|
||||||
|
goto enoent;
|
||||||
|
|
||||||
|
/* If nothing was written to the destination, we found no address. */
|
||||||
|
if (dst == odst)
|
||||||
|
goto enoent;
|
||||||
|
/* If no CIDR spec was given, infer width from net class. */
|
||||||
|
if (bits == -1) {
|
||||||
|
if (*odst >= 240) /* Class E */
|
||||||
|
bits = 32;
|
||||||
|
else if (*odst >= 224) /* Class D */
|
||||||
|
bits = 8;
|
||||||
|
else if (*odst >= 192) /* Class C */
|
||||||
|
bits = 24;
|
||||||
|
else if (*odst >= 128) /* Class B */
|
||||||
|
bits = 16;
|
||||||
|
else /* Class A */
|
||||||
|
bits = 8;
|
||||||
|
/* If imputed mask is narrower than specified octets, widen. */
|
||||||
|
if (bits < ((dst - odst) * 8))
|
||||||
|
bits = (int)(dst - odst) * 8;
|
||||||
|
/*
|
||||||
|
* If there are no additional bits specified for a class D
|
||||||
|
* address adjust bits to 4.
|
||||||
|
*/
|
||||||
|
if (bits == 8 && *odst == 224)
|
||||||
|
bits = 4;
|
||||||
|
}
|
||||||
|
/* Extend network to cover the actual mask. */
|
||||||
|
while (bits > ((dst - odst) * 8)) {
|
||||||
|
if (size-- <= 0U)
|
||||||
|
goto emsgsize;
|
||||||
|
*dst++ = '\0';
|
||||||
|
}
|
||||||
|
return (bits);
|
||||||
|
|
||||||
|
enoent:
|
||||||
|
errno = ENOENT;
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
emsgsize:
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getbits(const char *src, int *bitsp)
|
||||||
|
{
|
||||||
|
static const char digits[] = "0123456789";
|
||||||
|
int n;
|
||||||
|
int val;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
val = 0;
|
||||||
|
n = 0;
|
||||||
|
while ((ch = *src++) != '\0') {
|
||||||
|
const char *pch;
|
||||||
|
|
||||||
|
pch = strchr(digits, ch);
|
||||||
|
if (pch != NULL) {
|
||||||
|
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||||
|
return (0);
|
||||||
|
val *= 10;
|
||||||
|
val += (pch - digits);
|
||||||
|
if (val > 128) /* range */
|
||||||
|
return (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
return (0);
|
||||||
|
*bitsp = val;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getv4(const char *src, unsigned char *dst, int *bitsp)
|
||||||
|
{
|
||||||
|
static const char digits[] = "0123456789";
|
||||||
|
unsigned char *odst = dst;
|
||||||
|
int n;
|
||||||
|
unsigned int val;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
val = 0;
|
||||||
|
n = 0;
|
||||||
|
while ((ch = *src++) != '\0') {
|
||||||
|
const char *pch;
|
||||||
|
|
||||||
|
pch = strchr(digits, ch);
|
||||||
|
if (pch != NULL) {
|
||||||
|
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||||
|
return (0);
|
||||||
|
val *= 10;
|
||||||
|
val += (pch - digits);
|
||||||
|
if (val > 255) /* range */
|
||||||
|
return (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '.' || ch == '/') {
|
||||||
|
if (dst - odst > 3) /* too many octets? */
|
||||||
|
return (0);
|
||||||
|
*dst++ = val;
|
||||||
|
if (ch == '/')
|
||||||
|
return (getbits(src, bitsp));
|
||||||
|
val = 0;
|
||||||
|
n = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
return (0);
|
||||||
|
if (dst - odst > 3) /* too many octets? */
|
||||||
|
return (0);
|
||||||
|
*dst++ = val;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
|
||||||
|
{
|
||||||
|
static const char xdigits_l[] = "0123456789abcdef",
|
||||||
|
xdigits_u[] = "0123456789ABCDEF";
|
||||||
|
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||||
|
const char *xdigits, *curtok;
|
||||||
|
int ch, saw_xdigit;
|
||||||
|
unsigned int val;
|
||||||
|
int digits;
|
||||||
|
int bits;
|
||||||
|
size_t bytes;
|
||||||
|
int words;
|
||||||
|
int ipv4;
|
||||||
|
|
||||||
|
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||||
|
endp = tp + NS_IN6ADDRSZ;
|
||||||
|
colonp = NULL;
|
||||||
|
/* Leading :: requires some special handling. */
|
||||||
|
if (*src == ':')
|
||||||
|
if (*++src != ':')
|
||||||
|
goto enoent;
|
||||||
|
curtok = src;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
val = 0;
|
||||||
|
digits = 0;
|
||||||
|
bits = -1;
|
||||||
|
ipv4 = 0;
|
||||||
|
while ((ch = *src++) != '\0') {
|
||||||
|
const char *pch;
|
||||||
|
|
||||||
|
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||||
|
pch = strchr((xdigits = xdigits_u), ch);
|
||||||
|
if (pch != NULL) {
|
||||||
|
val <<= 4;
|
||||||
|
val |= (pch - xdigits);
|
||||||
|
if (++digits > 4)
|
||||||
|
goto enoent;
|
||||||
|
saw_xdigit = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == ':') {
|
||||||
|
curtok = src;
|
||||||
|
if (!saw_xdigit) {
|
||||||
|
if (colonp)
|
||||||
|
goto enoent;
|
||||||
|
colonp = tp;
|
||||||
|
continue;
|
||||||
|
} else if (*src == '\0')
|
||||||
|
goto enoent;
|
||||||
|
if (tp + NS_INT16SZ > endp)
|
||||||
|
return (0);
|
||||||
|
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (unsigned char) val & 0xff;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
digits = 0;
|
||||||
|
val = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||||
|
getv4(curtok, tp, &bits) > 0) {
|
||||||
|
tp += NS_INADDRSZ;
|
||||||
|
saw_xdigit = 0;
|
||||||
|
ipv4 = 1;
|
||||||
|
break; /* '\0' was seen by inet_pton4(). */
|
||||||
|
}
|
||||||
|
if (ch == '/' && getbits(src, &bits) > 0)
|
||||||
|
break;
|
||||||
|
goto enoent;
|
||||||
|
}
|
||||||
|
if (saw_xdigit) {
|
||||||
|
if (tp + NS_INT16SZ > endp)
|
||||||
|
goto enoent;
|
||||||
|
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||||
|
*tp++ = (unsigned char) val & 0xff;
|
||||||
|
}
|
||||||
|
if (bits == -1)
|
||||||
|
bits = 128;
|
||||||
|
|
||||||
|
words = (bits + 15) / 16;
|
||||||
|
if (words < 2)
|
||||||
|
words = 2;
|
||||||
|
if (ipv4)
|
||||||
|
words = 8;
|
||||||
|
endp = tmp + 2 * words;
|
||||||
|
|
||||||
|
if (colonp != NULL) {
|
||||||
|
/*
|
||||||
|
* Since some memmove()'s erroneously fail to handle
|
||||||
|
* overlapping regions, we'll do the shift by hand.
|
||||||
|
*/
|
||||||
|
const int n = (int)(tp - colonp);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (tp == endp)
|
||||||
|
goto enoent;
|
||||||
|
for (i = 1; i <= n; i++) {
|
||||||
|
endp[- i] = colonp[n - i];
|
||||||
|
colonp[n - i] = 0;
|
||||||
|
}
|
||||||
|
tp = endp;
|
||||||
|
}
|
||||||
|
if (tp != endp)
|
||||||
|
goto enoent;
|
||||||
|
|
||||||
|
bytes = (bits + 7) / 8;
|
||||||
|
if (bytes > size)
|
||||||
|
goto emsgsize;
|
||||||
|
memcpy(dst, tmp, bytes);
|
||||||
|
return (bits);
|
||||||
|
|
||||||
|
enoent:
|
||||||
|
errno = ENOENT;
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
emsgsize:
|
||||||
|
errno = EMSGSIZE;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int
|
||||||
|
* inet_net_pton(af, src, dst, size)
|
||||||
|
* convert network number from presentation to network format.
|
||||||
|
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||||
|
* "size" is in bytes and describes "dst".
|
||||||
|
* return:
|
||||||
|
* number of bits, either imputed classfully or specified with /CIDR,
|
||||||
|
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||||
|
* not a valid network specification.
|
||||||
|
* author:
|
||||||
|
* Paul Vixie (ISC), June 1996
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ares_inet_net_pton(int af, const char *src, void *dst, size_t size)
|
||||||
|
{
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
return (inet_net_pton_ipv4(src, dst, size));
|
||||||
|
case AF_INET6:
|
||||||
|
return (inet_net_pton_ipv6(src, dst, size));
|
||||||
|
default:
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_INET_PTON) || !defined(HAVE_INET_PTON_IPV6)
|
||||||
|
int ares_inet_pton(int af, const char *src, void *dst)
|
||||||
|
{
|
||||||
|
int size, result;
|
||||||
|
|
||||||
|
if (af == AF_INET)
|
||||||
|
size = sizeof(struct in_addr);
|
||||||
|
else if (af == AF_INET6)
|
||||||
|
size = sizeof(struct in6_addr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
result = ares_inet_net_pton(af, src, dst, size);
|
||||||
|
if (result == -1 && errno == ENOENT)
|
||||||
|
return 0;
|
||||||
|
return (result > -1 ? 1 : -1);
|
||||||
|
}
|
||||||
|
#endif
|
31
ares/inet_net_pton.h
Normal file
31
ares/inet_net_pton.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INET_NET_PTON_H
|
||||||
|
#define INET_NET_PTON_H
|
||||||
|
|
||||||
|
#if defined(HAVE_INET_PTON) && defined(HAVE_INET_PTON_IPV6)
|
||||||
|
#define ares_inet_pton(x,y,z) inet_pton(x,y,z)
|
||||||
|
#else
|
||||||
|
int ares_inet_pton(int af, const char *src, void *dst);
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_INET_NET_PTON) && defined(HAVE_INET_NET_PTON_IPV6)
|
||||||
|
#define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z)
|
||||||
|
#else
|
||||||
|
int ares_inet_net_pton(int af, const char *src, void *dst, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INET_NET_PTON_H */
|
206
ares/inet_ntop.c
Normal file
206
ares/inet_ntop.c
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||||
|
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||||
|
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||||
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(WATT32)
|
||||||
|
#include "nameser.h"
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_NAMESER_H
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ares_ipv6.h"
|
||||||
|
#include "inet_ntop.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(HAVE_INET_NTOP) || !defined(HAVE_INET_NTOP_IPV6)
|
||||||
|
|
||||||
|
#ifdef SPRINTF_CHAR
|
||||||
|
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||||
|
#else
|
||||||
|
# define SPRINTF(x) ((size_t)sprintf x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: Don't even consider trying to compile this on a system where
|
||||||
|
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
|
||||||
|
static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
|
||||||
|
|
||||||
|
/* char *
|
||||||
|
* inet_ntop(af, src, dst, size)
|
||||||
|
* convert a network format address to presentation format.
|
||||||
|
* return:
|
||||||
|
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
ares_inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
return (inet_ntop4(src, dst, size));
|
||||||
|
case AF_INET6:
|
||||||
|
return (inet_ntop6(src, dst, size));
|
||||||
|
default:
|
||||||
|
errno = EAFNOSUPPORT;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* const char *
|
||||||
|
* inet_ntop4(src, dst, size)
|
||||||
|
* format an IPv4 address, more or less like inet_ntoa()
|
||||||
|
* return:
|
||||||
|
* `dst' (as a const)
|
||||||
|
* notes:
|
||||||
|
* (1) uses no statics
|
||||||
|
* (2) takes a unsigned char* not an in_addr as input
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
static const char fmt[] = "%u.%u.%u.%u";
|
||||||
|
char tmp[sizeof "255.255.255.255"];
|
||||||
|
|
||||||
|
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(dst, tmp);
|
||||||
|
return (dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* const char *
|
||||||
|
* inet_ntop6(src, dst, size)
|
||||||
|
* convert IPv6 binary address into presentation (printable) format
|
||||||
|
* author:
|
||||||
|
* Paul Vixie, 1996.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Note that int32_t and int16_t need only be "at least" large enough
|
||||||
|
* to contain a value of the specified size. On some systems, like
|
||||||
|
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||||
|
* Keep this in mind if you think this function should have been coded
|
||||||
|
* to use pointer overlays. All the world's not a VAX.
|
||||||
|
*/
|
||||||
|
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||||
|
struct { int base, len; } best, cur;
|
||||||
|
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preprocess:
|
||||||
|
* Copy the input (bytewise) array into a wordwise array.
|
||||||
|
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||||
|
*/
|
||||||
|
memset(words, '\0', sizeof words);
|
||||||
|
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||||
|
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||||
|
best.base = -1;
|
||||||
|
cur.base = -1;
|
||||||
|
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||||
|
if (words[i] == 0) {
|
||||||
|
if (cur.base == -1)
|
||||||
|
cur.base = i, cur.len = 1;
|
||||||
|
else
|
||||||
|
cur.len++;
|
||||||
|
} else {
|
||||||
|
if (cur.base != -1) {
|
||||||
|
if (best.base == -1 || cur.len > best.len)
|
||||||
|
best = cur;
|
||||||
|
cur.base = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur.base != -1) {
|
||||||
|
if (best.base == -1 || cur.len > best.len)
|
||||||
|
best = cur;
|
||||||
|
}
|
||||||
|
if (best.base != -1 && best.len < 2)
|
||||||
|
best.base = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format the result.
|
||||||
|
*/
|
||||||
|
tp = tmp;
|
||||||
|
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||||
|
/* Are we inside the best run of 0x00's? */
|
||||||
|
if (best.base != -1 && i >= best.base &&
|
||||||
|
i < (best.base + best.len)) {
|
||||||
|
if (i == best.base)
|
||||||
|
*tp++ = ':';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Are we following an initial run of 0x00s or any real hex? */
|
||||||
|
if (i != 0)
|
||||||
|
*tp++ = ':';
|
||||||
|
/* Is this address an encapsulated IPv4? */
|
||||||
|
if (i == 6 && best.base == 0 &&
|
||||||
|
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||||
|
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||||
|
return (NULL);
|
||||||
|
tp += strlen(tp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tp += SPRINTF((tp, "%x", words[i]));
|
||||||
|
}
|
||||||
|
/* Was it a trailing run of 0x00's? */
|
||||||
|
if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
|
||||||
|
*tp++ = ':';
|
||||||
|
*tp++ = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for overflow, copy, and we're done.
|
||||||
|
*/
|
||||||
|
if ((size_t)(tp - tmp) > size) {
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
strcpy(dst, tmp);
|
||||||
|
return (dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
ares/inet_ntop.h
Normal file
26
ares/inet_ntop.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INET_NTOP_H
|
||||||
|
#define INET_NTOP_H
|
||||||
|
|
||||||
|
#ifdef HAVE_INET_NTOP
|
||||||
|
#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)
|
||||||
|
#else
|
||||||
|
const char *ares_inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INET_NET_NTOP_H */
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#define EINPROGRESS WSAEINPROGRESS
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define EMSGSIZE WSAEMSGSIZE
|
||||||
|
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||||
|
|
||||||
/* Structure for scatter/gather I/O. */
|
/* Structure for scatter/gather I/O. */
|
||||||
struct iovec
|
struct iovec
|
||||||
@@ -37,7 +39,9 @@ int ares_gettimeofday(struct timeval *tv, struct timezone *tz);
|
|||||||
#endif /* !NETWARE */
|
#endif /* !NETWARE */
|
||||||
|
|
||||||
#define NS_CMPRSFLGS 0xc0
|
#define NS_CMPRSFLGS 0xc0
|
||||||
|
#define NS_IN6ADDRSZ 16
|
||||||
|
#define NS_INT16SZ 2
|
||||||
|
#define NS_INADDRSZ 4
|
||||||
|
|
||||||
/* Flag bits indicating name compression. */
|
/* Flag bits indicating name compression. */
|
||||||
#define INDIR_MASK NS_CMPRSFLGS
|
#define INDIR_MASK NS_CMPRSFLGS
|
||||||
|
11
ares/setup.h
11
ares/setup.h
@@ -78,15 +78,4 @@ int ares_strcasecmp(const char *s1, const char *s2);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_PF_INET6
|
|
||||||
#define PF_INET6 AF_INET6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
|
||||||
struct in6_addr
|
|
||||||
{
|
|
||||||
unsigned char s6_addr[16];
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ARES_SETUP_H */
|
#endif /* ARES_SETUP_H */
|
||||||
|
28
buildconf
28
buildconf
@@ -85,6 +85,14 @@ fi
|
|||||||
|
|
||||||
echo "buildconf: automake version $am_version (ok)"
|
echo "buildconf: automake version $am_version (ok)"
|
||||||
|
|
||||||
|
ac=`findtool aclocal`
|
||||||
|
|
||||||
|
if test -z "$ac"; then
|
||||||
|
echo "buildconf: aclocal not found. Weird automake installation!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "buildconf: aclocal found"
|
||||||
|
fi
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# libtool check
|
# libtool check
|
||||||
@@ -142,6 +150,13 @@ fi
|
|||||||
|
|
||||||
echo "buildconf: libtool version $lt_version (ok)"
|
echo "buildconf: libtool version $lt_version (ok)"
|
||||||
|
|
||||||
|
if test -f "$LIBTOOLIZE"; then
|
||||||
|
echo "buildconf: libtoolize found"
|
||||||
|
else
|
||||||
|
echo "buildconf: libtoolize not found. Weird libtool installation!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# m4 check
|
# m4 check
|
||||||
#
|
#
|
||||||
@@ -155,6 +170,10 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
# perl check
|
||||||
|
#
|
||||||
|
PERL=`findtool perl`
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -164,8 +183,13 @@ echo "buildconf: running libtoolize"
|
|||||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
|
||||||
echo "buildconf: running aclocal"
|
echo "buildconf: running aclocal"
|
||||||
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
|
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
|
||||||
echo "buildconf: running aclocal hack to convert all mv to mv -f"
|
if test -n "$PERL"; then
|
||||||
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
|
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
|
||||||
|
else
|
||||||
|
echo "buildconf: perl not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo "buildconf: running autoheader"
|
echo "buildconf: running autoheader"
|
||||||
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
|
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
|
||||||
echo "buildconf: cp lib/config.h.in src/config.h.in"
|
echo "buildconf: cp lib/config.h.in src/config.h.in"
|
||||||
|
193
configure.ac
193
configure.ac
@@ -7,7 +7,7 @@ dnl We don't know the version number "staticly" so we use a dash here
|
|||||||
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
||||||
|
|
||||||
dnl configure script copyright
|
dnl configure script copyright
|
||||||
AC_COPYRIGHT([Copyright (c) 1998 - 2004 Daniel Stenberg, <daniel@haxx.se>
|
AC_COPYRIGHT([Copyright (c) 1998 - 2005 Daniel Stenberg, <daniel@haxx.se>
|
||||||
This configure script may be copied, distributed and modified under the
|
This configure script may be copied, distributed and modified under the
|
||||||
terms of the curl license; see COPYING for more details])
|
terms of the curl license; see COPYING for more details])
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ AC_SUBST(PKGADD_VENDOR)
|
|||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl initialize all the info variables
|
dnl initialize all the info variables
|
||||||
curl_ssl_msg="no (--with-ssl)"
|
curl_ssl_msg="no (--with-ssl / --with-gnutls)"
|
||||||
curl_zlib_msg="no (--with-zlib)"
|
curl_zlib_msg="no (--with-zlib)"
|
||||||
curl_krb4_msg="no (--with-krb4*)"
|
curl_krb4_msg="no (--with-krb4*)"
|
||||||
curl_gss_msg="no (--with-gssapi)"
|
curl_gss_msg="no (--with-gssapi)"
|
||||||
@@ -122,6 +122,14 @@ case $host in
|
|||||||
*-*-mingw*)
|
*-*-mingw*)
|
||||||
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
|
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
<20> <20>AC_MSG_CHECKING([if we need CURL_STATICLIB])
|
||||||
|
if test "X$enable_shared" = "Xno"
|
||||||
|
then
|
||||||
|
AC_DEFINE(CURL_STATICLIB, 1, [when not building a shared library])
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
<20> <20>else
|
||||||
|
<20> <20> <20>AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
@@ -747,11 +755,7 @@ AC_HELP_STRING([--with-ssl=PATH],[where to look for SSL, PATH points to the SSL
|
|||||||
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
AC_HELP_STRING([--without-ssl], [disable SSL]),
|
||||||
OPT_SSL=$withval)
|
OPT_SSL=$withval)
|
||||||
|
|
||||||
if test X"$OPT_SSL" = Xno
|
if test X"$OPT_SSL" != Xno; then
|
||||||
then
|
|
||||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
|
|
||||||
else
|
|
||||||
|
|
||||||
dnl backup the pre-ssl variables
|
dnl backup the pre-ssl variables
|
||||||
CLEANLDFLAGS="$LDFLAGS"
|
CLEANLDFLAGS="$LDFLAGS"
|
||||||
CLEANCPPFLAGS="$CPPFLAGS"
|
CLEANCPPFLAGS="$CPPFLAGS"
|
||||||
@@ -840,10 +844,7 @@ else
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
if test X"$HAVECRYPTO" != X"yes"; then
|
if test X"$HAVECRYPTO" = X"yes"; then
|
||||||
AC_MSG_WARN([crypto lib was not found; SSL will be disabled])
|
|
||||||
|
|
||||||
else
|
|
||||||
dnl This is only reasonable to do if crypto actually is there: check for
|
dnl This is only reasonable to do if crypto actually is there: check for
|
||||||
dnl SSL libs NOTE: it is important to do this AFTER the crypto lib
|
dnl SSL libs NOTE: it is important to do this AFTER the crypto lib
|
||||||
|
|
||||||
@@ -868,13 +869,13 @@ else
|
|||||||
dnl Have the libraries--check for SSLeay/OpenSSL headers
|
dnl Have the libraries--check for SSLeay/OpenSSL headers
|
||||||
AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
|
AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
|
||||||
openssl/pem.h openssl/ssl.h openssl/err.h,
|
openssl/pem.h openssl/ssl.h openssl/err.h,
|
||||||
curl_ssl_msg="enabled"
|
curl_ssl_msg="enabled (OpenSSL)"
|
||||||
OPENSSL_ENABLED=1
|
OPENSSL_ENABLED=1
|
||||||
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
|
||||||
|
|
||||||
if test $ac_cv_header_openssl_x509_h = no; then
|
if test $ac_cv_header_openssl_x509_h = no; then
|
||||||
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h,
|
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h,
|
||||||
curl_ssl_msg="enabled"
|
curl_ssl_msg="enabled (OpenSSL)"
|
||||||
OPENSSL_ENABLED=1)
|
OPENSSL_ENABLED=1)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -898,11 +899,6 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl **********************************************************************
|
|
||||||
dnl Check for the CA bundle
|
|
||||||
dnl **********************************************************************
|
|
||||||
|
|
||||||
if test X"$OPENSSL_ENABLED" = X"1"; then
|
if test X"$OPENSSL_ENABLED" = X"1"; then
|
||||||
dnl If the ENGINE library seems to be around, check for the OpenSSL engine
|
dnl If the ENGINE library seems to be around, check for the OpenSSL engine
|
||||||
dnl stuff, it is kind of "separated" from the main SSL check
|
dnl stuff, it is kind of "separated" from the main SSL check
|
||||||
@@ -912,30 +908,6 @@ dnl **********************************************************************
|
|||||||
AC_CHECK_FUNCS( ENGINE_load_builtin_engines )
|
AC_CHECK_FUNCS( ENGINE_load_builtin_engines )
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_MSG_CHECKING([CA cert bundle install path])
|
|
||||||
|
|
||||||
AC_ARG_WITH(ca-bundle,
|
|
||||||
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
|
||||||
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
|
||||||
[ ca="$withval" ],
|
|
||||||
[
|
|
||||||
if test "x$prefix" != xNONE; then
|
|
||||||
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
|
||||||
else
|
|
||||||
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
|
||||||
fi
|
|
||||||
] )
|
|
||||||
|
|
||||||
if test X"$OPT_SSL" = Xno; then
|
|
||||||
ca="no"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$ca" != "xno"; then
|
|
||||||
CURL_CA_BUNDLE='"'$ca'"'
|
|
||||||
AC_SUBST(CURL_CA_BUNDLE)
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$ca])
|
|
||||||
|
|
||||||
dnl these can only exist if openssl exists
|
dnl these can only exist if openssl exists
|
||||||
|
|
||||||
AC_CHECK_FUNCS( RAND_status \
|
AC_CHECK_FUNCS( RAND_status \
|
||||||
@@ -955,8 +927,6 @@ AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Check for the random seed preferences
|
dnl Check for the random seed preferences
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -989,6 +959,115 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ----------------------------------------------------
|
||||||
|
dnl FIX: only check for GnuTLS if OpenSSL is not enabled
|
||||||
|
dnl ----------------------------------------------------
|
||||||
|
|
||||||
|
dnl Default to compiler & linker defaults for GnuTLS files & libraries.
|
||||||
|
OPT_GNUTLS=off
|
||||||
|
|
||||||
|
AC_ARG_WITH(gnutls,dnl
|
||||||
|
AC_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to the installation root (default: /usr/local/)])
|
||||||
|
AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]),
|
||||||
|
OPT_GNUTLS=$withval)
|
||||||
|
|
||||||
|
if test "$OPENSSL_ENABLED" != "1"; then
|
||||||
|
|
||||||
|
if test X"$OPT_GNUTLS" != Xoff; then
|
||||||
|
if test "x$OPT_GNUTLS" = "xyes"; then
|
||||||
|
check=`libgnutls-config --version 2>/dev/null`
|
||||||
|
if test -n "$check"; then
|
||||||
|
addlib=`libgnutls-config --libs`
|
||||||
|
addcflags=`libgnutls-config --cflags`
|
||||||
|
version=`libgnutls-config --version`
|
||||||
|
gtlsprefix=`libgnutls-config --prefix`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
addlib=`$OPT_GNUTLS/bin/libgnutls-config --libs`
|
||||||
|
addcflags=`$OPT_GNUTLS/bin/libgnutls-config --cflags`
|
||||||
|
version=`$OPT_GNUTLS/bin/libgnutls-config --version 2>/dev/null`
|
||||||
|
gtlsprefix=$OPT_GNUTLS
|
||||||
|
if test -z "$version"; then
|
||||||
|
version="unknown"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test -n "$addlib"; then
|
||||||
|
|
||||||
|
CLEANLDFLAGS="$LDFLAGS"
|
||||||
|
CLEANCPPFLAGS="$CPPFLAGS"
|
||||||
|
|
||||||
|
LDFLAGS="$LDFLAGS $addlib"
|
||||||
|
if test "$addcflags" != "-I/usr/include"; then
|
||||||
|
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_LIB(gnutls, gnutls_check_version,
|
||||||
|
[
|
||||||
|
AC_DEFINE(USE_GNUTLS, 1, [if GnuTLS is enabled])
|
||||||
|
AC_SUBST(USE_GNUTLS, [1])
|
||||||
|
USE_GNUTLS="yes"
|
||||||
|
curl_ssl_msg="enabled (GnuTLS)"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
LDFLAGS="$CLEANLDFLAGS"
|
||||||
|
CPPFLAGS="$CLEANCPPFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "x$USE_GNUTLS" = "xyes"; then
|
||||||
|
AC_MSG_NOTICE([detected GnuTLS version $version])
|
||||||
|
|
||||||
|
dnl when shared libs were found in a path that the run-time
|
||||||
|
dnl linker doesn't search through, we need to add it to
|
||||||
|
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||||
|
dnl due to this
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$gtlsprefix/lib$libsuff"
|
||||||
|
export LD_LIBRARY_PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi dnl GNUTLS not disabled
|
||||||
|
|
||||||
|
if test X"$USE_GNUTLS" != "Xyes"; then
|
||||||
|
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
||||||
|
AC_MSG_WARN([Use --with-ssl or --with-gnutls to address this.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi dnl OPENSSL != 1
|
||||||
|
|
||||||
|
dnl **********************************************************************
|
||||||
|
dnl Check for the CA bundle
|
||||||
|
dnl **********************************************************************
|
||||||
|
|
||||||
|
if test X"$USE_GNUTLS$OPENSSL_ENABLED" != "X"; then
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([CA cert bundle install path])
|
||||||
|
|
||||||
|
AC_ARG_WITH(ca-bundle,
|
||||||
|
AC_HELP_STRING([--with-ca-bundle=FILE], [File name to install the CA bundle as])
|
||||||
|
AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
|
||||||
|
[ ca="$withval" ],
|
||||||
|
[
|
||||||
|
if test "x$prefix" != xNONE; then
|
||||||
|
ca="\${prefix}/share/curl/curl-ca-bundle.crt"
|
||||||
|
else
|
||||||
|
ca="$ac_default_prefix/share/curl/curl-ca-bundle.crt"
|
||||||
|
fi
|
||||||
|
] )
|
||||||
|
|
||||||
|
if test "x$ca" != "xno"; then
|
||||||
|
CURL_CA_BUNDLE='"'$ca'"'
|
||||||
|
AC_SUBST(CURL_CA_BUNDLE)
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([$ca])
|
||||||
|
fi dnl only done if some kind of SSL was enabled
|
||||||
|
|
||||||
|
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
dnl Check for the presence of ZLIB libraries and headers
|
dnl Check for the presence of ZLIB libraries and headers
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
@@ -1321,6 +1400,8 @@ AC_CHECK_TYPE(ssize_t, ,
|
|||||||
TYPE_SOCKLEN_T
|
TYPE_SOCKLEN_T
|
||||||
TYPE_IN_ADDR_T
|
TYPE_IN_ADDR_T
|
||||||
|
|
||||||
|
TYPE_SOCKADDR_STORAGE
|
||||||
|
|
||||||
AC_FUNC_SELECT_ARGTYPES
|
AC_FUNC_SELECT_ARGTYPES
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
@@ -1414,9 +1495,22 @@ AC_CHECK_DECL(basename, ,
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl poll() might be badly emulated, as in Mac OS X 10.3 (and other BSDs?) and
|
AC_MSG_CHECKING([if we are Mac OS X (to disable poll)])
|
||||||
dnl to find out we make an extra check here!
|
disable_poll=no
|
||||||
if test "$ac_cv_func_poll" = "yes"; then
|
case $host in
|
||||||
|
*-*-darwin*)
|
||||||
|
disable_poll="yes";
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT($disable_poll)
|
||||||
|
|
||||||
|
if test "$disable_poll" = "no"; then
|
||||||
|
|
||||||
|
dnl poll() might be badly emulated, as in Mac OS X 10.3 (and other BSDs?) and
|
||||||
|
dnl to find out we make an extra check here!
|
||||||
|
if test "$ac_cv_func_poll" = "yes"; then
|
||||||
AC_MSG_CHECKING([if poll works with NULL inputs])
|
AC_MSG_CHECKING([if poll works with NULL inputs])
|
||||||
AC_RUN_IFELSE([
|
AC_RUN_IFELSE([
|
||||||
#ifdef HAVE_SYS_POLL_H
|
#ifdef HAVE_SYS_POLL_H
|
||||||
@@ -1435,8 +1529,8 @@ if test "$ac_cv_func_poll" = "yes"; then
|
|||||||
AC_MSG_RESULT(cross-compiling assumes yes)
|
AC_MSG_RESULT(cross-compiling assumes yes)
|
||||||
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
|
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
|
||||||
) dnl end of AC_RUN_IFELSE
|
) dnl end of AC_RUN_IFELSE
|
||||||
fi
|
fi dnl poll() was found
|
||||||
|
fi dnl poll()-check is not disabled
|
||||||
|
|
||||||
|
|
||||||
AC_PATH_PROG( PERL, perl, ,
|
AC_PATH_PROG( PERL, perl, ,
|
||||||
@@ -1727,4 +1821,5 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
|||||||
Built-in manual: ${curl_manual_msg}
|
Built-in manual: ${curl_manual_msg}
|
||||||
Verbose errors: ${curl_verbose_msg}
|
Verbose errors: ${curl_verbose_msg}
|
||||||
SSPI support: ${curl_sspi_msg}
|
SSPI support: ${curl_sspi_msg}
|
||||||
|
ca cert path: ${ca}
|
||||||
])
|
])
|
||||||
|
63
docs/FAQ
63
docs/FAQ
@@ -1,4 +1,4 @@
|
|||||||
Updated: December 21, 2004 (http://curl.haxx.se/docs/faq.html)
|
Updated: April 13, 2005 (http://curl.haxx.se/docs/faq.html)
|
||||||
_ _ ____ _
|
_ _ ____ _
|
||||||
___| | | | _ \| |
|
___| | | | _ \| |
|
||||||
/ __| | | | |_) | |
|
/ __| | | | |_) | |
|
||||||
@@ -43,6 +43,7 @@ FAQ
|
|||||||
3.15 Can I do recursive fetches with curl?
|
3.15 Can I do recursive fetches with curl?
|
||||||
3.16 What certificates do I need when I use SSL?
|
3.16 What certificates do I need when I use SSL?
|
||||||
3.17 How do I list the root dir of an FTP server?
|
3.17 How do I list the root dir of an FTP server?
|
||||||
|
3.18 Can I use curl to send a POST/PUT and not wait for a response?
|
||||||
|
|
||||||
4. Running Problems
|
4. Running Problems
|
||||||
4.1 Problems connecting to SSL servers.
|
4.1 Problems connecting to SSL servers.
|
||||||
@@ -74,6 +75,9 @@ FAQ
|
|||||||
5.7 Link errors when building libcurl on Windows!
|
5.7 Link errors when building libcurl on Windows!
|
||||||
5.8 libcurl.so.3: open failed: No such file or directory
|
5.8 libcurl.so.3: open failed: No such file or directory
|
||||||
5.9 How does libcurl resolve host names?
|
5.9 How does libcurl resolve host names?
|
||||||
|
5.10 How do I prevent libcurl from writing the response to stdout?
|
||||||
|
5.11 How do I make libcurl not receive the whole HTTP response?
|
||||||
|
5.12 Can I make libcurl fake or hide my real IP address?
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
6.1 I have a GPL program, can I use the libcurl library?
|
6.1 I have a GPL program, can I use the libcurl library?
|
||||||
@@ -97,7 +101,7 @@ FAQ
|
|||||||
cURL is the name of the project. The name is a play on 'Client for URLs',
|
cURL is the name of the project. The name is a play on 'Client for URLs',
|
||||||
originally with URL spelled in uppercase to make it obvious it deals with
|
originally 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
|
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
|
an abbreviation for "Client URL Request Library" or why not the recursive
|
||||||
version: "Curl URL Request Library".
|
version: "Curl URL Request Library".
|
||||||
|
|
||||||
The cURL project produces two products:
|
The cURL project produces two products:
|
||||||
@@ -296,8 +300,8 @@ FAQ
|
|||||||
|
|
||||||
2.2 Does curl work/build with other SSL libraries?
|
2.2 Does curl work/build with other SSL libraries?
|
||||||
|
|
||||||
Curl has been written to use OpenSSL, although there should not be much
|
Curl has been written to use OpenSSL or GnuTLS, although there should not be
|
||||||
problems using a different library. If anyone does "port" curl to use a
|
many problems using a different library. If anyone does "port" curl to use a
|
||||||
different SSL library, we are of course very interested in getting the
|
different SSL library, we are of course very interested in getting the
|
||||||
patch!
|
patch!
|
||||||
|
|
||||||
@@ -503,9 +507,9 @@ FAQ
|
|||||||
If the server doesn't require this, you don't need a client certificate.
|
If the server doesn't require this, you don't need a client certificate.
|
||||||
|
|
||||||
- Server certificate. The server you communicate with has a server
|
- Server certificate. The server you communicate with has a server
|
||||||
certificate. You can and should verify this certficate to make sure that
|
certificate. You can and should verify this certificate to make sure that
|
||||||
you are truly talking to the real server and not a server impersonating
|
you are truly talking to the real server and not a server impersonating
|
||||||
it. The server certificate verifaction process is made by using a
|
it. The server certificate verification process is made by using a
|
||||||
Certificate Authority certificate ("CA cert") that was used to sign the
|
Certificate Authority certificate ("CA cert") that was used to sign the
|
||||||
server certificate. Server certificate verification is enabled by default
|
server certificate. Server certificate verification is enabled by default
|
||||||
in curl and libcurl and is often the reason for problems as explained in
|
in curl and libcurl and is often the reason for problems as explained in
|
||||||
@@ -533,6 +537,10 @@ FAQ
|
|||||||
|
|
||||||
curl ftp://ftp.sunet.se//tmp/
|
curl ftp://ftp.sunet.se//tmp/
|
||||||
|
|
||||||
|
3.18 Can I use curl to send a POST/PUT and not wait for a response?
|
||||||
|
|
||||||
|
No.
|
||||||
|
|
||||||
|
|
||||||
4. Running Problems
|
4. Running Problems
|
||||||
|
|
||||||
@@ -733,12 +741,20 @@ FAQ
|
|||||||
|
|
||||||
Yes.
|
Yes.
|
||||||
|
|
||||||
We have written the libcurl code specificly adjusted for multi-threaded
|
We have written the libcurl code specifically adjusted for multi-threaded
|
||||||
programs. libcurl will use thread-safe functions instead of non-safe ones if
|
programs. libcurl will use thread-safe functions instead of non-safe ones if
|
||||||
your system has such.
|
your system has such.
|
||||||
|
|
||||||
We would appreciate some kind of report or README file from those who have
|
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
|
||||||
used libcurl in a threaded environment.
|
need to provide one or two locking functions:
|
||||||
|
|
||||||
|
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||||
|
|
||||||
|
If you use a GnuTLS-powered libcurl in a multi-threaded environment, you
|
||||||
|
need to provide locking function(s) for libgcrypt (which is used by GnuTLS
|
||||||
|
for the crypto functions).
|
||||||
|
|
||||||
|
[informative link missing]
|
||||||
|
|
||||||
5.2 How can I receive all data into a large memory chunk?
|
5.2 How can I receive all data into a large memory chunk?
|
||||||
|
|
||||||
@@ -877,6 +893,35 @@ FAQ
|
|||||||
A - gethostbyname() on plain ipv4 windows hosts
|
A - gethostbyname() on plain ipv4 windows hosts
|
||||||
B - getaddrinfo() on ipv6-enabled windows hosts
|
B - getaddrinfo() on ipv6-enabled windows hosts
|
||||||
|
|
||||||
|
Also note that libcurl never resolves or reverse-lookups addresses given as
|
||||||
|
pure numbers, such as 127.0.0.1 or ::1.
|
||||||
|
|
||||||
|
5.10 How do I prevent libcurl from writing the response to stdout?
|
||||||
|
|
||||||
|
libcurl provides a default built-in write function that writes received data
|
||||||
|
to stdout. Set a WRITEFUNCTION to receive the data, or possibly set
|
||||||
|
WRITEDATA to a different FILE * handle.
|
||||||
|
|
||||||
|
5.11 How do I make libcurl not receive the whole HTTP response?
|
||||||
|
|
||||||
|
You make the write callback (or progress callback) return an error and
|
||||||
|
libcurl will then abort the transfer.
|
||||||
|
|
||||||
|
5.12 Can I make libcurl fake or hide my real IP address?
|
||||||
|
|
||||||
|
No. libcurl operates on a higher level than so. Besides, faking IP address
|
||||||
|
would imply sending IP packages with a made-up source address, and then you
|
||||||
|
normally get a problem with intercepting the packages sent back as they
|
||||||
|
would then not be routed to you!
|
||||||
|
|
||||||
|
If you use a proxy to access remote sites, the sites will not see your local
|
||||||
|
IP address but instead the address of the proxy.
|
||||||
|
|
||||||
|
Also note that on many networks NATs or other IP-munging techniques are used
|
||||||
|
that makes you see and use a different IP address locally than what the
|
||||||
|
remote server will see you coming from.
|
||||||
|
|
||||||
|
|
||||||
6. License Issues
|
6. License Issues
|
||||||
|
|
||||||
Curl and libcurl are released under a MIT/X derivate license. The license is
|
Curl and libcurl are released under a MIT/X derivate license. The license is
|
||||||
|
@@ -114,6 +114,8 @@ distributions and otherwise retrieved as part of other software.
|
|||||||
September 2002, with the release of curl 7.10 it is released under the MIT
|
September 2002, with the release of curl 7.10 it is released under the MIT
|
||||||
license only.
|
license only.
|
||||||
|
|
||||||
|
January 2003. Started working on the distributed curl tests. The autobuilds.
|
||||||
|
|
||||||
February 2003, the curl site averages at 20000 visits weekly. At any given
|
February 2003, the curl site averages at 20000 visits weekly. At any given
|
||||||
moment, there's an average of 3 people browsing the curl.haxx.se site.
|
moment, there's an average of 3 people browsing the curl.haxx.se site.
|
||||||
|
|
||||||
@@ -139,3 +141,7 @@ August 2004:
|
|||||||
Number of public functions in libcurl: 36
|
Number of public functions in libcurl: 36
|
||||||
Amount of public web site mirrors: 12
|
Amount of public web site mirrors: 12
|
||||||
Number of known libcurl bindings: 26
|
Number of known libcurl bindings: 26
|
||||||
|
|
||||||
|
April 2005:
|
||||||
|
|
||||||
|
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||||
|
@@ -578,14 +578,14 @@ PORTS
|
|||||||
- MIPS IRIX 6.2, 6.5
|
- MIPS IRIX 6.2, 6.5
|
||||||
- MIPS Linux
|
- MIPS Linux
|
||||||
- Pocket PC/Win CE 3.0
|
- Pocket PC/Win CE 3.0
|
||||||
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1
|
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
|
||||||
- PowerPC Darwin 1.0
|
- PowerPC Darwin 1.0
|
||||||
- PowerPC Linux
|
- PowerPC Linux
|
||||||
- PowerPC Mac OS 9
|
- PowerPC Mac OS 9
|
||||||
- PowerPC Mac OS X
|
- PowerPC Mac OS X
|
||||||
- SINIX-Z v5
|
- SINIX-Z v5
|
||||||
- Sparc Linux
|
- Sparc Linux
|
||||||
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8
|
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
|
||||||
- Sparc SunOS 4.1.X
|
- Sparc SunOS 4.1.X
|
||||||
- StrongARM (and other ARM) RISC OS 3.1, 4.02
|
- StrongARM (and other ARM) RISC OS 3.1, 4.02
|
||||||
- StrongARM Linux 2.4
|
- StrongARM Linux 2.4
|
||||||
@@ -596,14 +596,14 @@ PORTS
|
|||||||
- i386 Esix 4.1
|
- i386 Esix 4.1
|
||||||
- i386 FreeBSD
|
- i386 FreeBSD
|
||||||
- i386 HURD
|
- i386 HURD
|
||||||
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
|
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
|
||||||
- i386 NetBSD
|
- i386 NetBSD
|
||||||
- i386 Novell NetWare
|
- i386 Novell NetWare
|
||||||
- i386 OS/2
|
- i386 OS/2
|
||||||
- i386 OpenBSD
|
- i386 OpenBSD
|
||||||
- i386 SCO unix
|
- i386 SCO unix
|
||||||
- i386 Solaris 2.7
|
- i386 Solaris 2.7
|
||||||
- i386 Windows 95, 98, ME, NT, 2000
|
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
|
||||||
- i386 QNX 6
|
- i386 QNX 6
|
||||||
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
|
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
|
||||||
- ia64 Linux 2.3.99
|
- ia64 Linux 2.3.99
|
||||||
|
@@ -92,9 +92,6 @@ may have been fixed since this was written!
|
|||||||
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
libcurl thinks of it as the *compressed* length. Some explanations are here:
|
||||||
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
http://curl.haxx.se/mail/lib-2003-06/0146.html
|
||||||
|
|
||||||
4. 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.
|
|
||||||
|
|
||||||
3. GOPHER transfers seem broken
|
3. GOPHER transfers seem broken
|
||||||
|
|
||||||
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
2. If a HTTP server responds to a HEAD request and includes a body (thus
|
||||||
|
@@ -32,7 +32,15 @@ OpenSSL http://www.openssl.org/source/license.html
|
|||||||
makes it "incompatible" with GPL. You are not allowed to ship binaries
|
makes it "incompatible" with GPL. You are not allowed to ship binaries
|
||||||
that link with OpenSSL that includes GPL code (unless that specific
|
that link with OpenSSL that includes GPL code (unless that specific
|
||||||
GPL code includes an exception for OpenSSL - a habit that is growing
|
GPL code includes an exception for OpenSSL - a habit that is growing
|
||||||
more and more common).
|
more and more common). If OpenSSL's licensing is a problem for you,
|
||||||
|
consider using GnuTLS instead.
|
||||||
|
|
||||||
|
GnuTLS http://www.gnutls.org/
|
||||||
|
|
||||||
|
Uses the LGPL[3] license. If this is a problem for you, consider using
|
||||||
|
OpenSSL instead. Also note that GnuTLS itself depends on and uses
|
||||||
|
other libs (libgcrypt and libgpg-error) and they too are LGPL- or
|
||||||
|
GPL-licensed.
|
||||||
|
|
||||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||||
|
|
||||||
@@ -84,3 +92,5 @@ OpenLDAP http://www.openldap.org/software/release/license.html
|
|||||||
[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
|
[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
|
||||||
[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
|
[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
|
||||||
how to write such an exception to the GPL
|
how to write such an exception to the GPL
|
||||||
|
[3] = LGPL - GNU Lesser General Public License:
|
||||||
|
http://www.gnu.org/licenses/lgpl.html
|
||||||
|
202
docs/THANKS
202
docs/THANKS
@@ -1,110 +1,94 @@
|
|||||||
This project has been alive for several years. Countless people have provided
|
This project has been alive for many years. Countless people have provided
|
||||||
feedback that have improved curl. Here follows a (incomplete) list of people
|
feedback that have improved curl. Here follows a list of people that have
|
||||||
that have contributed with non-trivial parts:
|
contributed (a-z order).
|
||||||
|
|
||||||
Daniel Stenberg <daniel@haxx.se>
|
If you have contributed but are missing here, please let us know!
|
||||||
Rafael Sagula <sagula@inf.ufrgs.br>
|
|
||||||
Sampo Kellomaki <sampo@iki.fi>
|
Alan Pinstein, Albert Chin-A-Young, Albert Choy, Aleksandar Milivojevic, Alex
|
||||||
Linas Vepstas <linas@linas.org>
|
aka WindEagle, Alex Neblett, Alex Suykov, Alexander Kourakos, Alexander
|
||||||
Bjorn Reese <breese@mail1.stofanet.dk>
|
Krasnostavsky, Alexander Zhuravlev, Alexis Carvalho, Andi Jahja, Andreas Damm,
|
||||||
Johan Anderson <johan@homemail.com>
|
Andreas Olsson, Andreas Rieke, Andrew Francis, Andrew Fuller, Andr<64>s Garc<72>a,
|
||||||
Kjell Ericson <Kjell.Ericson@haxx.se>
|
Andy Cedilnik, Andy Serpa, Angus Mackay, Antoine Calando, Anton Kalmykov,
|
||||||
Troy Engel <tengel@sonic.net>
|
Arkadiusz Miskiewicz, Augustus Saunders, Avery Fay, Ben Greear, Benjamin
|
||||||
Ryan Nelson <ryan@inch.com>
|
Gerard, Bertrand Demiddelaer, Bjorn Reese, Bj<42>rn Stenberg, Bob Schader, Brad
|
||||||
Bj<EFBFBD>rn Stenberg <bjorn@haxx.se>
|
Burdick, Brent Beardsley, Brian Akins, Brian R Duffy, Bruce Mitchener, Bryan
|
||||||
Angus Mackay <amackay@gus.ml.org>
|
Henderson, Bryan Henderson , Bryan Kemp, Caolan McNamara, Casey O'Donnell,
|
||||||
Eric Young <eay@cryptsoft.com>
|
Chih-Chung Chang, Chris "Bob Bob", Chris Combes, Chris Gaukroger, Chris
|
||||||
Simon Dick <simond@totally.irrelevant.org>
|
Maltby, Christian Kurz, Christian Robottom Reis, Christophe Demory, Christophe
|
||||||
Oren Tirosh <oren@monty.hishome.net>
|
Legry, Christopher R. Palmer, Clarence Gardner, Clifford Wolf, Cody Jones,
|
||||||
Steven G. Johnson <stevenj@alum.mit.edu>
|
Colin Watson, Colm Buckley, Cory Nelson, Craig Davison, Craig Markwardt, Cris
|
||||||
Gilbert Ramirez Jr. <gram@verdict.uthscsa.edu>
|
Bailiff, Cyrill Osterwalder, Damien Adant, Dan Becker, Dan C, Dan Fandrich,
|
||||||
Andr<EFBFBD>s Garc<72>a <ornalux@redestb.es>
|
Dan Torop, Dan Zitter, Daniel at touchtunes, Daniel Stenberg, Dave Dribin,
|
||||||
Douglas E. Wegscheid <wegscd@whirlpool.com>
|
Dave Halbakken, Dave Hamilton, Dave May, David Byron, David Cohen, David
|
||||||
Mark Butler <butlerm@xmission.com>
|
Eriksson, David Houlder, David Hull, David J Meyer, David James, David Kimdon,
|
||||||
Eric Thelin <eric@generation-i.com>
|
David LeBlanc, David Odin, David Phillips, David Shaw, David Tarendash, David
|
||||||
Marc Boucher <marc@mbsi.ca>
|
Thiel, Detlef Schmier, Diego Casorran, Dimitris Sarris, Dinar, Dirk
|
||||||
Greg Onufer <Greg.Onufer@Eng.Sun.COM>
|
Eddelbuettel, Dirk Manske, Dolbneff A.V, Domenico Andreoli, Dominick Meglio,
|
||||||
Doug Kaufman <dkaufman@rahul.net>
|
Doug Kaufman, Doug Porter, Douglas E. Wegscheid, Douglas R. Horner, Dustin
|
||||||
David Eriksson <david@2good.com>
|
Boswell, Dylan Ellicott, Dylan Salisbury, Early Ehlinger, Edin Kadribasic,
|
||||||
Ralph Beckmann <rabe@uni-paderborn.de>
|
Ellis Pritchard, Emiliano Ida, Enrico Scholz, Enrik Berkhan, Eric Lavigne,
|
||||||
T. Yamada <tai@imasy.or.jp>
|
Eric Melville, Eric Rautman, Eric Thelin, Eric Vergnaud, Eric Young, Erick
|
||||||
Lars J. Aas <larsa@sim.no>
|
Nuwendam, Erwan Legrand, Erwin Authried, Evan Jordan, Fabrizio Ammollo, Fedor
|
||||||
J<EFBFBD>rn Hartroth <Joern.Hartroth@computer.org>
|
Karpelevitch, Felix von Leitner, Florian Schoppmann, Forrest Cahoon, Frank
|
||||||
Matthew Clarke <clamat@van.maves.ca>
|
Keeney, Frank Ticheler, Fred New, Fred Noz, Frederic Lepied, Gautam Mani, Gaz
|
||||||
Linus Nielsen Feltzing <linus@haxx.se>
|
Iqbal, Georg Horn, Georg Huettenegger, Gerd v. Egidy, Gerhard Herre, Giaslas
|
||||||
Felix von Leitner <felix@convergence.de>
|
Georgios, Gilad, Gilbert Ramirez Jr., Gisle Vanem, Giuseppe Attardi, Giuseppe
|
||||||
Dan Zitter <dzitter@zitter.net>
|
D'Ambrosio, Glen Nakamura, Glen Scott, Greg Hewgill, Greg Onufer, Grigory
|
||||||
Jongki Suwandi <Jongki.Suwandi@eng.sun.com>
|
Entin, Guenole Bescon, Guillaume Arluison, Gustaf Hui, Gwenole Beauchesne,
|
||||||
Chris Maltby <chris@aurema.com>
|
G<EFBFBD>tz Babin-Ebell, G<>nter Knauf, Hamish Mackenzie, Hanno Kranzhoff, Hans
|
||||||
Ron Zapp <rzapper@yahoo.com>
|
Steegers, Hardeep Singh, Harshal Pradhan, Heikki Korpela, Henrik Storner,
|
||||||
Paul Marquis <pmarquis@iname.com>
|
Hzhijun, Ian Ford, Ian Gulliver, Ian Wilkes, Ignacio Vazquez-Abrams, Ilguiz
|
||||||
Ellis Pritchard <ellis@citria.com>
|
Latypov, Ingo Ralf Blum, Ingo Wilken, Jacky Lam, Jacob Meuser, James Bursa,
|
||||||
Damien Adant <dams@usa.net>
|
James Clancy, James Cone, James Gallagher, James Griffiths, James MacMillan,
|
||||||
Chris <cbayliss@csc.come>
|
Jamie Lokier, Jamie Wilkinson, Jason S. Priebe, Jean-Claude Chauve, Jean-Louis
|
||||||
Marco G. Salvagno <mgs@whiz.cjb.net>
|
Lemaire, Jean-Marc Ranger, Jean-Philippe Barrette-LaPierre, Jeff Lawson, Jeff
|
||||||
Paul Marquis <pmarquis@iname.com>
|
Phillips, Jeffrey Pohlmeyer, Jeremy Friesner, Jesper Jensen, Jesse Noller, Jim
|
||||||
David LeBlanc <dleblanc@qnx.com>
|
Drash, Joe Halpin, Joel Chen, Johan Anderson, Johan Nilsson, John Crow, John
|
||||||
Rich Gray at Plus Technologies
|
Janssen, John Lask, John McGowan, Jon Travis, Jon Turner, Jonas Forsman,
|
||||||
Luong Dinh Dung <u8luong@lhsystems.hu>
|
Jonatan Lander, Jonathan Hseu, Jongki Suwandi, Josh Kapell, Juan F. Codagnone,
|
||||||
Torsten Foertsch <torsten.foertsch@gmx.net>
|
Juan Ignacio Herv<72>s, Juergen Wilke, Jukka Pihl, Julian Noble, Jun-ichiro
|
||||||
Kristian K<>hntopp <kris@koehntopp.de>
|
itojun Hagino, Jurij Smakov, J<>rg Mueller-Tolk, J<>rn Hartroth, Kai Sommerfeld,
|
||||||
Fred Noz <FNoz@siac.com>
|
Kai-Uwe Rommel, Kang-Jin Lee, Karol Pietrzak, Keith MacDonald, Keith McGuigan,
|
||||||
Caolan McNamara <caolan@csn.ul.ie>
|
Ken Hirsch, Ken Rastatter, Kevin Fisk, Kevin Roth, Kimmo Kinnunen, Kjell
|
||||||
Albert Chin-A-Young <china@thewrittenword.com>
|
Ericson, Kjetil Jacobsen, Klevtsov Vadim, Kris Kennaway, Krishnendu Majumdar,
|
||||||
Stephen Kick <skick@epicrealm.com>
|
Kristian K<>hntopp, Kyle Sallee, Lachlan O'Dea, Larry Campbell, Larry Fahnoe,
|
||||||
Martin Hedenfalk <mhe@stacken.kth.se>
|
Lars Gustafsson, Lars J. Aas, Lars Nilsson, Lars Torben Wilson, Legoff
|
||||||
Richard Prescott <rip at step.polymtl.ca>
|
Vincent, Lehel Bernadt, Len Krause, Linas Vepstas, Ling Thio, Linus Nielsen
|
||||||
Jason S. Priebe <priebe@wral-tv.com>
|
Feltzing, Loic Dachary, Loren Kirkby, Luca Altea, Luca Alteas, Lucas Adamski,
|
||||||
T. Bharath <TBharath@responsenetworks.com>
|
Lukasz Czekierda, Luke Call, Luong Dinh Dung, Maciej W. Rozycki, Marc Boucher,
|
||||||
Alexander Kourakos <awk@users.sourceforge.net>
|
Marcelo Juchem , Marcin Konicki, Marco G. Salvagno, Marcus Webster, Mark
|
||||||
James Griffiths <griffiths_james@yahoo.com>
|
Butler, Markus Moeller, Markus Oberhumer, Martijn Koster, Martin C. Martin,
|
||||||
Loic Dachary <loic@senga.org>
|
Martin Hedenfalk, Marty Kuhrt, Maruko, Massimiliano Ziccardi, Mathias
|
||||||
Robert Weaver <robert.weaver@sabre.com>
|
Axelsson, Mats Lidell, Matt Veenstra, Matthew Blain, Matthew Clarke, Maurice
|
||||||
Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
Barnum, Mekonikum, Mettgut Jamalla, Michael Benedict, Michael Curtis, Michael
|
||||||
Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
Mealling, Michal Bonino, Mihai Ionescu, Mike Bytnar, Mike Dobbs, Miklos
|
||||||
Frederic Lepied <flepied@mandrakesoft.com>
|
Nemeth, Mitz Wark, Mohamed Lrhazi, Mohun Biswas, Moonesamy, Nathan O'Sullivan,
|
||||||
Georg Horn <horn@koblenz-net.de>
|
Naveen Noel, Neil Dunbar, Neil Spring, Nic Roets, Nick Gimbrone, Nick Humfrey,
|
||||||
Cris Bailiff <c.bailiff@awayweb.com>
|
Nico Baggus, Nicolas Berloquin, Nicolas Croiset, Niels van Tongeren, Nikita
|
||||||
Sterling Hughes <sterling@designmultimedia.com>
|
Schmidt, nk, Nodak Sodak, Oren Tirosh, P R Schaffner, Patrick Bihan-Faou,
|
||||||
S. Moonesamy
|
Patrick Smith, Paul Harrington, Paul Marquis, Paul Moore, Paul Nolan, Pavel
|
||||||
Ingo Wilken <iw@WWW.Ecce-Terram.DE>
|
Cenek, Pavel Orehov, Pawel A. Gajda, Pedro Neves, Pete Su, Peter Bray, Peter
|
||||||
Pawel A. Gajda <mis@k2.net.pl>
|
Forret, Peter Pentchev, Peter Sylvester, Peter Todd, Peter Verhas, Peter
|
||||||
Patrick Bihan-Faou
|
Wullinger, Phil Karn, Philip Gladstone, Philippe Hameau, Philippe Raoult,
|
||||||
Nico Baggus <Nico.Baggus@mail.ing.nl>
|
Pierre, Puneet Pawaia, Rafael Sagula, Ralph Beckmann, Ralph Mitchell, Ramana
|
||||||
Sergio Ballestrero
|
Mokkapati, Randy McMurchy, Reinout van Schouwen, Renaud Chaillat, Renaud
|
||||||
Andrew Francis <locust@familyhealth.com.au>
|
Duhaut, Rene Bernhardt, Rene Rebe, Ricardo Cadime, Rich Gray, Richard Archer,
|
||||||
Tomasz Lacki <Tomasz.Lacki@primark.pl>
|
Richard Atterer, Richard Bramante, Richard Cooper, Richard Gorton, Richard
|
||||||
Georg Huettenegger <georg@ist.org>
|
Prescott, Rick Jones, Rick Richardson, Rob Stanzel, Robert D. Young, Robert
|
||||||
John Lask <johnlask@hotmail.com>
|
Olson, Robert Weaver, Robin Kay, Rodney Simmons, Roland Krikava, Roland
|
||||||
Eric Lavigne <erlavigne@wanadoo.fr>
|
Zimmermann, Roman Koifman, Ron Zapp, Rosimildo da Silva, Roy Shan, Rune
|
||||||
Marcus Webster <marcus.webster@phocis.com>
|
Kleveland, Ryan Nelson, S. Moonesamy, Salvador D<>vila, Salvatore Sorrentino,
|
||||||
G<EFBFBD>tz Babin-Ebell <babin<69>ebell@trustcenter.de>
|
Sampo Kellomaki, Samuel D<>az Garc<72>a, Samuel Listopad, Sander Gates, Saul good,
|
||||||
Andreas Damm <andreas-sourceforge@radab.org>
|
Sebastien Willemijns, Sergio Ballestrero, Seshubabu Pasam, Shard, Shawn
|
||||||
Jacky Lam <sylam@emsoftltd.com>
|
Poulson, Siddhartha Prakash Jain, Simon Dick, Simon Liu, Spiridonoff A.V,
|
||||||
James Gallagher <jgallagher@gso.uri.edu>
|
Stadler Stephan, Stefan Ulrich, Stephan Bergmann, Stephen Kick, Stephen More,
|
||||||
Kjetil Jacobsen <kjetilja@cs.uit.no>
|
Sterling Hughes, Steve Green, Steve Lhomme, Steve Marx, Steve Oliphant, Steven
|
||||||
Markus F.X.J. Oberhumer <markus@oberhumer.com>
|
Bazyl, Steven G. Johnson, Stoned Elipot, Sven Neuhaus, swalkaus at yahoo.com,
|
||||||
Miklos Nemeth <mnemeth@kfkisystems.com>
|
S<EFBFBD>bastien Willemijns, T. Bharath, T. Yamada, Thomas Schwinge, Thomas Tonino,
|
||||||
Kevin Roth <kproth@users.sourceforge.net>
|
Tim Baker, Tim Bartley, Tim Costello, Tim Sneddon, Toby Peterson, Tom Benoist,
|
||||||
Ralph Mitchell <rmitchell@eds.com>
|
Tom Lee, Tom Mattison, Tom Moers, Tom Zerucha, Tomas Pospisek, Tomas Szepe,
|
||||||
Dan Fandrich <dan@coneharvesters.com>
|
Tomasz Lacki, Tommy Tam, Ton Voon, Tor Arntsen, Torsten Foertsch, Toshiyuki
|
||||||
Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
|
Maezawa, Traian Nicolescu, Troels Walsted Hansen, Troy Engel, Ulrich Zadow,
|
||||||
Richard Bramante <RBramante@on.com>
|
Vincent Bronner, Vincent Penquerc'h, Vincent Sanders, Vojtech Janota, Vojtech
|
||||||
Daniel Kouril <kouril@ics.muni.cz>
|
Minarik, Walter J. Mack, Wayne Haigh, Werner Koch, Wesley Laxton, Wez Furlong,
|
||||||
Dirk Manske <dm@nettraffic.de>
|
Wilfredo Sanchez, Wojciech Zwiefka, Yarram Sunil, Zvi Har'El
|
||||||
David Meyer <meyer@paracel.com>
|
|
||||||
Dominick Meglio <codemstr@ptd.net>
|
|
||||||
Gisle Vanem <gvanem@broadpark.no>
|
|
||||||
Giuseppe Attardi <attardi@di.unipi.it>
|
|
||||||
Tor Arntsen <tor@spacetec.no>
|
|
||||||
David Byron <DByron@everdreamcorp.com>
|
|
||||||
David Phillips
|
|
||||||
Alexander Krasnostavsky
|
|
||||||
G<EFBFBD>nter Knauf
|
|
||||||
Bertrand Demiddelaer
|
|
||||||
Peter Sylvester
|
|
||||||
Alexis S. L. Carvalho
|
|
||||||
Casey O'Donnell
|
|
||||||
Marty Kuhrt
|
|
||||||
James Bursa
|
|
||||||
Greg Hewgill
|
|
||||||
|
26
docs/TODO
26
docs/TODO
@@ -26,7 +26,7 @@ TODO
|
|||||||
|
|
||||||
* More data sharing. curl_share_* functions already exist and work, and they
|
* More data sharing. curl_share_* functions already exist and work, and they
|
||||||
can be extended to share more. For example, enable sharing of the ares
|
can be extended to share more. For example, enable sharing of the ares
|
||||||
channel.
|
channel and the connection cache.
|
||||||
|
|
||||||
* Introduce a new error code indicating authentication problems (for proxy
|
* Introduce a new error code indicating authentication problems (for proxy
|
||||||
CONNECT error 407 for example). This cannot be an error code, we must not
|
CONNECT error 407 for example). This cannot be an error code, we must not
|
||||||
@@ -35,16 +35,15 @@ TODO
|
|||||||
|
|
||||||
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
|
||||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||||
|
To support ipv6 interface addresses properly.
|
||||||
|
|
||||||
* Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
* Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
||||||
GET_FTP_DATA_IP. Return a string with the used IP. Suggested by Alan.
|
GET_FTP_DATA_IP. Return a string with the used IP. Suggested by Alan.
|
||||||
|
|
||||||
LIBCURL - multi interface
|
LIBCURL - multi interface
|
||||||
|
|
||||||
* Add a curl_multi_fdset() alternative that returns only two arrays with file
|
* Add a curl_multi_fdset() alternative. this allows apps to avoid the
|
||||||
desrciptors for reading and writing to allow the app to use whatever
|
FD_SETSIZE problem with select().
|
||||||
function it prefers. Plus, this allows apps to avoid the FD_SETSIZE problem
|
|
||||||
with select().
|
|
||||||
|
|
||||||
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
|
||||||
|
|
||||||
@@ -68,9 +67,6 @@ TODO
|
|||||||
* Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in
|
* Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in
|
||||||
the process to avoid doing a resolve and connect in vain.
|
the process to avoid doing a resolve and connect in vain.
|
||||||
|
|
||||||
* Code overhaul to make it more state-machine like and to _never_ block on
|
|
||||||
waiting for server responses when used with the multi interface.
|
|
||||||
|
|
||||||
* Support GSS/Kerberos 5 for ftp file transfer. This will allow user
|
* Support GSS/Kerberos 5 for ftp file transfer. This will allow user
|
||||||
authentication and file encryption. Possible libraries and example clients
|
authentication and file encryption. Possible libraries and example clients
|
||||||
are available from MIT or Heimdal. Requsted by Markus Moeller.
|
are available from MIT or Heimdal. Requsted by Markus Moeller.
|
||||||
@@ -146,14 +142,12 @@ TODO
|
|||||||
it be? There's so much that could be done if it were! (brought by Chris
|
it be? There's so much that could be done if it were! (brought by Chris
|
||||||
Clark)
|
Clark)
|
||||||
|
|
||||||
* Make curl's SSL layer option capable of using other free SSL libraries.
|
* Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||||
Such as the Mozilla Security Services
|
Mozilla Security Services
|
||||||
(http://www.mozilla.org/projects/security/pki/nss/) and GnuTLS
|
(http://www.mozilla.org/projects/security/pki/nss/), MatrixSSL
|
||||||
(http://www.gnu.org/software/gnutls/) This subject has been brought up
|
(http://www.matrixssl.org/) or yaSSL (http://yassl.com/). At least the
|
||||||
again recently since GPL-licensed applications that link with libcurl MAY
|
latter two could be alternatives for those looking to reduce the footprint
|
||||||
NOT distribute binaries that use OpenSSL without adding an exception clause
|
of libcurl built with OpenSSL or GnuTLS.
|
||||||
to the GPL license. See the LICENSE-MIXING document and this:
|
|
||||||
http://www.gnome.org/~markmc/openssl-and-the-gpl.html
|
|
||||||
|
|
||||||
LDAP
|
LDAP
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ Version Numbers and Releases
|
|||||||
N is pre-release number
|
N is pre-release number
|
||||||
|
|
||||||
One of these numbers will get bumped in each new release. The numbers to the
|
One of these numbers will get bumped in each new release. The numbers to the
|
||||||
right of a bumped number will be reset to zero. If Z is zero, it is not
|
right of a bumped number will be reset to zero. If Z is zero, it may not be
|
||||||
included in the version number. The pre release number is only included in
|
included in the version number. The pre release number is only included in
|
||||||
pre releases (they're never used in public, official, releases).
|
pre releases (they're never used in public, official, releases).
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ Version Numbers and Releases
|
|||||||
|
|
||||||
As a service to any application that might want to support new libcurl
|
As a service to any application that might want to support new libcurl
|
||||||
features while still being able to build with older versions, all releases
|
features while still being able to build with older versions, all releases
|
||||||
have the libcurl version stored in the curl/curl.h file using a static
|
have the libcurl version stored in the curl/curlver.h file using a static
|
||||||
numbering scheme that can be used for comparison. The version number is
|
numbering scheme that can be used for comparison. The version number is
|
||||||
defined as:
|
defined as:
|
||||||
|
|
||||||
@@ -62,3 +62,6 @@ Version Numbers and Releases
|
|||||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
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
|
always a greater number in a more recent release. It makes comparisons with
|
||||||
greater than and less than work.
|
greater than and less than work.
|
||||||
|
|
||||||
|
This number is also available as three separate defines:
|
||||||
|
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.
|
||||||
|
37
docs/curl.1
37
docs/curl.1
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl 1 "29 Mar 2005" "Curl 7.13.2" "Curl Manual"
|
.TH curl 1 "28 Apr 2005" "Curl 7.14.0" "Curl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl \- transfer a URL
|
curl \- transfer a URL
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -497,6 +497,20 @@ line. So, it could look similar to this:
|
|||||||
url = "http://curl.haxx.se/docs/"
|
url = "http://curl.haxx.se/docs/"
|
||||||
|
|
||||||
This option can be used multiple times.
|
This option can be used multiple times.
|
||||||
|
|
||||||
|
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
||||||
|
config file and uses it if found. The default config file is checked for in
|
||||||
|
the following places in this order:
|
||||||
|
|
||||||
|
1) curl tries to find the "home dir": It first checks for the CURL_HOME and
|
||||||
|
then the HOME environment variables. Failing that, it uses getpwuid() on
|
||||||
|
unix-like systems (which returns the home dir given the current user in your
|
||||||
|
system). On Windows, it then checks for the APPDATA variable, or as a last
|
||||||
|
resort the '%USERPROFILE%\Application Data'.
|
||||||
|
|
||||||
|
2) On windows, if there is no _curlrc file in the home dir, it checks for one
|
||||||
|
in the same dir the executable curl is placed. On unix-like systems, it will
|
||||||
|
simply try to load .curlrc from the determined home dir.
|
||||||
.IP "--limit-rate <speed>"
|
.IP "--limit-rate <speed>"
|
||||||
Specify the maximum transfer rate you want curl to use. This feature is useful
|
Specify the maximum transfer rate you want curl to use. This feature is useful
|
||||||
if you have a limited pipe and you'd like your transfer not use your entire
|
if you have a limited pipe and you'd like your transfer not use your entire
|
||||||
@@ -700,8 +714,9 @@ If this option is used several times, the last one will be used. Disable the
|
|||||||
use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command
|
use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command
|
||||||
instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++.
|
instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++.
|
||||||
.IP "-q"
|
.IP "-q"
|
||||||
If used as the first parameter on the command line, the \fI$HOME/.curlrc\fP
|
If used as the first parameter on the command line, the \fIcurlrc\fP config
|
||||||
file will not be read and used as a config file.
|
file will not be read and used. See the \fI-K/--config\fP for details on the
|
||||||
|
default config file search path.
|
||||||
.IP "-Q/--quote <command>"
|
.IP "-Q/--quote <command>"
|
||||||
(FTP) Send an arbitrary command to the remote FTP server. Quote commands are
|
(FTP) Send an arbitrary command to the remote FTP server. Quote commands are
|
||||||
sent BEFORE the transfer is taking place (just after the initial PWD command
|
sent BEFORE the transfer is taking place (just after the initial PWD command
|
||||||
@@ -870,6 +885,11 @@ to read for untrained humans.
|
|||||||
|
|
||||||
If this option is used several times, the last one will be used. (Added in
|
If this option is used several times, the last one will be used. (Added in
|
||||||
7.9.7)
|
7.9.7)
|
||||||
|
.IP "--trace-time"
|
||||||
|
Prepends a time stamp to each trace or verbose line that curl displays.
|
||||||
|
|
||||||
|
If this option is used several times, each occurrence will toggle it on/off.
|
||||||
|
(Added in 7.14.0 )
|
||||||
.IP "-u/--user <user:password>"
|
.IP "-u/--user <user:password>"
|
||||||
Specify user and password to use for server authentication. Overrides
|
Specify user and password to use for server authentication. Overrides
|
||||||
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
|
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
|
||||||
@@ -887,9 +907,9 @@ This option may be used any number of times. To control where this URL is
|
|||||||
written, use the \fI-o/--output\fP or the \fI-O/--remote-name\fP options.
|
written, use the \fI-o/--output\fP or the \fI-O/--remote-name\fP options.
|
||||||
.IP "-v/--verbose"
|
.IP "-v/--verbose"
|
||||||
Makes the fetching more verbose/talkative. Mostly usable for debugging. Lines
|
Makes the fetching more verbose/talkative. Mostly usable for debugging. Lines
|
||||||
starting with '>' means data sent by curl, '<' means data received by curl
|
starting with '>' means "header data" sent by curl, '<' means "header data"
|
||||||
that is hidden in normal cases and lines starting with '*' means additional
|
received by curl that is hidden in normal cases and lines starting with '*'
|
||||||
info provided by curl.
|
means additional info provided by curl.
|
||||||
|
|
||||||
Note that if you only want HTTP headers in the output, \fI-i/--include\fP
|
Note that if you only want HTTP headers in the output, \fI-i/--include\fP
|
||||||
might be option you're looking for.
|
might be option you're looking for.
|
||||||
@@ -933,6 +953,9 @@ SPNEGO Negotiate authentication is supported.
|
|||||||
This curl supports transfers of large files, files larger than 2GB.
|
This curl supports transfers of large files, files larger than 2GB.
|
||||||
.IP "IDN"
|
.IP "IDN"
|
||||||
This curl supports IDN - international domain names.
|
This curl supports IDN - international domain names.
|
||||||
|
.IP "SSPI"
|
||||||
|
SSPI is supported. If you use NTLM and set a blank user name, curl will
|
||||||
|
authenticate with your current user and password.
|
||||||
.RE
|
.RE
|
||||||
.IP "-w/--write-out <format>"
|
.IP "-w/--write-out <format>"
|
||||||
Defines what to display after a completed and successful operation. The format
|
Defines what to display after a completed and successful operation. The format
|
||||||
@@ -1284,5 +1307,5 @@ http://curl.haxx.se
|
|||||||
ftp://ftp.sunet.se/pub/www/utilities/curl/
|
ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR ftp (1),
|
.BR ftp (1),
|
||||||
.BR wget (1),
|
.BR wget (1)
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
|
|||||||
post-callback.c multi-app.c multi-double.c multi-single.c \
|
post-callback.c multi-app.c multi-double.c multi-single.c \
|
||||||
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
|
||||||
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
|
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
|
||||||
anyauthput.c htmltitle.cc htmltidy.c
|
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "done"
|
@echo "done"
|
||||||
|
77
docs/examples/opensslthreadlock.c
Normal file
77
docs/examples/opensslthreadlock.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Example source code to show one way to set the necessary OpenSSL locking
|
||||||
|
* callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
|
||||||
|
* libcurl built to use OpenSSL.
|
||||||
|
*
|
||||||
|
* This is not a complete stand-alone example.
|
||||||
|
*
|
||||||
|
* Author: Jeremy Brown
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MUTEX_TYPE pthread_mutex_t
|
||||||
|
#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
|
||||||
|
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
|
||||||
|
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||||
|
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||||
|
#define THREAD_ID pthread_self( )
|
||||||
|
|
||||||
|
|
||||||
|
void handle_error(const char *file, int lineno, const char *msg){
|
||||||
|
fprintf(stderr, ** %s:%i %s\n, file, lineno, msg);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
/* exit(-1); */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This array will store all of the mutexes available to OpenSSL. */
|
||||||
|
static MUTEX_TYPE *mutex_buf= NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void locking_function(int mode, int n, const char * file, int line)
|
||||||
|
{
|
||||||
|
if (mode & CRYPTO_LOCK)
|
||||||
|
MUTEX_LOCK(mutex_buf[n]);
|
||||||
|
else
|
||||||
|
MUTEX_UNLOCK(mutex_buf[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long id_function(void)
|
||||||
|
{
|
||||||
|
return ((unsigned long)THREAD_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread_setup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
|
||||||
|
if (!mutex_buf)
|
||||||
|
return 0;
|
||||||
|
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||||
|
MUTEX_SETUP(mutex_buf[i]);
|
||||||
|
CRYPTO_set_id_callback(id_function);
|
||||||
|
CRYPTO_set_locking_callback(locking_function);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread_cleanup(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!mutex_buf)
|
||||||
|
return 0;
|
||||||
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
CRYPTO_set_locking_callback(NULL);
|
||||||
|
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||||
|
MUTEX_CLEANUP(mutex_buf[i]);
|
||||||
|
free(mutex_buf);
|
||||||
|
mutex_buf = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH curl_easy_setopt 3 "25 Jan 2005" "libcurl 7.13.0" "libcurl Manual"
|
.TH curl_easy_setopt 3 "12 May 2005" "libcurl 7.14.0" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_easy_setopt - set options for a curl easy handle
|
curl_easy_setopt - set options for a curl easy handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -410,7 +410,7 @@ is a more secure way to do authentication over public networks than the
|
|||||||
regular old-fashioned Basic method.
|
regular old-fashioned Basic method.
|
||||||
.IP CURLAUTH_GSSNEGOTIATE
|
.IP CURLAUTH_GSSNEGOTIATE
|
||||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
||||||
"Negotiate") method was designed by Microsoft and is used in their web
|
\&"Negotiate") method was designed by Microsoft and is used in their web
|
||||||
applications. It is primarily meant as a support for Kerberos5 authentication
|
applications. It is primarily meant as a support for Kerberos5 authentication
|
||||||
but may be also used along with another authentication methods. For more
|
but may be also used along with another authentication methods. For more
|
||||||
information see IETF draft draft-brezak-spnego-http-04.txt.
|
information see IETF draft draft-brezak-spnego-http-04.txt.
|
||||||
@@ -442,7 +442,7 @@ use. Note that for some methods, this will induce an extra network
|
|||||||
round-trip. Set the actual name and password with the
|
round-trip. Set the actual name and password with the
|
||||||
\fICURLOPT_PROXYUSERPWD\fP option. The bitmask can be constructed by or'ing
|
\fICURLOPT_PROXYUSERPWD\fP option. The bitmask can be constructed by or'ing
|
||||||
together the bits listed above for the \fICURLOPT_HTTPAUTH\fP option. As of
|
together the bits listed above for the \fICURLOPT_HTTPAUTH\fP option. As of
|
||||||
this writing, only Basic and NTLM work. (Added in 7.10.7)
|
this writing, only Basic, Digest and NTLM work. (Added in 7.10.7)
|
||||||
.SH HTTP OPTIONS
|
.SH HTTP OPTIONS
|
||||||
.IP CURLOPT_AUTOREFERER
|
.IP CURLOPT_AUTOREFERER
|
||||||
Pass a non-zero parameter to enable this. When enabled, libcurl will
|
Pass a non-zero parameter to enable this. When enabled, libcurl will
|
||||||
@@ -996,28 +996,60 @@ operations.
|
|||||||
\fBNOTE:\fP If the crypto device cannot be set,
|
\fBNOTE:\fP If the crypto device cannot be set,
|
||||||
\fICURLE_SSL_ENGINE_SETFAILED\fP is returned.
|
\fICURLE_SSL_ENGINE_SETFAILED\fP is returned.
|
||||||
.IP CURLOPT_SSLVERSION
|
.IP CURLOPT_SSLVERSION
|
||||||
Pass a long as parameter. Set what version of SSL to attempt to use, 2 or
|
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||||
3. By default, the SSL library will try to solve this by itself although some
|
The available options are:
|
||||||
servers make this difficult why you at times may have to use this option.
|
.RS
|
||||||
|
.IP CURL_SSLVERSION_DEFAULT
|
||||||
|
The default action. When libcurl built with OpenSSL, this will attempt to
|
||||||
|
figure out the remote SSL protocol version. Unfortunately there are a lot of
|
||||||
|
ancient and broken servers in use which cannot handle this technique and will
|
||||||
|
fail to connect. When libcurl is built with GnuTLS, this will mean SSLv3.
|
||||||
|
.IP CURL_SSLVERSION_TLSv1
|
||||||
|
Force TLSv1
|
||||||
|
.IP CURL_SSLVERSION_SSLv2
|
||||||
|
Force SSLv2
|
||||||
|
.IP CURL_SSLVERSION_SSLv3
|
||||||
|
Force SSLv3
|
||||||
|
.RE
|
||||||
.IP CURLOPT_SSL_VERIFYPEER
|
.IP CURLOPT_SSL_VERIFYPEER
|
||||||
Pass a long that is set to a zero value to stop curl from verifying the peer's
|
Pass a long as parameter.
|
||||||
certificate (7.10 starting setting this option to non-zero by default).
|
|
||||||
Alternate certificates to verify against can be specified with the
|
This option determines whether curl verifies the authenticity of the
|
||||||
\fICURLOPT_CAINFO\fP option or a certificate directory can be specified with
|
peer's certificate. A nonzero value means curl verifies; zero means it
|
||||||
the \fICURLOPT_CAPATH\fP option. As of 7.10, curl installs a default bundle.
|
doesn't. The default is nonzero, but before 7.10, it was zero.
|
||||||
\fICURLOPT_SSL_VERIFYHOST\fP may also need to be set to 1 or 0 if
|
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is disabled (it defaults to 2).
|
When negotiating an SSL connection, the server sends a certificate
|
||||||
|
indicating its identity. Curl verifies whether the certificate is
|
||||||
|
authentic, i.e. that you can trust that the server is who the
|
||||||
|
certificate says it is. This trust is based on a chain of digital
|
||||||
|
signatures, rooted in certification authority (CA) certificates you
|
||||||
|
supply. As of 7.10, curl installs a default bundle of CA certificates
|
||||||
|
and you can specify alternate certificates with the
|
||||||
|
\fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP option.
|
||||||
|
|
||||||
|
When \fICURLOPT_SSL_VERIFYPEER\fP is nonzero, and the verification
|
||||||
|
fails to prove that the certificate is authentic, the connection
|
||||||
|
fails. When the option is zero, the connection succeeds regardless.
|
||||||
|
|
||||||
|
Authenticating the certificate is not by itself very useful. You
|
||||||
|
typically want to ensure that the server, as authentically identified
|
||||||
|
by its certificate, is the server you mean to be talking to. Use
|
||||||
|
\fICURLOPT_SSL_VERIFYHOST\fP to control that.
|
||||||
.IP CURLOPT_CAINFO
|
.IP CURLOPT_CAINFO
|
||||||
Pass a char * to a zero terminated string naming a file holding one or more
|
Pass a char * to a zero terminated string naming a file holding one or more
|
||||||
certificates to verify the peer with. This only makes sense when used in
|
certificates to verify the peer with. This makes sense only when used in
|
||||||
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option.
|
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
|
||||||
|
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
|
||||||
|
even indicate an accessible file.
|
||||||
.IP CURLOPT_CAPATH
|
.IP CURLOPT_CAPATH
|
||||||
Pass a char * to a zero terminated string naming a directory holding multiple
|
Pass a char * to a zero terminated string naming a directory holding
|
||||||
CA certificates to verify the peer with. The certificate directory must be
|
multiple CA certificates to verify the peer with. The certificate
|
||||||
prepared using the openssl c_rehash utility. This only makes sense when used
|
directory must be prepared using the openssl c_rehash utility. This
|
||||||
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. The
|
makes sense only when used in combination with the
|
||||||
\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
|
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP
|
||||||
limitation in openssl. (Added in 7.9.8)
|
is zero, \fICURLOPT_CAPATH\fP need not even indicate an accessible
|
||||||
|
path. The \fICURLOPT_CAPATH\fP function apparently does not work in
|
||||||
|
Windows due to some limitation in openssl. (Added in 7.9.8)
|
||||||
.IP CURLOPT_RANDOM_FILE
|
.IP CURLOPT_RANDOM_FILE
|
||||||
Pass a char * to a zero terminated file name. The file will be used to read
|
Pass a char * to a zero terminated file name. The file will be used to read
|
||||||
from to seed the random engine for SSL. The more random the specified file is,
|
from to seed the random engine for SSL. The more random the specified file is,
|
||||||
@@ -1026,9 +1058,34 @@ the more secure the SSL connection will become.
|
|||||||
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
|
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
|
||||||
socket. It will be used to seed the random engine for SSL.
|
socket. It will be used to seed the random engine for SSL.
|
||||||
.IP CURLOPT_SSL_VERIFYHOST
|
.IP CURLOPT_SSL_VERIFYHOST
|
||||||
Pass a long. Set if we should verify the Common name from the peer certificate
|
Pass a long as parameter.
|
||||||
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)
|
This option determines whether curl verifies that the server claims to be
|
||||||
|
who you want it to be.
|
||||||
|
|
||||||
|
When negotiating an SSL connection, the server sends a certificate
|
||||||
|
indicating its identity.
|
||||||
|
|
||||||
|
When \fICURLOPT_SSL_VERIFYHOST\fP is 2, that certificate must indicate
|
||||||
|
that the server is the server to which you meant to connect, or the
|
||||||
|
connection fails.
|
||||||
|
|
||||||
|
Curl considers the server the intended one when the Common Name field
|
||||||
|
or a Subject Alternate Name field in the certificate matches the host
|
||||||
|
name in the URL to which you told Curl to connect.
|
||||||
|
|
||||||
|
When the value is 1, the certificate must contain a Common Name field,
|
||||||
|
but it doesn't matter what name it says. (This is not ordinarily a
|
||||||
|
useful setting).
|
||||||
|
|
||||||
|
When the value is 0, the connection succeeds regardless of the names in
|
||||||
|
the certificate.
|
||||||
|
|
||||||
|
The default, since 7.10, is 2.
|
||||||
|
|
||||||
|
The checking this option controls is of the identity that the server
|
||||||
|
\fIclaims\fP. The server could be lying. To control lying, see
|
||||||
|
\fICURLOPT_SSL_VERIFYPEER\fP.
|
||||||
.IP CURLOPT_SSL_CIPHER_LIST
|
.IP CURLOPT_SSL_CIPHER_LIST
|
||||||
Pass a char *, pointing to a zero terminated string holding the list of
|
Pass a char *, pointing to a zero terminated string holding the list of
|
||||||
ciphers to use for the SSL connection. The list must be syntactically correct,
|
ciphers to use for the SSL connection. The list must be syntactically correct,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.TH curl_multi_fdset 3 "15 Apr 2004" "libcurl 7.9.5" "libcurl Manual"
|
.TH curl_multi_fdset 3 "25 Apr 2005" "libcurl 7.9.5" "libcurl Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
curl_multi_fdset - extracts file descriptor information from a multi handle
|
curl_multi_fdset - extracts file descriptor information from a multi handle
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -15,15 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
|||||||
.ad
|
.ad
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This function extracts file descriptor information from a given multi_handle.
|
This function extracts file descriptor information from a given multi_handle.
|
||||||
libcurl returns its fd_set sets. The application can use these to select()
|
libcurl returns its fd_set sets. The application can use these to select() on,
|
||||||
on. The \fIcurl_multi_perform(3)\fP function should be called as soon as one
|
but be sure to FD_ZERO them before calling this function as
|
||||||
of them are ready to be read from or written to.
|
\fIcurl_multi_fdset(3)\fP only adds its own descriptors it doesn't zero or
|
||||||
|
otherwise remove any other. The \fIcurl_multi_perform(3)\fP function should be
|
||||||
|
called as soon as one of them are ready to be read from or written to.
|
||||||
|
|
||||||
|
If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when
|
||||||
|
this function returns. Otherwise it will contain the higher descriptor number
|
||||||
|
libcurl set.
|
||||||
|
|
||||||
You should also be aware that when doing select(), you should consider using a
|
You should also be aware that when doing select(), you should consider using a
|
||||||
rather small (single-digit number of seconds) timeout and call
|
rather small (single-digit number of seconds) timeout and call
|
||||||
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
|
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
|
||||||
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
|
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
|
||||||
you'd think.
|
you'd think and want.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
CURLMcode type, general libcurl multi interface error code. See
|
CURLMcode type, general libcurl multi interface error code. See
|
||||||
\fIlibcurl-errors(3)\fP
|
\fIlibcurl-errors(3)\fP
|
||||||
|
@@ -34,7 +34,7 @@ typedef struct {
|
|||||||
const char *host; /* human readable string */
|
const char *host; /* human readable string */
|
||||||
int features; /* bitmask, see below */
|
int features; /* bitmask, see below */
|
||||||
char *ssl_version; /* human readable string */
|
char *ssl_version; /* human readable string */
|
||||||
long ssl_version_num; /* number */
|
long ssl_version_num; /* not used, always zero */
|
||||||
const char *libz_version; /* human readable string */
|
const char *libz_version; /* human readable string */
|
||||||
const char **protocols; /* list of protocols */
|
const char **protocols; /* list of protocols */
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
.\" * $Id$
|
.\" * $Id$
|
||||||
.\" **************************************************************************
|
.\" **************************************************************************
|
||||||
.\"
|
.\"
|
||||||
.TH libcurl-tutorial 3 "25 Jan 2005" "libcurl" "libcurl programming"
|
.TH libcurl-tutorial 3 "9 May 2005" "libcurl" "libcurl programming"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libcurl-tutorial \- libcurl programming tutorial
|
libcurl-tutorial \- libcurl programming tutorial
|
||||||
.SH "Objective"
|
.SH "Objective"
|
||||||
@@ -246,17 +246,27 @@ you intend to make another transfer. libcurl will then attempt to re-use the
|
|||||||
previous
|
previous
|
||||||
|
|
||||||
.SH "Multi-threading Issues"
|
.SH "Multi-threading Issues"
|
||||||
libcurl is completely thread safe, except for two issues: signals and alarm
|
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
|
||||||
handlers. Signals are needed for a SIGPIPE handler, and the alarm() call is
|
it easy or multi or whatever) between multiple threads. Only use one handle in
|
||||||
used to deal with timeouts (during DNS lookup).
|
one thread at a time.
|
||||||
|
|
||||||
|
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
|
||||||
|
handlers. Signals are used timeouting name resolves (during DNS lookup) - when
|
||||||
|
built without c-ares support and not on Windows..
|
||||||
|
|
||||||
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
||||||
then of course using OpenSSL multi-threaded and it has itself a few
|
then of course using OpenSSL/GnuTLS multi-threaded and those libs have their
|
||||||
requirements on this. Basically, you need to provide one or two functions to
|
own requirements on this issue. Basically, you need to provide one or two
|
||||||
allow it to function properly. For all details, see this:
|
functions to allow it to function properly. For all details, see this:
|
||||||
|
|
||||||
|
OpenSSL
|
||||||
|
|
||||||
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
|
||||||
|
|
||||||
|
GnuTLS
|
||||||
|
|
||||||
|
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
|
||||||
|
|
||||||
When using multiple threads you should set the CURLOPT_NOSIGNAL option to
|
When using multiple threads you should set the CURLOPT_NOSIGNAL option to
|
||||||
TRUE for all handles. Everything will work fine except that timeouts are not
|
TRUE for all handles. Everything will work fine except that timeouts are not
|
||||||
honored during the DNS lookup - which you can work around by building libcurl
|
honored during the DNS lookup - which you can work around by building libcurl
|
||||||
|
@@ -1358,7 +1358,7 @@ typedef struct {
|
|||||||
const char *host; /* OS/host/cpu/machine when configured */
|
const char *host; /* OS/host/cpu/machine when configured */
|
||||||
int features; /* bitmask, see defines below */
|
int features; /* bitmask, see defines below */
|
||||||
const char *ssl_version; /* human readable string */
|
const char *ssl_version; /* human readable string */
|
||||||
long ssl_version_num; /* number */
|
long ssl_version_num; /* not used anymore, always 0 */
|
||||||
const char *libz_version; /* human readable string */
|
const char *libz_version; /* human readable string */
|
||||||
/* protocols is terminated by an entry with a NULL protoname */
|
/* protocols is terminated by an entry with a NULL protoname */
|
||||||
const char * const *protocols;
|
const char * const *protocols;
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.13.2-CVS"
|
#define LIBCURL_VERSION "7.14.0-CVS"
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||||
@@ -44,12 +44,12 @@
|
|||||||
always a greater number in a more recent release. It makes comparisons with
|
always a greater number in a more recent release. It makes comparisons with
|
||||||
greater than and less than work.
|
greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x070d02
|
#define LIBCURL_VERSION_NUM 0x070e00
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 13
|
#define LIBCURL_VERSION_MINOR 14
|
||||||
#define LIBCURL_VERSION_PATCH 2
|
#define LIBCURL_VERSION_PATCH 0
|
||||||
|
|
||||||
#endif /* __CURL_CURLVER_H */
|
#endif /* __CURL_CURLVER_H */
|
||||||
|
@@ -23,16 +23,8 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
/*
|
/*
|
||||||
This is meant to be the "external" header file. Don't give away any
|
This is an "external" header file. Don't give away any internals here!
|
||||||
internals here!
|
|
||||||
|
|
||||||
This document presents a mixture of ideas from at least:
|
|
||||||
- Daniel Stenberg
|
|
||||||
- Steve Dekorte
|
|
||||||
- Sterling Hughes
|
|
||||||
- Ben Greear
|
|
||||||
|
|
||||||
-------------------------------------------
|
|
||||||
GOALS
|
GOALS
|
||||||
|
|
||||||
o Enable a "pull" interface. The application that uses libcurl decides where
|
o Enable a "pull" interface. The application that uses libcurl decides where
|
||||||
@@ -82,6 +74,22 @@ extern "C" {
|
|||||||
|
|
||||||
typedef void CURLM;
|
typedef void CURLM;
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL_MULTI_SOCKET /* this is not set by anything yet */
|
||||||
|
|
||||||
|
#ifndef curl_socket_typedef
|
||||||
|
/* Public socket typedef */
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef SOCKET curl_socket_t;
|
||||||
|
#define CURL_SOCKET_BAD INVALID_SOCKET
|
||||||
|
#else
|
||||||
|
typedef int curl_socket_t;
|
||||||
|
#define CURL_SOCKET_BAD -1
|
||||||
|
#endif
|
||||||
|
#define curl_socket_typedef
|
||||||
|
#endif /* curl_socket_typedef */
|
||||||
|
|
||||||
|
#endif /* HAVE_CURL_MULTI_SOCKET */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
|
CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
|
||||||
CURLM_OK,
|
CURLM_OK,
|
||||||
@@ -113,6 +121,7 @@ typedef struct CURLMsg CURLMsg;
|
|||||||
* Name: curl_multi_init()
|
* Name: curl_multi_init()
|
||||||
*
|
*
|
||||||
* Desc: inititalize multi-style curl usage
|
* Desc: inititalize multi-style curl usage
|
||||||
|
*
|
||||||
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN CURLM *curl_multi_init(void);
|
CURL_EXTERN CURLM *curl_multi_init(void);
|
||||||
@@ -121,6 +130,7 @@ CURL_EXTERN CURLM *curl_multi_init(void);
|
|||||||
* Name: curl_multi_add_handle()
|
* Name: curl_multi_add_handle()
|
||||||
*
|
*
|
||||||
* Desc: add a standard curl handle to the multi stack
|
* Desc: add a standard curl handle to the multi stack
|
||||||
|
*
|
||||||
* Returns: CURLMcode type, general multi error code.
|
* Returns: CURLMcode type, general multi error code.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||||
@@ -130,6 +140,7 @@ CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
|||||||
* Name: curl_multi_remove_handle()
|
* Name: curl_multi_remove_handle()
|
||||||
*
|
*
|
||||||
* Desc: removes a curl handle from the multi stack again
|
* Desc: removes a curl handle from the multi stack again
|
||||||
|
*
|
||||||
* Returns: CURLMcode type, general multi error code.
|
* Returns: CURLMcode type, general multi error code.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||||
@@ -141,6 +152,7 @@ CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
|||||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||||
* them are ready.
|
* them are ready.
|
||||||
|
*
|
||||||
* Returns: CURLMcode type, general multi error code.
|
* Returns: CURLMcode type, general multi error code.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||||
@@ -175,6 +187,7 @@ CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
|||||||
* touch any individual easy handles in any way. We need to define
|
* touch any individual easy handles in any way. We need to define
|
||||||
* in what state those handles will be if this function is called
|
* in what state those handles will be if this function is called
|
||||||
* in the middle of a transfer.
|
* in the middle of a transfer.
|
||||||
|
*
|
||||||
* Returns: CURLMcode type, general multi error code.
|
* Returns: CURLMcode type, general multi error code.
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||||
@@ -211,16 +224,107 @@ CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
|
|||||||
int *msgs_in_queue);
|
int *msgs_in_queue);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NAME curl_multi_strerror()
|
* Name: curl_multi_strerror()
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* Desc: 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.
|
||||||
*
|
*
|
||||||
* The curl_multi_strerror function may be used to turn a CURLMcode value
|
* Returns: A pointer to a zero-terminated error message.
|
||||||
* into the equivalent human readable error string. This is useful
|
|
||||||
* for printing meaningful error messages.
|
|
||||||
*/
|
*/
|
||||||
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL_MULTI_SOCKET
|
||||||
|
/*
|
||||||
|
* Name: curl_multi_socket() and
|
||||||
|
* curl_multi_socket_all()
|
||||||
|
*
|
||||||
|
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||||
|
* application to pass in one of the file descriptors that have been
|
||||||
|
* detected to have "action" on them and let libcurl perform. This
|
||||||
|
* allows libcurl to not have to scan through all possible file
|
||||||
|
* descriptors to check for this. The app is recommended to pass in
|
||||||
|
* the 'easy' argument (or set it to CURL_EASY_NONE) to make libcurl
|
||||||
|
* figure out the internal structure even faster and easier. If the
|
||||||
|
* easy argument is set to something else than CURL_EASY_NONE, the
|
||||||
|
* 's' (socket) argument will be ignored by libcurl.
|
||||||
|
*
|
||||||
|
* It also informs the application about updates in the socket (file
|
||||||
|
* descriptor) status by doing none, one or multiple calls to the
|
||||||
|
* curl_socket_callback. It thus updates the status with changes
|
||||||
|
* since the previous time this function was used. If 'callback' is
|
||||||
|
* NULL, no callback will be called. A status change may also be a
|
||||||
|
* new timeout only, having the same IN/OUT status as before.
|
||||||
|
*
|
||||||
|
* If a previous wait for socket action(s) timed out, you should call
|
||||||
|
* this function with the socket argument set to
|
||||||
|
* CURL_SOCKET_TIMEOUT. If you want to force libcurl to (re-)check
|
||||||
|
* all its internal sockets, and call the callback with status for
|
||||||
|
* all sockets no matter what the previous state is, you call
|
||||||
|
* curl_multi_socket_all() instead.
|
||||||
|
*
|
||||||
|
* curl_multi_perform() is thus the equivalent of calling
|
||||||
|
* curl_multi_socket_all(handle, NULL, NULL);
|
||||||
|
*
|
||||||
|
* IMPLEMENTATION: libcurl will need an internal hash table to map
|
||||||
|
* socket numbers to internal easy handles for the cases when 'easy'
|
||||||
|
* is set to CURL_EASY_NONE.
|
||||||
|
*
|
||||||
|
* Regarding the timeout argument in the callback: it is the timeout
|
||||||
|
* (in milliseconds) for waiting on action on this socket (and the
|
||||||
|
* given time period starts when the callback is called) until you
|
||||||
|
* should call curl_multi_socket() with the timeout stuff mentioned
|
||||||
|
* above. If "actions" happens on the socket before the timeout
|
||||||
|
* happens, remember that the timout timer keeps ticking until told
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* The "what" argument has one of five values:
|
||||||
|
*
|
||||||
|
* 0 CURL_POLL_NONE (0) - register, not interested in readiness
|
||||||
|
* 1 CURL_POLL_IN - register, interested in read readiness
|
||||||
|
* 2 CURL_POLL_OUT - register, interested in write readiness
|
||||||
|
* 3 CURL_POLL_INOUT - register, interested in both
|
||||||
|
* 4 CURL_POLL_REMOVE - deregister
|
||||||
|
*/
|
||||||
|
#define CURL_POLL_NONE 0
|
||||||
|
#define CURL_POLL_IN 1
|
||||||
|
#define CURL_POLL_OUT 2
|
||||||
|
#define CURL_POLL_INOUT 3
|
||||||
|
#define CURL_POLL_REMOVE 4
|
||||||
|
|
||||||
|
#define CURL_EASY_NONE (CURL *)0
|
||||||
|
#define CURL_EASY_TIMEOUT (CURL *)0
|
||||||
|
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
|
||||||
|
|
||||||
|
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
|
||||||
|
curl_socket_t s, /* socket */
|
||||||
|
int what, /* see above */
|
||||||
|
long ms, /* timeout for wait */
|
||||||
|
void *userp); /* "private" pointer */
|
||||||
|
|
||||||
|
CURLMcode curl_multi_socket(CURLM *multi_handle,
|
||||||
|
curl_socket_t s,
|
||||||
|
CURL *easy,
|
||||||
|
curl_socket_callback callback,
|
||||||
|
void *userp); /* passed to callback */
|
||||||
|
|
||||||
|
CURLMcode curl_multi_socket_all(CURLM *multi_handle,
|
||||||
|
curl_socket_callback callback,
|
||||||
|
void *userp); /* passed to callback */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name: curl_multi_timeout()
|
||||||
|
*
|
||||||
|
* Desc: Returns the maximum number of milliseconds the app is allowed to
|
||||||
|
* wait before curl_multi_socket() or curl_multi_perform() must be
|
||||||
|
* called (to allow libcurl's timed events to take place).
|
||||||
|
*
|
||||||
|
* Returns: CURLM error code.
|
||||||
|
*/
|
||||||
|
CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds);
|
||||||
|
|
||||||
|
#endif /* HAVE_CURL_MULTI_SOCKET */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@@ -43,7 +43,8 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
|
|||||||
$(OBJ_DIR)\hostip4.obj $(OBJ_DIR)\hostthre.obj &
|
$(OBJ_DIR)\hostip4.obj $(OBJ_DIR)\hostthre.obj &
|
||||||
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.obj &
|
||||||
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
|
||||||
$(OBJ_DIR)\select.obj
|
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
|
||||||
|
$(OBJ_DIR)\gtls.obj
|
||||||
|
|
||||||
RESOURCE = $(OBJ_DIR)\libcurl.res
|
RESOURCE = $(OBJ_DIR)\libcurl.res
|
||||||
|
|
||||||
@@ -355,3 +356,9 @@ $(OBJ_DIR)\parsedate.obj: parsedate.c setup.h config-win32.h ..\include\curl\cur
|
|||||||
..\include\curl\multi.h ..\include\curl\curl.h
|
..\include\curl\multi.h ..\include\curl\curl.h
|
||||||
|
|
||||||
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h select.h
|
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h select.h
|
||||||
|
|
||||||
|
$(OBJ_DIR)\gtls.obj: gtls.c setup.h config-win32.h
|
||||||
|
|
||||||
|
$(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h urldata.h cookie.h &
|
||||||
|
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sslgen.h &
|
||||||
|
ssluse.h gtls.h sendf.h strequal.h url.h memory.h memdebug.h
|
||||||
|
@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
|||||||
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
|
||||||
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
|
||||||
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
|
||||||
select.c
|
select.c gtls.c sslgen.c
|
||||||
|
|
||||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
||||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||||
@@ -17,4 +17,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
|
|||||||
http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h \
|
http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h \
|
||||||
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
|
||||||
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
|
||||||
setup.h transfer.h select.h easyif.h multiif.h parsedate.h
|
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
|
||||||
|
gtls.h
|
||||||
|
|
||||||
|
@@ -13,11 +13,11 @@ NDKBASE = c:/novell
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
#ZLIB_PATH = ../../zlib-1.2.1
|
#ZLIB_PATH = ../../zlib-1.2.2
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../openssl-0.9.7d
|
OPENSSL_PATH = ../../openssl-0.9.7g
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INSTDIR
|
ifndef INSTDIR
|
||||||
@@ -336,7 +336,14 @@ config.h: Makefile.netware
|
|||||||
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
|
||||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||||
|
ifdef DISABLE_LDAP
|
||||||
@echo $(DL)#define CURL_DISABLE_LDAP 1$(DL) >> $@
|
@echo $(DL)#define CURL_DISABLE_LDAP 1$(DL) >> $@
|
||||||
|
else
|
||||||
|
@echo $(DL)#define DL_LDAP_FILE "lldapsdk.nlm"$(DL) >> $@
|
||||||
|
endif
|
||||||
|
ifdef ENABLE_IPV6
|
||||||
|
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||||
|
endif
|
||||||
ifdef NW_WINSOCK
|
ifdef NW_WINSOCK
|
||||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||||
else
|
else
|
||||||
|
@@ -12,7 +12,7 @@ objs = o.base64 o.connect o.cookie o.dict \
|
|||||||
o.memdebug o.mprintf o.netrc o.parsedate o.progress \
|
o.memdebug o.mprintf o.netrc o.parsedate o.progress \
|
||||||
o.security o.select o.sendf o.speedcheck o.ssluse \
|
o.security o.select o.sendf o.speedcheck o.ssluse \
|
||||||
o.strequal o.strtok o.telnet o.timeval \
|
o.strequal o.strtok o.telnet o.timeval \
|
||||||
o.transfer o.url o.version o.strtoofft
|
o.transfer o.url o.version o.strtoofft o.sslgen o.gtls
|
||||||
|
|
||||||
# Compile options:
|
# Compile options:
|
||||||
linkopts = -o libcurl
|
linkopts = -o libcurl
|
||||||
@@ -119,6 +119,12 @@ o.sendf: c.sendf
|
|||||||
o.speedcheck: c.speedcheck
|
o.speedcheck: c.speedcheck
|
||||||
gcc $(compileropts) -c -o speedcheck.o c.speedcheck
|
gcc $(compileropts) -c -o speedcheck.o c.speedcheck
|
||||||
|
|
||||||
|
o.gtls: c.gtls
|
||||||
|
gcc $(compileropts) -c -o gtls.o c.gtls
|
||||||
|
|
||||||
|
o.sslgen: c.sslgen
|
||||||
|
gcc $(compileropts) -c -o sslgen.o c.sslgen
|
||||||
|
|
||||||
o.ssluse: c.ssluse
|
o.ssluse: c.ssluse
|
||||||
gcc $(compileropts) -c -o ssluse.o c.ssluse
|
gcc $(compileropts) -c -o ssluse.o c.ssluse
|
||||||
|
|
||||||
|
@@ -72,6 +72,7 @@ CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D_DEBUG /GZ
|
|||||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
|
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
|
||||||
|
CFLAGSLIB = /DCURL_STATICLIB
|
||||||
LNKDLL = link.exe /DLL
|
LNKDLL = link.exe /DLL
|
||||||
LNKLIB = link.exe /lib
|
LNKLIB = link.exe /lib
|
||||||
LFLAGS = /nologo
|
LFLAGS = /nologo
|
||||||
@@ -99,7 +100,7 @@ LFLAGS = $(LFLAGS) $(WINDOWS_SDK_PATH)\lib\secur32.lib
|
|||||||
TARGET = $(LIB_NAME).lib
|
TARGET = $(LIB_NAME).lib
|
||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG)
|
CC = $(CCNODBG) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ TARGET = $(LIB_NAME).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(CFLAGSZLIB)
|
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ TARGET = $(LIB_NAME).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(CFLAGSSSL)
|
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ DIROBJ = $(CFG)
|
|||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -185,7 +186,7 @@ TARGET = $(LIB_NAME).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(CFLAGSZLIB)
|
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -198,7 +199,7 @@ DIROBJ = $(CFG)
|
|||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -236,7 +237,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
|||||||
TARGET = $(LIB_NAME_DEBUG).lib
|
TARGET = $(LIB_NAME_DEBUG).lib
|
||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG)
|
CC = $(CCDEBUG) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||||
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -260,7 +261,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSZLIB)
|
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -272,7 +273,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSSSL)
|
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -285,7 +286,7 @@ DIROBJ = $(CFG)
|
|||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||||
LNK = $(LNKLIB) $(SSLLIBS) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(SSLLIBS) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -297,7 +298,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
|
|||||||
DIROBJ = $(CFG)
|
DIROBJ = $(CFG)
|
||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSZLIB)
|
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -310,7 +311,7 @@ DIROBJ = $(CFG)
|
|||||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||||
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
|
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -428,6 +429,7 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\telnet.obj \
|
$(DIROBJ)\telnet.obj \
|
||||||
$(DIROBJ)\parsedate.obj \
|
$(DIROBJ)\parsedate.obj \
|
||||||
$(DIROBJ)\getenv.obj \
|
$(DIROBJ)\getenv.obj \
|
||||||
|
$(DIROBJ)\gtls.obj \
|
||||||
$(DIROBJ)\inet_pton.obj \
|
$(DIROBJ)\inet_pton.obj \
|
||||||
$(DIROBJ)\hostip.obj \
|
$(DIROBJ)\hostip.obj \
|
||||||
$(DIROBJ)\hostasyn.obj \
|
$(DIROBJ)\hostasyn.obj \
|
||||||
@@ -443,6 +445,7 @@ X_OBJS= \
|
|||||||
$(DIROBJ)\progress.obj \
|
$(DIROBJ)\progress.obj \
|
||||||
$(DIROBJ)\sendf.obj \
|
$(DIROBJ)\sendf.obj \
|
||||||
$(DIROBJ)\speedcheck.obj \
|
$(DIROBJ)\speedcheck.obj \
|
||||||
|
$(DIROBJ)\sslgen.obj \
|
||||||
$(DIROBJ)\ssluse.obj \
|
$(DIROBJ)\ssluse.obj \
|
||||||
$(DIROBJ)\timeval.obj \
|
$(DIROBJ)\timeval.obj \
|
||||||
$(DIROBJ)\url.obj \
|
$(DIROBJ)\url.obj \
|
||||||
|
17
lib/TODO.gnutls
Normal file
17
lib/TODO.gnutls
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
Things to fix for the GnuTLS support
|
||||||
|
====================================
|
||||||
|
|
||||||
|
* make the configure --with-ssl option first check for OpenSSL and then for
|
||||||
|
GnuTLS if OpenSSL wasn't detected.
|
||||||
|
|
||||||
|
* Get NTLM working using the functions provided by libgcrypt, since GnuTLS
|
||||||
|
already depends on that to function. Not strictly SSL/TLS related, but
|
||||||
|
hey... Another option is to get available DES and MD4 source code from the
|
||||||
|
cryptopp library. They are fine license-wise, but are C++.
|
||||||
|
|
||||||
|
* SSL engine stuff?
|
||||||
|
|
||||||
|
SRP for TLS
|
||||||
|
|
||||||
|
* Work out a common method with Peter Sylvester's OpenSSL-patch for SRP
|
||||||
|
on the TLS to provide name and password
|
@@ -235,6 +235,10 @@
|
|||||||
/* lber dynamic library file */
|
/* lber dynamic library file */
|
||||||
/* #undef DL_LBER_FILE */
|
/* #undef DL_LBER_FILE */
|
||||||
|
|
||||||
|
/* Defines set for VS2005 to _not_ deprecate a few functions we use. */
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
|
||||||
/* ldap dynamic library file */
|
/* ldap dynamic library file */
|
||||||
#define DL_LDAP_FILE "wldap32.dll"
|
#define DL_LDAP_FILE "wldap32.dll"
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#define HAVE_BASENAME 1
|
#define HAVE_BASENAME 1
|
||||||
#define HAVE_CLOSESOCKET 1
|
#define HAVE_CLOSESOCKET 1
|
||||||
#define HAVE_FCNTL_H 1
|
#define HAVE_FCNTL_H 1
|
||||||
|
#define HAVE_FIONBIO 1
|
||||||
#define HAVE_GETHOSTBYADDR 1
|
#define HAVE_GETHOSTBYADDR 1
|
||||||
#define HAVE_GETHOSTNAME 1
|
#define HAVE_GETHOSTNAME 1
|
||||||
#define HAVE_GETPASS 1
|
#define HAVE_GETPASS 1
|
||||||
@@ -104,7 +105,10 @@
|
|||||||
|
|
||||||
#define in_addr_t u_long
|
#define in_addr_t u_long
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
|
|
||||||
|
#if __GNUC__ < 4 /* gcc 4.x built-in ? */
|
||||||
#define ssize_t int
|
#define ssize_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@@ -133,6 +133,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
|||||||
int nonblock /* TRUE or FALSE */)
|
int nonblock /* TRUE or FALSE */)
|
||||||
{
|
{
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
|
#define SETBLOCK 0
|
||||||
#ifdef HAVE_O_NONBLOCK
|
#ifdef HAVE_O_NONBLOCK
|
||||||
/* most recent unix versions */
|
/* most recent unix versions */
|
||||||
int flags;
|
int flags;
|
||||||
@@ -142,46 +143,52 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
|
|||||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
else
|
else
|
||||||
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 1
|
#define SETBLOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FIONBIO
|
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||||
/* older unix versions */
|
/* older unix versions */
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = nonblock;
|
flags = nonblock;
|
||||||
return ioctl(sockfd, FIONBIO, &flags);
|
return ioctl(sockfd, FIONBIO, &flags);
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 2
|
#define SETBLOCK 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IOCTLSOCKET
|
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||||
/* Windows? */
|
/* Windows? */
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
flags = nonblock;
|
flags = nonblock;
|
||||||
|
|
||||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 3
|
#define SETBLOCK 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IOCTLSOCKET_CASE
|
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||||
/* presumably for Amiga */
|
/* presumably for Amiga */
|
||||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 4
|
#define SETBLOCK 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SO_NONBLOCK
|
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||||
/* BeOS */
|
/* BeOS */
|
||||||
long b = nonblock ? 1 : 0;
|
long b = nonblock ? 1 : 0;
|
||||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 5
|
#define SETBLOCK 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||||
return 0; /* returns success */
|
return 0; /* returns success */
|
||||||
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 6
|
#define SETBLOCK 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SETBLOCK
|
#if (SETBLOCK == 0)
|
||||||
#error "no non-blocking method was found/used/set"
|
#error "no non-blocking method was found/used/set"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -345,7 +352,8 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
|
|
||||||
if(!bindworked) {
|
if(!bindworked) {
|
||||||
data->state.os_errno = Curl_ourerrno();
|
data->state.os_errno = Curl_ourerrno();
|
||||||
failf(data, "%s", Curl_strerror(conn, data->state.os_errno));
|
failf(data, "bind failure: %s",
|
||||||
|
Curl_strerror(conn, data->state.os_errno));
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,14 +653,14 @@ singleipconnect(struct connectdata *conn,
|
|||||||
CURLcode res = bindlocal(conn, sockfd);
|
CURLcode res = bindlocal(conn, sockfd);
|
||||||
if(res) {
|
if(res) {
|
||||||
sclose(sockfd); /* close socket and bail out */
|
sclose(sockfd); /* close socket and bail out */
|
||||||
return res;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set socket non-blocking */
|
/* set socket non-blocking */
|
||||||
Curl_nonblock(sockfd, TRUE);
|
Curl_nonblock(sockfd, TRUE);
|
||||||
|
|
||||||
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
|
rc = connect(sockfd, ai->ai_addr, (socklen_t)ai->ai_addrlen);
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_ourerrno();
|
||||||
|
@@ -309,7 +309,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
co->expires =
|
co->expires =
|
||||||
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
|
atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + (long)now;
|
||||||
}
|
}
|
||||||
else if(strequal("expires", name)) {
|
else if(strequal("expires", name)) {
|
||||||
co->expirestr=strdup(whatptr);
|
co->expirestr=strdup(whatptr);
|
||||||
@@ -317,7 +317,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
|||||||
badcookie = TRUE;
|
badcookie = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
co->expires = curl_getdate(what, &now);
|
co->expires = (long)curl_getdate(what, &now);
|
||||||
}
|
}
|
||||||
else if(!co->name) {
|
else if(!co->name) {
|
||||||
co->name = strdup(name);
|
co->name = strdup(name);
|
||||||
|
@@ -75,7 +75,7 @@
|
|||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "getinfo.h"
|
#include "getinfo.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
@@ -201,7 +201,7 @@ CURLcode curl_global_init(long flags)
|
|||||||
Curl_ccalloc = (curl_calloc_callback)calloc;
|
Curl_ccalloc = (curl_calloc_callback)calloc;
|
||||||
|
|
||||||
if (flags & CURL_GLOBAL_SSL)
|
if (flags & CURL_GLOBAL_SSL)
|
||||||
if (!Curl_SSL_init())
|
if (!Curl_ssl_init())
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
if (flags & CURL_GLOBAL_WIN32)
|
if (flags & CURL_GLOBAL_WIN32)
|
||||||
@@ -266,7 +266,7 @@ void curl_global_cleanup(void)
|
|||||||
Curl_global_host_cache_dtor();
|
Curl_global_host_cache_dtor();
|
||||||
|
|
||||||
if (init_flags & CURL_GLOBAL_SSL)
|
if (init_flags & CURL_GLOBAL_SSL)
|
||||||
Curl_SSL_cleanup();
|
Curl_ssl_cleanup();
|
||||||
|
|
||||||
if (init_flags & CURL_GLOBAL_WIN32)
|
if (init_flags & CURL_GLOBAL_WIN32)
|
||||||
win32_cleanup();
|
win32_cleanup();
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -464,7 +464,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
|||||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||||
else
|
else
|
||||||
current_form->namelength =
|
current_form->namelength =
|
||||||
array_state?(long)array_value:va_arg(params, long);
|
array_state?(long)array_value:(long)va_arg(params, long);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1550,7 +1550,7 @@ char *Curl_FormBoundary(void)
|
|||||||
if(!retstring)
|
if(!retstring)
|
||||||
return NULL; /* failed */
|
return NULL; /* failed */
|
||||||
|
|
||||||
srand(time(NULL)+randomizer++); /* seed */
|
srand((unsigned int)time(NULL)+randomizer++); /* seed */
|
||||||
|
|
||||||
strcpy(retstring, "----------------------------");
|
strcpy(retstring, "----------------------------");
|
||||||
|
|
||||||
|
73
lib/ftp.c
73
lib/ftp.c
@@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
#include "strtoofft.h"
|
#include "strtoofft.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@@ -266,8 +266,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
|||||||
|
|
||||||
ptr=buf + ftp->nread_resp;
|
ptr=buf + ftp->nread_resp;
|
||||||
|
|
||||||
perline= ptr-ftp->linestart_resp; /* number of bytes in the current line,
|
perline= (int)(ptr-ftp->linestart_resp); /* number of bytes in the current
|
||||||
so far */
|
line, so far */
|
||||||
keepon=TRUE;
|
keepon=TRUE;
|
||||||
|
|
||||||
while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) {
|
while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) {
|
||||||
@@ -777,9 +777,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
/******************************************************************
|
/******************************************************************
|
||||||
* IPv6-specific section
|
* IPv6-specific section
|
||||||
*/
|
*/
|
||||||
|
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||||
struct addrinfo *res, *ai;
|
|
||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
|
#else
|
||||||
|
char ss[256]; /* this should be big enough to fit a lot */
|
||||||
|
#endif
|
||||||
|
struct addrinfo *res, *ai;
|
||||||
socklen_t sslen;
|
socklen_t sslen;
|
||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
struct sockaddr *sa=(struct sockaddr *)&ss;
|
struct sockaddr *sa=(struct sockaddr *)&ss;
|
||||||
@@ -866,13 +869,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (portsock == CURL_SOCKET_BAD) {
|
if (portsock == CURL_SOCKET_BAD) {
|
||||||
failf(data, "%s", Curl_strerror(conn,error));
|
failf(data, "socket failure: %s", Curl_strerror(conn,error));
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sslen = sizeof(ss);
|
sslen = sizeof(ss);
|
||||||
if (getsockname(portsock, sa, &sslen) < 0) {
|
if (getsockname(portsock, sa, &sslen) < 0) {
|
||||||
failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
|
failf(data, "getsockname(): %s", Curl_strerror(conn,Curl_ourerrno()));
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1739,7 +1742,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
|||||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||||
year, month, day, hour, minute, second);
|
year, month, day, hour, minute, second);
|
||||||
/* now, convert this into a time() value: */
|
/* now, convert this into a time() value: */
|
||||||
data->info.filetime = curl_getdate(buf, &secs);
|
data->info.filetime = (long)curl_getdate(buf, &secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we asked for a time of the file and we actually got one as well,
|
/* If we asked for a time of the file and we actually got one as well,
|
||||||
@@ -2013,7 +2016,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
|||||||
do the TLS stuff */
|
do the TLS stuff */
|
||||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
result = Curl_SSLConnect(conn, SECONDARYSOCKET);
|
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2086,7 +2089,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
|||||||
char *bytes;
|
char *bytes;
|
||||||
bytes=strstr(buf, " bytes");
|
bytes=strstr(buf, " bytes");
|
||||||
if(bytes--) {
|
if(bytes--) {
|
||||||
long in=bytes-buf;
|
long in=(long)(bytes-buf);
|
||||||
/* this is a hint there is size information in there! ;-) */
|
/* this is a hint there is size information in there! ;-) */
|
||||||
while(--in) {
|
while(--in) {
|
||||||
/* scan for the left parenthesis and break there */
|
/* scan for the left parenthesis and break there */
|
||||||
@@ -2121,7 +2124,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
|||||||
/* since we only have a plaintext TCP connection here, we must now
|
/* since we only have a plaintext TCP connection here, we must now
|
||||||
do the TLS stuff */
|
do the TLS stuff */
|
||||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||||
result = Curl_SSLConnect(conn, SECONDARYSOCKET);
|
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2148,7 +2151,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
|||||||
state(conn, FTP_STOP); /* this phase is over */
|
state(conn, FTP_STOP); /* this phase is over */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "%s", buf+4);
|
failf(data, "RETR response: %03d", ftpcode);
|
||||||
return CURLE_FTP_COULDNT_RETR_FILE;
|
return CURLE_FTP_COULDNT_RETR_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2160,11 +2163,9 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
|||||||
static CURLcode ftp_state_loggedin(struct connectdata *conn)
|
static CURLcode ftp_state_loggedin(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
infof(data, "We have successfully logged in\n");
|
|
||||||
|
|
||||||
#ifdef HAVE_KRB4
|
#ifdef HAVE_KRB4
|
||||||
if(data->set.krb4) {
|
if(conn->data->set.krb4) {
|
||||||
/* We are logged in, asked to use Kerberos. Set the requested
|
/* We are logged in, asked to use Kerberos. Set the requested
|
||||||
* protection level
|
* protection level
|
||||||
*/
|
*/
|
||||||
@@ -2276,7 +2277,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
static const char * const ftpauth[] = {
|
static const char * const ftpauth[] = {
|
||||||
"SSL", "TLS"
|
"SSL", "TLS"
|
||||||
};
|
};
|
||||||
size_t nread;
|
size_t nread = 0;
|
||||||
|
|
||||||
if(ftp->sendleft) {
|
if(ftp->sendleft) {
|
||||||
/* we have a piece of a command still left to send */
|
/* we have a piece of a command still left to send */
|
||||||
@@ -2373,8 +2374,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if((ftpcode == 234) || (ftpcode == 334)) {
|
if((ftpcode == 234) || (ftpcode == 334)) {
|
||||||
/* Curl_SSLConnect is BLOCKING */
|
/* Curl_ssl_connect is BLOCKING */
|
||||||
result = Curl_SSLConnect(conn, FIRSTSOCKET);
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if(CURLE_OK == result) {
|
if(CURLE_OK == result) {
|
||||||
conn->protocol |= PROT_FTPS;
|
conn->protocol |= PROT_FTPS;
|
||||||
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
||||||
@@ -2487,7 +2488,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
|
state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||||
infof(data, "protocol connect phase DONE\n");
|
DEBUGF(infof(data, "protocol connect phase DONE\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTP_QUOTE:
|
case FTP_QUOTE:
|
||||||
@@ -2677,7 +2678,7 @@ static CURLcode ftp_easy_statemach(struct connectdata *conn)
|
|||||||
|
|
||||||
rc = Curl_select(ftp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
rc = Curl_select(ftp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
||||||
ftp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
|
ftp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
|
||||||
timeout_ms);
|
(int)timeout_ms);
|
||||||
|
|
||||||
if(rc == -1) {
|
if(rc == -1) {
|
||||||
failf(data, "select error");
|
failf(data, "select error");
|
||||||
@@ -2748,7 +2749,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
|
|||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
/* FTPS is simply ftp with SSL for the control channel */
|
/* FTPS is simply ftp with SSL for the control channel */
|
||||||
/* now, perform the SSL initialization for this socket */
|
/* now, perform the SSL initialization for this socket */
|
||||||
result = Curl_SSLConnect(conn, FIRSTSOCKET);
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2820,7 +2821,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
|
|||||||
if(data->set.upload) {
|
if(data->set.upload) {
|
||||||
if((-1 != data->set.infilesize) &&
|
if((-1 != data->set.infilesize) &&
|
||||||
(data->set.infilesize != *ftp->bytecountp) &&
|
(data->set.infilesize != *ftp->bytecountp) &&
|
||||||
!data->set.crlf) {
|
!data->set.crlf &&
|
||||||
|
!ftp->no_transfer) {
|
||||||
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
|
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
|
||||||
" out of %" FORMAT_OFF_T " bytes)",
|
" out of %" FORMAT_OFF_T " bytes)",
|
||||||
*ftp->bytecountp, data->set.infilesize);
|
*ftp->bytecountp, data->set.infilesize);
|
||||||
@@ -3025,7 +3027,6 @@ static CURLcode ftp_range(struct connectdata *conn)
|
|||||||
curl_off_t totalsize=-1;
|
curl_off_t totalsize=-1;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *ptr2;
|
char *ptr2;
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
struct FTP *ftp = conn->proto.ftp;
|
struct FTP *ftp = conn->proto.ftp;
|
||||||
|
|
||||||
if(conn->bits.use_range && conn->range) {
|
if(conn->bits.use_range && conn->range) {
|
||||||
@@ -3040,26 +3041,29 @@ static CURLcode ftp_range(struct connectdata *conn)
|
|||||||
if((-1 == to) && (from>=0)) {
|
if((-1 == to) && (from>=0)) {
|
||||||
/* X - */
|
/* X - */
|
||||||
conn->resume_from = from;
|
conn->resume_from = from;
|
||||||
infof(data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n", from);
|
DEBUGF(infof(conn->data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n",
|
||||||
|
from));
|
||||||
}
|
}
|
||||||
else if(from < 0) {
|
else if(from < 0) {
|
||||||
/* -Y */
|
/* -Y */
|
||||||
totalsize = -from;
|
totalsize = -from;
|
||||||
conn->maxdownload = -from;
|
conn->maxdownload = -from;
|
||||||
conn->resume_from = from;
|
conn->resume_from = from;
|
||||||
infof(data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n", totalsize);
|
DEBUGF(infof(conn->data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n",
|
||||||
|
totalsize));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* X-Y */
|
/* X-Y */
|
||||||
totalsize = to-from;
|
totalsize = to-from;
|
||||||
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
|
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
|
||||||
conn->resume_from = from;
|
conn->resume_from = from;
|
||||||
infof(data, "FTP RANGE from %" FORMAT_OFF_T
|
DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
|
||||||
" getting %" FORMAT_OFF_T " bytes\n", from, conn->maxdownload);
|
" getting %" FORMAT_OFF_T " bytes\n",
|
||||||
|
from, conn->maxdownload));
|
||||||
}
|
}
|
||||||
infof(data, "range-download from %" FORMAT_OFF_T
|
DEBUGF(infof(conn->data, "range-download from %" FORMAT_OFF_T
|
||||||
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
|
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
|
||||||
from, to, conn->maxdownload);
|
from, to, conn->maxdownload));
|
||||||
ftp->dont_check = TRUE; /* dont check for successful transfer */
|
ftp->dont_check = TRUE; /* dont check for successful transfer */
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@@ -3081,7 +3085,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
/* the ftp struct is inited in Curl_ftp_connect() */
|
/* the ftp struct is inited in Curl_ftp_connect() */
|
||||||
struct FTP *ftp = conn->proto.ftp;
|
struct FTP *ftp = conn->proto.ftp;
|
||||||
|
|
||||||
infof(data, "DO-MORE phase starts\n");
|
DEBUGF(infof(data, "DO-MORE phase starts\n"));
|
||||||
|
|
||||||
if(!ftp->no_transfer && !conn->bits.no_body) {
|
if(!ftp->no_transfer && !conn->bits.no_body) {
|
||||||
/* a transfer is about to take place */
|
/* a transfer is about to take place */
|
||||||
@@ -3118,7 +3122,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
|||||||
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||||
|
|
||||||
/* end of transfer */
|
/* end of transfer */
|
||||||
infof(data, "DO-MORE phase ends\n");
|
DEBUGF(infof(data, "DO-MORE phase ends\n"));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3140,9 +3144,8 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
/* this is FTP and no proxy */
|
/* this is FTP and no proxy */
|
||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
struct SessionHandle *data=conn->data;
|
|
||||||
|
|
||||||
infof(data, "DO phase starts\n");
|
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||||
|
|
||||||
*dophase_done = FALSE; /* not done yet */
|
*dophase_done = FALSE; /* not done yet */
|
||||||
|
|
||||||
@@ -3161,7 +3164,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
|||||||
*connected = conn->bits.tcpconnect;
|
*connected = conn->bits.tcpconnect;
|
||||||
|
|
||||||
if(*dophase_done)
|
if(*dophase_done)
|
||||||
infof(data, "DO phase is comlete\n");
|
DEBUGF(infof(conn->data, "DO phase is comlete\n"));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3818,7 +3821,7 @@ CURLcode Curl_ftp_doing(struct connectdata *conn,
|
|||||||
if(*dophase_done) {
|
if(*dophase_done) {
|
||||||
result = ftp_dophase_done(conn, FALSE /* not connected */);
|
result = ftp_dophase_done(conn, FALSE /* not connected */);
|
||||||
|
|
||||||
infof(conn->data, "DO phase is comlete\n");
|
DEBUGF(infof(conn->data, "DO phase is comlete\n"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
|
|
||||||
/* Make this the last #include */
|
/* Make this the last #include */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@@ -182,7 +182,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
*param_longp = data->info.numconnects;
|
*param_longp = data->info.numconnects;
|
||||||
break;
|
break;
|
||||||
case CURLINFO_SSL_ENGINES:
|
case CURLINFO_SSL_ENGINES:
|
||||||
*param_slistp = Curl_SSL_engines_list(data);
|
*param_slistp = Curl_ssl_engines_list(data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
|
490
lib/gtls.c
Normal file
490
lib/gtls.c
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
|
||||||
|
* but sslgen.c should ever call or use these functions.
|
||||||
|
*
|
||||||
|
* Note: don't use the GnuTLS' *_t variable type names in this source code,
|
||||||
|
* since they were not present in 1.0.X.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <gnutls/x509.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "gtls.h"
|
||||||
|
#include "sslgen.h"
|
||||||
|
#include "parsedate.h"
|
||||||
|
#include "connect.h" /* for the connect timeout */
|
||||||
|
#include "select.h"
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
#include "memory.h"
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/* Enable GnuTLS debugging by defining GTLSDEBUG */
|
||||||
|
/*#define GTLSDEBUG */
|
||||||
|
|
||||||
|
#ifdef GTLSDEBUG
|
||||||
|
static void tls_log_func(int level, const char *str)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "|<%d>| %s", level, str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Global GnuTLS init, called from Curl_ssl_init() */
|
||||||
|
int Curl_gtls_init(void)
|
||||||
|
{
|
||||||
|
gnutls_global_init();
|
||||||
|
#ifdef GTLSDEBUG
|
||||||
|
gnutls_global_set_log_function(tls_log_func);
|
||||||
|
gnutls_global_set_log_level(2);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Curl_gtls_cleanup(void)
|
||||||
|
{
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void showtime(struct SessionHandle *data,
|
||||||
|
const char *text,
|
||||||
|
time_t stamp)
|
||||||
|
{
|
||||||
|
struct tm *tm;
|
||||||
|
#ifdef HAVE_GMTIME_R
|
||||||
|
struct tm buffer;
|
||||||
|
tm = (struct tm *)gmtime_r(&stamp, &buffer);
|
||||||
|
#else
|
||||||
|
tm = gmtime(&stamp);
|
||||||
|
#endif
|
||||||
|
snprintf(data->state.buffer,
|
||||||
|
BUFSIZE,
|
||||||
|
"\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
|
||||||
|
text,
|
||||||
|
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||||
|
tm->tm_mday,
|
||||||
|
Curl_month[tm->tm_mon],
|
||||||
|
tm->tm_year + 1900,
|
||||||
|
tm->tm_hour,
|
||||||
|
tm->tm_min,
|
||||||
|
tm->tm_sec);
|
||||||
|
infof(data, "%s", data->state.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called after the TCP connect has completed. Setup the TLS
|
||||||
|
* layer and do all necessary magic.
|
||||||
|
*/
|
||||||
|
CURLcode
|
||||||
|
Curl_gtls_connect(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
|
||||||
|
{
|
||||||
|
const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
gnutls_session session;
|
||||||
|
int rc;
|
||||||
|
unsigned int cert_list_size;
|
||||||
|
const gnutls_datum *chainp;
|
||||||
|
unsigned int verify_status;
|
||||||
|
gnutls_x509_crt x509_cert;
|
||||||
|
char certbuf[256]; /* big enough? */
|
||||||
|
size_t size;
|
||||||
|
unsigned int algo;
|
||||||
|
unsigned int bits;
|
||||||
|
time_t clock;
|
||||||
|
const char *ptr;
|
||||||
|
void *ssl_sessionid;
|
||||||
|
size_t ssl_idsize;
|
||||||
|
|
||||||
|
/* GnuTLS only supports TLSv1 (and SSLv3?) */
|
||||||
|
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
|
||||||
|
failf(data, "GnuTLS does not support SSLv2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a cred struct */
|
||||||
|
rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
|
||||||
|
if(rc < 0) {
|
||||||
|
failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data->set.ssl.CAfile) {
|
||||||
|
/* set the trusted CA cert bundle file */
|
||||||
|
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
|
||||||
|
data->set.ssl.CAfile,
|
||||||
|
GNUTLS_X509_FMT_PEM);
|
||||||
|
if(rc < 0) {
|
||||||
|
infof(data, "error reading ca cert file %s (%s)\n",
|
||||||
|
data->set.ssl.CAfile, gnutls_strerror(rc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize TLS session as a client */
|
||||||
|
rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
|
||||||
|
if(rc) {
|
||||||
|
failf(data, "gnutls_init() failed: %d", rc);
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convenient assign */
|
||||||
|
session = conn->ssl[sockindex].session;
|
||||||
|
|
||||||
|
/* Use default priorities */
|
||||||
|
rc = gnutls_set_default_priority(session);
|
||||||
|
if(rc < 0)
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
|
||||||
|
/* Sets the priority on the certificate types supported by gnutls. Priority
|
||||||
|
is higher for types specified before others. After specifying the types
|
||||||
|
you want, you must append a 0. */
|
||||||
|
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
|
||||||
|
if(rc < 0)
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
|
||||||
|
/* put the anonymous credentials to the current session */
|
||||||
|
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||||
|
conn->ssl[sockindex].cred);
|
||||||
|
|
||||||
|
/* set the connection handle (file descriptor for the socket) */
|
||||||
|
gnutls_transport_set_ptr(session,
|
||||||
|
(gnutls_transport_ptr)conn->sock[sockindex]);
|
||||||
|
|
||||||
|
/* This might be a reconnect, so we check for a session ID in the cache
|
||||||
|
to speed up things */
|
||||||
|
|
||||||
|
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
|
||||||
|
/* we got a session id, use it! */
|
||||||
|
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
|
||||||
|
|
||||||
|
/* Informational message */
|
||||||
|
infof (data, "SSL re-using session ID\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = gnutls_handshake(session);
|
||||||
|
|
||||||
|
if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
|
||||||
|
long timeout_ms;
|
||||||
|
long has_passed;
|
||||||
|
|
||||||
|
if(data->set.timeout || data->set.connecttimeout) {
|
||||||
|
/* get the most strict timeout of the ones converted to milliseconds */
|
||||||
|
if(data->set.timeout &&
|
||||||
|
(data->set.timeout>data->set.connecttimeout))
|
||||||
|
timeout_ms = data->set.timeout*1000;
|
||||||
|
else
|
||||||
|
timeout_ms = data->set.connecttimeout*1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
timeout_ms = DEFAULT_CONNECT_TIMEOUT;
|
||||||
|
|
||||||
|
/* Evaluate in milliseconds how much time that has passed */
|
||||||
|
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
|
|
||||||
|
/* subtract the passed time */
|
||||||
|
timeout_ms -= has_passed;
|
||||||
|
|
||||||
|
if(timeout_ms < 0) {
|
||||||
|
/* a precaution, no need to continue if time already is up */
|
||||||
|
failf(data, "SSL connection timeout");
|
||||||
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = Curl_select(conn->sock[sockindex],
|
||||||
|
conn->sock[sockindex], (int)timeout_ms);
|
||||||
|
if(rc > 0)
|
||||||
|
/* reabable or writable, go loop*/
|
||||||
|
continue;
|
||||||
|
else if(0 == rc) {
|
||||||
|
/* timeout */
|
||||||
|
failf(data, "SSL connection timeout");
|
||||||
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* anything that gets here is fatally bad */
|
||||||
|
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
} while(1);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
failf(data, "gnutls_handshake() failed: %d", rc);
|
||||||
|
/* gnutls_perror(ret); */
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function will return the peer's raw certificate (chain) as sent by
|
||||||
|
the peer. These certificates are in raw format (DER encoded for
|
||||||
|
X.509). In case of a X.509 then a certificate list may be present. The
|
||||||
|
first certificate in the list is the peer's certificate, following the
|
||||||
|
issuer's certificate, then the issuer's issuer etc. */
|
||||||
|
|
||||||
|
chainp = gnutls_certificate_get_peers(session, &cert_list_size);
|
||||||
|
if(!chainp) {
|
||||||
|
if(data->set.ssl.verifyhost) {
|
||||||
|
failf(data, "failed to get server cert");
|
||||||
|
return CURLE_SSL_PEER_CERTIFICATE;
|
||||||
|
}
|
||||||
|
infof(data, "\t common name: WARNING couldn't obtain\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function will try to verify the peer's certificate and return its
|
||||||
|
status (trusted, invalid etc.). The value of status should be one or more
|
||||||
|
of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
|
||||||
|
avoid denial of service attacks some default upper limits regarding the
|
||||||
|
certificate key size and chain size are set. To override them use
|
||||||
|
gnutls_certificate_set_verify_limits(). */
|
||||||
|
|
||||||
|
rc = gnutls_certificate_verify_peers2(session, &verify_status);
|
||||||
|
if (rc < 0) {
|
||||||
|
failf(data, "server cert verify failed: %d", rc);
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify_status is a bitmask of gnutls_certificate_status bits */
|
||||||
|
if(verify_status & GNUTLS_CERT_INVALID) {
|
||||||
|
if (data->set.ssl.verifypeer) {
|
||||||
|
failf(data, "server certificate verification failed. CAfile: %s",
|
||||||
|
data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
|
||||||
|
return CURLE_SSL_CACERT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "\t server certificate verification FAILED\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "\t server certificate verification OK\n");
|
||||||
|
|
||||||
|
/* initialize an X.509 certificate structure. */
|
||||||
|
gnutls_x509_crt_init(&x509_cert);
|
||||||
|
|
||||||
|
/* convert the given DER or PEM encoded Certificate to the native
|
||||||
|
gnutls_x509_crt_t format */
|
||||||
|
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
|
||||||
|
|
||||||
|
size=sizeof(certbuf);
|
||||||
|
rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
|
||||||
|
0, /* the first and only one */
|
||||||
|
FALSE,
|
||||||
|
certbuf,
|
||||||
|
&size);
|
||||||
|
if(rc) {
|
||||||
|
infof(data, "error fetching CN from cert:%s\n",
|
||||||
|
gnutls_strerror(rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function will check if the given certificate's subject matches the
|
||||||
|
given hostname. This is a basic implementation of the matching described
|
||||||
|
in RFC2818 (HTTPS), which takes into account wildcards, and the subject
|
||||||
|
alternative name PKIX extension. Returns non zero on success, and zero on
|
||||||
|
failure. */
|
||||||
|
rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
|
||||||
|
|
||||||
|
if(!rc) {
|
||||||
|
if (data->set.ssl.verifyhost > 1) {
|
||||||
|
failf(data, "SSL: certificate subject name (%s) does not match "
|
||||||
|
"target host name '%s'", certbuf, conn->host.dispname);
|
||||||
|
gnutls_x509_crt_deinit(x509_cert);
|
||||||
|
return CURLE_SSL_PEER_CERTIFICATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "\t common name: %s (does not match '%s')\n",
|
||||||
|
certbuf, conn->host.dispname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "\t common name: %s (matched)\n", certbuf);
|
||||||
|
|
||||||
|
/* Show:
|
||||||
|
|
||||||
|
- ciphers used
|
||||||
|
- subject
|
||||||
|
- start date
|
||||||
|
- expire date
|
||||||
|
- common name
|
||||||
|
- issuer
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* public key algorithm's parameters */
|
||||||
|
algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
|
||||||
|
infof(data, "\t certificate public key: %s\n",
|
||||||
|
gnutls_pk_algorithm_get_name(algo));
|
||||||
|
|
||||||
|
/* version of the X.509 certificate. */
|
||||||
|
infof(data, "\t certificate version: #%d\n",
|
||||||
|
gnutls_x509_crt_get_version(x509_cert));
|
||||||
|
|
||||||
|
|
||||||
|
size = sizeof(certbuf);
|
||||||
|
gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
|
||||||
|
infof(data, "\t subject: %s\n", certbuf);
|
||||||
|
|
||||||
|
clock = gnutls_x509_crt_get_activation_time(x509_cert);
|
||||||
|
showtime(data, "start date", clock);
|
||||||
|
|
||||||
|
clock = gnutls_x509_crt_get_expiration_time(x509_cert);
|
||||||
|
showtime(data, "expire date", clock);
|
||||||
|
|
||||||
|
size = sizeof(certbuf);
|
||||||
|
gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
|
||||||
|
infof(data, "\t issuer: %s\n", certbuf);
|
||||||
|
|
||||||
|
gnutls_x509_crt_deinit(x509_cert);
|
||||||
|
|
||||||
|
/* compression algorithm (if any) */
|
||||||
|
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
|
||||||
|
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
|
||||||
|
infof(data, "\t compression: %s\n", ptr);
|
||||||
|
|
||||||
|
/* the name of the cipher used. ie 3DES. */
|
||||||
|
ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
|
||||||
|
infof(data, "\t cipher: %s\n", ptr);
|
||||||
|
|
||||||
|
/* the MAC algorithms name. ie SHA1 */
|
||||||
|
ptr = gnutls_mac_get_name(gnutls_mac_get(session));
|
||||||
|
infof(data, "\t MAC: %s\n", ptr);
|
||||||
|
|
||||||
|
if(!ssl_sessionid) {
|
||||||
|
/* this session was not previously in the cache, add it now */
|
||||||
|
|
||||||
|
/* get the session ID data size */
|
||||||
|
gnutls_session_get_data(session, NULL, &ssl_idsize);
|
||||||
|
ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */
|
||||||
|
|
||||||
|
if(ssl_sessionid) {
|
||||||
|
/* extract session ID to the allocated buffer */
|
||||||
|
gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);
|
||||||
|
|
||||||
|
/* store this session id */
|
||||||
|
return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* return number of sent (non-SSL) bytes */
|
||||||
|
int Curl_gtls_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
void *mem,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_gtls_close_all(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
/* FIX: make the OpenSSL code more generic and use parts of it here */
|
||||||
|
(void)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_one(struct connectdata *conn,
|
||||||
|
int index)
|
||||||
|
{
|
||||||
|
if(conn->ssl[index].session) {
|
||||||
|
gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
|
||||||
|
gnutls_deinit(conn->ssl[index].session);
|
||||||
|
}
|
||||||
|
gnutls_certificate_free_credentials(conn->ssl[index].cred);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_gtls_close(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
if(conn->ssl[0].use)
|
||||||
|
close_one(conn, 0);
|
||||||
|
if(conn->ssl[1].use)
|
||||||
|
close_one(conn, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the read would block we return -1 and set 'wouldblock' to TRUE.
|
||||||
|
* Otherwise we return the amount of data read. Other errors should return -1
|
||||||
|
* and set 'wouldblock' to FALSE.
|
||||||
|
*/
|
||||||
|
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int num, /* socketindex */
|
||||||
|
char *buf, /* store read data here */
|
||||||
|
size_t buffersize, /* max amount to read */
|
||||||
|
bool *wouldblock)
|
||||||
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
|
||||||
|
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
|
||||||
|
*wouldblock = TRUE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*wouldblock = FALSE;
|
||||||
|
if (!ret) {
|
||||||
|
failf(conn->data, "Peer closed the TLS connection");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
failf(conn->data, "GnuTLS recv error (%d): %s",
|
||||||
|
(int)ret, gnutls_strerror(ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_gtls_session_free(void *ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Curl_gtls_version(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
return snprintf(buffer, size, " GnuTLS/%s", gnutls_check_version(NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_GNUTLS */
|
45
lib/gtls.h
Normal file
45
lib/gtls.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef __GTLS_H
|
||||||
|
#define __GTLS_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
int Curl_gtls_init(void);
|
||||||
|
int Curl_gtls_cleanup(void);
|
||||||
|
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
|
||||||
|
|
||||||
|
/* tell GnuTLS to close down all open information regarding connections (and
|
||||||
|
thus session ID caching etc) */
|
||||||
|
void Curl_gtls_close_all(struct SessionHandle *data);
|
||||||
|
void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
|
||||||
|
|
||||||
|
/* return number of sent (non-SSL) bytes */
|
||||||
|
int Curl_gtls_send(struct connectdata *conn, int sockindex,
|
||||||
|
void *mem, size_t len);
|
||||||
|
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int num, /* socketindex */
|
||||||
|
char *buf, /* store read data here */
|
||||||
|
size_t buffersize, /* max amount to read */
|
||||||
|
bool *wouldblock);
|
||||||
|
void Curl_gtls_session_free(void *ptr);
|
||||||
|
size_t Curl_gtls_version(char *buffer, size_t size);
|
||||||
|
|
||||||
|
#endif
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _REENTRANT
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#else
|
#else
|
||||||
@@ -550,7 +548,7 @@ CURLcode Curl_resolv_fdset(struct connectdata *conn,
|
|||||||
|
|
||||||
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
|
||||||
FD_SET(td->dummy_sock,write_fd_set);
|
FD_SET(td->dummy_sock,write_fd_set);
|
||||||
*max_fdp = td->dummy_sock;
|
*max_fdp = (int)td->dummy_sock;
|
||||||
}
|
}
|
||||||
(void) read_fd_set;
|
(void) read_fd_set;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
236
lib/http.c
236
lib/http.c
@@ -85,7 +85,7 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "cookie.h"
|
#include "cookie.h"
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
#include "http_digest.h"
|
#include "http_digest.h"
|
||||||
#include "http_ntlm.h"
|
#include "http_ntlm.h"
|
||||||
#include "http_negotiate.h"
|
#include "http_negotiate.h"
|
||||||
@@ -416,7 +416,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
|||||||
/* Send proxy authentication header if needed */
|
/* Send proxy authentication header if needed */
|
||||||
if (conn->bits.httpproxy &&
|
if (conn->bits.httpproxy &&
|
||||||
(conn->bits.tunnel_proxy == proxytunnel)) {
|
(conn->bits.tunnel_proxy == proxytunnel)) {
|
||||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
#ifdef USE_NTLM
|
||||||
if(authproxy->picked == CURLAUTH_NTLM) {
|
if(authproxy->picked == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, TRUE);
|
result = Curl_output_ntlm(conn, TRUE);
|
||||||
@@ -465,6 +465,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
|||||||
/* To prevent the user+password to get sent to other than the original
|
/* To prevent the user+password to get sent to other than the original
|
||||||
host due to a location-follow, we do some weirdo checks here */
|
host due to a location-follow, we do some weirdo checks here */
|
||||||
if(!data->state.this_is_a_follow ||
|
if(!data->state.this_is_a_follow ||
|
||||||
|
conn->bits.netrc ||
|
||||||
!data->state.first_host ||
|
!data->state.first_host ||
|
||||||
curl_strequal(data->state.first_host, conn->host.name) ||
|
curl_strequal(data->state.first_host, conn->host.name) ||
|
||||||
data->set.http_disable_hostname_check_before_authentication) {
|
data->set.http_disable_hostname_check_before_authentication) {
|
||||||
@@ -484,7 +485,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
#ifdef USE_NTLM
|
||||||
if(authhost->picked == CURLAUTH_NTLM) {
|
if(authhost->picked == CURLAUTH_NTLM) {
|
||||||
auth=(char *)"NTLM";
|
auth=(char *)"NTLM";
|
||||||
result = Curl_output_ntlm(conn, FALSE);
|
result = Curl_output_ntlm(conn, FALSE);
|
||||||
@@ -597,7 +598,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
#ifdef USE_NTLM
|
||||||
/* NTLM support requires the SSL crypto libs */
|
/* NTLM support requires the SSL crypto libs */
|
||||||
if(checkprefix("NTLM", start)) {
|
if(checkprefix("NTLM", start)) {
|
||||||
*availp |= CURLAUTH_NTLM;
|
*availp |= CURLAUTH_NTLM;
|
||||||
@@ -810,6 +811,8 @@ struct send_buffer {
|
|||||||
};
|
};
|
||||||
typedef struct send_buffer send_buffer;
|
typedef struct send_buffer send_buffer;
|
||||||
|
|
||||||
|
static CURLcode add_custom_headers(struct connectdata *conn,
|
||||||
|
send_buffer *req_buffer);
|
||||||
static CURLcode
|
static CURLcode
|
||||||
add_buffer(send_buffer *in, const void *inptr, size_t size);
|
add_buffer(send_buffer *in, const void *inptr, size_t size);
|
||||||
|
|
||||||
@@ -884,10 +887,11 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
|
|
||||||
*bytes_written += amount;
|
*bytes_written += amount;
|
||||||
|
|
||||||
|
if(http) {
|
||||||
if((size_t)amount != size) {
|
if((size_t)amount != size) {
|
||||||
/* The whole request could not be sent in one system call. We must queue
|
/* The whole request could not be sent in one system call. We must
|
||||||
it up and send it later when we get the chance. We must not loop here
|
queue it up and send it later when we get the chance. We must not
|
||||||
and wait until it might work again. */
|
loop here and wait until it might work again. */
|
||||||
|
|
||||||
size -= amount;
|
size -= amount;
|
||||||
|
|
||||||
@@ -913,6 +917,18 @@ CURLcode add_buffer_send(send_buffer *in,
|
|||||||
http->sending = HTTPSEND_BODY;
|
http->sending = HTTPSEND_BODY;
|
||||||
/* the full buffer was sent, clean up and return */
|
/* the full buffer was sent, clean up and return */
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if((size_t)amount != size)
|
||||||
|
/* We have no continue-send mechanism now, fail. This can only happen
|
||||||
|
when this function is used from the CONNECT sending function. We
|
||||||
|
currently (stupidly) assume that the whole request is always sent
|
||||||
|
away in the first single chunk.
|
||||||
|
|
||||||
|
This needs FIXing.
|
||||||
|
*/
|
||||||
|
return CURLE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(in->buffer)
|
if(in->buffer)
|
||||||
free(in->buffer);
|
free(in->buffer);
|
||||||
free(in);
|
free(in);
|
||||||
@@ -1037,9 +1053,15 @@ Curl_compareheader(char *headerline, /* line to check */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ConnectHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
|
* ConnectHTTPProxyTunnel() requires that we're connected to a HTTP
|
||||||
* function will issue the necessary commands to get a seamless tunnel through
|
* proxy. This function will issue the necessary commands to get a seamless
|
||||||
* this proxy. After that, the socket can be used just as a normal socket.
|
* tunnel through this proxy. After that, the socket can be used just as a
|
||||||
|
* normal socket.
|
||||||
|
*
|
||||||
|
* This badly needs to be rewritten. CONNECT should be sent and dealt with
|
||||||
|
* like any ordinary HTTP request, and not specially crafted like this. This
|
||||||
|
* function only remains here like this for now since the rewrite is a bit too
|
||||||
|
* much work to do at the moment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
||||||
@@ -1062,6 +1084,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
char *line_start;
|
char *line_start;
|
||||||
char *host_port;
|
char *host_port;
|
||||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||||
|
send_buffer *req_buffer;
|
||||||
|
|
||||||
#define SELECT_OK 0
|
#define SELECT_OK 0
|
||||||
#define SELECT_ERROR 1
|
#define SELECT_ERROR 1
|
||||||
@@ -1079,26 +1102,66 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
conn->newurl = NULL;
|
conn->newurl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize a dynamic send-buffer */
|
||||||
|
req_buffer = add_buffer_init();
|
||||||
|
|
||||||
|
if(!req_buffer)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
host_port = aprintf("%s:%d", hostname, remote_port);
|
host_port = aprintf("%s:%d", hostname, remote_port);
|
||||||
if(!host_port)
|
if(!host_port)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Setup the proxy-authorization header, if any */
|
/* Setup the proxy-authorization header, if any */
|
||||||
result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
|
result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
|
||||||
if(CURLE_OK == result) {
|
|
||||||
|
|
||||||
/* OK, now send the connect request to the proxy */
|
if(CURLE_OK == result) {
|
||||||
|
char *host=(char *)"";
|
||||||
|
const char *proxyconn="";
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = checkheaders(data, "Host:");
|
||||||
|
if(!ptr) {
|
||||||
|
host = aprintf("Host: %s\r\n", host_port);
|
||||||
|
if(!host)
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
ptr = checkheaders(data, "Proxy-Connection:");
|
||||||
|
if(!ptr)
|
||||||
|
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||||
|
|
||||||
|
if(CURLE_OK == result) {
|
||||||
|
/* Send the connect request to the proxy */
|
||||||
|
/* BLOCKING */
|
||||||
result =
|
result =
|
||||||
Curl_sendf(tunnelsocket, conn,
|
add_bufferf(req_buffer,
|
||||||
"CONNECT %s:%d HTTP/1.0\015\012"
|
"CONNECT %s:%d HTTP/1.0\r\n"
|
||||||
"%s"
|
"%s" /* Host: */
|
||||||
"%s"
|
"%s" /* Proxy-Authorization */
|
||||||
"\r\n",
|
"%s" /* User-Agent */
|
||||||
|
"%s", /* Proxy-Connection */
|
||||||
hostname, remote_port,
|
hostname, remote_port,
|
||||||
|
host,
|
||||||
conn->allocptr.proxyuserpwd?
|
conn->allocptr.proxyuserpwd?
|
||||||
conn->allocptr.proxyuserpwd:"",
|
conn->allocptr.proxyuserpwd:"",
|
||||||
data->set.useragent?conn->allocptr.uagent:""
|
data->set.useragent?conn->allocptr.uagent:"",
|
||||||
);
|
proxyconn);
|
||||||
|
|
||||||
|
if(CURLE_OK == result)
|
||||||
|
result = add_custom_headers(conn, req_buffer);
|
||||||
|
|
||||||
|
if(host && *host)
|
||||||
|
free(host);
|
||||||
|
|
||||||
|
if(CURLE_OK == result)
|
||||||
|
/* CRLF terminate the request */
|
||||||
|
result = add_bufferf(req_buffer, "\r\n");
|
||||||
|
|
||||||
|
if(CURLE_OK == result)
|
||||||
|
/* Now send off the request */
|
||||||
|
result = add_buffer_send(req_buffer, conn,
|
||||||
|
&data->info.request_size);
|
||||||
|
}
|
||||||
if(result)
|
if(result)
|
||||||
failf(data, "Failed sending CONNECT to proxy");
|
failf(data, "Failed sending CONNECT to proxy");
|
||||||
}
|
}
|
||||||
@@ -1268,8 +1331,8 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(conn->protocol & PROT_HTTPS) {
|
if(conn->protocol & PROT_HTTPS) {
|
||||||
/* now, perform the SSL initialization for this socket */
|
/* perform SSL initialization for this socket */
|
||||||
result = Curl_SSLConnect(conn, FIRSTSOCKET);
|
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1347,6 +1410,62 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check and possibly add an Expect: header */
|
||||||
|
static CURLcode expect100(struct SessionHandle *data,
|
||||||
|
send_buffer *req_buffer)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
||||||
|
!checkheaders(data, "Expect:")) {
|
||||||
|
/* if not doing HTTP 1.0 or 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) */
|
||||||
|
result = add_bufferf(req_buffer,
|
||||||
|
"Expect: 100-continue\r\n");
|
||||||
|
if(result == CURLE_OK)
|
||||||
|
data->set.expect100header = TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode add_custom_headers(struct connectdata *conn,
|
||||||
|
send_buffer *req_buffer)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
char *ptr;
|
||||||
|
struct curl_slist *headers=conn->data->set.headers;
|
||||||
|
|
||||||
|
while(headers) {
|
||||||
|
ptr = strchr(headers->data, ':');
|
||||||
|
if(ptr) {
|
||||||
|
/* we require a colon for this to be a true header */
|
||||||
|
|
||||||
|
ptr++; /* pass the colon */
|
||||||
|
while(*ptr && isspace((int)*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if(*ptr) {
|
||||||
|
/* only send this if the contents was non-blank */
|
||||||
|
|
||||||
|
if(conn->allocptr.host &&
|
||||||
|
/* a Host: header was sent already, don't pass on any custom Host:
|
||||||
|
header as that will produce *two* in the same request! */
|
||||||
|
curl_strnequal("Host:", headers->data, 5))
|
||||||
|
;
|
||||||
|
else {
|
||||||
|
|
||||||
|
result = add_bufferf(req_buffer, "%s\r\n", headers->data);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headers = headers->next;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
||||||
* request is to be performed. This creates and sends a properly constructed
|
* request is to be performed. This creates and sends a properly constructed
|
||||||
@@ -1598,8 +1717,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!checkheaders(data, "Pragma:"))
|
http->p_pragma =
|
||||||
http->p_pragma = "Pragma: no-cache\r\n";
|
(!checkheaders(data, "Pragma:") &&
|
||||||
|
(conn->bits.httpproxy && !conn->bits.tunnel_proxy) )?
|
||||||
|
"Pragma: no-cache\r\n":NULL;
|
||||||
|
|
||||||
if(!checkheaders(data, "Accept:"))
|
if(!checkheaders(data, "Accept:"))
|
||||||
http->p_accept = "Accept: */*\r\n";
|
http->p_accept = "Accept: */*\r\n";
|
||||||
@@ -1705,7 +1826,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
|
||||||
|
|
||||||
send_buffer *req_buffer;
|
send_buffer *req_buffer;
|
||||||
struct curl_slist *headers=data->set.headers;
|
|
||||||
curl_off_t postsize; /* off_t type to be able to hold a large file size */
|
curl_off_t postsize; /* off_t type to be able to hold a large file size */
|
||||||
|
|
||||||
/* initialize a dynamic send-buffer */
|
/* initialize a dynamic send-buffer */
|
||||||
@@ -1728,6 +1848,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
"%s" /* accept */
|
"%s" /* accept */
|
||||||
"%s" /* accept-encoding */
|
"%s" /* accept-encoding */
|
||||||
"%s" /* referer */
|
"%s" /* referer */
|
||||||
|
"%s" /* Proxy-Connection */
|
||||||
"%s",/* transfer-encoding */
|
"%s",/* transfer-encoding */
|
||||||
|
|
||||||
request,
|
request,
|
||||||
@@ -1746,6 +1867,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
|
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
|
||||||
conn->allocptr.accept_encoding:"",
|
conn->allocptr.accept_encoding:"",
|
||||||
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> */,
|
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> */,
|
||||||
|
(conn->bits.httpproxy && !conn->bits.tunnel_proxy)?
|
||||||
|
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||||
te
|
te
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1852,33 +1975,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(headers) {
|
result = add_custom_headers(conn, req_buffer);
|
||||||
ptr = strchr(headers->data, ':');
|
|
||||||
if(ptr) {
|
|
||||||
/* we require a colon for this to be a true header */
|
|
||||||
|
|
||||||
ptr++; /* pass the colon */
|
|
||||||
while(*ptr && isspace((int)*ptr))
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
if(*ptr) {
|
|
||||||
/* only send this if the contents was non-blank */
|
|
||||||
|
|
||||||
if(conn->allocptr.host &&
|
|
||||||
/* a Host: header was sent already, don't pass on any custom Host:
|
|
||||||
header as that will produce *two* in the same request! */
|
|
||||||
curl_strnequal("Host:", headers->data, 5))
|
|
||||||
;
|
|
||||||
else {
|
|
||||||
|
|
||||||
result = add_bufferf(req_buffer, "%s\r\n", headers->data);
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
headers = headers->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
http->postdata = NULL; /* nothing to post at this point */
|
http->postdata = NULL; /* nothing to post at this point */
|
||||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||||
@@ -1928,18 +2027,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
result = expect100(data, req_buffer);
|
||||||
!checkheaders(data, "Expect:")) {
|
|
||||||
/* if not doing HTTP 1.0 or 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) */
|
|
||||||
result = add_bufferf(req_buffer,
|
|
||||||
"Expect: 100-continue\r\n");
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
data->set.expect100header = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!checkheaders(data, "Content-Type:")) {
|
if(!checkheaders(data, "Content-Type:")) {
|
||||||
/* Get Content-Type: line from Curl_formpostheader.
|
/* Get Content-Type: line from Curl_formpostheader.
|
||||||
@@ -2002,18 +2092,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
result = expect100(data, req_buffer);
|
||||||
!checkheaders(data, "Expect:")) {
|
|
||||||
/* if not HTTP 1.0 or 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) */
|
|
||||||
result = add_bufferf(req_buffer,
|
|
||||||
"Expect: 100-continue\r\n");
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
data->set.expect100header = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */
|
result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */
|
||||||
if(result)
|
if(result)
|
||||||
@@ -2121,21 +2202,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
/* set the upload size to the progress meter */
|
/* set the upload size to the progress meter */
|
||||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||||
|
|
||||||
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
result = expect100(data, req_buffer);
|
||||||
!checkheaders(data, "Expect:")) {
|
if(result)
|
||||||
/* if not HTTP 1.0 or disabled explicitly, we add a Expect:
|
return result;
|
||||||
100-continue to the headers which actually speeds up post
|
|
||||||
operations (as there is one packet coming back from the web
|
|
||||||
server) */
|
|
||||||
add_bufferf(req_buffer,
|
|
||||||
"Expect: 100-continue\r\n");
|
|
||||||
data->set.expect100header = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
|
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
result = expect100(data, req_buffer);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
|
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
|
||||||
|
|
||||||
if(data->set.postfieldsize) {
|
if(data->set.postfieldsize) {
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
#ifdef USE_NTLM
|
||||||
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
|
|
||||||
|
|
||||||
/* -- WIN32 approved -- */
|
/* -- WIN32 approved -- */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -769,5 +768,5 @@ Curl_ntlm_cleanup(struct connectdata *conn)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_SSLEAY */
|
#endif /* USE_NTLM */
|
||||||
#endif /* !CURL_DISABLE_HTTP */
|
#endif /* !CURL_DISABLE_HTTP */
|
||||||
|
@@ -39,6 +39,9 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
|
|||||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||||
|
|
||||||
void Curl_ntlm_cleanup(struct connectdata *conn);
|
void Curl_ntlm_cleanup(struct connectdata *conn);
|
||||||
|
#if !defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
|
||||||
|
#define Curl_ntlm_cleanup(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
||||||
|
@@ -110,7 +110,7 @@ char *Curl_if2ip(const char *interface, char *buf, int buf_size)
|
|||||||
|
|
||||||
struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr;
|
struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr;
|
||||||
memcpy(&in, &(s->sin_addr.s_addr), sizeof(in));
|
memcpy(&in, &(s->sin_addr.s_addr), sizeof(in));
|
||||||
ip = Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
|
ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
|
||||||
}
|
}
|
||||||
sclose(dummy);
|
sclose(dummy);
|
||||||
}
|
}
|
||||||
|
@@ -114,7 +114,7 @@ inet_pton4(const char *src, unsigned char *dst)
|
|||||||
const char *pch;
|
const char *pch;
|
||||||
|
|
||||||
if ((pch = strchr(digits, ch)) != NULL) {
|
if ((pch = strchr(digits, ch)) != NULL) {
|
||||||
u_int val = *tp * 10 + (pch - digits);
|
u_int val = *tp * 10 + (u_int)(pch - digits);
|
||||||
|
|
||||||
if (val > 255)
|
if (val > 255)
|
||||||
return (0);
|
return (0);
|
||||||
|
@@ -43,6 +43,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
|
|||||||
$(TMP_DIR)/ftp.o \
|
$(TMP_DIR)/ftp.o \
|
||||||
$(TMP_DIR)/getenv.o \
|
$(TMP_DIR)/getenv.o \
|
||||||
$(TMP_DIR)/getinfo.o \
|
$(TMP_DIR)/getinfo.o \
|
||||||
|
$(TMP_DIR)/gtls.o \
|
||||||
$(TMP_DIR)/hash.o \
|
$(TMP_DIR)/hash.o \
|
||||||
$(TMP_DIR)/hostares.o \
|
$(TMP_DIR)/hostares.o \
|
||||||
$(TMP_DIR)/hostasyn.o \
|
$(TMP_DIR)/hostasyn.o \
|
||||||
@@ -73,6 +74,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
|
|||||||
$(TMP_DIR)/sendf.o \
|
$(TMP_DIR)/sendf.o \
|
||||||
$(TMP_DIR)/share.o \
|
$(TMP_DIR)/share.o \
|
||||||
$(TMP_DIR)/speedcheck.o \
|
$(TMP_DIR)/speedcheck.o \
|
||||||
|
$(TMP_DIR)/sslgen.o \
|
||||||
$(TMP_DIR)/ssluse.o \
|
$(TMP_DIR)/ssluse.o \
|
||||||
$(TMP_DIR)/strequal.o \
|
$(TMP_DIR)/strequal.o \
|
||||||
$(TMP_DIR)/strerror.o \
|
$(TMP_DIR)/strerror.o \
|
||||||
|
@@ -10,15 +10,14 @@ ATCPSDKI= /GG/netinclude
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -I$(ATCPSDKI) -m68020-60 -noixemul -I. -I../include -W -Wall
|
CFLAGS = -I$(ATCPSDKI) -m68020-60 -noixemul -I. -I../include -W -Wall
|
||||||
|
|
||||||
OBJS = \
|
OBJS = amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c easy.c \
|
||||||
amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c \
|
escape.c file.c formdata.c ftp.c getenv.c getinfo.c hash.c hostip.c \
|
||||||
easy.c escape.c file.c formdata.c ftp.c getenv.c \
|
hostip4.c hostsyn.c http.c http_chunks.c http_digest.c \
|
||||||
getinfo.c hash.c hostip.c hostip4.c hostsyn.c http.c http_chunks.c \
|
http_negotiate.c http_ntlm.c if2ip.c inet_ntop.c inet_pton.c krb4.c \
|
||||||
http_digest.c http_negotiate.c http_ntlm.c if2ip.c inet_ntop.c \
|
ldap.c llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
|
||||||
inet_pton.c krb4.c ldap.c \
|
progress.c security.c select.c sendf.c share.c speedcheck.c ssluse.c \
|
||||||
llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
|
strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c \
|
||||||
progress.c security.c select.c sendf.c share.c speedcheck.c \
|
sslgen.c gtls.c
|
||||||
ssluse.c strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c
|
|
||||||
|
|
||||||
all: $(OBJS:.c=.o)
|
all: $(OBJS:.c=.o)
|
||||||
ar cru libcurl.a $(OBJS:.c=.o)
|
ar cru libcurl.a $(OBJS:.c=.o)
|
||||||
|
249
lib/makefile.dj
249
lib/makefile.dj
@@ -32,243 +32,264 @@ realclean vclean: clean
|
|||||||
# DO NOT DELETE THIS LINE
|
# DO NOT DELETE THIS LINE
|
||||||
$(OBJ_DIR)/file.o: file.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
$(OBJ_DIR)/file.o: file.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h progress.h sendf.h escape.h \
|
http_chunks.h hostip.h hash.h llist.h progress.h sendf.h escape.h \
|
||||||
file.h speedcheck.h getinfo.h transfer.h url.h memory.h \
|
file.h speedcheck.h getinfo.h transfer.h url.h memory.h parsedate.h \
|
||||||
../include/curl/mprintf.h memdebug.h
|
../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/timeval.o: timeval.c timeval.h setup.h config.h
|
$(OBJ_DIR)/timeval.o: timeval.c timeval.h setup.h config.h
|
||||||
$(OBJ_DIR)/base64.o: base64.c setup.h config.h ../include/curl/mprintf.h \
|
$(OBJ_DIR)/base64.o: base64.c setup.h config.h ../include/curl/mprintf.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h base64.h memory.h memdebug.h
|
../include/curl/multi.h base64.h memory.h ../include/curl/curl.h \
|
||||||
|
memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostip.o: hostip.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostip.o: hostip.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
inet_ntop.h ../include/curl/mprintf.h memory.h memdebug.h
|
inet_ntop.h ../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/progress.o: progress.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/progress.o: progress.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h progress.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
../include/curl/mprintf.h
|
sendf.h progress.h ../include/curl/mprintf.h
|
||||||
$(OBJ_DIR)/formdata.o: formdata.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/formdata.o: formdata.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h strequal.h memory.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h strequal.h \
|
||||||
../include/curl/mprintf.h memdebug.h
|
memory.h ../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/cookie.o: cookie.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/cookie.o: cookie.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h strequal.h strtok.h sendf.h \
|
http_chunks.h hostip.h hash.h llist.h strequal.h strtok.h sendf.h \
|
||||||
memory.h memdebug.h
|
memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/http.o: http.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
$(OBJ_DIR)/http.o: http.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.h \
|
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.h \
|
||||||
base64.h strequal.h ssluse.h http_digest.h http_ntlm.h http_negotiate.h \
|
base64.h strequal.h sslgen.h http_digest.h http_ntlm.h http_negotiate.h \
|
||||||
url.h share.h http.h memory.h select.h ../include/curl/mprintf.h \
|
url.h share.h http.h memory.h select.h parsedate.h \
|
||||||
memdebug.h
|
../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/sendf.o: sendf.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/sendf.o: sendf.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h connect.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
../include/curl/mprintf.h memory.h strerror.h memdebug.h
|
sendf.h connect.h sslgen.h ../include/curl/mprintf.h memory.h \
|
||||||
|
strerror.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/ftp.o: ftp.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/ftp.o: ftp.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h if2ip.h progress.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
transfer.h escape.h http.h ftp.h strtoofft.h strequal.h ssluse.h \
|
sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h strtoofft.h \
|
||||||
connect.h strerror.h memory.h inet_ntop.h select.h \
|
strequal.h sslgen.h connect.h strerror.h memory.h inet_ntop.h select.h \
|
||||||
../include/curl/mprintf.h memdebug.h
|
parsedate.h ../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/url.o: url.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
$(OBJ_DIR)/url.o: url.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h netrc.h base64.h ssluse.h if2ip.h \
|
http_chunks.h hostip.h hash.h llist.h netrc.h base64.h sslgen.h \
|
||||||
transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h \
|
transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h \
|
||||||
share.h content_encoding.h http_digest.h http_negotiate.h select.h \
|
share.h content_encoding.h http_digest.h http_negotiate.h select.h \
|
||||||
ftp.h dict.h telnet.h http.h file.h ldap.h url.h connect.h inet_ntop.h \
|
multiif.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h connect.h \
|
||||||
ca-bundle.h ../include/curl/mprintf.h memory.h memdebug.h
|
inet_ntop.h http_ntlm.h ca-bundle.h ../include/curl/mprintf.h memory.h \
|
||||||
|
memdebug.h memory.h
|
||||||
$(OBJ_DIR)/dict.o: dict.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
$(OBJ_DIR)/dict.o: dict.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.h \
|
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.h \
|
||||||
strequal.h dict.h ../include/curl/mprintf.h
|
strequal.h dict.h ../include/curl/mprintf.h
|
||||||
$(OBJ_DIR)/if2ip.o: if2ip.c setup.h config.h if2ip.h memory.h ../include/curl/curl.h \
|
$(OBJ_DIR)/if2ip.o: if2ip.c setup.h config.h if2ip.h inet_ntop.h memory.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memdebug.h
|
../include/curl/multi.h ../include/curl/curl.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/speedcheck.o: speedcheck.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/speedcheck.o: speedcheck.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h speedcheck.h
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
$(OBJ_DIR)/ldap.o: ldap.c setup.h config.h urldata.h cookie.h ../include/curl/curl.h \
|
sendf.h speedcheck.h
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
$(OBJ_DIR)/ldap.o: ldap.c setup.h config.h
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h escape.h transfer.h \
|
|
||||||
strequal.h strtok.h ldap.h memory.h ../include/curl/mprintf.h \
|
|
||||||
memdebug.h
|
|
||||||
$(OBJ_DIR)/ssluse.o: ssluse.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/ssluse.o: ssluse.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h url.h inet_pton.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h url.h inet_pton.h \
|
||||||
ssluse.h connect.h strequal.h select.h ../include/curl/mprintf.h
|
ssluse.h connect.h strequal.h select.h sslgen.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
$(OBJ_DIR)/version.o: version.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/version.o: version.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h ../include/curl/mprintf.h
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
sslgen.h ../include/curl/mprintf.h
|
||||||
$(OBJ_DIR)/getenv.o: getenv.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/getenv.o: getenv.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memory.h memdebug.h
|
../include/curl/multi.h ../include/curl/curl.h memory.h memdebug.h \
|
||||||
|
memory.h
|
||||||
$(OBJ_DIR)/escape.o: escape.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/escape.o: escape.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memory.h ../include/curl/mprintf.h memdebug.h
|
../include/curl/multi.h ../include/curl/curl.h memory.h \
|
||||||
|
../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/mprintf.o: mprintf.c setup.h config.h ../include/curl/mprintf.h \
|
$(OBJ_DIR)/mprintf.o: mprintf.c setup.h config.h ../include/curl/mprintf.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memory.h memdebug.h
|
../include/curl/multi.h memory.h ../include/curl/curl.h memdebug.h \
|
||||||
|
memory.h
|
||||||
$(OBJ_DIR)/telnet.o: telnet.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/telnet.o: telnet.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h telnet.h \
|
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h telnet.h \
|
||||||
../include/curl/mprintf.h arpa_telnet.h memory.h select.h memdebug.h
|
../include/curl/mprintf.h arpa_telnet.h memory.h select.h memdebug.h \
|
||||||
|
memory.h
|
||||||
$(OBJ_DIR)/netrc.o: netrc.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/netrc.o: netrc.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h netrc.h strequal.h strtok.h memory.h \
|
../include/curl/multi.h ../include/curl/curl.h netrc.h strequal.h \
|
||||||
../include/curl/mprintf.h memdebug.h
|
strtok.h memory.h ../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/getinfo.o: getinfo.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/getinfo.o: getinfo.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h getinfo.h memory.h memdebug.h
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
getinfo.h memory.h sslgen.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/transfer.o: transfer.c setup.h config.h strtoofft.h \
|
$(OBJ_DIR)/transfer.o: transfer.c setup.h config.h strtoofft.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h strequal.h urldata.h cookie.h formdata.h \
|
../include/curl/multi.h ../include/curl/curl.h strequal.h urldata.h \
|
||||||
timeval.h e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
cookie.h formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
transfer.h sendf.h speedcheck.h progress.h http.h url.h getinfo.h \
|
netrc.h content_encoding.h transfer.h sendf.h speedcheck.h progress.h \
|
||||||
ssluse.h http_digest.h http_ntlm.h http_negotiate.h share.h memory.h \
|
http.h url.h getinfo.h sslgen.h http_digest.h http_ntlm.h \
|
||||||
select.h ../include/curl/mprintf.h memdebug.h
|
http_negotiate.h share.h memory.h select.h ../include/curl/mprintf.h \
|
||||||
|
memdebug.h memory.h
|
||||||
$(OBJ_DIR)/strequal.o: strequal.c setup.h config.h strequal.h ../include/curl/curl.h \
|
$(OBJ_DIR)/strequal.o: strequal.c setup.h config.h strequal.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h
|
../include/curl/multi.h ../include/curl/curl.h
|
||||||
$(OBJ_DIR)/easy.o: easy.c setup.h config.h strequal.h ../include/curl/curl.h \
|
$(OBJ_DIR)/easy.o: easy.c setup.h config.h strequal.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h transfer.h ssluse.h url.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
getinfo.h share.h memory.h progress.h ../include/curl/mprintf.h \
|
transfer.h sslgen.h url.h getinfo.h share.h memory.h progress.h \
|
||||||
memdebug.h
|
easyif.h ../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/security.o: security.c setup.h config.h
|
$(OBJ_DIR)/security.o: security.c setup.h config.h
|
||||||
$(OBJ_DIR)/krb4.o: krb4.c setup.h config.h
|
$(OBJ_DIR)/krb4.o: krb4.c setup.h config.h
|
||||||
$(OBJ_DIR)/memdebug.o: memdebug.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/memdebug.o: memdebug.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h ../include/curl/mprintf.h urldata.h cookie.h \
|
../include/curl/multi.h ../include/curl/curl.h \
|
||||||
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
../include/curl/mprintf.h urldata.h cookie.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
memory.h memdebug.h
|
http_chunks.h hostip.h hash.h llist.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/http_chunks.o: http_chunks.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/http_chunks.o: http_chunks.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h content_encoding.h http.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h content_encoding.h http.h \
|
||||||
memory.h ../include/curl/mprintf.h memdebug.h
|
memory.h ../include/curl/mprintf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/strtok.o: strtok.c setup.h config.h strtok.h
|
$(OBJ_DIR)/strtok.o: strtok.c setup.h config.h strtok.h
|
||||||
$(OBJ_DIR)/connect.o: connect.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/connect.o: connect.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h if2ip.h strerror.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h if2ip.h strerror.h \
|
||||||
connect.h memory.h select.h memdebug.h
|
connect.h memory.h select.h url.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/llist.o: llist.c setup.h config.h llist.h memory.h ../include/curl/curl.h \
|
$(OBJ_DIR)/llist.o: llist.c setup.h config.h llist.h memory.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memdebug.h
|
../include/curl/multi.h ../include/curl/curl.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hash.o: hash.c setup.h config.h hash.h llist.h memory.h \
|
$(OBJ_DIR)/hash.o: hash.c setup.h config.h hash.h llist.h memory.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h memdebug.h
|
../include/curl/multi.h ../include/curl/curl.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/multi.o: multi.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/multi.o: multi.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h transfer.h url.h connect.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
progress.h memory.h memdebug.h
|
transfer.h url.h connect.h progress.h memory.h easyif.h multiif.h \
|
||||||
|
sendf.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/content_encoding.o: content_encoding.c setup.h config.h urldata.h \
|
$(OBJ_DIR)/content_encoding.o: content_encoding.c setup.h config.h urldata.h \
|
||||||
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
|
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
|
||||||
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/easy.h ../include/curl/multi.h ../include/curl/curl.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h content_encoding.h \
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
memory.h memdebug.h
|
sendf.h content_encoding.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/share.o: share.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/share.o: share.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h urldata.h cookie.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h share.h memory.h memdebug.h
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
share.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/http_digest.o: http_digest.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/http_digest.o: http_digest.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h strequal.h base64.h md5.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h strequal.h base64.h md5.h \
|
||||||
http_digest.h strtok.h url.h memory.h ../include/curl/mprintf.h \
|
http_digest.h strtok.h url.h memory.h ../include/curl/mprintf.h \
|
||||||
memdebug.h
|
memdebug.h memory.h
|
||||||
$(OBJ_DIR)/md5.o: md5.c setup.h config.h md5.h
|
$(OBJ_DIR)/md5.o: md5.c setup.h config.h md5.h
|
||||||
$(OBJ_DIR)/http_negotiate.o: http_negotiate.c setup.h config.h
|
$(OBJ_DIR)/http_negotiate.o: http_negotiate.c setup.h config.h
|
||||||
$(OBJ_DIR)/http_ntlm.o: http_ntlm.c setup.h config.h
|
$(OBJ_DIR)/http_ntlm.o: http_ntlm.c setup.h config.h
|
||||||
$(OBJ_DIR)/inet_pton.o: inet_pton.c setup.h config.h
|
$(OBJ_DIR)/inet_pton.o: inet_pton.c setup.h config.h
|
||||||
$(OBJ_DIR)/strtoofft.o: strtoofft.c setup.h config.h strtoofft.h \
|
$(OBJ_DIR)/strtoofft.o: strtoofft.c setup.h config.h strtoofft.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h
|
../include/curl/multi.h ../include/curl/curl.h
|
||||||
$(OBJ_DIR)/strerror.o: strerror.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/strerror.o: strerror.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h strerror.h urldata.h cookie.h formdata.h \
|
../include/curl/multi.h ../include/curl/curl.h strerror.h urldata.h \
|
||||||
timeval.h e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
cookie.h formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h ../include/curl/mprintf.h
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
../include/curl/mprintf.h
|
||||||
$(OBJ_DIR)/hostares.o: hostares.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostares.o: hostares.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h memory.h memdebug.h
|
../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostasyn.o: hostasyn.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostasyn.o: hostasyn.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h memory.h memdebug.h
|
../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostip4.o: hostip4.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostip4.o: hostip4.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h memory.h memdebug.h
|
inet_pton.h ../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostip6.o: hostip6.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostip6.o: hostip6.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h memory.h memdebug.h
|
inet_pton.h ../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostsyn.o: hostsyn.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostsyn.o: hostsyn.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h memory.h memdebug.h
|
../include/curl/mprintf.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/hostthre.o: hostthre.c setup.h config.h urldata.h cookie.h \
|
$(OBJ_DIR)/hostthre.o: hostthre.c setup.h config.h urldata.h cookie.h \
|
||||||
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h formdata.h timeval.h \
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
http_chunks.h hostip.h hash.h llist.h sendf.h share.h strerror.h url.h \
|
||||||
../include/curl/mprintf.h inet_ntop.h memory.h memdebug.h
|
../include/curl/mprintf.h inet_ntop.h memory.h memdebug.h memory.h
|
||||||
$(OBJ_DIR)/inet_ntop.o: inet_ntop.c setup.h config.h
|
$(OBJ_DIR)/inet_ntop.o: inet_ntop.c setup.h config.h
|
||||||
$(OBJ_DIR)/parsedate.o: parsedate.c setup.h config.h ../include/curl/curl.h \
|
$(OBJ_DIR)/parsedate.o: parsedate.c setup.h config.h ../include/curl/curl.h \
|
||||||
../include/curl/curlver.h ../include/curl/easy.h \
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
../include/curl/multi.h
|
../include/curl/multi.h ../include/curl/curl.h
|
||||||
$(OBJ_DIR)/select.o: select.c setup.h config.h select.h
|
$(OBJ_DIR)/select.o: select.c setup.h config.h ../include/curl/curl.h \
|
||||||
|
../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h ../include/curl/curl.h urldata.h cookie.h \
|
||||||
|
formdata.h timeval.h e:/djgpp/contrib/zlib/zlib.h \
|
||||||
|
e:/djgpp/contrib/zlib/zconf.h http_chunks.h hostip.h hash.h llist.h \
|
||||||
|
connect.h select.h
|
||||||
|
$(OBJ_DIR)/gtls.o: gtls.c setup.h config.h
|
||||||
|
$(OBJ_DIR)/sslgen.o: sslgen.c setup.h config.h urldata.h cookie.h \
|
||||||
|
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.h \
|
||||||
|
../include/curl/multi.h ../include/curl/curl.h formdata.h timeval.h \
|
||||||
|
e:/djgpp/contrib/zlib/zlib.h e:/djgpp/contrib/zlib/zconf.h \
|
||||||
|
http_chunks.h hostip.h hash.h llist.h sslgen.h ssluse.h gtls.h sendf.h \
|
||||||
|
strequal.h url.h memory.h memdebug.h memory.h
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -345,7 +345,7 @@ void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
|
|||||||
{
|
{
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
MD5_Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
MD5_Update(&ctx, input, strlen((char *)input));
|
MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
|
||||||
MD5_Final(outbuffer, &ctx);
|
MD5_Final(outbuffer, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -759,8 +759,8 @@ static int dprintf_formatf(
|
|||||||
*w-- = digits[num % base];
|
*w-- = digits[num % base];
|
||||||
num /= base;
|
num /= base;
|
||||||
}
|
}
|
||||||
width -= workend - w;
|
width -= (long)(workend - w);
|
||||||
prec -= workend - w;
|
prec -= (long)(workend - w);
|
||||||
|
|
||||||
if (alt && base == 8 && prec <= 0) {
|
if (alt && base == 8 && prec <= 0) {
|
||||||
*w-- = '0';
|
*w-- = '0';
|
||||||
@@ -839,7 +839,7 @@ static int dprintf_formatf(
|
|||||||
|
|
||||||
if (prec != -1 && (size_t) prec < len)
|
if (prec != -1 && (size_t) prec < len)
|
||||||
len = prec;
|
len = prec;
|
||||||
width -= len;
|
width -= (long)len;
|
||||||
|
|
||||||
if (p->flags & FLAGS_ALT)
|
if (p->flags & FLAGS_ALT)
|
||||||
OUTCHAR('"');
|
OUTCHAR('"');
|
||||||
@@ -869,7 +869,7 @@ static int dprintf_formatf(
|
|||||||
base = 16;
|
base = 16;
|
||||||
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
|
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
|
||||||
alt = 1;
|
alt = 1;
|
||||||
num = (unsigned long) ptr;
|
num = (size_t) ptr;
|
||||||
is_neg = 0;
|
is_neg = 0;
|
||||||
goto number;
|
goto number;
|
||||||
}
|
}
|
||||||
|
10
lib/netrc.c
10
lib/netrc.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -103,7 +103,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
char *override = curl_getenv("CURL_DEBUG_NETRC");
|
char *override = curl_getenv("CURL_DEBUG_NETRC");
|
||||||
|
|
||||||
if (override) {
|
if (override) {
|
||||||
printf("NETRC: overridden " NETRC " file: %s\n", home);
|
fprintf(stderr, "NETRC: overridden " NETRC " file: %s\n", override);
|
||||||
netrcfile = override;
|
netrcfile = override;
|
||||||
netrc_alloc = TRUE;
|
netrc_alloc = TRUE;
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
/* and yes, this is our host! */
|
/* and yes, this is our host! */
|
||||||
state=HOSTVALID;
|
state=HOSTVALID;
|
||||||
#ifdef _NETRC_DEBUG
|
#ifdef _NETRC_DEBUG
|
||||||
printf("HOST: %s\n", tok);
|
fprintf(stderr, "HOST: %s\n", tok);
|
||||||
#endif
|
#endif
|
||||||
retcode=0; /* we did find our host */
|
retcode=0; /* we did find our host */
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
else {
|
else {
|
||||||
strncpy(login, tok, LOGINSIZE-1);
|
strncpy(login, tok, LOGINSIZE-1);
|
||||||
#ifdef _NETRC_DEBUG
|
#ifdef _NETRC_DEBUG
|
||||||
printf("LOGIN: %s\n", login);
|
fprintf(stderr, "LOGIN: %s\n", login);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
state_login=0;
|
state_login=0;
|
||||||
@@ -197,7 +197,7 @@ int Curl_parsenetrc(char *host,
|
|||||||
if (state_our_login || !specific_login) {
|
if (state_our_login || !specific_login) {
|
||||||
strncpy(password, tok, PASSWORDSIZE-1);
|
strncpy(password, tok, PASSWORDSIZE-1);
|
||||||
#ifdef _NETRC_DEBUG
|
#ifdef _NETRC_DEBUG
|
||||||
printf("PASSWORD: %s\n", password);
|
fprintf(stderr, "PASSWORD: %s\n", password);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
state_password=0;
|
state_password=0;
|
||||||
|
@@ -398,7 +398,7 @@ static time_t Curl_parsedate(const char *date)
|
|||||||
|
|
||||||
/* Add the time zone diff (between the given timezone and GMT) and the
|
/* Add the time zone diff (between the given timezone and GMT) and the
|
||||||
diff between the local time zone and GMT. */
|
diff between the local time zone and GMT. */
|
||||||
delta = (tzoff!=-1?tzoff:0) + (t - t2);
|
delta = (long)((tzoff!=-1?tzoff:0) + (t - t2));
|
||||||
|
|
||||||
if((delta>0) && (t + delta < t))
|
if((delta>0) && (t + delta < t))
|
||||||
return -1; /* time_t overflow */
|
return -1; /* time_t overflow */
|
||||||
|
@@ -151,7 +151,7 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
|
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
|
||||||
} while((r == -1) && (Curl_ourerrno() == EINTR));
|
} while((r == -1) && (Curl_ourerrno() == EINTR));
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -236,7 +236,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
|
r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
|
||||||
} while((r == -1) && (Curl_ourerrno() == EINTR));
|
} while((r == -1) && (Curl_ourerrno() == EINTR));
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
106
lib/sendf.c
106
lib/sendf.c
@@ -44,13 +44,18 @@
|
|||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "connect.h" /* for the Curl_ourerrno() proto */
|
#include "connect.h" /* for the Curl_ourerrno() proto */
|
||||||
|
#include "sslgen.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
#ifdef HAVE_KRB4
|
#ifdef HAVE_KRB4
|
||||||
#include "krb4.h"
|
#include "krb4.h"
|
||||||
|
#else
|
||||||
|
#define Curl_sec_write(a,b,c,d) -1
|
||||||
|
#define Curl_sec_read(a,b,c,d) -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
@@ -233,63 +238,18 @@ CURLcode Curl_write(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
CURLcode retcode;
|
CURLcode retcode;
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
|
||||||
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
|
||||||
us use the correct ssl handle. */
|
|
||||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||||
/* SSL_write() is said to return 'int' while write() and send() returns
|
|
||||||
'size_t' */
|
|
||||||
if (conn->ssl[num].use) {
|
|
||||||
int err;
|
|
||||||
char error_buffer[120]; /* OpenSSL documents that this must be at least
|
|
||||||
120 bytes long. */
|
|
||||||
unsigned long sslerror;
|
|
||||||
int rc = SSL_write(conn->ssl[num].handle, mem, (int)len);
|
|
||||||
|
|
||||||
if(rc < 0) {
|
if (conn->ssl[num].use)
|
||||||
err = SSL_get_error(conn->ssl[num].handle, rc);
|
/* only TRUE if SSL enabled */
|
||||||
|
bytes_written = Curl_ssl_send(conn, num, mem, len);
|
||||||
switch(err) {
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
/* The operation did not complete; the same TLS/SSL I/O function
|
|
||||||
should be called again later. This is basicly an EWOULDBLOCK
|
|
||||||
equivalent. */
|
|
||||||
*written = 0;
|
|
||||||
return CURLE_OK;
|
|
||||||
case SSL_ERROR_SYSCALL:
|
|
||||||
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
|
||||||
Curl_ourerrno());
|
|
||||||
return CURLE_SEND_ERROR;
|
|
||||||
case SSL_ERROR_SSL:
|
|
||||||
/* A failure in the SSL library occurred, usually a protocol error.
|
|
||||||
The OpenSSL error queue contains more information on the error. */
|
|
||||||
sslerror = ERR_get_error();
|
|
||||||
failf(conn->data, "SSL_write() error: %s\n",
|
|
||||||
ERR_error_string(sslerror, error_buffer));
|
|
||||||
return CURLE_SEND_ERROR;
|
|
||||||
}
|
|
||||||
/* a true error */
|
|
||||||
failf(conn->data, "SSL_write() return error %d\n", err);
|
|
||||||
return CURLE_SEND_ERROR;
|
|
||||||
}
|
|
||||||
bytes_written = rc;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
#else
|
if(conn->sec_complete)
|
||||||
(void)conn;
|
/* only TRUE if krb4 enabled */
|
||||||
#endif
|
|
||||||
#ifdef HAVE_KRB4
|
|
||||||
if(conn->sec_complete) {
|
|
||||||
bytes_written = Curl_sec_write(conn, sockfd, mem, len);
|
bytes_written = Curl_sec_write(conn, sockfd, mem, len);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif /* HAVE_KRB4 */
|
|
||||||
{
|
|
||||||
bytes_written = (ssize_t)swrite(sockfd, mem, len);
|
bytes_written = (ssize_t)swrite(sockfd, mem, len);
|
||||||
}
|
|
||||||
if(-1 == bytes_written) {
|
if(-1 == bytes_written) {
|
||||||
int err = Curl_ourerrno();
|
int err = Curl_ourerrno();
|
||||||
|
|
||||||
@@ -311,10 +271,7 @@ CURLcode Curl_write(struct connectdata *conn,
|
|||||||
failf(conn->data, "Send failure: %s",
|
failf(conn->data, "Send failure: %s",
|
||||||
Curl_strerror(conn, err));
|
Curl_strerror(conn, err));
|
||||||
}
|
}
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
*written = bytes_written;
|
*written = bytes_written;
|
||||||
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
||||||
|
|
||||||
@@ -376,7 +333,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
ssize_t *n) /* amount bytes read */
|
ssize_t *n) /* amount bytes read */
|
||||||
{
|
{
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
/* Set 'num' to 0 or 1, depending on which socket that has been sent here.
|
||||||
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
If it is the second socket, we set num to 1. Otherwise to 0. This lets
|
||||||
us use the correct ssl handle. */
|
us use the correct ssl handle. */
|
||||||
@@ -384,45 +341,17 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
|
|
||||||
*n=0; /* reset amount to zero */
|
*n=0; /* reset amount to zero */
|
||||||
|
|
||||||
if (conn->ssl[num].use) {
|
if(conn->ssl[num].use) {
|
||||||
nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, (int)buffersize);
|
nread = Curl_ssl_recv(conn, num, buf, buffersize);
|
||||||
|
|
||||||
if(nread < 0) {
|
if(nread == -1)
|
||||||
/* failed SSL_read */
|
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
|
||||||
int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
|
|
||||||
|
|
||||||
switch(err) {
|
|
||||||
case SSL_ERROR_NONE: /* this is not an error */
|
|
||||||
case SSL_ERROR_ZERO_RETURN: /* no more data */
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
/* there's data pending, re-invoke SSL_read() */
|
|
||||||
return -1; /* basicly EWOULDBLOCK */
|
|
||||||
default:
|
|
||||||
/* openssl/ssl.h says "look at error stack/return value/errno" */
|
|
||||||
{
|
|
||||||
char error_buffer[120]; /* OpenSSL documents that this must be at
|
|
||||||
least 120 bytes long. */
|
|
||||||
unsigned long sslerror = ERR_get_error();
|
|
||||||
failf(conn->data, "SSL read: %s, errno %d",
|
|
||||||
ERR_error_string(sslerror, error_buffer),
|
|
||||||
Curl_ourerrno() );
|
|
||||||
}
|
|
||||||
return CURLE_RECV_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#else
|
|
||||||
(void)conn;
|
|
||||||
#endif
|
|
||||||
*n=0; /* reset amount to zero */
|
*n=0; /* reset amount to zero */
|
||||||
#ifdef HAVE_KRB4
|
|
||||||
if(conn->sec_complete)
|
if(conn->sec_complete)
|
||||||
nread = Curl_sec_read(conn, sockfd, buf, buffersize);
|
nread = Curl_sec_read(conn, sockfd, buf, buffersize);
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
nread = sread(sockfd, buf, buffersize);
|
nread = sread(sockfd, buf, buffersize);
|
||||||
|
|
||||||
if(-1 == nread) {
|
if(-1 == nread) {
|
||||||
@@ -434,10 +363,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
}
|
}
|
||||||
#endif /* USE_SSLEAY */
|
|
||||||
*n = nread;
|
*n = nread;
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
63
lib/setup.h
63
lib/setup.h
@@ -30,10 +30,14 @@
|
|||||||
#define CURL_DISABLE_DICT
|
#define CURL_DISABLE_DICT
|
||||||
#define CURL_DISABLE_FILE
|
#define CURL_DISABLE_FILE
|
||||||
#define CURL_DISABLE_GOPHER
|
#define CURL_DISABLE_GOPHER
|
||||||
#endif
|
#endif /* HTTP_ONLY */
|
||||||
|
|
||||||
#if !defined(WIN32) && defined(__WIN32__)
|
#if !defined(WIN32) && defined(__WIN32__)
|
||||||
/* This should be a good Borland fix. Alexander J. Oss told us! */
|
/* This should be a good Borland fix. */
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
#if !defined(WIN32) && defined(_WIN32)
|
||||||
|
/* This works for VS2005 on x64 */
|
||||||
#define WIN32
|
#define WIN32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -46,9 +50,9 @@
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* hand-modified win32 config.h! */
|
/* hand-modified win32 config.h! */
|
||||||
#include "config-win32.h"
|
#include "config-win32.h"
|
||||||
#endif
|
#endif /* WIN32 */
|
||||||
#endif
|
#endif /* WIN32_WCE */
|
||||||
#endif
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#ifdef macintosh
|
#ifdef macintosh
|
||||||
/* hand-modified MacOS config.h! */
|
/* hand-modified MacOS config.h! */
|
||||||
@@ -78,7 +82,7 @@ typedef unsigned char bool;
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define LONG_LONG __int64
|
#define LONG_LONG __int64
|
||||||
#define ENABLE_64BIT
|
#define ENABLE_64BIT
|
||||||
#endif
|
#endif /* _MSC_VER */
|
||||||
#endif /* HAVE_LONGLONG */
|
#endif /* HAVE_LONGLONG */
|
||||||
|
|
||||||
#ifndef SIZEOF_CURL_OFF_T
|
#ifndef SIZEOF_CURL_OFF_T
|
||||||
@@ -93,15 +97,15 @@ typedef unsigned char bool;
|
|||||||
#define FORMAT_OFF_T "lld"
|
#define FORMAT_OFF_T "lld"
|
||||||
#else
|
#else
|
||||||
#define FORMAT_OFF_T "ld"
|
#define FORMAT_OFF_T "ld"
|
||||||
#endif
|
#endif /* SIZEOF_CURL_OFF_T */
|
||||||
|
|
||||||
/*#ifdef NEED_REENTRANT*/
|
#ifndef _REENTRANT
|
||||||
/* Solaris needs _REENTRANT set for a few function prototypes and things to
|
/* Solaris needs _REENTRANT set for a few function prototypes and things to
|
||||||
appear in the #include files. We need to #define it before all #include
|
appear in the #include files. We need to #define it before all #include
|
||||||
files. Unixware needs it to build proper reentrant code. Others may also
|
files. Unixware needs it to build proper reentrant code. Others may also
|
||||||
need it. */
|
need it. */
|
||||||
#define _REENTRANT
|
#define _REENTRANT
|
||||||
/*#endif */
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef HAVE_ASSERT_H
|
#ifdef HAVE_ASSERT_H
|
||||||
@@ -131,7 +135,7 @@ typedef unsigned char bool;
|
|||||||
#define HAVE_MSG_NOSIGNAL 1 /* we have MSG_NOSIGNAL */
|
#define HAVE_MSG_NOSIGNAL 1 /* we have MSG_NOSIGNAL */
|
||||||
#else
|
#else
|
||||||
#define SEND_4TH_ARG 0
|
#define SEND_4TH_ARG 0
|
||||||
#endif
|
#endif /* MSG_NOSIGNAL */
|
||||||
|
|
||||||
/* To make large file support transparent even on Windows */
|
/* To make large file support transparent even on Windows */
|
||||||
#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
|
#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
|
||||||
@@ -143,7 +147,7 @@ typedef unsigned char bool;
|
|||||||
#define fstat(fd,st) _fstati64(fd,st)
|
#define fstat(fd,st) _fstati64(fd,st)
|
||||||
#else
|
#else
|
||||||
#define struct_stat struct stat
|
#define struct_stat struct stat
|
||||||
#endif
|
#endif /* Win32 with large file support */
|
||||||
|
|
||||||
/* Below we define four functions. They should
|
/* Below we define four functions. They should
|
||||||
1. close a socket
|
1. close a socket
|
||||||
@@ -158,7 +162,7 @@ typedef unsigned char bool;
|
|||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
|
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
|
||||||
#endif
|
#endif /* WIN32_LEAN_AND_MEAN */
|
||||||
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
#include <winsock2.h> /* required by telnet.c */
|
#include <winsock2.h> /* required by telnet.c */
|
||||||
@@ -170,8 +174,11 @@ typedef unsigned char bool;
|
|||||||
|
|
||||||
#if !defined(__GNUC__) || defined(__MINGW32__)
|
#if !defined(__GNUC__) || defined(__MINGW32__)
|
||||||
#define sclose(x) closesocket(x)
|
#define sclose(x) closesocket(x)
|
||||||
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
|
|
||||||
#define swrite(x,y,z) (size_t)send(x,y,z, SEND_4TH_ARG)
|
/* Since Windows doesn't have/use the POSIX prototype for send() and recv(),
|
||||||
|
we typecast the third argument in the macros to avoid compiler warnings. */
|
||||||
|
#define sread(x,y,z) recv(x,y,(int)(z), SEND_4TH_ARG)
|
||||||
|
#define swrite(x,y,z) (size_t)send(x,y, (int)(z), SEND_4TH_ARG)
|
||||||
#undef HAVE_ALARM
|
#undef HAVE_ALARM
|
||||||
#else
|
#else
|
||||||
/* gcc-for-win is still good :) */
|
/* gcc-for-win is still good :) */
|
||||||
@@ -179,12 +186,12 @@ typedef unsigned char bool;
|
|||||||
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
|
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
|
||||||
#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
|
#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
|
||||||
#define HAVE_ALARM
|
#define HAVE_ALARM
|
||||||
#endif
|
#endif /* !GNU or mingw */
|
||||||
|
|
||||||
#define DIR_CHAR "\\"
|
#define DIR_CHAR "\\"
|
||||||
#define DOT_CHAR "_"
|
#define DOT_CHAR "_"
|
||||||
|
|
||||||
#else
|
#else /* WIN32 */
|
||||||
|
|
||||||
#ifdef DJGPP
|
#ifdef DJGPP
|
||||||
#define sclose(x) close_s(x)
|
#define sclose(x) close_s(x)
|
||||||
@@ -197,21 +204,21 @@ typedef unsigned char bool;
|
|||||||
#undef word
|
#undef word
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else /* DJGPP */
|
||||||
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
#define sclose(x) closesocket(x)
|
#define sclose(x) closesocket(x)
|
||||||
#define sread(x,y,z) (ssize_t)recv(x,y,z, SEND_4TH_ARG)
|
#define sread(x,y,z) (ssize_t)recv(x,y,z, SEND_4TH_ARG)
|
||||||
#define swrite(x,y,z) (ssize_t)send(x,y,z, SEND_4TH_ARG)
|
#define swrite(x,y,z) (ssize_t)send(x,y,z, SEND_4TH_ARG)
|
||||||
#else
|
#else /* __BEOS__ */
|
||||||
#define sclose(x) close(x)
|
#define sclose(x) close(x)
|
||||||
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
|
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
|
||||||
#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
|
#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
|
||||||
#endif
|
#endif /* __BEOS__ */
|
||||||
|
|
||||||
#define HAVE_ALARM
|
#define HAVE_ALARM
|
||||||
|
|
||||||
#endif
|
#endif /* DJGPP */
|
||||||
|
|
||||||
#ifdef _AMIGASF
|
#ifdef _AMIGASF
|
||||||
#undef HAVE_ALARM
|
#undef HAVE_ALARM
|
||||||
@@ -231,7 +238,7 @@ typedef unsigned char bool;
|
|||||||
int fileno( FILE *stream);
|
int fileno( FILE *stream);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/* now typedef our socket type */
|
/* now typedef our socket type */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -280,4 +287,18 @@ typedef int curl_socket_t;
|
|||||||
#define HAVE_INET_NTOA_R_2_ARGS 1
|
#define HAVE_INET_NTOA_R_2_ARGS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_GNUTLS) || defined(USE_SSLEAY)
|
||||||
|
#define USE_SSL /* Either OpenSSL || GnuTLS */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
||||||
|
#define USE_NTLM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
#define DEBUGF(x) x
|
||||||
|
#else
|
||||||
|
#define DEBUGF(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __CONFIG_H */
|
#endif /* __CONFIG_H */
|
||||||
|
541
lib/sslgen.c
Normal file
541
lib/sslgen.c
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* This file is for "generic" SSL functions that all libcurl internals should
|
||||||
|
use. It is responsible for calling the proper 'ossl' function in ssluse.c
|
||||||
|
(OpenSSL based) or the 'gtsl' function in gtsl.c (GnuTLS based).
|
||||||
|
|
||||||
|
SSL-functions in libcurl should call functions in this source file, and not
|
||||||
|
to any specific SSL-layer.
|
||||||
|
|
||||||
|
Curl_ssl_ - prefix for generic ones
|
||||||
|
Curl_ossl_ - prefix for OpenSSL ones
|
||||||
|
Curl_gtls_ - prefix for GnuTLS ones
|
||||||
|
|
||||||
|
"SSL/TLS Strong Encryption: An Introduction"
|
||||||
|
http://httpd.apache.org/docs-2.0/ssl/ssl_intro.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#define SSLGEN_C
|
||||||
|
#include "sslgen.h" /* generic SSL protos etc */
|
||||||
|
#include "ssluse.h" /* OpenSSL versions */
|
||||||
|
#include "gtls.h" /* GnuTLS versions */
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "strequal.h"
|
||||||
|
#include "url.h"
|
||||||
|
#include "memory.h"
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/* "global" init done? */
|
||||||
|
static bool init_ssl=FALSE;
|
||||||
|
|
||||||
|
static bool safe_strequal(char* str1, char* str2);
|
||||||
|
|
||||||
|
static bool safe_strequal(char* str1, char* str2)
|
||||||
|
{
|
||||||
|
if(str1 && str2)
|
||||||
|
/* both pointers point to something then compare them */
|
||||||
|
return strequal(str1, str2);
|
||||||
|
else
|
||||||
|
/* if both pointers are NULL then treat them as equal */
|
||||||
|
return (!str1 && !str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Curl_ssl_config_matches(struct ssl_config_data* data,
|
||||||
|
struct ssl_config_data* needle)
|
||||||
|
{
|
||||||
|
if((data->version == needle->version) &&
|
||||||
|
(data->verifypeer == needle->verifypeer) &&
|
||||||
|
(data->verifyhost == needle->verifyhost) &&
|
||||||
|
safe_strequal(data->CApath, needle->CApath) &&
|
||||||
|
safe_strequal(data->CAfile, needle->CAfile) &&
|
||||||
|
safe_strequal(data->random_file, needle->random_file) &&
|
||||||
|
safe_strequal(data->egdsocket, needle->egdsocket) &&
|
||||||
|
safe_strequal(data->cipher_list, needle->cipher_list))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Curl_clone_ssl_config(struct ssl_config_data *source,
|
||||||
|
struct ssl_config_data *dest)
|
||||||
|
{
|
||||||
|
dest->verifyhost = source->verifyhost;
|
||||||
|
dest->verifypeer = source->verifypeer;
|
||||||
|
dest->version = source->version;
|
||||||
|
|
||||||
|
if(source->CAfile) {
|
||||||
|
dest->CAfile = strdup(source->CAfile);
|
||||||
|
if(!dest->CAfile)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source->CApath) {
|
||||||
|
dest->CApath = strdup(source->CApath);
|
||||||
|
if(!dest->CApath)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source->cipher_list) {
|
||||||
|
dest->cipher_list = strdup(source->cipher_list);
|
||||||
|
if(!dest->cipher_list)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source->egdsocket) {
|
||||||
|
dest->egdsocket = strdup(source->egdsocket);
|
||||||
|
if(!dest->egdsocket)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source->random_file) {
|
||||||
|
dest->random_file = strdup(source->random_file);
|
||||||
|
if(!dest->random_file)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_free_ssl_config(struct ssl_config_data* sslc)
|
||||||
|
{
|
||||||
|
if(sslc->CAfile)
|
||||||
|
free(sslc->CAfile);
|
||||||
|
|
||||||
|
if(sslc->CApath)
|
||||||
|
free(sslc->CApath);
|
||||||
|
|
||||||
|
if(sslc->cipher_list)
|
||||||
|
free(sslc->cipher_list);
|
||||||
|
|
||||||
|
if(sslc->egdsocket)
|
||||||
|
free(sslc->egdsocket);
|
||||||
|
|
||||||
|
if(sslc->random_file)
|
||||||
|
free(sslc->random_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global SSL init
|
||||||
|
*
|
||||||
|
* @retval 0 error initializing SSL
|
||||||
|
* @retval 1 SSL initialized successfully
|
||||||
|
*/
|
||||||
|
int Curl_ssl_init(void)
|
||||||
|
{
|
||||||
|
/* make sure this is only done once */
|
||||||
|
if(init_ssl)
|
||||||
|
return 1;
|
||||||
|
init_ssl = TRUE; /* never again */
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_init();
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
return Curl_gtls_init();
|
||||||
|
#else
|
||||||
|
/* no SSL support */
|
||||||
|
return 1;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Global cleanup */
|
||||||
|
void Curl_ssl_cleanup(void)
|
||||||
|
{
|
||||||
|
if(init_ssl) {
|
||||||
|
/* only cleanup if we did a previous init */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
Curl_ossl_cleanup();
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
Curl_gtls_cleanup();
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
init_ssl = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode
|
||||||
|
Curl_ssl_connect(struct connectdata *conn, int sockindex)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSL
|
||||||
|
/* mark this is being ssl enabled from here on. */
|
||||||
|
conn->ssl[sockindex].use = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_connect(conn, sockindex);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
return Curl_gtls_connect(conn, sockindex);
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* without SSL */
|
||||||
|
(void)conn;
|
||||||
|
(void)sockindex;
|
||||||
|
return CURLE_OK;
|
||||||
|
#endif /* USE_SSL */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SSL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there's a session ID for the given connection in the cache, and if
|
||||||
|
* there's one suitable, it is provided. Returns TRUE when no entry matched.
|
||||||
|
*/
|
||||||
|
int Curl_ssl_getsessionid(struct connectdata *conn,
|
||||||
|
void **ssl_sessionid,
|
||||||
|
size_t *idsize) /* set 0 if unknown */
|
||||||
|
{
|
||||||
|
struct curl_ssl_session *check;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
long i;
|
||||||
|
|
||||||
|
for(i=0; i< data->set.ssl.numsessions; i++) {
|
||||||
|
check = &data->state.session[i];
|
||||||
|
if(!check->sessionid)
|
||||||
|
/* not session ID means blank entry */
|
||||||
|
continue;
|
||||||
|
if(curl_strequal(conn->host.name, check->name) &&
|
||||||
|
(conn->remote_port == check->remote_port) &&
|
||||||
|
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
|
||||||
|
/* yes, we have a session ID! */
|
||||||
|
data->state.sessionage++; /* increase general age */
|
||||||
|
check->age = data->state.sessionage; /* set this as used in this age */
|
||||||
|
*ssl_sessionid = check->sessionid;
|
||||||
|
if(idsize)
|
||||||
|
*idsize = check->idsize;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ssl_sessionid = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kill a single session ID entry in the cache.
|
||||||
|
*/
|
||||||
|
static int kill_session(struct curl_ssl_session *session)
|
||||||
|
{
|
||||||
|
if(session->sessionid) {
|
||||||
|
/* defensive check */
|
||||||
|
|
||||||
|
/* free the ID the SSL-layer specific way */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
Curl_ossl_session_free(session->sessionid);
|
||||||
|
#else
|
||||||
|
Curl_gtls_session_free(session->sessionid);
|
||||||
|
#endif
|
||||||
|
session->sessionid=NULL;
|
||||||
|
session->age = 0; /* fresh */
|
||||||
|
|
||||||
|
Curl_free_ssl_config(&session->ssl_config);
|
||||||
|
|
||||||
|
Curl_safefree(session->name);
|
||||||
|
session->name = NULL; /* no name */
|
||||||
|
|
||||||
|
return 0; /* ok */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store session id in the session cache. The ID passed on to this function
|
||||||
|
* must already have been extracted and allocated the proper way for the SSL
|
||||||
|
* layer. Curl_XXXX_session_free() will be called to free/kill the session ID
|
||||||
|
* later on.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||||
|
void *ssl_sessionid,
|
||||||
|
size_t idsize)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct SessionHandle *data=conn->data; /* the mother of all structs */
|
||||||
|
struct curl_ssl_session *store = &data->state.session[0];
|
||||||
|
long oldest_age=data->state.session[0].age; /* zero if unused */
|
||||||
|
char *clone_host;
|
||||||
|
|
||||||
|
clone_host = strdup(conn->host.name);
|
||||||
|
if(!clone_host)
|
||||||
|
return CURLE_OUT_OF_MEMORY; /* bail out */
|
||||||
|
|
||||||
|
/* Now we should add the session ID and the host name to the cache, (remove
|
||||||
|
the oldest if necessary) */
|
||||||
|
|
||||||
|
/* find an empty slot for us, or find the oldest */
|
||||||
|
for(i=1; (i<data->set.ssl.numsessions) &&
|
||||||
|
data->state.session[i].sessionid; i++) {
|
||||||
|
if(data->state.session[i].age < oldest_age) {
|
||||||
|
oldest_age = data->state.session[i].age;
|
||||||
|
store = &data->state.session[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i == data->set.ssl.numsessions)
|
||||||
|
/* cache is full, we must "kill" the oldest entry! */
|
||||||
|
kill_session(store);
|
||||||
|
else
|
||||||
|
store = &data->state.session[i]; /* use this slot */
|
||||||
|
|
||||||
|
/* now init the session struct wisely */
|
||||||
|
store->sessionid = ssl_sessionid;
|
||||||
|
store->idsize = idsize;
|
||||||
|
store->age = data->state.sessionage; /* set current age */
|
||||||
|
store->name = clone_host; /* clone host name */
|
||||||
|
store->remote_port = conn->remote_port; /* port number */
|
||||||
|
|
||||||
|
if (!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Curl_ssl_close_all(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSL
|
||||||
|
int i;
|
||||||
|
/* kill the session ID cache */
|
||||||
|
if(data->state.session) {
|
||||||
|
for(i=0; i< data->set.ssl.numsessions; i++)
|
||||||
|
/* the single-killer function handles empty table slots */
|
||||||
|
kill_session(&data->state.session[i]);
|
||||||
|
|
||||||
|
/* free the cache data */
|
||||||
|
free(data->state.session);
|
||||||
|
data->state.session = NULL;
|
||||||
|
}
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
Curl_ossl_close_all(data);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
Curl_gtls_close_all(data);
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
#else /* USE_SSL */
|
||||||
|
(void)data;
|
||||||
|
#endif /* USE_SSL */
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_ssl_close(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
if(conn->ssl[FIRSTSOCKET].use) {
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
Curl_ossl_close(conn);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
Curl_gtls_close(conn);
|
||||||
|
#else
|
||||||
|
(void)conn;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selects an (Open)SSL crypto engine
|
||||||
|
*/
|
||||||
|
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_set_engine(data, engine);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
/* FIX: add code here */
|
||||||
|
(void)data;
|
||||||
|
(void)engine;
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
#else
|
||||||
|
/* no SSL layer */
|
||||||
|
(void)data;
|
||||||
|
(void)engine;
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selects an (Open?)SSL crypto engine
|
||||||
|
*/
|
||||||
|
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_set_engine_default(data);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
/* FIX: add code here */
|
||||||
|
(void)data;
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
#else
|
||||||
|
/* No SSL layer */
|
||||||
|
(void)data;
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return list of OpenSSL crypto engine names. */
|
||||||
|
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_engines_list(data);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
/* FIX: add code here? */
|
||||||
|
(void)data;
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
(void)data;
|
||||||
|
return NULL;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return number of sent (non-SSL) bytes */
|
||||||
|
int Curl_ssl_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
void *mem,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_send(conn, sockindex, mem, len);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
return Curl_gtls_send(conn, sockindex, mem, len);
|
||||||
|
#else
|
||||||
|
(void)conn;
|
||||||
|
(void)sockindex;
|
||||||
|
(void)mem;
|
||||||
|
(void)len;
|
||||||
|
return 0;
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return number of received (decrypted) bytes */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||||
|
* a regular CURLcode value.
|
||||||
|
*/
|
||||||
|
int Curl_ssl_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int sockindex, /* socketindex */
|
||||||
|
char *mem, /* store read data here */
|
||||||
|
size_t len) /* max amount to read */
|
||||||
|
{
|
||||||
|
#ifdef USE_SSL
|
||||||
|
ssize_t nread;
|
||||||
|
bool block = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
nread = Curl_ossl_recv(conn, sockindex, mem, len, &block);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
nread = Curl_gtls_recv(conn, sockindex, mem, len, &block);
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
if(nread == -1) {
|
||||||
|
infof(conn->data, "Curl_xxx_rcvs returned -1, block = %s\n",
|
||||||
|
block?"TRUE":"FALSE");
|
||||||
|
if(!block)
|
||||||
|
return 0; /* this is a true error, not EWOULDBLOCK */
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)nread;
|
||||||
|
|
||||||
|
#else /* USE_SSL */
|
||||||
|
(void)conn;
|
||||||
|
(void)sockindex;
|
||||||
|
(void)mem;
|
||||||
|
(void)len;
|
||||||
|
return 0;
|
||||||
|
#endif /* USE_SSL */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This sets up a session ID cache to the specified size. Make sure this code
|
||||||
|
* is agnostic to what underlying SSL technology we use.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSL
|
||||||
|
struct curl_ssl_session *session;
|
||||||
|
|
||||||
|
if(data->state.session)
|
||||||
|
/* this is just a precaution to prevent multiple inits */
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
session = (struct curl_ssl_session *)
|
||||||
|
calloc(sizeof(struct curl_ssl_session), amount);
|
||||||
|
if(!session)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* store the info in the SSL section */
|
||||||
|
data->set.ssl.numsessions = amount;
|
||||||
|
data->state.session = session;
|
||||||
|
data->state.sessionage = 1; /* this is brand new */
|
||||||
|
#else
|
||||||
|
/* without SSL, do nothing */
|
||||||
|
(void)data;
|
||||||
|
(void)amount;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Curl_ssl_version(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
return Curl_ossl_version(buffer, size);
|
||||||
|
#else
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
return Curl_gtls_version(buffer, size);
|
||||||
|
#else
|
||||||
|
(void)buffer;
|
||||||
|
(void)size;
|
||||||
|
return 0; /* no SSL support */
|
||||||
|
#endif /* USE_GNUTLS */
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
}
|
||||||
|
|
72
lib/sslgen.h
Normal file
72
lib/sslgen.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef __SSLGEN_H
|
||||||
|
#define __SSLGEN_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
bool Curl_ssl_config_matches(struct ssl_config_data* data,
|
||||||
|
struct ssl_config_data* needle);
|
||||||
|
bool Curl_clone_ssl_config(struct ssl_config_data* source,
|
||||||
|
struct ssl_config_data* dest);
|
||||||
|
void Curl_free_ssl_config(struct ssl_config_data* sslc);
|
||||||
|
|
||||||
|
int Curl_ssl_init(void);
|
||||||
|
void Curl_ssl_cleanup(void);
|
||||||
|
CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
|
||||||
|
void Curl_ssl_close(struct connectdata *conn);
|
||||||
|
/* tell the SSL stuff to close down all open information regarding
|
||||||
|
connections (and thus session ID caching etc) */
|
||||||
|
void Curl_ssl_close_all(struct SessionHandle *data);
|
||||||
|
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
|
||||||
|
/* Sets engine as default for all SSL operations */
|
||||||
|
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
|
||||||
|
int Curl_ssl_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
void *mem,
|
||||||
|
size_t len);
|
||||||
|
int Curl_ssl_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int sockindex, /* socketindex */
|
||||||
|
char *mem, /* store read data here */
|
||||||
|
size_t len); /* max amount to read */
|
||||||
|
|
||||||
|
/* init the SSL session ID cache */
|
||||||
|
CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
|
||||||
|
/* extract a session ID */
|
||||||
|
int Curl_ssl_getsessionid(struct connectdata *conn,
|
||||||
|
void **ssl_sessionid,
|
||||||
|
size_t *idsize) /* set 0 if unknown */;
|
||||||
|
/* add a new session ID */
|
||||||
|
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||||
|
void *ssl_sessionid,
|
||||||
|
size_t idsize);
|
||||||
|
|
||||||
|
|
||||||
|
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
|
||||||
|
|
||||||
|
size_t Curl_ssl_version(char *buffer, size_t size);
|
||||||
|
|
||||||
|
#if !defined(USE_SSL) && !defined(SSLGEN_C)
|
||||||
|
/* set up blank macros for none-SSL builds */
|
||||||
|
#define Curl_ssl_close_all(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
443
lib/ssluse.c
443
lib/ssluse.c
@@ -22,8 +22,13 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The original SSL code for curl was written by
|
* Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
|
||||||
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
|
* but sslgen.c should ever call or use these functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The original SSLeay-using code for curl was written by Linas Vepstas and
|
||||||
|
* Sampo Kellomaki 1998.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
@@ -47,6 +52,7 @@
|
|||||||
#include "connect.h" /* Curl_ourerrno() proto */
|
#include "connect.h" /* Curl_ourerrno() proto */
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
|
#include "sslgen.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -519,27 +525,20 @@ static char *SSL_strerror(unsigned long error, char *buf, size_t size)
|
|||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "global" init done? */
|
|
||||||
static int init_ssl=0;
|
|
||||||
|
|
||||||
/* we have the "SSL is seeded" boolean global for the application to
|
/* we have the "SSL is seeded" boolean global for the application to
|
||||||
prevent multiple time-consuming seedings in vain */
|
prevent multiple time-consuming seedings in vain */
|
||||||
static bool ssl_seeded = FALSE;
|
static bool ssl_seeded = FALSE;
|
||||||
#endif /* USE_SSLEAY */
|
#endif /* USE_SSLEAY */
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
/**
|
/**
|
||||||
* Global SSL init
|
* Global SSL init
|
||||||
*
|
*
|
||||||
* @retval 0 error initializing SSL
|
* @retval 0 error initializing SSL
|
||||||
* @retval 1 SSL initialized successfully
|
* @retval 1 SSL initialized successfully
|
||||||
*/
|
*/
|
||||||
int Curl_SSL_init(void)
|
int Curl_ossl_init(void)
|
||||||
{
|
{
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
/* make sure this is only done once */
|
|
||||||
if(init_ssl)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
|
#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
|
||||||
ENGINE_load_builtin_engines();
|
ENGINE_load_builtin_engines();
|
||||||
#endif
|
#endif
|
||||||
@@ -551,22 +550,16 @@ int Curl_SSL_init(void)
|
|||||||
if (!SSLeay_add_ssl_algorithms())
|
if (!SSLeay_add_ssl_algorithms())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
init_ssl++; /* never again */
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* SSL disabled, do nothing */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global cleanup */
|
#endif /* USE_SSLEAY */
|
||||||
void Curl_SSL_cleanup(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
if(init_ssl) {
|
|
||||||
/* only cleanup if we did a previous init */
|
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
|
||||||
|
/* Global cleanup */
|
||||||
|
void Curl_ossl_cleanup(void)
|
||||||
|
{
|
||||||
/* Free the SSL error strings */
|
/* Free the SSL error strings */
|
||||||
ERR_free_strings();
|
ERR_free_strings();
|
||||||
|
|
||||||
@@ -583,25 +576,13 @@ void Curl_SSL_cleanup(void)
|
|||||||
later */
|
later */
|
||||||
CRYPTO_cleanup_all_ex_data();
|
CRYPTO_cleanup_all_ex_data();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_ssl=0; /* not inited any more */
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* SSL disabled, do nothing */
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_SSLEAY
|
#endif /* USE_SSLEAY */
|
||||||
void Curl_SSL_Close(struct connectdata *conn)
|
|
||||||
{
|
|
||||||
(void)conn;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Selects an OpenSSL crypto engine
|
/* Selects an OpenSSL crypto engine
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_SSL_set_engine(struct SessionHandle *data, const char *engine)
|
CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
|
||||||
{
|
{
|
||||||
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
||||||
ENGINE *e = ENGINE_by_id(engine);
|
ENGINE *e = ENGINE_by_id(engine);
|
||||||
@@ -633,11 +614,12 @@ CURLcode Curl_SSL_set_engine(struct SessionHandle *data, const char *engine)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets above engine as default for all SSL operations
|
#ifdef USE_SSLEAY
|
||||||
|
/* Sets engine as default for all SSL operations
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_SSL_set_engine_default(struct SessionHandle *data)
|
CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||||
if (data->state.engine) {
|
if (data->state.engine) {
|
||||||
if (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
|
if (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
|
||||||
infof(data,"set default crypto engine %s\n", data->state.engine);
|
infof(data,"set default crypto engine %s\n", data->state.engine);
|
||||||
@@ -650,12 +632,13 @@ CURLcode Curl_SSL_set_engine_default(struct SessionHandle *data)
|
|||||||
#else
|
#else
|
||||||
(void) data;
|
(void) data;
|
||||||
#endif
|
#endif
|
||||||
return (CURLE_OK);
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
|
||||||
/* Return list of OpenSSL crypto engine names.
|
/* Return list of OpenSSL crypto engine names.
|
||||||
*/
|
*/
|
||||||
struct curl_slist *Curl_SSL_engines_list(struct SessionHandle *data)
|
struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
struct curl_slist *list = NULL;
|
struct curl_slist *list = NULL;
|
||||||
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
|
||||||
@@ -674,9 +657,8 @@ struct curl_slist *Curl_SSL_engines_list(struct SessionHandle *data)
|
|||||||
/*
|
/*
|
||||||
* This function is called when an SSL connection is closed.
|
* This function is called when an SSL connection is closed.
|
||||||
*/
|
*/
|
||||||
void Curl_SSL_Close(struct connectdata *conn)
|
void Curl_ossl_close(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
if(conn->ssl[FIRSTSOCKET].use) {
|
|
||||||
int i;
|
int i;
|
||||||
/*
|
/*
|
||||||
ERR_remove_state() frees the error queue associated with
|
ERR_remove_state() frees the error queue associated with
|
||||||
@@ -705,186 +687,32 @@ void Curl_SSL_Close(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
connssl->use = FALSE; /* get back to ordinary socket usage */
|
connssl->use = FALSE; /* get back to ordinary socket usage */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Curl_ossl_session_free(void *ptr)
|
||||||
/*
|
|
||||||
* This sets up a session cache to the specified size.
|
|
||||||
*/
|
|
||||||
CURLcode Curl_SSL_InitSessions(struct SessionHandle *data, long amount)
|
|
||||||
{
|
{
|
||||||
struct curl_ssl_session *session;
|
|
||||||
|
|
||||||
if(data->state.session)
|
|
||||||
/* this is just a precaution to prevent multiple inits */
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
session = (struct curl_ssl_session *)
|
|
||||||
malloc(amount * sizeof(struct curl_ssl_session));
|
|
||||||
if(!session)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* "blank out" the newly allocated memory */
|
|
||||||
memset(session, 0, amount * sizeof(struct curl_ssl_session));
|
|
||||||
|
|
||||||
/* store the info in the SSL section */
|
|
||||||
data->set.ssl.numsessions = amount;
|
|
||||||
data->state.session = session;
|
|
||||||
data->state.sessionage = 1; /* this is brand new */
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if there's a session ID for the given connection in the cache,
|
|
||||||
* and if there's one suitable, it is returned.
|
|
||||||
*/
|
|
||||||
static int Get_SSL_Session(struct connectdata *conn,
|
|
||||||
SSL_SESSION **ssl_sessionid)
|
|
||||||
{
|
|
||||||
struct curl_ssl_session *check;
|
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
long i;
|
|
||||||
|
|
||||||
for(i=0; i< data->set.ssl.numsessions; i++) {
|
|
||||||
check = &data->state.session[i];
|
|
||||||
if(!check->sessionid)
|
|
||||||
/* not session ID means blank entry */
|
|
||||||
continue;
|
|
||||||
if(curl_strequal(conn->host.name, check->name) &&
|
|
||||||
(conn->remote_port == check->remote_port) &&
|
|
||||||
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
|
|
||||||
/* yes, we have a session ID! */
|
|
||||||
data->state.sessionage++; /* increase general age */
|
|
||||||
check->age = data->state.sessionage; /* set this as used in this age */
|
|
||||||
*ssl_sessionid = check->sessionid;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*ssl_sessionid = (SSL_SESSION *)NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Kill a single session ID entry in the cache.
|
|
||||||
*/
|
|
||||||
static int Kill_Single_Session(struct curl_ssl_session *session)
|
|
||||||
{
|
|
||||||
if(session->sessionid) {
|
|
||||||
/* defensive check */
|
|
||||||
|
|
||||||
/* free the ID */
|
/* free the ID */
|
||||||
SSL_SESSION_free(session->sessionid);
|
SSL_SESSION_free(ptr);
|
||||||
session->sessionid=NULL;
|
|
||||||
session->age = 0; /* fresh */
|
|
||||||
|
|
||||||
Curl_free_ssl_config(&session->ssl_config);
|
|
||||||
|
|
||||||
Curl_safefree(session->name);
|
|
||||||
session->name = NULL; /* no name */
|
|
||||||
|
|
||||||
return 0; /* ok */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called when the 'data' struct is going away. Close
|
* This function is called when the 'data' struct is going away. Close
|
||||||
* down everything and free all resources!
|
* down everything and free all resources!
|
||||||
*/
|
*/
|
||||||
int Curl_SSL_Close_All(struct SessionHandle *data)
|
int Curl_ossl_close_all(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if(data->state.session) {
|
|
||||||
for(i=0; i< data->set.ssl.numsessions; i++)
|
|
||||||
/* the single-killer function handles empty table slots */
|
|
||||||
Kill_Single_Session(&data->state.session[i]);
|
|
||||||
|
|
||||||
/* free the cache data */
|
|
||||||
free(data->state.session);
|
|
||||||
data->state.session = NULL;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||||
if(data->state.engine) {
|
if(data->state.engine) {
|
||||||
ENGINE_finish(data->state.engine);
|
ENGINE_finish(data->state.engine);
|
||||||
ENGINE_free(data->state.engine);
|
ENGINE_free(data->state.engine);
|
||||||
data->state.engine = NULL;
|
data->state.engine = NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)data;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Extract the session id and store it in the session cache.
|
|
||||||
*/
|
|
||||||
static CURLcode Store_SSL_Session(struct connectdata *conn,
|
|
||||||
struct ssl_connect_data *ssl)
|
|
||||||
{
|
|
||||||
SSL_SESSION *ssl_sessionid;
|
|
||||||
int i;
|
|
||||||
struct SessionHandle *data=conn->data; /* the mother of all structs */
|
|
||||||
struct curl_ssl_session *store = &data->state.session[0];
|
|
||||||
long oldest_age=data->state.session[0].age; /* zero if unused */
|
|
||||||
char *clone_host;
|
|
||||||
|
|
||||||
clone_host = strdup(conn->host.name);
|
|
||||||
if(!clone_host)
|
|
||||||
return CURLE_OUT_OF_MEMORY; /* bail out */
|
|
||||||
|
|
||||||
/* ask OpenSSL, say please */
|
|
||||||
|
|
||||||
#ifdef HAVE_SSL_GET1_SESSION
|
|
||||||
ssl_sessionid = SSL_get1_session(ssl->handle);
|
|
||||||
|
|
||||||
/* SSL_get1_session() will increment the reference
|
|
||||||
count and the session will stay in memory until explicitly freed with
|
|
||||||
SSL_SESSION_free(3), regardless of its state.
|
|
||||||
This function was introduced in openssl 0.9.5a. */
|
|
||||||
#else
|
|
||||||
ssl_sessionid = SSL_get_session(ssl->handle);
|
|
||||||
|
|
||||||
/* if SSL_get1_session() is unavailable, use SSL_get_session().
|
|
||||||
This is an inferior option because the session can be flushed
|
|
||||||
at any time by openssl. It is included only so curl compiles
|
|
||||||
under versions of openssl < 0.9.5a.
|
|
||||||
|
|
||||||
WARNING: How curl behaves if it's session is flushed is
|
|
||||||
untested.
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now we should add the session ID and the host name to the cache, (remove
|
|
||||||
the oldest if necessary) */
|
|
||||||
|
|
||||||
/* find an empty slot for us, or find the oldest */
|
|
||||||
for(i=1; (i<data->set.ssl.numsessions) &&
|
|
||||||
data->state.session[i].sessionid; i++) {
|
|
||||||
if(data->state.session[i].age < oldest_age) {
|
|
||||||
oldest_age = data->state.session[i].age;
|
|
||||||
store = &data->state.session[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i == data->set.ssl.numsessions)
|
|
||||||
/* cache is full, we must "kill" the oldest entry! */
|
|
||||||
Kill_Single_Session(store);
|
|
||||||
else
|
|
||||||
store = &data->state.session[i]; /* use this slot */
|
|
||||||
|
|
||||||
/* now init the session struct wisely */
|
|
||||||
store->sessionid = ssl_sessionid;
|
|
||||||
store->age = data->state.sessionage; /* set current age */
|
|
||||||
store->name = clone_host; /* clone host name */
|
|
||||||
store->remote_port = conn->remote_port; /* port number */
|
|
||||||
|
|
||||||
if (!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
|
static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
|
||||||
const char *prefix,
|
const char *prefix,
|
||||||
ASN1_UTCTIME *tm)
|
ASN1_UTCTIME *tm)
|
||||||
@@ -1280,28 +1108,25 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
/* ====================================================== */
|
/* ====================================================== */
|
||||||
CURLcode
|
CURLcode
|
||||||
Curl_SSLConnect(struct connectdata *conn,
|
Curl_ossl_connect(struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
{
|
{
|
||||||
CURLcode retcode = CURLE_OK;
|
CURLcode retcode = CURLE_OK;
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
int err;
|
int err;
|
||||||
long lerr;
|
long lerr;
|
||||||
int what;
|
int what;
|
||||||
char * str;
|
char * str;
|
||||||
SSL_METHOD *req_method;
|
SSL_METHOD *req_method;
|
||||||
SSL_SESSION *ssl_sessionid=NULL;
|
void *ssl_sessionid=NULL;
|
||||||
ASN1_TIME *certdate;
|
ASN1_TIME *certdate;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
curl_socket_t sockfd = conn->sock[sockindex];
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
|
||||||
/* mark this is being ssl enabled from here on out. */
|
|
||||||
connssl->use = TRUE;
|
|
||||||
|
|
||||||
if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {
|
if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {
|
||||||
/* Make funny stuff to get random input */
|
/* Make funny stuff to get random input */
|
||||||
random_the_seed(data);
|
random_the_seed(data);
|
||||||
@@ -1447,10 +1272,8 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
|
|
||||||
connssl->server_cert = 0x0;
|
connssl->server_cert = 0x0;
|
||||||
|
|
||||||
if(!conn->bits.reuse) {
|
/* Check if there's a cached ID we can/should use here! */
|
||||||
/* We're not re-using a connection, check if there's a cached ID we
|
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
|
||||||
can/should use here! */
|
|
||||||
if(!Get_SSL_Session(conn, &ssl_sessionid)) {
|
|
||||||
/* we got a session id, use it! */
|
/* we got a session id, use it! */
|
||||||
if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
|
if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
|
||||||
failf(data, "SSL: SSL_set_session failed: %s",
|
failf(data, "SSL: SSL_set_session failed: %s",
|
||||||
@@ -1460,7 +1283,6 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
/* Informational message */
|
/* Informational message */
|
||||||
infof (data, "SSL re-using session ID\n");
|
infof (data, "SSL re-using session ID\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* pass the raw socket into the SSL layers */
|
/* pass the raw socket into the SSL layers */
|
||||||
if (!SSL_set_fd(connssl->handle, sockfd)) {
|
if (!SSL_set_fd(connssl->handle, sockfd)) {
|
||||||
@@ -1473,16 +1295,13 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
int writefd;
|
int writefd;
|
||||||
int readfd;
|
int readfd;
|
||||||
long timeout_ms;
|
long timeout_ms;
|
||||||
|
long has_passed;
|
||||||
|
|
||||||
/* Find out if any timeout is set. If not, use 300 seconds.
|
/* Find out if any timeout is set. If not, use 300 seconds.
|
||||||
Otherwise, figure out the most strict timeout of the two possible one
|
Otherwise, figure out the most strict timeout of the two possible one
|
||||||
and then how much time that has elapsed to know how much time we
|
and then how much time that has elapsed to know how much time we
|
||||||
allow for the connect call */
|
allow for the connect call */
|
||||||
if(data->set.timeout || data->set.connecttimeout) {
|
if(data->set.timeout || data->set.connecttimeout) {
|
||||||
long has_passed;
|
|
||||||
|
|
||||||
/* Evaluate in milliseconds how much time that has passed */
|
|
||||||
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
|
||||||
|
|
||||||
/* get the most strict timeout of the ones converted to milliseconds */
|
/* get the most strict timeout of the ones converted to milliseconds */
|
||||||
if(data->set.timeout &&
|
if(data->set.timeout &&
|
||||||
@@ -1490,6 +1309,13 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
timeout_ms = data->set.timeout*1000;
|
timeout_ms = data->set.timeout*1000;
|
||||||
else
|
else
|
||||||
timeout_ms = data->set.connecttimeout*1000;
|
timeout_ms = data->set.connecttimeout*1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* no particular time-out has been set */
|
||||||
|
timeout_ms= DEFAULT_CONNECT_TIMEOUT;
|
||||||
|
|
||||||
|
/* Evaluate in milliseconds how much time that has passed */
|
||||||
|
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||||
|
|
||||||
/* subtract the passed time */
|
/* subtract the passed time */
|
||||||
timeout_ms -= has_passed;
|
timeout_ms -= has_passed;
|
||||||
@@ -1499,11 +1325,6 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
failf(data, "SSL connection timeout");
|
failf(data, "SSL connection timeout");
|
||||||
return CURLE_OPERATION_TIMEOUTED;
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
/* no particular time-out has been set */
|
|
||||||
timeout_ms= DEFAULT_CONNECT_TIMEOUT;
|
|
||||||
|
|
||||||
|
|
||||||
readfd = CURL_SOCKET_BAD;
|
readfd = CURL_SOCKET_BAD;
|
||||||
writefd = CURL_SOCKET_BAD;
|
writefd = CURL_SOCKET_BAD;
|
||||||
@@ -1586,12 +1407,7 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
return CURLE_OPERATION_TIMEDOUT;
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if !defined(WIN32) && defined(EINTR)
|
/* anything that gets here is fatally bad */
|
||||||
/* For platforms without EINTR all errnos are bad */
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue; /* retry the select() */
|
|
||||||
#endif
|
|
||||||
/* anything other than the unimportant EINTR is fatally bad */
|
|
||||||
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
|
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1605,9 +1421,30 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
if(!ssl_sessionid) {
|
if(!ssl_sessionid) {
|
||||||
/* Since this is not a cached session ID, then we want to stach this one
|
/* Since this is not a cached session ID, then we want to stach this one
|
||||||
in the cache! */
|
in the cache! */
|
||||||
retcode = Store_SSL_Session(conn, connssl);
|
SSL_SESSION *ssl_sessionid;
|
||||||
|
#ifdef HAVE_SSL_GET1_SESSION
|
||||||
|
ssl_sessionid = SSL_get1_session(connssl->handle);
|
||||||
|
|
||||||
|
/* SSL_get1_session() will increment the reference
|
||||||
|
count and the session will stay in memory until explicitly freed with
|
||||||
|
SSL_SESSION_free(3), regardless of its state.
|
||||||
|
This function was introduced in openssl 0.9.5a. */
|
||||||
|
#else
|
||||||
|
ssl_sessionid = SSL_get_session(connssl->handle);
|
||||||
|
|
||||||
|
/* if SSL_get1_session() is unavailable, use SSL_get_session().
|
||||||
|
This is an inferior option because the session can be flushed
|
||||||
|
at any time by openssl. It is included only so curl compiles
|
||||||
|
under versions of openssl < 0.9.5a.
|
||||||
|
|
||||||
|
WARNING: How curl behaves if it's session is flushed is
|
||||||
|
untested.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
retcode = Curl_ssl_addsessionid(conn, ssl_sessionid,
|
||||||
|
0 /* unknown size */);
|
||||||
if(retcode) {
|
if(retcode) {
|
||||||
failf(data,"failure to store ssl session");
|
failf(data, "failed to store ssl session");
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1686,9 +1523,145 @@ Curl_SSLConnect(struct connectdata *conn,
|
|||||||
|
|
||||||
X509_free(connssl->server_cert);
|
X509_free(connssl->server_cert);
|
||||||
connssl->server_cert = NULL;
|
connssl->server_cert = NULL;
|
||||||
#else /* USE_SSLEAY */
|
|
||||||
(void)conn;
|
|
||||||
(void)sockindex;
|
|
||||||
#endif
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return number of sent (non-SSL) bytes */
|
||||||
|
int Curl_ossl_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
void *mem,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
/* SSL_write() is said to return 'int' while write() and send() returns
|
||||||
|
'size_t' */
|
||||||
|
int err;
|
||||||
|
char error_buffer[120]; /* OpenSSL documents that this must be at least 120
|
||||||
|
bytes long. */
|
||||||
|
unsigned long sslerror;
|
||||||
|
int rc = SSL_write(conn->ssl[sockindex].handle, mem, (int)len);
|
||||||
|
|
||||||
|
if(rc < 0) {
|
||||||
|
err = SSL_get_error(conn->ssl[sockindex].handle, rc);
|
||||||
|
|
||||||
|
switch(err) {
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
/* The operation did not complete; the same TLS/SSL I/O function
|
||||||
|
should be called again later. This is basicly an EWOULDBLOCK
|
||||||
|
equivalent. */
|
||||||
|
return 0;
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
|
||||||
|
Curl_ourerrno());
|
||||||
|
return -1;
|
||||||
|
case SSL_ERROR_SSL:
|
||||||
|
/* A failure in the SSL library occurred, usually a protocol error.
|
||||||
|
The OpenSSL error queue contains more information on the error. */
|
||||||
|
sslerror = ERR_get_error();
|
||||||
|
failf(conn->data, "SSL_write() error: %s\n",
|
||||||
|
ERR_error_string(sslerror, error_buffer));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* a true error */
|
||||||
|
failf(conn->data, "SSL_write() return error %d\n", err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return rc; /* number of bytes */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the read would block we return -1 and set 'wouldblock' to TRUE.
|
||||||
|
* Otherwise we return the amount of data read. Other errors should return -1
|
||||||
|
* and set 'wouldblock' to FALSE.
|
||||||
|
*/
|
||||||
|
ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int num, /* socketindex */
|
||||||
|
char *buf, /* store read data here */
|
||||||
|
size_t buffersize, /* max amount to read */
|
||||||
|
bool *wouldblock)
|
||||||
|
{
|
||||||
|
char error_buffer[120]; /* OpenSSL documents that this must be at
|
||||||
|
least 120 bytes long. */
|
||||||
|
unsigned long sslerror;
|
||||||
|
ssize_t nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf,
|
||||||
|
(int)buffersize);
|
||||||
|
*wouldblock = FALSE;
|
||||||
|
if(nread < 0) {
|
||||||
|
/* failed SSL_read */
|
||||||
|
int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
|
||||||
|
|
||||||
|
switch(err) {
|
||||||
|
case SSL_ERROR_NONE: /* this is not an error */
|
||||||
|
case SSL_ERROR_ZERO_RETURN: /* no more data */
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
/* there's data pending, re-invoke SSL_read() */
|
||||||
|
*wouldblock = TRUE;
|
||||||
|
return -1; /* basically EWOULDBLOCK */
|
||||||
|
default:
|
||||||
|
/* openssl/ssl.h says "look at error stack/return value/errno" */
|
||||||
|
sslerror = ERR_get_error();
|
||||||
|
failf(conn->data, "SSL read: %s, errno %d",
|
||||||
|
ERR_error_string(sslerror, error_buffer),
|
||||||
|
Curl_ourerrno() );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Curl_ossl_version(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
#if (SSLEAY_VERSION_NUMBER >= 0x905000)
|
||||||
|
{
|
||||||
|
char sub[2];
|
||||||
|
unsigned long ssleay_value;
|
||||||
|
sub[1]='\0';
|
||||||
|
ssleay_value=SSLeay();
|
||||||
|
if(ssleay_value < 0x906000) {
|
||||||
|
ssleay_value=SSLEAY_VERSION_NUMBER;
|
||||||
|
sub[0]='\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(ssleay_value&0xff0) {
|
||||||
|
sub[0]=(char)((ssleay_value>>4)&0xff) + 'a' -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sub[0]='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx%s",
|
||||||
|
(ssleay_value>>28)&0xf,
|
||||||
|
(ssleay_value>>20)&0xff,
|
||||||
|
(ssleay_value>>12)&0xff,
|
||||||
|
sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
|
||||||
|
|
||||||
|
#if (SSLEAY_VERSION_NUMBER >= 0x900000)
|
||||||
|
return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx",
|
||||||
|
(SSLEAY_VERSION_NUMBER>>28)&0xff,
|
||||||
|
(SSLEAY_VERSION_NUMBER>>20)&0xff,
|
||||||
|
(SSLEAY_VERSION_NUMBER>>12)&0xf);
|
||||||
|
|
||||||
|
#else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
|
||||||
|
{
|
||||||
|
char sub[2];
|
||||||
|
sub[1]='\0';
|
||||||
|
if(SSLEAY_VERSION_NUMBER&0x0f) {
|
||||||
|
sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sub[0]='\0';
|
||||||
|
|
||||||
|
return snprintf(buffer, size, " SSL/%x.%x.%x%s",
|
||||||
|
(SSLEAY_VERSION_NUMBER>>12)&0xff,
|
||||||
|
(SSLEAY_VERSION_NUMBER>>8)&0xf,
|
||||||
|
(SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
|
||||||
|
}
|
||||||
|
#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
|
||||||
|
#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
|
||||||
|
}
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
|
50
lib/ssluse.h
50
lib/ssluse.h
@@ -22,27 +22,43 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header should only be needed to get included by sslgen.c and ssluse.c
|
||||||
|
*/
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex);
|
CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
|
||||||
|
void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
|
||||||
int Curl_SSL_init(void); /* Global SSL init */
|
/* tell OpenSSL to close down all open information regarding connections (and
|
||||||
void Curl_SSL_cleanup(void); /* Global SSL cleanup */
|
thus session ID caching etc) */
|
||||||
|
int Curl_ossl_close_all(struct SessionHandle *data);
|
||||||
/* init the SSL session ID cache */
|
|
||||||
CURLcode Curl_SSL_InitSessions(struct SessionHandle *, long);
|
|
||||||
void Curl_SSL_Close(struct connectdata *conn); /* close a SSL connection */
|
|
||||||
|
|
||||||
/* tell the SSL stuff to close down all open information regarding
|
|
||||||
connections (and thus session ID caching etc) */
|
|
||||||
int Curl_SSL_Close_All(struct SessionHandle *data);
|
|
||||||
|
|
||||||
/* Sets an OpenSSL engine */
|
/* Sets an OpenSSL engine */
|
||||||
CURLcode Curl_SSL_set_engine(struct SessionHandle *data, const char *engine);
|
CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
|
||||||
|
|
||||||
/* Sets above engine as default for all SSL operations */
|
/* function provided for the generic SSL-layer, called when a session id
|
||||||
CURLcode Curl_SSL_set_engine_default(struct SessionHandle *data);
|
should be freed */
|
||||||
|
void Curl_ossl_session_free(void *ptr);
|
||||||
|
|
||||||
|
/* Sets engine as default for all SSL operations */
|
||||||
|
CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data);
|
||||||
|
|
||||||
/* Build list of OpenSSL engines */
|
/* Build list of OpenSSL engines */
|
||||||
struct curl_slist *Curl_SSL_engines_list(struct SessionHandle *data);
|
struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
|
||||||
|
|
||||||
|
int Curl_ossl_init(void);
|
||||||
|
void Curl_ossl_cleanup(void);
|
||||||
|
|
||||||
|
int Curl_ossl_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
void *mem,
|
||||||
|
size_t len);
|
||||||
|
ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
|
||||||
|
int num, /* socketindex */
|
||||||
|
char *buf, /* store read data here */
|
||||||
|
size_t buffersize, /* max amount to read */
|
||||||
|
bool *wouldblock);
|
||||||
|
|
||||||
|
size_t Curl_ossl_version(char *buffer, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -25,14 +25,6 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* These two actually are public functions, which are in <curl/curl.h>
|
|
||||||
*/
|
|
||||||
int curl_strequal(const char *first, const char *second);
|
|
||||||
int curl_strnequal(const char *first, const char *second, size_t max);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define strequal(a,b) curl_strequal(a,b)
|
#define strequal(a,b) curl_strequal(a,b)
|
||||||
#define strnequal(a,b,c) curl_strnequal(a,b,c)
|
#define strnequal(a,b,c) curl_strnequal(a,b,c)
|
||||||
|
|
||||||
@@ -45,7 +37,7 @@ char *Curl_strcasestr(const char *haystack, const char *needle);
|
|||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
#ifndef HAVE_STRLCAT
|
||||||
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
|
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
|
||||||
size_t Curl_strlcat(char *dst, const char *src, size_t siz);
|
|
||||||
#endif
|
#endif
|
||||||
|
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -571,7 +571,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
|
|||||||
else {
|
else {
|
||||||
if (!get_winsock_error(err, buf, max) &&
|
if (!get_winsock_error(err, buf, max) &&
|
||||||
!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
||||||
LANG_NEUTRAL, buf, max, NULL))
|
LANG_NEUTRAL, buf, (DWORD)max, NULL))
|
||||||
snprintf(buf, max, "Unknown error %d (%#x)", err, err);
|
snprintf(buf, max, "Unknown error %d (%#x)", err, err);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -94,7 +94,7 @@
|
|||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
#include "getinfo.h"
|
#include "getinfo.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
#include "http_digest.h"
|
#include "http_digest.h"
|
||||||
#include "http_ntlm.h"
|
#include "http_ntlm.h"
|
||||||
#include "http_negotiate.h"
|
#include "http_negotiate.h"
|
||||||
@@ -243,6 +243,7 @@ CURLcode Curl_readrewind(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
|
/* FIX: this is nasty OpenSSL-specific code that really shouldn't be here */
|
||||||
static int data_pending(struct connectdata *conn)
|
static int data_pending(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
if(conn->ssl[FIRSTSOCKET].handle)
|
if(conn->ssl[FIRSTSOCKET].handle)
|
||||||
@@ -269,9 +270,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
ssize_t nread; /* number of bytes read */
|
ssize_t nread; /* number of bytes read */
|
||||||
int didwhat=0;
|
int didwhat=0;
|
||||||
|
|
||||||
int fd_read;
|
curl_socket_t fd_read;
|
||||||
int fd_write;
|
curl_socket_t fd_write;
|
||||||
int select_res;
|
curl_socket_t select_res;
|
||||||
|
|
||||||
curl_off_t contentlength;
|
curl_off_t contentlength;
|
||||||
|
|
||||||
@@ -286,6 +287,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
fd_write = CURL_SOCKET_BAD;
|
fd_write = CURL_SOCKET_BAD;
|
||||||
|
|
||||||
select_res = Curl_select(fd_read, fd_write, 0);
|
select_res = Curl_select(fd_read, fd_write, 0);
|
||||||
|
if(select_res == CSELECT_ERR) {
|
||||||
|
failf(data, "select/poll returned error");
|
||||||
|
return CURLE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* If we still have reading to do, we check if we have a readable
|
/* If we still have reading to do, we check if we have a readable
|
||||||
@@ -394,7 +399,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
|
|
||||||
/* decrease the size of the remaining (supposed) header line */
|
/* decrease the size of the remaining (supposed) header line */
|
||||||
rest_length = (k->end_ptr - k->str)+1;
|
rest_length = (k->end_ptr - k->str)+1;
|
||||||
nread -= rest_length;
|
nread -= (ssize_t)rest_length;
|
||||||
|
|
||||||
k->str = k->end_ptr + 1; /* move past new line */
|
k->str = k->end_ptr + 1; /* move past new line */
|
||||||
|
|
||||||
@@ -519,8 +524,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
data->info.header_size += headerlen;
|
data->info.header_size += (long)headerlen;
|
||||||
conn->headerbytecount += headerlen;
|
conn->headerbytecount += (long)headerlen;
|
||||||
|
|
||||||
conn->deductheadercount =
|
conn->deductheadercount =
|
||||||
(100 == k->httpcode)?conn->headerbytecount:0;
|
(100 == k->httpcode)?conn->headerbytecount:0;
|
||||||
@@ -696,6 +701,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
* fields. */
|
* fields. */
|
||||||
conn->size=0;
|
conn->size=0;
|
||||||
conn->maxdownload=0;
|
conn->maxdownload=0;
|
||||||
|
k->ignorecl = TRUE; /* ignore Content-Length headers */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* nothing */
|
/* nothing */
|
||||||
@@ -712,7 +718,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
the header completely if we get a 416 response as then we're
|
the header completely if we get a 416 response as then we're
|
||||||
resuming a document that we don't get, and this header contains
|
resuming a document that we don't get, and this header contains
|
||||||
info about the true size of the document we didn't get now. */
|
info about the true size of the document we didn't get now. */
|
||||||
if ((k->httpcode != 416) &&
|
if (!k->ignorecl &&
|
||||||
checkprefix("Content-Length:", k->p)) {
|
checkprefix("Content-Length:", k->p)) {
|
||||||
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
|
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
|
||||||
if (data->set.max_filesize &&
|
if (data->set.max_filesize &&
|
||||||
@@ -898,7 +904,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
|
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
|
||||||
&secs);
|
&secs);
|
||||||
if(data->set.get_filetime)
|
if(data->set.get_filetime)
|
||||||
data->info.filetime = k->timeofdoc;
|
data->info.filetime = (long)k->timeofdoc;
|
||||||
}
|
}
|
||||||
else if((checkprefix("WWW-Authenticate:", k->p) &&
|
else if((checkprefix("WWW-Authenticate:", k->p) &&
|
||||||
(401 == k->httpcode)) ||
|
(401 == k->httpcode)) ||
|
||||||
@@ -961,8 +967,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
data->info.header_size += k->hbuflen;
|
data->info.header_size += (long)k->hbuflen;
|
||||||
conn->headerbytecount += k->hbuflen;
|
conn->headerbytecount += (long)k->hbuflen;
|
||||||
|
|
||||||
/* reset hbufp pointer && hbuflen */
|
/* reset hbufp pointer && hbuflen */
|
||||||
k->hbufp = data->state.headerbuff;
|
k->hbufp = data->state.headerbuff;
|
||||||
@@ -1385,7 +1391,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
conn->size - k->bytecount);
|
conn->size - k->bytecount);
|
||||||
return CURLE_PARTIAL_FILE;
|
return CURLE_PARTIAL_FILE;
|
||||||
}
|
}
|
||||||
else if(conn->bits.chunk &&
|
else if(!(conn->bits.no_body) &&
|
||||||
|
conn->bits.chunk &&
|
||||||
(conn->proto.http->chunk.state != CHUNK_STOP)) {
|
(conn->proto.http->chunk.state != CHUNK_STOP)) {
|
||||||
/*
|
/*
|
||||||
* In chunked mode, return an error if the connection is closed prior to
|
* In chunked mode, return an error if the connection is closed prior to
|
||||||
@@ -1499,7 +1506,7 @@ void Curl_single_fdset(struct connectdata *conn,
|
|||||||
*max_fd = -1; /* init */
|
*max_fd = -1; /* init */
|
||||||
if(conn->keep.keepon & KEEP_READ) {
|
if(conn->keep.keepon & KEEP_READ) {
|
||||||
FD_SET(conn->sockfd, read_fd_set);
|
FD_SET(conn->sockfd, read_fd_set);
|
||||||
*max_fd = conn->sockfd;
|
*max_fd = (int)conn->sockfd;
|
||||||
}
|
}
|
||||||
if(conn->keep.keepon & KEEP_WRITE) {
|
if(conn->keep.keepon & KEEP_WRITE) {
|
||||||
FD_SET(conn->writesockfd, write_fd_set);
|
FD_SET(conn->writesockfd, write_fd_set);
|
||||||
@@ -1507,7 +1514,7 @@ void Curl_single_fdset(struct connectdata *conn,
|
|||||||
/* since sockets are curl_socket_t nowadays, we typecast it to int here
|
/* since sockets are curl_socket_t nowadays, we typecast it to int here
|
||||||
to compare it nicely */
|
to compare it nicely */
|
||||||
if((int)conn->writesockfd > *max_fd)
|
if((int)conn->writesockfd > *max_fd)
|
||||||
*max_fd = conn->writesockfd;
|
*max_fd = (int)conn->writesockfd;
|
||||||
}
|
}
|
||||||
/* we don't use exceptions, only touch that one to prevent compiler
|
/* we don't use exceptions, only touch that one to prevent compiler
|
||||||
warnings! */
|
warnings! */
|
||||||
@@ -1551,8 +1558,8 @@ Transfer(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
int fd_read;
|
curl_socket_t fd_read;
|
||||||
int fd_write;
|
curl_socket_t fd_write;
|
||||||
int interval_ms;
|
int interval_ms;
|
||||||
|
|
||||||
interval_ms = 1 * 1000;
|
interval_ms = 1 * 1000;
|
||||||
@@ -1597,20 +1604,17 @@ Transfer(struct connectdata *conn)
|
|||||||
*/
|
*/
|
||||||
CURLcode Curl_pretransfer(struct SessionHandle *data)
|
CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
|
CURLcode res;
|
||||||
if(!data->change.url)
|
if(!data->change.url)
|
||||||
/* we can't do anything wihout URL */
|
/* we can't do anything wihout URL */
|
||||||
return CURLE_URL_MALFORMAT;
|
return CURLE_URL_MALFORMAT;
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
/* Init the SSL session ID cache here. We do it here since we want to do it
|
||||||
{
|
after the *_setopt() calls (that could change the size of the cache) but
|
||||||
/* Init the SSL session ID cache here. We do it here since we want to do
|
before any transfer takes place. */
|
||||||
it after the *_setopt() calls (that could change the size of the cache)
|
res = Curl_ssl_initsessions(data, data->set.ssl.numsessions);
|
||||||
but before any transfer takes place. */
|
|
||||||
CURLcode res = Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
|
|
||||||
if(res)
|
if(res)
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
data->set.followlocation=0; /* reset the location-follow counter */
|
data->set.followlocation=0; /* reset the location-follow counter */
|
||||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||||
|
189
lib/url.c
189
lib/url.c
@@ -102,7 +102,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
|
|||||||
|
|
||||||
#include "formdata.h"
|
#include "formdata.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "ssluse.h"
|
#include "sslgen.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
#include "transfer.h"
|
#include "transfer.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
@@ -154,7 +154,6 @@ static bool ConnectionExists(struct SessionHandle *data,
|
|||||||
struct connectdata **usethis);
|
struct connectdata **usethis);
|
||||||
static long ConnectionStore(struct SessionHandle *data,
|
static long ConnectionStore(struct SessionHandle *data,
|
||||||
struct connectdata *conn);
|
struct connectdata *conn);
|
||||||
static bool safe_strequal(char* str1, char* str2);
|
|
||||||
|
|
||||||
#ifndef USE_ARES
|
#ifndef USE_ARES
|
||||||
/* not for Win32, unless it is cygwin
|
/* not for Win32, unless it is cygwin
|
||||||
@@ -211,11 +210,8 @@ CURLcode Curl_close(struct SessionHandle *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SSLEAY
|
|
||||||
/* Close down all open SSL info and sessions */
|
/* Close down all open SSL info and sessions */
|
||||||
Curl_SSL_Close_All(data);
|
Curl_ssl_close_all(data);
|
||||||
#endif
|
|
||||||
|
|
||||||
Curl_safefree(data->state.first_host);
|
Curl_safefree(data->state.first_host);
|
||||||
Curl_safefree(data->state.scratch);
|
Curl_safefree(data->state.scratch);
|
||||||
|
|
||||||
@@ -832,7 +828,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
{
|
{
|
||||||
long auth = va_arg(param, long);
|
long auth = va_arg(param, long);
|
||||||
/* switch off bits we can't support */
|
/* switch off bits we can't support */
|
||||||
#if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
|
#ifndef USE_NTLM
|
||||||
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GSSAPI
|
#ifndef HAVE_GSSAPI
|
||||||
@@ -852,7 +848,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
{
|
{
|
||||||
long auth = va_arg(param, long);
|
long auth = va_arg(param, long);
|
||||||
/* switch off bits we can't support */
|
/* switch off bits we can't support */
|
||||||
#ifndef USE_SSLEAY
|
#ifndef USE_NTLM
|
||||||
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_GSSAPI
|
#ifndef HAVE_GSSAPI
|
||||||
@@ -1153,14 +1149,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
*/
|
*/
|
||||||
argptr = va_arg(param, char *);
|
argptr = va_arg(param, char *);
|
||||||
if (argptr && argptr[0])
|
if (argptr && argptr[0])
|
||||||
result = Curl_SSL_set_engine(data, argptr);
|
result = Curl_ssl_set_engine(data, argptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_SSLENGINE_DEFAULT:
|
case CURLOPT_SSLENGINE_DEFAULT:
|
||||||
/*
|
/*
|
||||||
* flag to set engine as default.
|
* flag to set engine as default.
|
||||||
*/
|
*/
|
||||||
result = Curl_SSL_set_engine_default(data);
|
result = Curl_ssl_set_engine_default(data);
|
||||||
break;
|
break;
|
||||||
case CURLOPT_CRLF:
|
case CURLOPT_CRLF:
|
||||||
/*
|
/*
|
||||||
@@ -1446,13 +1442,11 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
|
|
||||||
data->state.authproxy.done = FALSE;
|
data->state.authproxy.done = FALSE;
|
||||||
data->state.authproxy.picked =
|
data->state.authproxy.picked =
|
||||||
data->state.authhost.want;
|
data->state.authproxy.want;
|
||||||
|
|
||||||
data->state.authproblem = FALSE;
|
data->state.authproblem = FALSE;
|
||||||
|
|
||||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
|
|
||||||
Curl_ntlm_cleanup(conn);
|
Curl_ntlm_cleanup(conn);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->curl_disconnect)
|
if(conn->curl_disconnect)
|
||||||
@@ -1481,7 +1475,7 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
|||||||
freed with idn_free() since this was
|
freed with idn_free() since this was
|
||||||
allocated by libidn */
|
allocated by libidn */
|
||||||
#endif
|
#endif
|
||||||
Curl_SSL_Close(conn);
|
Curl_ssl_close(conn);
|
||||||
|
|
||||||
/* close possibly still open sockets */
|
/* close possibly still open sockets */
|
||||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
|
||||||
@@ -1754,7 +1748,7 @@ static int handleSock5Proxy(const char *proxy_name,
|
|||||||
ssize_t written;
|
ssize_t written;
|
||||||
int result;
|
int result;
|
||||||
CURLcode code;
|
CURLcode code;
|
||||||
int sock = conn->sock[FIRSTSOCKET];
|
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||||
|
|
||||||
Curl_nonblock(sock, FALSE);
|
Curl_nonblock(sock, FALSE);
|
||||||
|
|
||||||
@@ -2223,7 +2217,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
char *at;
|
char *at;
|
||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
struct connectdata *conn;
|
struct connectdata *conn;
|
||||||
struct connectdata *conn_temp;
|
struct connectdata *conn_temp = NULL;
|
||||||
size_t urllen;
|
size_t urllen;
|
||||||
struct Curl_dns_entry *hostaddr;
|
struct Curl_dns_entry *hostaddr;
|
||||||
#if defined(HAVE_ALARM) && !defined(USE_ARES)
|
#if defined(HAVE_ALARM) && !defined(USE_ARES)
|
||||||
@@ -2419,10 +2413,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
|
|
||||||
if(checkprefix("GOPHER.", conn->host.name))
|
if(checkprefix("GOPHER.", conn->host.name))
|
||||||
strcpy(conn->protostr, "gopher");
|
strcpy(conn->protostr, "gopher");
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSL
|
||||||
else if(checkprefix("FTPS", conn->host.name))
|
else if(checkprefix("FTPS", conn->host.name))
|
||||||
strcpy(conn->protostr, "ftps");
|
strcpy(conn->protostr, "ftps");
|
||||||
#endif /* USE_SSLEAY */
|
#endif /* USE_SSL */
|
||||||
else if(checkprefix("FTP.", conn->host.name))
|
else if(checkprefix("FTP.", conn->host.name))
|
||||||
strcpy(conn->protostr, "ftp");
|
strcpy(conn->protostr, "ftp");
|
||||||
else if(checkprefix("TELNET.", conn->host.name))
|
else if(checkprefix("TELNET.", conn->host.name))
|
||||||
@@ -2713,8 +2707,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
|
|
||||||
if (strequal(conn->protostr, "HTTP")) {
|
if (strequal(conn->protostr, "HTTP")) {
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_HTTP;
|
||||||
data->set.use_port:PORT_HTTP;
|
|
||||||
conn->remote_port = PORT_HTTP;
|
conn->remote_port = PORT_HTTP;
|
||||||
conn->protocol |= PROT_HTTP;
|
conn->protocol |= PROT_HTTP;
|
||||||
conn->curl_do = Curl_http;
|
conn->curl_do = Curl_http;
|
||||||
@@ -2728,10 +2721,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (strequal(conn->protostr, "HTTPS")) {
|
else if (strequal(conn->protostr, "HTTPS")) {
|
||||||
#if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
|
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
|
||||||
|
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_HTTPS;
|
||||||
data->set.use_port:PORT_HTTPS;
|
|
||||||
conn->remote_port = PORT_HTTPS;
|
conn->remote_port = PORT_HTTPS;
|
||||||
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
||||||
|
|
||||||
@@ -2740,16 +2732,15 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
conn->curl_done = Curl_http_done;
|
conn->curl_done = Curl_http_done;
|
||||||
conn->curl_connect = Curl_http_connect;
|
conn->curl_connect = Curl_http_connect;
|
||||||
|
|
||||||
#else /* USE_SSLEAY */
|
#else /* USE_SS */
|
||||||
failf(data, LIBCURL_NAME
|
failf(data, LIBCURL_NAME
|
||||||
" was built with SSL disabled, https: not supported!");
|
" was built with SSL disabled, https: not supported!");
|
||||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
#endif /* !USE_SSLEAY */
|
#endif /* !USE_SSL */
|
||||||
}
|
}
|
||||||
else if (strequal(conn->protostr, "GOPHER")) {
|
else if (strequal(conn->protostr, "GOPHER")) {
|
||||||
#ifndef CURL_DISABLE_GOPHER
|
#ifndef CURL_DISABLE_GOPHER
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_GOPHER;
|
||||||
data->set.use_port:PORT_GOPHER;
|
|
||||||
conn->remote_port = PORT_GOPHER;
|
conn->remote_port = PORT_GOPHER;
|
||||||
/* Skip /<item-type>/ in path if present */
|
/* Skip /<item-type>/ in path if present */
|
||||||
if (isdigit((int)conn->path[1])) {
|
if (isdigit((int)conn->path[1])) {
|
||||||
@@ -2774,7 +2765,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
int port = PORT_FTP;
|
int port = PORT_FTP;
|
||||||
|
|
||||||
if(strequal(conn->protostr, "FTPS")) {
|
if(strequal(conn->protostr, "FTPS")) {
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSL
|
||||||
conn->protocol |= PROT_FTPS|PROT_SSL;
|
conn->protocol |= PROT_FTPS|PROT_SSL;
|
||||||
conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
|
conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
|
||||||
port = PORT_FTPS;
|
port = PORT_FTPS;
|
||||||
@@ -2782,11 +2773,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
failf(data, LIBCURL_NAME
|
failf(data, LIBCURL_NAME
|
||||||
" was built with SSL disabled, ftps: not supported!");
|
" was built with SSL disabled, ftps: not supported!");
|
||||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
#endif /* !USE_SSLEAY */
|
#endif /* !USE_SSL */
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = port;
|
||||||
data->set.use_port:port;
|
|
||||||
conn->remote_port = port;
|
conn->remote_port = port;
|
||||||
conn->protocol |= PROT_FTP;
|
conn->protocol |= PROT_FTP;
|
||||||
|
|
||||||
@@ -2858,8 +2848,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
/* telnet testing factory */
|
/* telnet testing factory */
|
||||||
conn->protocol |= PROT_TELNET;
|
conn->protocol |= PROT_TELNET;
|
||||||
|
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_TELNET;
|
||||||
data->set.use_port: PORT_TELNET;
|
|
||||||
conn->remote_port = PORT_TELNET;
|
conn->remote_port = PORT_TELNET;
|
||||||
conn->curl_do = Curl_telnet;
|
conn->curl_do = Curl_telnet;
|
||||||
conn->curl_done = Curl_telnet_done;
|
conn->curl_done = Curl_telnet_done;
|
||||||
@@ -2871,8 +2860,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
else if (strequal(conn->protostr, "DICT")) {
|
else if (strequal(conn->protostr, "DICT")) {
|
||||||
#ifndef CURL_DISABLE_DICT
|
#ifndef CURL_DISABLE_DICT
|
||||||
conn->protocol |= PROT_DICT;
|
conn->protocol |= PROT_DICT;
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_DICT;
|
||||||
data->set.use_port:PORT_DICT;
|
|
||||||
conn->remote_port = PORT_DICT;
|
conn->remote_port = PORT_DICT;
|
||||||
conn->curl_do = Curl_dict;
|
conn->curl_do = Curl_dict;
|
||||||
conn->curl_done = NULL; /* no DICT-specific done */
|
conn->curl_done = NULL; /* no DICT-specific done */
|
||||||
@@ -2884,8 +2872,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
else if (strequal(conn->protostr, "LDAP")) {
|
else if (strequal(conn->protostr, "LDAP")) {
|
||||||
#ifndef CURL_DISABLE_LDAP
|
#ifndef CURL_DISABLE_LDAP
|
||||||
conn->protocol |= PROT_LDAP;
|
conn->protocol |= PROT_LDAP;
|
||||||
conn->port = (data->set.use_port && data->state.allow_port)?
|
conn->port = PORT_LDAP;
|
||||||
data->set.use_port:PORT_LDAP;
|
|
||||||
conn->remote_port = PORT_LDAP;
|
conn->remote_port = PORT_LDAP;
|
||||||
conn->curl_do = Curl_ldap;
|
conn->curl_do = Curl_ldap;
|
||||||
conn->curl_done = NULL; /* no LDAP-specific done */
|
conn->curl_done = NULL; /* no LDAP-specific done */
|
||||||
@@ -3098,7 +3085,31 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
else
|
else
|
||||||
tmp = strrchr(conn->host.name, ':');
|
tmp = strrchr(conn->host.name, ':');
|
||||||
|
|
||||||
if (tmp) {
|
if(data->set.use_port && data->state.allow_port) {
|
||||||
|
/* if set, we use this and ignore the port possibly given in the URL */
|
||||||
|
conn->remote_port = (unsigned short)data->set.use_port;
|
||||||
|
if(tmp)
|
||||||
|
*tmp = '\0'; /* cut off the name there anyway - if there was a port
|
||||||
|
number - since the port number is to be ignored! */
|
||||||
|
if(conn->bits.httpproxy) {
|
||||||
|
/* we need to create new URL with the new port number */
|
||||||
|
char *url;
|
||||||
|
|
||||||
|
url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port,
|
||||||
|
conn->path);
|
||||||
|
if(!url)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
if(data->change.url_alloc)
|
||||||
|
free(data->change.url);
|
||||||
|
|
||||||
|
data->change.url = url;
|
||||||
|
data->change.url_alloc = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tmp) {
|
||||||
|
/* no CURLOPT_PORT given, extract the one from the URL */
|
||||||
|
|
||||||
char *rest;
|
char *rest;
|
||||||
unsigned long port;
|
unsigned long port;
|
||||||
|
|
||||||
@@ -3136,16 +3147,24 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
user, passwd);
|
user, passwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn->bits.netrc = FALSE;
|
||||||
if (data->set.use_netrc != CURL_NETRC_IGNORED) {
|
if (data->set.use_netrc != CURL_NETRC_IGNORED) {
|
||||||
if(Curl_parsenetrc(conn->host.name,
|
if(Curl_parsenetrc(conn->host.name,
|
||||||
user, passwd,
|
user, passwd,
|
||||||
data->set.netrc_file)) {
|
data->set.netrc_file)) {
|
||||||
infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n",
|
infof(data, "Couldn't find host %s in the " DOT_CHAR
|
||||||
|
"netrc file, using defaults\n",
|
||||||
conn->host.name);
|
conn->host.name);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
/* set bits.netrc TRUE to remember that we got the name from a .netrc
|
||||||
|
file, so that it is safe to use even if we followed a Location: to a
|
||||||
|
different host or similar. */
|
||||||
|
conn->bits.netrc = TRUE;
|
||||||
|
|
||||||
conn->bits.user_passwd = 1; /* enable user+password */
|
conn->bits.user_passwd = 1; /* enable user+password */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If our protocol needs a password and we have none, use the defaults */
|
/* If our protocol needs a password and we have none, use the defaults */
|
||||||
if ( (conn->protocol & PROT_FTP) &&
|
if ( (conn->protocol & PROT_FTP) &&
|
||||||
@@ -3354,9 +3373,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
#ifdef HAVE_ALARM
|
#ifdef HAVE_ALARM
|
||||||
/* alarm() makes a signal get sent when the timeout fires off, and that
|
/* alarm() makes a signal get sent when the timeout fires off, and that
|
||||||
will abort system calls */
|
will abort system calls */
|
||||||
prev_alarm = alarm(data->set.connecttimeout?
|
prev_alarm = alarm((unsigned int) (data->set.connecttimeout?
|
||||||
data->set.connecttimeout:
|
data->set.connecttimeout:
|
||||||
data->set.timeout);
|
data->set.timeout));
|
||||||
/* We can expect the conn->created time to be "now", as that was just
|
/* We can expect the conn->created time to be "now", as that was just
|
||||||
recently set in the beginning of this function and nothing slow
|
recently set in the beginning of this function and nothing slow
|
||||||
has been done since then until now. */
|
has been done since then until now. */
|
||||||
@@ -3739,89 +3758,3 @@ CURLcode Curl_do_more(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool safe_strequal(char* str1, char* str2)
|
|
||||||
{
|
|
||||||
if(str1 && str2)
|
|
||||||
/* both pointers point to something then compare them */
|
|
||||||
return strequal(str1, str2);
|
|
||||||
else
|
|
||||||
/* if both pointers are NULL then treat them as equal */
|
|
||||||
return (!str1 && !str2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Curl_ssl_config_matches(struct ssl_config_data* data,
|
|
||||||
struct ssl_config_data* needle)
|
|
||||||
{
|
|
||||||
if((data->version == needle->version) &&
|
|
||||||
(data->verifypeer == needle->verifypeer) &&
|
|
||||||
(data->verifyhost == needle->verifyhost) &&
|
|
||||||
safe_strequal(data->CApath, needle->CApath) &&
|
|
||||||
safe_strequal(data->CAfile, needle->CAfile) &&
|
|
||||||
safe_strequal(data->random_file, needle->random_file) &&
|
|
||||||
safe_strequal(data->egdsocket, needle->egdsocket) &&
|
|
||||||
safe_strequal(data->cipher_list, needle->cipher_list))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Curl_clone_ssl_config(struct ssl_config_data *source,
|
|
||||||
struct ssl_config_data *dest)
|
|
||||||
{
|
|
||||||
dest->verifyhost = source->verifyhost;
|
|
||||||
dest->verifypeer = source->verifypeer;
|
|
||||||
dest->version = source->version;
|
|
||||||
|
|
||||||
if(source->CAfile) {
|
|
||||||
dest->CAfile = strdup(source->CAfile);
|
|
||||||
if(!dest->CAfile)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source->CApath) {
|
|
||||||
dest->CApath = strdup(source->CApath);
|
|
||||||
if(!dest->CApath)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source->cipher_list) {
|
|
||||||
dest->cipher_list = strdup(source->cipher_list);
|
|
||||||
if(!dest->cipher_list)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source->egdsocket) {
|
|
||||||
dest->egdsocket = strdup(source->egdsocket);
|
|
||||||
if(!dest->egdsocket)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source->random_file) {
|
|
||||||
dest->random_file = strdup(source->random_file);
|
|
||||||
if(!dest->random_file)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl_free_ssl_config(struct ssl_config_data* sslc)
|
|
||||||
{
|
|
||||||
if(sslc->CAfile)
|
|
||||||
free(sslc->CAfile);
|
|
||||||
|
|
||||||
if(sslc->CApath)
|
|
||||||
free(sslc->CApath);
|
|
||||||
|
|
||||||
if(sslc->cipher_list)
|
|
||||||
free(sslc->cipher_list);
|
|
||||||
|
|
||||||
if(sslc->egdsocket)
|
|
||||||
free(sslc->egdsocket);
|
|
||||||
|
|
||||||
if(sslc->random_file)
|
|
||||||
free(sslc->random_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user