Compare commits

..

240 Commits

Author SHA1 Message Date
Daniel Stenberg
55225106b6 Version 7.14.0 2005-05-16 12:58:41 +00:00
Daniel Stenberg
1a31bff9fe return, not exit, on several places 2005-05-16 07:07:00 +00:00
Dominick Meglio
4eaa3329ec Converted some macros to use NS_* so they work on non-IPv6 systems 2005-05-15 16:31:01 +00:00
Dominick Meglio
028d78b993 Forgot to ares_-ize inet_ntop 2005-05-15 04:38:53 +00:00
Daniel Stenberg
944af98be6 fix warning about redefined symbol 2005-05-14 21:15:36 +00:00
Daniel Stenberg
2789b2b0ad replaced the CRLF newlines with plain LF ones 2005-05-14 20:45:49 +00:00
Dominick Meglio
7dded571de Added an inet_ntop function from BIND for systems that do not have it 2005-05-14 18:35:20 +00:00
Gisle Vanem
95fe8372e8 Updated generated dependencies. 2005-05-14 06:04:21 +00:00
Gisle Vanem
ecdcb0ef67 Some patches for (a stricter/smarter) gcc 4.0 and
warnings like:
  'x' may be used uninitialized in this function.
2005-05-14 06:00:40 +00:00
Gisle Vanem
6a04a03eb5 'ssize_t' seems to be a gcc 4.x built-in. 2005-05-14 05:59:26 +00:00
Gisle Vanem
0c96056a94 Change for systems with >1 ways of setting (non-)blocking
mode. (djgpp/Watt-32 has 3 ways). Should rewrite this using
"#elif ..", but maybe there is still broken cpp around?
2005-05-14 05:58:52 +00:00
Daniel Stenberg
f518a5e231 updated 2005-05-13 23:00:06 +00:00
Daniel Stenberg
f581c1062e uses select() instead of poll() even on Mac OS X 10.4 2005-05-13 22:24:50 +00:00
Daniel Stenberg
0b3deceea3 adjusted the configure to always skip the fine-poll() test on Mac OS X (darwin) 2005-05-13 21:19:21 +00:00
Daniel Stenberg
fa4cd8868c remove blank lines 2005-05-12 21:56:26 +00:00
Daniel Stenberg
8c573ca7f3 CURLOPT_SSLVERSION clarified 2005-05-12 21:49:42 +00:00
Daniel Stenberg
5a5cf3a51d -z bad use warning and NTLM proxy auth in reconnect fix 2005-05-12 14:00:27 +00:00
Daniel Stenberg
3f23e8443e oops, found by bug reported in bug report #1200661 2005-05-12 13:44:25 +00:00
Daniel Stenberg
a00f9b093c spell 2005-05-12 12:53:02 +00:00
Daniel Stenberg
5f538ce3f8 typecast to fix warning on 64bit systems 2005-05-12 08:51:30 +00:00
Daniel Stenberg
ebcaa3d579 warn about bad -z syntax 2005-05-12 07:28:03 +00:00
Daniel Stenberg
60e26199a2 MatrixSSL and yaSSL are two free libs we _could_ support 2005-05-11 11:56:04 +00:00
Daniel Stenberg
11defd180c mention the select() error fix as well 2005-05-11 10:23:59 +00:00
Daniel Stenberg
c82c1691ee the new HTTP headers 2005-05-11 09:56:53 +00:00
Daniel Stenberg
364562f209 removed duplicate 2005-05-11 09:56:10 +00:00
Daniel Stenberg
5d9fc28fa7 Modified the default HTTP headers used by libcurl:
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"
2005-05-11 09:52:59 +00:00
Daniel Stenberg
e5ec5c284f prevent NS_IN6ADDRSZ from getting set to zero if the struct doesn't exist 2005-05-11 06:47:09 +00:00
Daniel Stenberg
a90e33ad71 Hm, this doesn't feel right. The error bits returned from Curl_select() can
be returned at times when we want to ignore them. Test case 160 fails on Linux,
so I modify the comparison to check for _only_ the error bit set...
2005-05-10 23:02:37 +00:00
Daniel Stenberg
62ab21ce7d me stupid, errno is not set for mere select()-exceptions 2005-05-10 22:48:26 +00:00
Daniel Stenberg
cc8e8db1e5 include protos to fix warnings 2005-05-10 22:46:24 +00:00
Daniel Stenberg
b19cba2016 If Curl_select() returns with the error bit set, bail out. 2005-05-10 22:44:08 +00:00
Daniel Stenberg
315a9c95d5 prevent 64bit warnings 2005-05-10 11:21:57 +00:00
Daniel Stenberg
e010ac9706 allow the ares/config.h display to fail 2005-05-10 11:19:12 +00:00
Daniel Stenberg
e4c0a85da0 Jeremy Brown's OpenSSL thread-locking example 2005-05-09 21:12:03 +00:00
Daniel Stenberg
d3e4cdd5b0 new counter 2005-05-09 13:57:58 +00:00
Daniel Stenberg
763b812dc7 Jamie Lokier added. And I now recounted the amount better: 437 named as of now. 2005-05-09 13:53:42 +00:00
Daniel Stenberg
3269dfb4ab update the "PORTS" section a little 2005-05-09 13:26:41 +00:00
Daniel Stenberg
e816bd259f add multi-thread details for GnuTLS 2005-05-09 13:13:38 +00:00
Daniel Stenberg
a295408e09 new mirror, added amount of contributors 2005-05-09 12:34:55 +00:00
Daniel Stenberg
42a34c7cd7 Jeff is short for Jeffrey 2005-05-09 11:43:23 +00:00
Daniel Stenberg
9a72751958 updated with the current RELEASE-NOTES names 2005-05-09 11:39:20 +00:00
Daniel Stenberg
314e6fa80b I decided to make this list more complete. I took the 5-year anniversary list
from 2003 and added all names from all release notes in the CVS (there is a
slight gap though). I removed names with only first names (Like "Chris" and
"Ralph") , as that won't make anyone happy and we might list their full names
as well anyway.

This list is now intended to include _all_ people that contribute: big or
small. 389 names at the time of this commit.
2005-05-09 09:11:39 +00:00
Daniel Stenberg
b2b66f749a no need to display src/config.h anymore since it is a duplicate of lib/config.h
but we could use having a look at ares/config.h when that is used
2005-05-09 07:45:30 +00:00
Daniel Stenberg
708ed6fded silence compiler warnings 2005-05-08 22:45:01 +00:00
Daniel Stenberg
5c30fa50d6 fix warnings about unused variables for non-debug builds 2005-05-07 20:41:16 +00:00
Daniel Stenberg
fc33c424d9 fix 2005-05-07 20:28:39 +00:00
Daniel Stenberg
b04d6dd0b1 January 2003. Started working on the distributed curl tests. The autobuilds. 2005-05-07 14:23:32 +00:00
Daniel Stenberg
9c5f79c56a DEBUGF() is a new conveniant macro to add infof() calls (or similar) for
debug builds only. Made the ftp code use it on several places.
2005-05-07 13:57:07 +00:00
Daniel Stenberg
ef5eea689a Added an active disconnected state, to make the code clearer. 2005-05-07 13:52:07 +00:00
Daniel Stenberg
fd191deb49 removed unnecessary logging to ease REAL debuggin 2005-05-07 08:55:37 +00:00
Daniel Stenberg
e1da1ff7d3 one more command line option, fixed the AIX 4.3 enabled IPv6 build (it now
detects a bad Ipv6 situation and disables it automatically)
2005-05-06 23:46:35 +00:00
Daniel Stenberg
2b00ed7ef8 Added two test cases for multipart formpost over a proxy with --anyauth. Our
HTTP test server is a bit limited though, as it never responds to the POST
request until all data has been sent (and received)...
2005-05-06 23:22:33 +00:00
Daniel Stenberg
d960ea959d When a server is clearly running, curl is now invoked to verify that it can
download a file from the server before the server is considered fine to use
for the given test case. This should fix the cases where the server can run
but curl cannot work with it.
2005-05-06 23:21:34 +00:00
Daniel Stenberg
274842ec41 use calloc instead of malloc to save a call to memset() 2005-05-05 06:04:00 +00:00
Daniel Stenberg
c06da7c84a now add --trace-time by default for curl tests 2005-05-04 21:58:47 +00:00
Daniel Stenberg
cea117b509 removed lots of (now) redundant logging 2005-05-04 21:57:07 +00:00
Daniel Stenberg
6078c938b2 modify a value we are allowed to 2005-05-04 21:51:09 +00:00
Daniel Stenberg
9e95dd4821 improved logging (all FTP protocol data, both ways) to possibly help us realize
why sometimes the control connection dies after a RETR has been sent
2005-05-04 21:49:30 +00:00
Daniel Stenberg
0cc8b57d4f towards 7.14.0 - really 2005-05-04 15:11:09 +00:00
Daniel Stenberg
2179e6e797 prevent memory leak when built SSL disabled 2005-05-04 14:52:51 +00:00
Daniel Stenberg
7dde3d1825 *MAN* was this hard to track down. Had I just read the docs properly from the
start... Anyway, fork() + exec() makes _two_ pids (in perl) that we need to
track and kill after use. Thankyouverymuch.
2005-05-03 23:14:43 +00:00
Daniel Stenberg
a0fe950b75 add more info to the log to ease debugging 2005-05-03 23:13:24 +00:00
Daniel Stenberg
44985e8884 improved failf() error messages 2005-05-02 22:53:55 +00:00
Daniel Stenberg
f03366bcbf the new functions and the upcoming ipv6 calls for the next version to become
1.3.0
2005-05-02 22:33:57 +00:00
Daniel Stenberg
d43ea83033 corrected copyright years 2005-05-02 14:33:58 +00:00
Daniel Stenberg
11bdba0007 corrected copyright year 2005-05-02 14:33:07 +00:00
Daniel Stenberg
07e58aaa79 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.
2005-05-02 14:06:27 +00:00
Daniel Stenberg
a31ddd363b Now configure checks for struct sockaddr_storage and the ftp code tries
to survive without it if not found. AIX 4.3 targetted adjustment.
2005-05-02 11:56:15 +00:00
Daniel Stenberg
ed9e10f2d8 another <case> converted to sysread 2005-05-02 11:55:17 +00:00
Daniel Stenberg
02ae3c2810 read from the open2 filehandle with sysread, not <handle> 2005-05-02 11:31:15 +00:00
Daniel Stenberg
669ebb5f71 Fixed the FTP server read stuff when waiting for a connect after a PASV/EPSV.
Made the ftp server use the passed in pidfile name, and made runtests.pl
pass it in properly.
2005-05-02 10:22:09 +00:00
Daniel Stenberg
9a3e0e52cb fix the server for the slow response case 2005-05-02 10:03:12 +00:00
Daniel Stenberg
b0f856213d 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.
2005-05-02 09:38:19 +00:00
Daniel Stenberg
6f4ff1f2bf When starting the ftp server, wait a few seconds to make really sure that
a pidfile for the server appears as otherwise it failed.
2005-05-02 09:08:44 +00:00
Daniel Stenberg
d3eea61f1f Make sure there's no pidfile if we cannot start the initial sockfilt tool -
this happens for some ipv6-enabled hosts on which sockfilt cannot listen
on ipv6.
2005-05-02 09:08:02 +00:00
Daniel Stenberg
d59d81fae8 two bugfixes, one change and one test script modification 2005-05-02 08:40:20 +00:00
Daniel Stenberg
329ca40b6f two bugs, one change 2005-05-02 07:59:47 +00:00
Daniel Stenberg
e71bd416f4 blank a few more environment variables before running a test 2005-05-02 07:54:25 +00:00
Daniel Stenberg
ad66fc6cc2 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.
2005-05-02 07:53:25 +00:00
Daniel Stenberg
d12b44204b Bryan Henderson's fine update of SSL_VERIFYPEER and SSL_VERIFYHOST 2005-05-02 07:28:40 +00:00
Daniel Stenberg
4be2136de4 prevent two compiler warnings on comparisons between signed and unsigned 2005-05-01 23:16:51 +00:00
Daniel Stenberg
c4dbed040b fixed to use fork()+exec() to start test servers 2005-05-01 13:20:53 +00:00
Daniel Stenberg
366b62af2d always use the libcurl-provided *printf() functions 2005-05-01 12:56:09 +00:00
Daniel Stenberg
a6955aa486 util.h added as "source" to make it get added in dist archives 2005-05-01 12:51:27 +00:00
Daniel Stenberg
ad30341fa2 logfile name is const 2005-04-30 23:35:51 +00:00
Daniel Stenberg
23da55a9f1 Moved common code to util.[ch] instead of having it duplicated in sws.c
and sockfilt.c. For good-to-have functions for the servers written in C.
2005-04-30 23:30:55 +00:00
Daniel Stenberg
41e6292e7b there cannot be chunked problem when no_body (HEAD) is true since without
body there is nothing chunked-encoded!
2005-04-30 23:07:38 +00:00
Daniel Stenberg
ae1d6f29d9 singleipconnect() returns a socket descriptor, not a CURLcode (but perhaps
we should make it do that...)
2005-04-30 15:16:39 +00:00
Daniel Stenberg
ccfc1ddbef more fixes 2005-04-29 12:34:53 +00:00
Daniel Stenberg
002de1eae2 Updated with (new and old) default config file search path explanation. 2005-04-28 21:26:30 +00:00
Daniel Stenberg
63621bae81 Set mode text on the section that is written by curl in text mode, to allow
the runtests.pl to check this differently on operating systems that
differentiate on this.
2005-04-28 21:07:07 +00:00
Daniel Stenberg
85f9e6c4b9 basic signal handler for sigint and sigkill 2005-04-28 21:06:17 +00:00
Daniel Stenberg
967ec296c0 fixed the attribute parser to better handle multiple ones, with or without
quotes around the contents
2005-04-28 21:05:40 +00:00
Daniel Stenberg
c6aae9b1d7 moved two functions to ftp.pm, made some more changes on stopping servers
and fixed the textmode attribute thing for windows a bit
2005-04-28 21:04:58 +00:00
Daniel Stenberg
913c370c25 moved in functions from runtests.pl to enable the ftpserver to use the
killslaves function
2005-04-28 21:04:08 +00:00
Daniel Stenberg
e5472bbd21 AF_INET6 for ipv6 addresses! 2005-04-28 14:31:25 +00:00
Daniel Stenberg
957c258c6d no, the kill servers messages need to be verbose, they're too frequent 2005-04-28 14:25:48 +00:00
Daniel Stenberg
abee109cd1 display killed pids to make it easier to see for autobuilds etc 2005-04-28 14:03:08 +00:00
Daniel Stenberg
502e5ae6e1 historic thing we will not use 2005-04-28 13:55:34 +00:00
Daniel Stenberg
b8417be1f2 removed ftpsserver.pl 2005-04-28 13:55:16 +00:00
Daniel Stenberg
9e037431b4 When staring a HTTP server, use the pidfile preferably since it turns out
sometimes the server can start but curl cannot speak to it, and then we must
remember the server (in order to kill it properly) anyway.

Also, make sure to kill all servers on exit everywhere.
2005-04-28 13:54:48 +00:00
Daniel Stenberg
f71b3676bb ignore more generated files 2005-04-28 11:22:18 +00:00
Daniel Stenberg
50fe7b5e35 remove unused ftps-server code and fixed two warnings 2005-04-28 08:23:25 +00:00
Daniel Stenberg
9fb253388b if diff -u makes zero output, try diff -c instead 2005-04-28 08:20:33 +00:00
Daniel Stenberg
8cf1786296 kill slave processes when they fail 2005-04-28 07:36:55 +00:00
Daniel Stenberg
51b17b299c 1. no longer ask the server for the HTTPS pid, as it returns the HTTP pid
(problem identified by Dan F)
2. initial text mode fix for file checks, to allow better text file testing
on windows (with regard to line endings)
3. fixed to use the proper ftpserver pidfile to find pid
2005-04-28 06:50:42 +00:00
Daniel Stenberg
78882e4642 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.
2005-04-27 21:24:58 +00:00
Daniel Stenberg
8465a367a4 listen(..., 1) as 0 doesn't work on Tru64! 2005-04-27 12:28:04 +00:00
Daniel Stenberg
3bcfe678ab display listening port in log 2005-04-27 12:27:23 +00:00
Daniel Stenberg
d5403f3a5b show what error codes we test for too, and show 10 test case numbers 2005-04-27 10:12:41 +00:00
Daniel Stenberg
26abb48533 keyword update 2005-04-27 09:59:47 +00:00
Daniel Stenberg
177848ed27 detect SSL library properly and display it on startup 2005-04-27 09:59:29 +00:00
Daniel Stenberg
656a2e93d7 fixing 2005-04-26 21:47:31 +00:00
Daniel Stenberg
6b1220b61d Cory Nelson's work on nuking compiler warnings when building on x64 with
VS2005.
2005-04-26 13:08:49 +00:00
Daniel Stenberg
9d7330d879 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.
2005-04-26 13:08:18 +00:00
Daniel Stenberg
26a5954fa0 adding a bunch of comments for each #endif 2005-04-26 10:55:52 +00:00
Daniel Stenberg
01165e08e0 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.
2005-04-25 21:39:48 +00:00
Daniel Stenberg
6e1633a6c5 be specific about what max_fd contains after a call 2005-04-25 08:55:55 +00:00
Daniel Stenberg
a8ff0a21bf 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.
2005-04-24 22:25:04 +00:00
Daniel Stenberg
b8bc6bed97 2 days, 4 fixes 2005-04-23 22:08:15 +00:00
Daniel Stenberg
1a4402038c Alex Suykov's ftp upload show progress meter patch, slightly adjusted. 2005-04-23 21:26:27 +00:00
Gunter Knauf
5ac51cc9b5 fix for recent changes. 2005-04-23 11:59:06 +00:00
Daniel Stenberg
c12159ce21 show up to 5 (random) test cases using the keyword 2005-04-22 22:29:48 +00:00
Daniel Stenberg
4485503ecc keywords added 2005-04-22 21:59:08 +00:00
Daniel Stenberg
200ac588cc Dave Dribin: set CURL_STATICLIB when it builds static library variants. 2005-04-22 21:16:22 +00:00
Daniel Stenberg
0bb040822d Andres Garcia's fix for building static curl on windows. 2005-04-22 21:13:27 +00:00
Daniel Stenberg
543fbe14ee Fixed the CN extraction 2005-04-22 20:56:26 +00:00
Daniel Stenberg
e02ab66120 update the copyright year 2005-04-22 20:49:35 +00:00
Daniel Stenberg
76c7c694c5 modified this year 2005-04-22 20:48:07 +00:00
Daniel Stenberg
f0057977b7 ignore the memdump file when showing files after a failure 2005-04-22 20:47:35 +00:00
Daniel Stenberg
e8e43f06af copyright this year 2005-04-22 20:47:21 +00:00
Daniel Stenberg
04b35e86d5 Fixed for Mac OS X builds based on excellent feedback from Heinz Stockinger. 2005-04-22 15:01:02 +00:00
Gunter Knauf
64ab85da4f changes for building with IPV6. 2005-04-22 13:03:17 +00:00
Daniel Stenberg
b8d7a13ea3 modified the test case success reporting, added "test N out of Y" and
"remaining: [time]" outputs to hint users about what to expect
2005-04-22 11:51:06 +00:00
Daniel Stenberg
78a76dc905 test 256 is like test 38 but with proxy + proxy auth 2005-04-22 10:15:21 +00:00
Daniel Stenberg
5fa5fff0e9 keywords 2005-04-22 10:06:58 +00:00
Daniel Stenberg
d323b3d816 Set the retry delay variables after the option parsing, as bug report
#1187787 points out.
2005-04-22 10:01:49 +00:00
Daniel Stenberg
b685b5672a added missing headers 2005-04-21 20:11:31 +00:00
Gunter Knauf
8f6c2f87c8 changes for building with IPV6 and LDAP. 2005-04-20 23:41:25 +00:00
Daniel Stenberg
f30e8b11eb prevent compiler warning 2005-04-19 23:38:57 +00:00
Daniel Stenberg
8bd6d6a4de added typecast when converting from long to unsigned short, to prevent compiler warning 2005-04-19 23:37:45 +00:00
Daniel Stenberg
b3a8f438fc indented source to look more like other ares code,
added (somewhat ugly) typecasts to build warning-free on 64bit platforms (the
result of a (char *) - (char *) cannot be stored in an int universally)
2005-04-19 23:36:21 +00:00
Daniel Stenberg
e78ddf0a95 sortlist_alloc() is never used on win32, so ifdef out it to prevent warning 2005-04-19 23:26:14 +00:00
Daniel Stenberg
5f0366c2cb only define _REENTRANT if not already defined, and only in setup.h 2005-04-19 23:19:23 +00:00
Daniel Stenberg
779ca09775 Check for and config for the ca cert bundle properly when built with GnuTLS.
Previously this was only done for OpenSSL builds.
2005-04-19 22:23:37 +00:00
Daniel Stenberg
313f1a1e83 when --with-gnutls is used, we assume a bin/libgnutls-config file in the
given prefix. Building something with gnutls without it just is too error-
prone.
2005-04-19 22:12:34 +00:00
Daniel Stenberg
21337f4776 remove the warning for a lacking crypto lib since it migth just be a gnutls
build...
2005-04-19 22:03:10 +00:00
Daniel Stenberg
53a8e5655b added CURLOPT_PORT test when using proxy 2005-04-19 08:10:04 +00:00
Daniel Stenberg
2d85585ae1 two bugfixes of today 2005-04-18 19:53:25 +00:00
Daniel Stenberg
63d109f7be 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.
2005-04-18 19:41:04 +00:00
Daniel Stenberg
c904b6b5bf 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.
2005-04-18 17:14:58 +00:00
Daniel Stenberg
6a27449922 digest works in the proxyauth too 2005-04-18 14:32:48 +00:00
Daniel Stenberg
9a9c07f571 Initial curl_multi_socket() stuff, #ifdef'ed out for now but committed for
documentational purposes.
2005-04-18 11:40:50 +00:00
Daniel Stenberg
4382204e1b better fix for the socket -1 case 2005-04-18 08:59:46 +00:00
Daniel Stenberg
6d3114efe2 ignore sockfilt 2005-04-18 08:51:04 +00:00
Daniel Stenberg
b62baaed95 safety measure to avoid using -1 as socket 2005-04-18 08:49:46 +00:00
Daniel Stenberg
9b391e531b allow some more time 2005-04-18 08:49:21 +00:00
Daniel Stenberg
a0c7a6d22b ARGH my stupidity is endless. Ipv4-only hosts don't send EPRT or LPRT. 2005-04-18 07:56:43 +00:00
Daniel Stenberg
14424f7058 Modified the FTP server to use the new 'sockfilt' program to do all the socket
level stuff. The FTP server communicates with sockfilt using perl's open2().
This enables easier IPv6 support and hopefully FTP-SSL support in the future.
Added four test cases for FTP-ipv6.
2005-04-18 06:57:44 +00:00
Daniel Stenberg
6063dff8d0 Modified to not mix ordinary print to STDOUT with a system() that prints to
stdout, since I've found cases on Solaris where the second output mixes with
the first and thus the big check-script doesn't properly find the first
string in the output stream.
2005-04-18 05:46:10 +00:00
Daniel Stenberg
7fba9ed398 somewhat clarified that this only sets the fd_sets and expects them to be
cleared before this function is called
2005-04-17 23:01:46 +00:00
Daniel Stenberg
53280a196b keywords added 2005-04-16 23:15:19 +00:00
Daniel Stenberg
0bf9a5704b minor edits, report the test cases without keywords 2005-04-16 23:15:12 +00:00
Daniel Stenberg
8182d17ae1 starting to produce a summary in HTML 2005-04-16 12:43:32 +00:00
Daniel Stenberg
69b1ac7dcd avoid warning on windows 2005-04-16 12:30:01 +00:00
Daniel Stenberg
b15507aac3 clarify that > in the verbose output can contain newlines 2005-04-16 12:24:12 +00:00
Daniel Stenberg
6c2f583f51 keywords added 2005-04-16 00:00:35 +00:00
Daniel Stenberg
a72eaddda3 initial tool to report info/keywords of the test cases 2005-04-15 23:48:58 +00:00
Daniel Stenberg
dc050e45df started adding "keywords" for each test, to better allow us to sum up what
kind of tests we have and how many tests that test certain features
2005-04-15 23:48:31 +00:00
Daniel Stenberg
2fcbf13920 add needed include 2005-04-15 21:51:46 +00:00
Dominick Meglio
099ae31523 Attempted to fix c-ares not building on non-IPv6 systems 2005-04-15 15:25:16 +00:00
Daniel Stenberg
c2fcdf3a02 if libgnutls-config isn't found in the given path, deal with it nicer (but
it is still likely to not do very good since it can't figure out all the lib
dependencies)
2005-04-15 08:45:35 +00:00
Daniel Stenberg
2056a538b9 Two new slowdown tests for better testing of the FTP response reader function
when the response come in many small chunks.
2005-04-14 22:52:42 +00:00
Daniel Stenberg
cd1144dc24 make the ftp server support reply/servercmd, and make SLOWDOWN work, and
update the docs accordingly
2005-04-14 22:52:08 +00:00
Daniel Stenberg
e9d068b913 oops, only negative numbers are errors 2005-04-13 21:17:05 +00:00
Dan Fandrich
ec2ad57c32 Mention GnuTLS and fix a few spelling errors. 2005-04-13 19:31:00 +00:00
Daniel Stenberg
316adac511 don't bail out just because the ca file has a problem, it might be OK 2005-04-13 12:38:01 +00:00
Daniel Stenberg
d7b11d4c33 fix port number 2005-04-13 12:37:38 +00:00
Daniel Stenberg
c52aa6df33 GnuTLS support 2005-04-13 08:50:13 +00:00
Daniel Stenberg
a19b23b59f extended the multi-thread explanation 2005-04-13 08:47:59 +00:00
Daniel Stenberg
4e26b2a65b fix compiler warning 2005-04-13 06:52:03 +00:00
Dan Fandrich
7c4feac6db Allow environment variables to override default autotools. 2005-04-13 00:32:33 +00:00
Daniel Stenberg
e01e364c37 next release will be version 7.14.0 thanks to the added GnuTLS support 2005-04-12 14:17:07 +00:00
Daniel Stenberg
c13a3d7b84 Provides an unconditional strlcat() proto even if strlcat() was found by
configure. An attempt to fix warnings when we build and the strlcat() function
is provided by one if the libs (gss or krb4) since then we have no protos
for it in a system header.
2005-04-12 07:56:57 +00:00
Daniel Stenberg
67805b6dc5 requires OpenSSL, as our GnuTLS doesn't provide support for
CURLOPT_SSL_CTX_FUNCTION (yet).
2005-04-12 07:19:34 +00:00
Daniel Stenberg
0050ab2a3d support tests that requires 'OpenSSL' specificly 2005-04-12 07:18:48 +00:00
Daniel Stenberg
60e66c6cbf credits 2005-04-11 14:07:02 +00:00
Daniel Stenberg
5ad2a253e8 refresh 2005-04-11 13:50:19 +00:00
Daniel Stenberg
b5d50e9298 5.12 Can I make libcurl fake or hide my real IP address? 2005-04-11 13:39:55 +00:00
Daniel Stenberg
37f7362aca HTTP 304 response with Content-Length: header 2005-04-10 22:56:46 +00:00
Dominick Meglio
bee198def5 Removed usage of u_int and u_char 2005-04-09 23:46:31 +00:00
Daniel Stenberg
f09e479fd6 Blah, revert my removal of the extra check since the problem is there for real.
Archived thread of the help-gnutls mailing list regarding this problem:

http://lists.gnu.org/archive/html/help-gnutls/2005-04/msg00000.html

(and I _am_ sorry for my confused behaviour on this problem.)
2005-04-09 22:33:14 +00:00
Daniel Stenberg
80fe93bc33 OK, I must've been halucinating or something because I no longer see the
bug I thought I saw before when I changed this...!
2005-04-09 21:38:14 +00:00
Dominick Meglio
ea03ad3bee Made sortlist support IPv6 (this can probably use some testing) 2005-04-09 19:59:59 +00:00
Dominick Meglio
feec421744 Made sortlist support CIDR matching for IPv4 2005-04-09 16:49:47 +00:00
Dominick Meglio
634982840e Added preliminary IPv6 support to ares_gethostbyname 2005-04-08 19:46:46 +00:00
Daniel Stenberg
fb3c85ab2f fixed the 304 response-with-content-length problem reported by Cory Nelson 2005-04-08 16:59:13 +00:00
Dominick Meglio
a9b7c3531c Added include for inet_net_pton.h to ares__get_hostent.c 2005-04-08 16:22:51 +00:00
Dominick Meglio
a7ba0d908d Made ares_gethostbyaddr support IPv6 by specifying AF_INET6 as the family 2005-04-08 15:41:31 +00:00
Daniel Stenberg
2fc70e2c5d re-arrange some code to prevent warnings on unreachable code 2005-04-08 09:25:48 +00:00
Daniel Stenberg
7ae3f0e70c include sys/types.h too when checking for headers as otherwise this breaks
on Solaris and FreeBSD. At least.
2005-04-08 08:48:17 +00:00
Marty Kuhrt
9afaa51e3f updated instructions 2005-04-08 05:07:04 +00:00
Marty Kuhrt
c736a719f1 fixed control_y trap problem 2005-04-08 05:06:31 +00:00
Marty Kuhrt
37a547842b cast the call to Curl_inet_ntop for DECC compiler squawk 2005-04-08 05:01:40 +00:00
Daniel Stenberg
b9f1d43921 Unfortunately, if a ca file name is set the function fails for whatever reason
(missing file, bad file, etc), gnutls will no longer handshake properly but it
just loops forever. Therefore, we must return error if we get an error when
setting the CA cert file name. This is not the same behaviour as with OpenSSL.

Question/report posted to the help-gnutls mailing list, April 8 2005.
2005-04-07 22:47:43 +00:00
Daniel Stenberg
bec6423c02 one down 2005-04-07 22:14:22 +00:00
Daniel Stenberg
241b2b4ae3 set LD_LIBRARY_PATH when GnuTLS has been found 2005-04-07 22:13:40 +00:00
Daniel Stenberg
14d9b56937 cut 'n paste error 2005-04-07 21:12:09 +00:00
Daniel Stenberg
1c3766eb46 GnuTLS updates 2005-04-07 21:10:31 +00:00
Daniel Stenberg
70024d61eb GnuTLS! 2005-04-07 21:05:45 +00:00
Daniel Stenberg
2085f133d6 added new files 2005-04-07 20:56:04 +00:00
Daniel Stenberg
2a045dfceb fixed to build after the GnuTLS fixes 2005-04-07 20:36:48 +00:00
Daniel Stenberg
893cbaaf2f added some blurb about the GnuTLS license 2005-04-07 15:28:56 +00:00
Daniel Stenberg
6e61939382 GnuTLS support added. There's now a "generic" SSL layer that we use all over
internally, with code provided by sslgen.c. All SSL-layer-specific code is
then written in ssluse.c (for OpenSSL) and gtls.c (for GnuTLS).

As far as possible, internals should not need to know what SSL layer that is
in use. Building with GnuTLS currently makes two test cases fail.

TODO.gnutls contains a few known outstanding issues for the GnuTLS support.

GnuTLS support is enabled with configure --with-gnutls
2005-04-07 15:27:13 +00:00
Daniel Stenberg
015a618172 ssl_version_num is not used anymore 2005-04-07 15:21:50 +00:00
Daniel Stenberg
2a8b91cdb9 ssl_version_num won't be used anymore since we will soon offer multiple SSL
layers and it won't make sense to provide a numerical version for it. I also
doubt that many people have used this for anything critical.
2005-04-07 15:18:51 +00:00
Daniel Stenberg
bebd5dbc5a Add support for --with-gnutls. If configure detects OpenSSL, you need to
to explicitly disable that first with --without-ssl. Initial attempt.
2005-04-07 15:12:03 +00:00
Daniel Stenberg
018dbfe058 bail out if perl is missing, it is needed for building curl anyway 2005-04-07 14:26:03 +00:00
Daniel Stenberg
c6ea597817 check for libtoolize and aclocal to doublecheck the installations better 2005-04-07 08:59:39 +00:00
Daniel Stenberg
175b00c0a2 Try harder to see if arpa/nameser_compat.h REALLY is a good header file to
include, as it seems at least some AIX versions don't really allow it to be
include at the same time as the original nameser.h.
2005-04-07 07:38:53 +00:00
Daniel Stenberg
5ebc6e305e add SSPI 2005-04-07 07:30:02 +00:00
Daniel Stenberg
993600761f Tupone Alfredo fixed includes of arpa/nameser_compat.h to build fine on Mac OS
X.
2005-04-06 22:27:42 +00:00
Daniel Stenberg
1d9fff80b7 better errno constant replacements, as mentioned by Gisle Vanem 2005-04-06 21:14:58 +00:00
Gisle Vanem
c712b84dd5 Include inet_net_pton.h for 'struct in6_addr'. Ideally this
should come from <ws2tcpip.h>, but Winsock 1.1 should
suffice.
2005-04-06 18:58:33 +00:00
Gisle Vanem
dcf8dd4b5e Moved inet_net_pton.h to HHEADERS. 2005-04-06 18:55:59 +00:00
Daniel Stenberg
ba26c3fb22 check for struct sizes and use those sizes if the NS_* defines are lacking
(IRIX 6.5.22 it seems)
2005-04-06 14:11:50 +00:00
Daniel Stenberg
41563607a8 moved the *_inet_pton protos to inet_net_pton.h instead 2005-04-06 14:02:37 +00:00
Daniel Stenberg
2d4dcfb740 made the ares_inet_net_pton() proto use size_t size, as the function in the
code uses that
2005-04-06 13:54:02 +00:00
Dan Fandrich
34854e70cf Removed extraneous comma 2005-04-06 00:39:48 +00:00
Daniel Stenberg
758d9fe852 too late hacking error 2005-04-05 21:14:59 +00:00
Daniel Stenberg
6a6c0e7a73 test time-conditioned FTP uploads 2005-04-05 21:07:27 +00:00
Daniel Stenberg
ee44eec3e1 Christophe Legry's fix to grok time-conditoned uploads 2005-04-05 20:59:12 +00:00
Daniel Stenberg
eccd0d8e37 with these changes, it builds on my win32 cross-compiler 2005-04-05 20:20:14 +00:00
Daniel Stenberg
983be0ec60 check for another arpa header 2005-04-05 20:19:55 +00:00
Daniel Stenberg
243a45d840 check for the arpa/* headers 2005-04-05 20:08:15 +00:00
Dominick Meglio
60ec804047 Provided implementations of inet_net_pton and inet_pton from BIND for systems that do not include these functions. These will be necessary for CIDR support and IPv6 support. 2005-04-05 18:26:55 +00:00
Daniel Stenberg
c53e9ccf4a 7.13.3 in progress 2005-04-05 15:11:51 +00:00
Daniel Stenberg
6e8e0418fc 5.11 How do I make libcurl not receive the whole HTTP response? 2005-04-05 14:38:38 +00:00
Daniel Stenberg
e9eb52305f two more actual FAQs 2005-04-05 14:36:37 +00:00
Daniel Stenberg
8501ae748c restart with a blank page again 2005-04-05 07:55:41 +00:00
367 changed files with 8709 additions and 2411 deletions

177
CHANGES
View File

@@ -7,6 +7,183 @@
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)
Daniel (4 April 2005)

View File

@@ -1,57 +1,58 @@
Curl and libcurl 7.13.2
Curl and libcurl 7.14.0
Public curl release number: 87
Releases counted from the very beginning: 114
Available command line options: 106
Public curl release number: 88
Releases counted from the very beginning: 115
Available command line options: 107
Available curl_easy_setopt() options: 122
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 contributors: 437
This release includes the following changes:
o Added --form-string
o libcurl can be built with SSPI support. curl_version_info() then returns
a new feature bit: CURL_VERSION_SSPI. configure --enable-sspi added
o Added --proxy-anyauth
o Added runtests.1 and testcurl.1 man pages
o modified default HTTP request headers
o curl --trace-time added for time stamping trace logs
o curl now respects the SSL_CERT_DIR and SSL_CERT_PATH environment variables
o more search paths for curl's default .curlrc config file check
o GnuTLS support, use configure --with-gnutls. Work on this was sponsored
by The Written Word.
This release includes the following bugfixes:
o the MSVC libcurl Makefile was fixed
o libcurl on Windows crash if resolver was active when easy handle was killed
o HTTP POST with auth and an initial 100 response before the 401/407
o configure's SSL-detection for msys/mingw
o better connection keep-alive when POSTing with HTTP Digest
o FTP-SSL
o reading FTP server response in multiple reads
o picking one out of multiple proxy auth methods
o inet_ntoa_r() when built with uClibc
o the so name issue for the LDAP library dynamic load
o crash when using SOCKS4 proxy
o a debug printf() was removed
o CURLOPT_FILETIME when downloading FTP corrupted data
o FTP upload resume now works even if no file is present on the site
o SSL seeding no longer attempts to read the whole random file
o uses select() instead of poll() even on Mac OS X 10.4
o reconnected proxy use with NTLM auth on the same handle
o warns about bad -z date syntax
o docs/THANKS now contains all known contributors
o builds out-of-the-box on (presumably ipv6-enabled) AIX 4.3 hosts
o curl --head could wrongly complain on bad chunked-encoding
o --interface SIGSEGVed on a bad address
o kill the HTTPS server better when stopping the test suite
o builds fine with VS2005 on x64
o auth fix for HTTP redirects and .netrc usage
o FTP uploads show the progress meter easier
o MSVC makefile fixes for static libcurl builds
o configure fix for static libcurl build on Windows
o --retry-delay
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:
o the cURL project is now over 7 years old
o daily curl binary builds for Windows fresh from CVS:
http://cool.haxx.se/curl-daily/
o curl-tracker is a new mailinglist for "tracker" activities:
http://cool.haxx.se/mailman/listinfo/curl-tracker
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
o http://curl.mirroring.de/ is a new german curl mirror
o pycurl 7.13.2: http://pycurl.sf.net/
o TclCurl 0.13.2: http://personal1.iddeo.es/andresgarci/tclcurl/english/
o http://curl.webhosting76.com/ is a new US curl mirror
o http://curl.meulie.net/ is a new Canadian curl mirror
This release would not have looked like this without help, code, reports and
advice from friends like these:
Dan Fandrich, Ignacio Vazquez-Abrams, Randy McMurchy, Dominick Meglio,
Jean-Marc Ranger, Tor Arntsen, Nodak Sodak, David Houlder, Gisle Vanem,
Christopher R. Palmer, Gwenole Beauchesne, Augustus Saunders, Jesper Jensen,
Tom Moers, Andres Garcia, Hardeep Singh, Marcelo Juchem
Christophe Legry, Cory Nelson, Gisle Vanem, Dan Fandrich, Toshiyuki Maezawa,
Olivier, Andres Garcia, Dave Dribin, Alex Suykov, Cory Nelson, Fred New,
Paul Moore, Alexander Zhuravlev, Bryan Henderson, Jeremy Brown, Allan,
Grigory Entin
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,6 +1,11 @@
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
@@ -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
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
@@ -24,7 +29,7 @@ To get fixed in 7.14.0
internally use and assume the multi interface. The select()-loop should
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

View File

@@ -122,6 +122,30 @@ dnl end of non-blocking try-compile test
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 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
@@ -234,7 +258,7 @@ exit (h == NULL ? 1 : 0); }],[
])
dnl ************************************************************
dnl check for working getaddrinfo()
dnl check for working getaddrinfo() that works with AI_NUMERICHOST
dnl
AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
@@ -249,6 +273,7 @@ int main(void)
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);

13
ares/AUTHORS Normal file
View 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

View File

@@ -1,5 +1,36 @@
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
- Dominick Meglio added ares_parse_aaaa_reply.c and did various

View File

@@ -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
# regular sources and headers
EXTRA_DIST = CHANGES README.cares Makefile.inc adig.c ahost.c $(man_MANS) \
$(MSVCFILES)
$(MSVCFILES) AUTHORS
VER=-version-info 0:0:0

View File

@@ -1,16 +1,17 @@
CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \
ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \
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_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 \
ares_parse_aaaa_reply.c
HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3
CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \
ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \
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_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 \
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 \
inet_net_pton.h ares_ipv6.h bitncmp.h
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3

View File

@@ -126,7 +126,10 @@ DL = '
#-include $(NDKBASE)/nlmconv/ncpfs.inc
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
@@ -256,6 +259,7 @@ config.h: Makefile.netware
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(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_NAMESER_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_DLFCN_H 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 STDC_HEADERS 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_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
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
else

View File

@@ -30,12 +30,15 @@
#include "ares.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;
int status, linesize, end_at_hostname, naliases;
struct in_addr addr;
struct in6_addr addr6;
int addrlen = sizeof(struct in_addr);
struct hostent *hostent = NULL;
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;
addr.s_addr = inet_addr(line);
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;
/* 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 *));
if (!hostent->h_addr_list)
break;
hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
hostent->h_addr_list[0] = malloc(addrlen);
if (!hostent->h_addr_list[0])
break;
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_addrtype = AF_INET;
hostent->h_length = sizeof(struct in_addr);
memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
hostent->h_addrtype = family;
hostent->h_length = addrlen;
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;
*host = hostent;
free(line);

View File

@@ -21,6 +21,9 @@
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -12,7 +12,6 @@
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include "setup.h"
#include <sys/types.h>
@@ -23,6 +22,9 @@
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdio.h>
@@ -31,6 +33,7 @@
#include "ares.h"
#include "ares_private.h"
#include "inet_net_pton.h"
#ifdef WATT32
#undef WIN32
@@ -39,7 +42,8 @@
struct addr_query {
/* Arguments passed to ares_gethostbyaddr() */
ares_channel channel;
struct in_addr addr;
union ares_addr addr;
int family;
ares_host_callback callback;
void *arg;
@@ -51,14 +55,21 @@ static void addr_callback(void *arg, int status, unsigned char *abuf,
int alen);
static void end_aquery(struct addr_query *aquery, int status,
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,
int family, ares_host_callback callback, void *arg)
{
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);
return;
@@ -71,7 +82,11 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
return;
}
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->arg = arg;
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)
{
const char *p;
char name[64];
char name[128];
int a1, a2, a3, a4, status;
struct hostent *host;
unsigned long addr;
@@ -92,18 +107,38 @@ static void next_lookup(struct addr_query *aquery)
switch (*p)
{
case 'b':
addr = ntohl(aquery->addr.s_addr);
a1 = (int)((addr >> 24) & 0xff);
a2 = (int)((addr >> 16) & 0xff);
a3 = (int)((addr >> 8) & 0xff);
a4 = (int)(addr & 0xff);
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
aquery->remaining_lookups = p + 1;
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
aquery);
if (aquery->family == AF_INET)
{
addr = ntohl(aquery->addr.addr4.s_addr);
a1 = (int)((addr >> 24) & 0xff);
a2 = (int)((addr >> 16) & 0xff);
a3 = (int)((addr >> 8) & 0xff);
a4 = (int)(addr & 0xff);
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
aquery->remaining_lookups = p + 1;
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
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;
case 'f':
status = file_lookup(&aquery->addr, &host);
status = file_lookup(&aquery->addr, aquery->family, &host);
if (status != ARES_ENOTFOUND)
{
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)
{
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr,
sizeof(struct in_addr), AF_INET, &host);
if (aquery->family == AF_INET)
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4,
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);
}
else if (status == ARES_EDESTRUCTION)
@@ -141,7 +180,7 @@ static void end_aquery(struct addr_query *aquery, int status,
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;
int status;
@@ -178,11 +217,23 @@ static int file_lookup(struct in_addr *addr, struct hostent **host)
fp = fopen(PATH_HOSTS, "r");
if (!fp)
return ARES_ENOTFOUND;
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS)
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
{
if (memcmp((*host)->h_addr, addr, sizeof(struct in_addr)) == 0)
break;
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;
}
else if (family == AF_INET6)
{
if (memcmp((*host)->h_addr, &addr->addr6, sizeof(struct in6_addr)) == 0)
break;
}
ares_free_hostent(*host);
}
fclose(fp);

View File

@@ -23,8 +23,13 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -33,6 +38,8 @@
#include "ares.h"
#include "ares_private.h"
#include "inet_net_pton.h"
#include "bitncmp.h"
#ifdef WATT32
#undef WIN32
@@ -44,7 +51,7 @@ struct host_query {
char *name;
ares_host_callback callback;
void *arg;
int family;
const char *remaining_lookups;
};
@@ -53,13 +60,17 @@ static void host_callback(void *arg, int status, unsigned char *abuf,
int alen);
static void end_hquery(struct host_query *hquery, int status,
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);
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,
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,
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,
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;
/* 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);
return;
}
if (fake_hostent(name, callback, arg))
if (fake_hostent(name, family, callback, arg))
return;
/* 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->name = strdup(name);
hquery->family = family;
if (!hquery->name)
{
free(hquery);
@@ -112,13 +124,17 @@ static void next_lookup(struct host_query *hquery)
case 'b':
/* DNS lookup */
hquery->remaining_lookups = p + 1;
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
hquery);
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,
hquery);
return;
case 'f':
/* Host file lookup */
status = file_lookup(hquery->name, &host);
status = file_lookup(hquery->name, hquery->family, &host);
if (status != ARES_ENOTFOUND)
{
end_hquery(hquery, status, host);
@@ -138,11 +154,27 @@ static void host_callback(void *arg, int status, unsigned char *abuf, int alen)
if (status == ARES_SUCCESS)
{
status = ares_parse_a_reply(abuf, alen, &host);
if (host && channel->nsort)
sort_addresses(host, channel->sortlist, channel->nsort);
if (hquery->family == AF_INET)
{
status = ares_parse_a_reply(abuf, alen, &host);
if (host && 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);
}
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)
end_hquery(hquery, status, NULL);
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
* 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)
{
struct in_addr addr;
struct hostent hostent;
const char *p;
char *aliases[1] = { NULL };
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. */
for (p = name; *p; p++)
{
if (!isdigit((unsigned char)*p) && *p != '.')
return 0;
}
if (family == AF_INET)
result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1);
else if (family == AF_INET6)
result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1);
/* It also only looks like an IP address if it's non-zero-length and
* doesn't end with a dot.
*/
if (p == name || *(p - 1) == '.')
if (!result)
return 0;
/* It looks like an IP address. Figure out what IP address it is. */
addr.s_addr = inet_addr(name);
if (addr.s_addr == INADDR_NONE)
if (family == AF_INET)
{
callback(arg, ARES_EBADNAME, NULL);
return 1;
hostent.h_length = sizeof(struct in_addr);
addrs[0] = (char *)&in;
}
else if (family == AF_INET6)
{
hostent.h_length = sizeof(struct in6_addr);
addrs[0] = (char *)&in6;
}
/* Duplicate the name, to avoid a constness violation. */
hostent.h_name = strdup(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. */
addrs[0] = (char *) &addr;
addrs[1] = NULL;
hostent.h_aliases = aliases;
hostent.h_addrtype = AF_INET;
hostent.h_length = sizeof(struct in_addr);
hostent.h_addrtype = family;
hostent.h_addr_list = addrs;
callback(arg, ARES_SUCCESS, &hostent);
@@ -213,7 +241,7 @@ static int fake_hostent(const char *name, ares_host_callback callback,
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;
char **alias;
@@ -252,7 +280,7 @@ static int file_lookup(const char *name, struct hostent **host)
if (!fp)
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)
break;
@@ -310,8 +338,66 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
for (i = 0; i < nsort; i++)
{
if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr)
break;
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;
}
return i;
}

View File

@@ -27,10 +27,17 @@
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -44,6 +51,7 @@
#include <errno.h>
#include "ares.h"
#include "ares_private.h"
#include "inet_net_pton.h"
#ifdef WATT32
#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 const char *try_option(const char *p, const char *q, const char *opt);
#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 void natural_mask(struct apattern *pat);
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,
const char *str)
{
struct apattern pat, *newsort;
struct apattern pat;
const char *q;
/* Add sortlist entries. */
while (*str && *str != ';')
{
int bits;
char ipbuf[16], ipbufpfx[32];
/* Find just the IP */
q = str;
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q))
q++;
if (ip_addr(str, (int)(q - str), &pat.addr) == 0)
memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = 0;
/* Find the prefix */
if (*q == '/')
{
/* We have a pattern address; now determine the mask. */
if (*q == '/')
const char *str2 = q+1;
while (*q && *q != ';' && !isspace((unsigned char)*q))
q++;
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)
{
str = q + 1;
while (*q && *q != ';' && !isspace((unsigned char)*q))
q++;
if (ip_addr(str, (int)(q - str), &pat.mask) != 0)
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);
}
else
natural_mask(&pat);
/* Add this pattern to our list. */
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
if (!newsort)
pat.family = AF_INET;
pat.type = PATTERN_MASK;
if (!sortlist_alloc(sortlist, nsort, &pat))
return ARES_ENOMEM;
newsort[*nsort] = pat;
*sortlist = newsort;
(*nsort)++;
}
else
{
@@ -969,15 +1011,24 @@ static const char *try_option(const char *p, const char *q, const char *opt)
}
#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. */
if (len > 15)
return -1;
memcpy(ipbuf, s, len);
ipbuf[len] = 0;
addr->s_addr = inet_addr(ipbuf);
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,
* 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
* still rely on it.
*/
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))
pat->mask.s_addr = htonl(IN_CLASSB_NET);
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
else
pat->mask.s_addr = htonl(IN_CLASSC_NET);
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
}
#endif

48
ares/ares_ipv6.h Normal file
View 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 */

View File

@@ -21,6 +21,9 @@
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -24,6 +24,9 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -23,13 +23,19 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>
#include <string.h>
#include "ares.h"
#include "ares_dns.h"
#include "inet_net_pton.h"
#include "ares_private.h"
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,

View File

@@ -23,6 +23,9 @@
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -69,6 +69,8 @@
#endif
#include "ares_ipv6.h"
struct send_request {
/* Remaining data to send */
const unsigned char *data;
@@ -124,9 +126,23 @@ struct query {
};
/* 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 in_addr addr;
struct in_addr mask;
union ares_addr addr;
union
{
union ares_addr addr;
unsigned short bits;
} mask;
int family;
unsigned short type;
};
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__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);
#ifdef CURLDEBUG

View File

@@ -27,6 +27,9 @@
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -21,6 +21,9 @@
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -21,6 +21,9 @@
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#ifdef HAVE_ARPA_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#endif
#include <stdlib.h>

View File

@@ -4,12 +4,12 @@
#define ARES__VERSION_H
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 2
#define ARES_VERSION_MINOR 3
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.2.0"
#define ARES_VERSION_STR "1.3.0"
const char *ares_version(int *version);

60
ares/bitncmp.c Normal file
View 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
View 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 */

View File

@@ -1,7 +1,7 @@
#!/bin/sh
libtoolize --copy --automake --force
aclocal
autoheader
autoconf
automake --add-missing
${LIBTOOLIZE:-libtoolize} --copy --automake --force
${ACLOCAL:-aclocal}
${AUTOHEADER:-autoheader}
${AUTOCONF:-autoconf}
${AUTOMAKE:-automake} --add-missing

View File

@@ -67,6 +67,20 @@ AC_CHECK_HEADERS(
sys/socket.h \
winsock.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
@@ -120,4 +134,141 @@ CARES_CHECK_STRUCT(
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)

439
ares/inet_net_pton.c Normal file
View 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
View 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
View 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
View 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 */

View File

@@ -16,6 +16,8 @@
#define EINPROGRESS WSAEINPROGRESS
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EMSGSIZE WSAEMSGSIZE
#define EAFNOSUPPORT WSAEAFNOSUPPORT
/* Structure for scatter/gather I/O. */
struct iovec
@@ -36,8 +38,10 @@ int ares_gettimeofday(struct timeval *tv, struct timezone *tz);
#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. */
#define INDIR_MASK NS_CMPRSFLGS
@@ -134,7 +138,7 @@ typedef enum __ns_opcode {
#define QUERY ns_o_query
#define NS_MAXLABEL 63
#define NS_MAXLABEL 63
#define MAXLABEL NS_MAXLABEL
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */

View File

@@ -78,15 +78,4 @@ int ares_strcasecmp(const char *s1, const char *s2);
#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 */

View File

@@ -85,6 +85,14 @@ fi
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
@@ -142,6 +150,13 @@ fi
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
#
@@ -155,6 +170,10 @@ else
exit 1
fi
#--------------------------------------------------------------------------
# perl check
#
PERL=`findtool perl`
# ------------------------------------------------------------
@@ -164,8 +183,13 @@ echo "buildconf: running libtoolize"
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The libtool command failed"
echo "buildconf: running aclocal"
${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The aclocal command line failed"
echo "buildconf: running aclocal hack to convert all mv to mv -f"
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
if test -n "$PERL"; then
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"
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
echo "buildconf: cp lib/config.h.in src/config.h.in"

View File

@@ -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/])
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
terms of the curl license; see COPYING for more details])
@@ -56,7 +56,7 @@ AC_SUBST(PKGADD_VENDOR)
dnl
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_krb4_msg="no (--with-krb4*)"
curl_gss_msg="no (--with-gssapi)"
@@ -122,6 +122,14 @@ case $host in
*-*-mingw*)
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
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)
@@ -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]),
OPT_SSL=$withval)
if test X"$OPT_SSL" = Xno
then
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
else
if test X"$OPT_SSL" != Xno; then
dnl backup the pre-ssl variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
@@ -840,10 +844,7 @@ else
])
if test X"$HAVECRYPTO" != X"yes"; then
AC_MSG_WARN([crypto lib was not found; SSL will be disabled])
else
if test X"$HAVECRYPTO" = X"yes"; then
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
@@ -868,13 +869,13 @@ else
dnl Have the libraries--check for SSLeay/OpenSSL headers
AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
openssl/pem.h openssl/ssl.h openssl/err.h,
curl_ssl_msg="enabled"
curl_ssl_msg="enabled (OpenSSL)"
OPENSSL_ENABLED=1
AC_DEFINE(USE_OPENSSL, 1, [if OpenSSL is in use]))
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,
curl_ssl_msg="enabled"
curl_ssl_msg="enabled (OpenSSL)"
OPENSSL_ENABLED=1)
fi
fi
@@ -898,11 +899,6 @@ else
fi
fi
dnl **********************************************************************
dnl Check for the CA bundle
dnl **********************************************************************
if test X"$OPENSSL_ENABLED" = X"1"; then
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
@@ -912,30 +908,6 @@ dnl **********************************************************************
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
AC_CHECK_FUNCS( RAND_status \
@@ -955,8 +927,6 @@ AC_HELP_STRING([--without-ca-bundle], [Don't install the CA bundle]),
fi
AM_CONDITIONAL(CABUNDLE, test x$ca != xno)
dnl **********************************************************************
dnl Check for the random seed preferences
dnl **********************************************************************
@@ -989,6 +959,115 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
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 Check for the presence of ZLIB libraries and headers
dnl **********************************************************************
@@ -1321,6 +1400,8 @@ AC_CHECK_TYPE(ssize_t, ,
TYPE_SOCKLEN_T
TYPE_IN_ADDR_T
TYPE_SOCKADDR_STORAGE
AC_FUNC_SELECT_ARGTYPES
dnl Checks for library functions.
@@ -1414,11 +1495,24 @@ AC_CHECK_DECL(basename, ,
#endif
)
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_RUN_IFELSE([
AC_MSG_CHECKING([if we are Mac OS X (to disable poll)])
disable_poll=no
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_RUN_IFELSE([
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
@@ -1429,14 +1523,14 @@ if test "$ac_cv_func_poll" = "yes"; then
return poll((void *)0, 0, 10 /*ms*/);
}
],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll]),
AC_MSG_RESULT(no),
AC_MSG_RESULT(cross-compiling assumes yes)
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
) dnl end of AC_RUN_IFELSE
fi
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll]),
AC_MSG_RESULT(no),
AC_MSG_RESULT(cross-compiling assumes yes)
AC_DEFINE(HAVE_POLL_FINE, 1, [If you have a fine poll])
) dnl end of AC_RUN_IFELSE
fi dnl poll() was found
fi dnl poll()-check is not disabled
AC_PATH_PROG( PERL, perl, ,
@@ -1727,4 +1821,5 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
Built-in manual: ${curl_manual_msg}
Verbose errors: ${curl_verbose_msg}
SSPI support: ${curl_sspi_msg}
ca cert path: ${ca}
])

View File

@@ -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.16 What certificates do I need when I use SSL?
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.1 Problems connecting to SSL servers.
@@ -74,6 +75,9 @@ FAQ
5.7 Link errors when building libcurl on Windows!
5.8 libcurl.so.3: open failed: No such file or directory
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.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',
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
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".
The cURL project produces two products:
@@ -296,8 +300,8 @@ FAQ
2.2 Does curl work/build with other SSL libraries?
Curl has been written to use OpenSSL, although there should not be much
problems using a different library. If anyone does "port" curl to use a
Curl has been written to use OpenSSL or GnuTLS, although there should not be
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
patch!
@@ -503,9 +507,9 @@ FAQ
If the server doesn't require this, you don't need a client certificate.
- 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
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
server certificate. Server certificate verification is enabled by default
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/
3.18 Can I use curl to send a POST/PUT and not wait for a response?
No.
4. Running Problems
@@ -733,12 +741,20 @@ FAQ
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
your system has such.
We would appreciate some kind of report or README file from those who have
used libcurl in a threaded environment.
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
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?
@@ -877,6 +893,35 @@ FAQ
A - gethostbyname() on plain ipv4 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
Curl and libcurl are released under a MIT/X derivate license. The license is

View File

@@ -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
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
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
Amount of public web site mirrors: 12
Number of known libcurl bindings: 26
April 2005:
GnuTLS can now optionally be used for the secure layer when curl is built.

View File

@@ -578,14 +578,14 @@ PORTS
- MIPS IRIX 6.2, 6.5
- MIPS Linux
- 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 Linux
- PowerPC Mac OS 9
- PowerPC Mac OS X
- SINIX-Z v5
- 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
- StrongARM (and other ARM) RISC OS 3.1, 4.02
- StrongARM Linux 2.4
@@ -596,14 +596,14 @@ PORTS
- i386 Esix 4.1
- i386 FreeBSD
- 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 Novell NetWare
- i386 OS/2
- i386 OpenBSD
- i386 SCO unix
- i386 Solaris 2.7
- i386 Windows 95, 98, ME, NT, 2000
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
- i386 QNX 6
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
- ia64 Linux 2.3.99

View File

@@ -92,9 +92,6 @@ may have been fixed since this was written!
libcurl thinks of it as the *compressed* length. Some explanations are here:
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
2. If a HTTP server responds to a HEAD request and includes a body (thus

View File

@@ -32,7 +32,15 @@ OpenSSL http://www.openssl.org/source/license.html
makes it "incompatible" with GPL. You are not allowed to ship binaries
that link with OpenSSL that includes GPL code (unless that specific
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
@@ -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
[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
how to write such an exception to the GPL
[3] = LGPL - GNU Lesser General Public License:
http://www.gnu.org/licenses/lgpl.html

View File

@@ -1,110 +1,94 @@
This project has been alive for several years. Countless people have provided
feedback that have improved curl. Here follows a (incomplete) list of people
that have contributed with non-trivial parts:
This project has been alive for many years. Countless people have provided
feedback that have improved curl. Here follows a list of people that have
contributed (a-z order).
Daniel Stenberg <daniel@haxx.se>
Rafael Sagula <sagula@inf.ufrgs.br>
Sampo Kellomaki <sampo@iki.fi>
Linas Vepstas <linas@linas.org>
Bjorn Reese <breese@mail1.stofanet.dk>
Johan Anderson <johan@homemail.com>
Kjell Ericson <Kjell.Ericson@haxx.se>
Troy Engel <tengel@sonic.net>
Ryan Nelson <ryan@inch.com>
Bj<EFBFBD>rn Stenberg <bjorn@haxx.se>
Angus Mackay <amackay@gus.ml.org>
Eric Young <eay@cryptsoft.com>
Simon Dick <simond@totally.irrelevant.org>
Oren Tirosh <oren@monty.hishome.net>
Steven G. Johnson <stevenj@alum.mit.edu>
Gilbert Ramirez Jr. <gram@verdict.uthscsa.edu>
Andr<EFBFBD>s Garc<72>a <ornalux@redestb.es>
Douglas E. Wegscheid <wegscd@whirlpool.com>
Mark Butler <butlerm@xmission.com>
Eric Thelin <eric@generation-i.com>
Marc Boucher <marc@mbsi.ca>
Greg Onufer <Greg.Onufer@Eng.Sun.COM>
Doug Kaufman <dkaufman@rahul.net>
David Eriksson <david@2good.com>
Ralph Beckmann <rabe@uni-paderborn.de>
T. Yamada <tai@imasy.or.jp>
Lars J. Aas <larsa@sim.no>
J<EFBFBD>rn Hartroth <Joern.Hartroth@computer.org>
Matthew Clarke <clamat@van.maves.ca>
Linus Nielsen Feltzing <linus@haxx.se>
Felix von Leitner <felix@convergence.de>
Dan Zitter <dzitter@zitter.net>
Jongki Suwandi <Jongki.Suwandi@eng.sun.com>
Chris Maltby <chris@aurema.com>
Ron Zapp <rzapper@yahoo.com>
Paul Marquis <pmarquis@iname.com>
Ellis Pritchard <ellis@citria.com>
Damien Adant <dams@usa.net>
Chris <cbayliss@csc.come>
Marco G. Salvagno <mgs@whiz.cjb.net>
Paul Marquis <pmarquis@iname.com>
David LeBlanc <dleblanc@qnx.com>
Rich Gray at Plus Technologies
Luong Dinh Dung <u8luong@lhsystems.hu>
Torsten Foertsch <torsten.foertsch@gmx.net>
Kristian K<>hntopp <kris@koehntopp.de>
Fred Noz <FNoz@siac.com>
Caolan McNamara <caolan@csn.ul.ie>
Albert Chin-A-Young <china@thewrittenword.com>
Stephen Kick <skick@epicrealm.com>
Martin Hedenfalk <mhe@stacken.kth.se>
Richard Prescott <rip at step.polymtl.ca>
Jason S. Priebe <priebe@wral-tv.com>
T. Bharath <TBharath@responsenetworks.com>
Alexander Kourakos <awk@users.sourceforge.net>
James Griffiths <griffiths_james@yahoo.com>
Loic Dachary <loic@senga.org>
Robert Weaver <robert.weaver@sabre.com>
Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
Jun-ichiro itojun Hagino <itojun@iijlab.net>
Frederic Lepied <flepied@mandrakesoft.com>
Georg Horn <horn@koblenz-net.de>
Cris Bailiff <c.bailiff@awayweb.com>
Sterling Hughes <sterling@designmultimedia.com>
S. Moonesamy
Ingo Wilken <iw@WWW.Ecce-Terram.DE>
Pawel A. Gajda <mis@k2.net.pl>
Patrick Bihan-Faou
Nico Baggus <Nico.Baggus@mail.ing.nl>
Sergio Ballestrero
Andrew Francis <locust@familyhealth.com.au>
Tomasz Lacki <Tomasz.Lacki@primark.pl>
Georg Huettenegger <georg@ist.org>
John Lask <johnlask@hotmail.com>
Eric Lavigne <erlavigne@wanadoo.fr>
Marcus Webster <marcus.webster@phocis.com>
G<EFBFBD>tz Babin-Ebell <babin<69>ebell@trustcenter.de>
Andreas Damm <andreas-sourceforge@radab.org>
Jacky Lam <sylam@emsoftltd.com>
James Gallagher <jgallagher@gso.uri.edu>
Kjetil Jacobsen <kjetilja@cs.uit.no>
Markus F.X.J. Oberhumer <markus@oberhumer.com>
Miklos Nemeth <mnemeth@kfkisystems.com>
Kevin Roth <kproth@users.sourceforge.net>
Ralph Mitchell <rmitchell@eds.com>
Dan Fandrich <dan@coneharvesters.com>
Jean-Philippe Barrette-LaPierre <jpb@rrette.com>
Richard Bramante <RBramante@on.com>
Daniel Kouril <kouril@ics.muni.cz>
Dirk Manske <dm@nettraffic.de>
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
If you have contributed but are missing here, please let us know!
Alan Pinstein, Albert Chin-A-Young, Albert Choy, Aleksandar Milivojevic, Alex
aka WindEagle, Alex Neblett, Alex Suykov, Alexander Kourakos, Alexander
Krasnostavsky, Alexander Zhuravlev, Alexis Carvalho, Andi Jahja, Andreas Damm,
Andreas Olsson, Andreas Rieke, Andrew Francis, Andrew Fuller, Andr<64>s Garc<72>a,
Andy Cedilnik, Andy Serpa, Angus Mackay, Antoine Calando, Anton Kalmykov,
Arkadiusz Miskiewicz, Augustus Saunders, Avery Fay, Ben Greear, Benjamin
Gerard, Bertrand Demiddelaer, Bjorn Reese, Bj<42>rn Stenberg, Bob Schader, Brad
Burdick, Brent Beardsley, Brian Akins, Brian R Duffy, Bruce Mitchener, Bryan
Henderson, Bryan Henderson , Bryan Kemp, Caolan McNamara, Casey O'Donnell,
Chih-Chung Chang, Chris "Bob Bob", Chris Combes, Chris Gaukroger, Chris
Maltby, Christian Kurz, Christian Robottom Reis, Christophe Demory, Christophe
Legry, Christopher R. Palmer, Clarence Gardner, Clifford Wolf, Cody Jones,
Colin Watson, Colm Buckley, Cory Nelson, Craig Davison, Craig Markwardt, Cris
Bailiff, Cyrill Osterwalder, Damien Adant, Dan Becker, Dan C, Dan Fandrich,
Dan Torop, Dan Zitter, Daniel at touchtunes, Daniel Stenberg, Dave Dribin,
Dave Halbakken, Dave Hamilton, Dave May, David Byron, David Cohen, David
Eriksson, David Houlder, David Hull, David J Meyer, David James, David Kimdon,
David LeBlanc, David Odin, David Phillips, David Shaw, David Tarendash, David
Thiel, Detlef Schmier, Diego Casorran, Dimitris Sarris, Dinar, Dirk
Eddelbuettel, Dirk Manske, Dolbneff A.V, Domenico Andreoli, Dominick Meglio,
Doug Kaufman, Doug Porter, Douglas E. Wegscheid, Douglas R. Horner, Dustin
Boswell, Dylan Ellicott, Dylan Salisbury, Early Ehlinger, Edin Kadribasic,
Ellis Pritchard, Emiliano Ida, Enrico Scholz, Enrik Berkhan, Eric Lavigne,
Eric Melville, Eric Rautman, Eric Thelin, Eric Vergnaud, Eric Young, Erick
Nuwendam, Erwan Legrand, Erwin Authried, Evan Jordan, Fabrizio Ammollo, Fedor
Karpelevitch, Felix von Leitner, Florian Schoppmann, Forrest Cahoon, Frank
Keeney, Frank Ticheler, Fred New, Fred Noz, Frederic Lepied, Gautam Mani, Gaz
Iqbal, Georg Horn, Georg Huettenegger, Gerd v. Egidy, Gerhard Herre, Giaslas
Georgios, Gilad, Gilbert Ramirez Jr., Gisle Vanem, Giuseppe Attardi, Giuseppe
D'Ambrosio, Glen Nakamura, Glen Scott, Greg Hewgill, Greg Onufer, Grigory
Entin, Guenole Bescon, Guillaume Arluison, Gustaf Hui, Gwenole Beauchesne,
G<EFBFBD>tz Babin-Ebell, G<>nter Knauf, Hamish Mackenzie, Hanno Kranzhoff, Hans
Steegers, Hardeep Singh, Harshal Pradhan, Heikki Korpela, Henrik Storner,
Hzhijun, Ian Ford, Ian Gulliver, Ian Wilkes, Ignacio Vazquez-Abrams, Ilguiz
Latypov, Ingo Ralf Blum, Ingo Wilken, Jacky Lam, Jacob Meuser, James Bursa,
James Clancy, James Cone, James Gallagher, James Griffiths, James MacMillan,
Jamie Lokier, Jamie Wilkinson, Jason S. Priebe, Jean-Claude Chauve, Jean-Louis
Lemaire, Jean-Marc Ranger, Jean-Philippe Barrette-LaPierre, Jeff Lawson, Jeff
Phillips, Jeffrey Pohlmeyer, Jeremy Friesner, Jesper Jensen, Jesse Noller, Jim
Drash, Joe Halpin, Joel Chen, Johan Anderson, Johan Nilsson, John Crow, John
Janssen, John Lask, John McGowan, Jon Travis, Jon Turner, Jonas Forsman,
Jonatan Lander, Jonathan Hseu, Jongki Suwandi, Josh Kapell, Juan F. Codagnone,
Juan Ignacio Herv<72>s, Juergen Wilke, Jukka Pihl, Julian Noble, Jun-ichiro
itojun Hagino, Jurij Smakov, J<>rg Mueller-Tolk, J<>rn Hartroth, Kai Sommerfeld,
Kai-Uwe Rommel, Kang-Jin Lee, Karol Pietrzak, Keith MacDonald, Keith McGuigan,
Ken Hirsch, Ken Rastatter, Kevin Fisk, Kevin Roth, Kimmo Kinnunen, Kjell
Ericson, Kjetil Jacobsen, Klevtsov Vadim, Kris Kennaway, Krishnendu Majumdar,
Kristian K<>hntopp, Kyle Sallee, Lachlan O'Dea, Larry Campbell, Larry Fahnoe,
Lars Gustafsson, Lars J. Aas, Lars Nilsson, Lars Torben Wilson, Legoff
Vincent, Lehel Bernadt, Len Krause, Linas Vepstas, Ling Thio, Linus Nielsen
Feltzing, Loic Dachary, Loren Kirkby, Luca Altea, Luca Alteas, Lucas Adamski,
Lukasz Czekierda, Luke Call, Luong Dinh Dung, Maciej W. Rozycki, Marc Boucher,
Marcelo Juchem , Marcin Konicki, Marco G. Salvagno, Marcus Webster, Mark
Butler, Markus Moeller, Markus Oberhumer, Martijn Koster, Martin C. Martin,
Martin Hedenfalk, Marty Kuhrt, Maruko, Massimiliano Ziccardi, Mathias
Axelsson, Mats Lidell, Matt Veenstra, Matthew Blain, Matthew Clarke, Maurice
Barnum, Mekonikum, Mettgut Jamalla, Michael Benedict, Michael Curtis, Michael
Mealling, Michal Bonino, Mihai Ionescu, Mike Bytnar, Mike Dobbs, Miklos
Nemeth, Mitz Wark, Mohamed Lrhazi, Mohun Biswas, Moonesamy, Nathan O'Sullivan,
Naveen Noel, Neil Dunbar, Neil Spring, Nic Roets, Nick Gimbrone, Nick Humfrey,
Nico Baggus, Nicolas Berloquin, Nicolas Croiset, Niels van Tongeren, Nikita
Schmidt, nk, Nodak Sodak, Oren Tirosh, P R Schaffner, Patrick Bihan-Faou,
Patrick Smith, Paul Harrington, Paul Marquis, Paul Moore, Paul Nolan, Pavel
Cenek, Pavel Orehov, Pawel A. Gajda, Pedro Neves, Pete Su, Peter Bray, Peter
Forret, Peter Pentchev, Peter Sylvester, Peter Todd, Peter Verhas, Peter
Wullinger, Phil Karn, Philip Gladstone, Philippe Hameau, Philippe Raoult,
Pierre, Puneet Pawaia, Rafael Sagula, Ralph Beckmann, Ralph Mitchell, Ramana
Mokkapati, Randy McMurchy, Reinout van Schouwen, Renaud Chaillat, Renaud
Duhaut, Rene Bernhardt, Rene Rebe, Ricardo Cadime, Rich Gray, Richard Archer,
Richard Atterer, Richard Bramante, Richard Cooper, Richard Gorton, Richard
Prescott, Rick Jones, Rick Richardson, Rob Stanzel, Robert D. Young, Robert
Olson, Robert Weaver, Robin Kay, Rodney Simmons, Roland Krikava, Roland
Zimmermann, Roman Koifman, Ron Zapp, Rosimildo da Silva, Roy Shan, Rune
Kleveland, Ryan Nelson, S. Moonesamy, Salvador D<>vila, Salvatore Sorrentino,
Sampo Kellomaki, Samuel D<>az Garc<72>a, Samuel Listopad, Sander Gates, Saul good,
Sebastien Willemijns, Sergio Ballestrero, Seshubabu Pasam, Shard, Shawn
Poulson, Siddhartha Prakash Jain, Simon Dick, Simon Liu, Spiridonoff A.V,
Stadler Stephan, Stefan Ulrich, Stephan Bergmann, Stephen Kick, Stephen More,
Sterling Hughes, Steve Green, Steve Lhomme, Steve Marx, Steve Oliphant, Steven
Bazyl, Steven G. Johnson, Stoned Elipot, Sven Neuhaus, swalkaus at yahoo.com,
S<EFBFBD>bastien Willemijns, T. Bharath, T. Yamada, Thomas Schwinge, Thomas Tonino,
Tim Baker, Tim Bartley, Tim Costello, Tim Sneddon, Toby Peterson, Tom Benoist,
Tom Lee, Tom Mattison, Tom Moers, Tom Zerucha, Tomas Pospisek, Tomas Szepe,
Tomasz Lacki, Tommy Tam, Ton Voon, Tor Arntsen, Torsten Foertsch, Toshiyuki
Maezawa, Traian Nicolescu, Troels Walsted Hansen, Troy Engel, Ulrich Zadow,
Vincent Bronner, Vincent Penquerc'h, Vincent Sanders, Vojtech Janota, Vojtech
Minarik, Walter J. Mack, Wayne Haigh, Werner Koch, Wesley Laxton, Wez Furlong,
Wilfredo Sanchez, Wojciech Zwiefka, Yarram Sunil, Zvi Har'El

View File

@@ -26,7 +26,7 @@ TODO
* 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
channel.
channel and the connection cache.
* Introduce a new error code indicating authentication problems (for proxy
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
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
GET_FTP_DATA_IP. Return a string with the used IP. Suggested by Alan.
LIBCURL - multi interface
* Add a curl_multi_fdset() alternative that returns only two arrays with file
desrciptors for reading and writing to allow the app to use whatever
function it prefers. Plus, this allows apps to avoid the FD_SETSIZE problem
with select().
* Add a curl_multi_fdset() alternative. this allows apps to avoid the
FD_SETSIZE problem with select().
* Add curl_multi_timeout() to make libcurl's ares-functionality better.
@@ -68,9 +67,6 @@ TODO
* 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.
* 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
authentication and file encryption. Possible libraries and example clients
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
Clark)
* Make curl's SSL layer option capable of using other free SSL libraries.
Such as the Mozilla Security Services
(http://www.mozilla.org/projects/security/pki/nss/) and GnuTLS
(http://www.gnu.org/software/gnutls/) This subject has been brought up
again recently since GPL-licensed applications that link with libcurl MAY
NOT distribute binaries that use OpenSSL without adding an exception clause
to the GPL license. See the LICENSE-MIXING document and this:
http://www.gnome.org/~markmc/openssl-and-the-gpl.html
* Make curl's SSL layer capable of using other free SSL libraries. Such as
Mozilla Security Services
(http://www.mozilla.org/projects/security/pki/nss/), MatrixSSL
(http://www.matrixssl.org/) or yaSSL (http://yassl.com/). At least the
latter two could be alternatives for those looking to reduce the footprint
of libcurl built with OpenSSL or GnuTLS.
LDAP

View File

@@ -20,7 +20,7 @@ Version Numbers and Releases
N is pre-release number
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
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
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
defined as:
@@ -62,3 +62,6 @@ Version Numbers and Releases
This 6-digit hexadecimal number does not show pre-release number, and it is
always a greater number in a more recent release. It makes comparisons with
greater than and less than work.
This number is also available as three separate defines:
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.

View File

@@ -21,7 +21,7 @@
.\" * $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
curl \- transfer a URL
.SH SYNOPSIS
@@ -497,6 +497,20 @@ line. So, it could look similar to this:
url = "http://curl.haxx.se/docs/"
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>"
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
@@ -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
instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++.
.IP "-q"
If used as the first parameter on the command line, the \fI$HOME/.curlrc\fP
file will not be read and used as a config file.
If used as the first parameter on the command line, the \fIcurlrc\fP config
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>"
(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
@@ -870,6 +885,11 @@ to read for untrained humans.
If this option is used several times, the last one will be used. (Added in
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>"
Specify user and password to use for server authentication. Overrides
\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.
.IP "-v/--verbose"
Makes the fetching more verbose/talkative. Mostly usable for debugging. Lines
starting with '>' means data sent by curl, '<' means data received by curl
that is hidden in normal cases and lines starting with '*' means additional
info provided by curl.
starting with '>' means "header data" sent by curl, '<' means "header data"
received by curl that is hidden in normal cases and lines starting with '*'
means additional info provided by curl.
Note that if you only want HTTP headers in the output, \fI-i/--include\fP
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.
.IP "IDN"
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
.IP "-w/--write-out <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/
.SH "SEE ALSO"
.BR ftp (1),
.BR wget (1),
.BR wget (1)

View File

@@ -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 \
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.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:
@echo "done"

View 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;
}

View File

@@ -21,7 +21,7 @@
.\" * $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
curl_easy_setopt - set options for a curl easy handle
.SH SYNOPSIS
@@ -410,7 +410,7 @@ is a more secure way to do authentication over public networks than the
regular old-fashioned Basic method.
.IP CURLAUTH_GSSNEGOTIATE
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
"Negotiate") method was designed by Microsoft and is used in their web
\&"Negotiate") method was designed by Microsoft and is used in their web
applications. It is primarily meant as a support for Kerberos5 authentication
but may be also used along with another authentication methods. For more
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
\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
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
.IP CURLOPT_AUTOREFERER
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,
\fICURLE_SSL_ENGINE_SETFAILED\fP is returned.
.IP CURLOPT_SSLVERSION
Pass a long as parameter. Set what version of SSL to attempt to use, 2 or
3. By default, the SSL library will try to solve this by itself although some
servers make this difficult why you at times may have to use this option.
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
The available options are:
.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
Pass a long that is set to a zero value to stop curl from verifying the peer's
certificate (7.10 starting setting this option to non-zero by default).
Alternate certificates to verify against can be specified with the
\fICURLOPT_CAINFO\fP option or a certificate directory can be specified with
the \fICURLOPT_CAPATH\fP option. As of 7.10, curl installs a default bundle.
\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).
Pass a long as parameter.
This option determines whether curl verifies the authenticity of the
peer's certificate. A nonzero value means curl verifies; zero means it
doesn't. The default is nonzero, but before 7.10, it was zero.
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
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
combination with the \fICURLOPT_SSL_VERIFYPEER\fP option.
certificates to verify the peer with. This makes sense only when used in
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
Pass a char * to a zero terminated string naming a directory holding multiple
CA certificates to verify the peer with. The certificate directory must be
prepared using the openssl c_rehash utility. This only makes sense when used
in combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. The
\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
limitation in openssl. (Added in 7.9.8)
Pass a char * to a zero terminated string naming a directory holding
multiple CA certificates to verify the peer with. The certificate
directory must be prepared using the openssl c_rehash utility. This
makes sense only when used in combination with the
\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP
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
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,
@@ -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
socket. It will be used to seed the random engine for SSL.
.IP CURLOPT_SSL_VERIFYHOST
Pass a long. Set if we should verify the Common name from the peer certificate
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)
Pass a long as parameter.
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
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,

View File

@@ -1,6 +1,6 @@
.\" $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
curl_multi_fdset - extracts file descriptor information from a multi handle
.SH SYNOPSIS
@@ -15,15 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
.ad
.SH DESCRIPTION
This function extracts file descriptor information from a given multi_handle.
libcurl returns its fd_set sets. The application can use these to select()
on. 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.
libcurl returns its fd_set sets. The application can use these to select() on,
but be sure to FD_ZERO them before calling this function as
\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
rather small (single-digit number of seconds) timeout and call
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
you'd think.
you'd think and want.
.SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. See
\fIlibcurl-errors(3)\fP

View File

@@ -34,7 +34,7 @@ typedef struct {
const char *host; /* human readable string */
int features; /* bitmask, see below */
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 **protocols; /* list of protocols */

View File

@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH libcurl-tutorial 3 "25 Jan 2005" "libcurl" "libcurl programming"
.TH libcurl-tutorial 3 "9 May 2005" "libcurl" "libcurl programming"
.SH NAME
libcurl-tutorial \- libcurl programming tutorial
.SH "Objective"
@@ -246,16 +246,26 @@ you intend to make another transfer. libcurl will then attempt to re-use the
previous
.SH "Multi-threading Issues"
libcurl is completely thread safe, except for two issues: signals and alarm
handlers. Signals are needed for a SIGPIPE handler, and the alarm() call is
used to deal with timeouts (during DNS lookup).
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
it easy or multi or whatever) between multiple threads. Only use one handle in
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
then of course using OpenSSL multi-threaded and it has itself a few
requirements on this. Basically, you need to provide one or two functions to
allow it to function properly. For all details, see this:
then of course using OpenSSL/GnuTLS multi-threaded and those libs have their
own requirements on this issue. Basically, you need to provide one or two
functions to allow it to function properly. For all details, see this:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
OpenSSL
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
TRUE for all handles. Everything will work fine except that timeouts are not

View File

@@ -1358,8 +1358,8 @@ typedef struct {
const char *host; /* OS/host/cpu/machine when configured */
int features; /* bitmask, see defines below */
const char *ssl_version; /* human readable string */
long ssl_version_num; /* number */
const char *libz_version; /* human readable string */
long ssl_version_num; /* not used anymore, always 0 */
const char *libz_version; /* human readable string */
/* protocols is terminated by an entry with a NULL protoname */
const char * const *protocols;

View File

@@ -28,7 +28,7 @@
/* This is the version number of the libcurl package from which this header
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
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
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
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 13
#define LIBCURL_VERSION_PATCH 2
#define LIBCURL_VERSION_MINOR 14
#define LIBCURL_VERSION_PATCH 0
#endif /* __CURL_CURLVER_H */

View File

@@ -23,16 +23,8 @@
* $Id$
***************************************************************************/
/*
This is meant to be the "external" header file. Don't give away any
internals here!
This is an "external" header file. Don't give away any internals here!
This document presents a mixture of ideas from at least:
- Daniel Stenberg
- Steve Dekorte
- Sterling Hughes
- Ben Greear
-------------------------------------------
GOALS
o Enable a "pull" interface. The application that uses libcurl decides where
@@ -82,6 +74,22 @@ extern "C" {
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 {
CURLM_CALL_MULTI_PERFORM=-1, /* please call curl_multi_perform() soon */
CURLM_OK,
@@ -113,6 +121,7 @@ typedef struct CURLMsg CURLMsg;
* Name: curl_multi_init()
*
* Desc: inititalize multi-style curl usage
*
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
*/
CURL_EXTERN CURLM *curl_multi_init(void);
@@ -121,6 +130,7 @@ CURL_EXTERN CURLM *curl_multi_init(void);
* Name: curl_multi_add_handle()
*
* Desc: add a standard curl handle to the multi stack
*
* Returns: CURLMcode type, general multi error code.
*/
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()
*
* Desc: removes a curl handle from the multi stack again
*
* Returns: CURLMcode type, general multi error code.
*/
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
* poll() on. We want curl_multi_perform() called as soon as one of
* them are ready.
*
* Returns: CURLMcode type, general multi error code.
*/
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
* in what state those handles will be if this function is called
* in the middle of a transfer.
*
* Returns: CURLMcode type, general multi error code.
*/
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);
/*
* 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
* into the equivalent human readable error string. This is useful
* for printing meaningful error messages.
* Returns: A pointer to a zero-terminated error message.
*/
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
} /* end of extern "C" */
#endif

View File

@@ -43,7 +43,8 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
$(OBJ_DIR)\hostip4.obj $(OBJ_DIR)\hostthre.obj &
$(OBJ_DIR)\hostip6.obj $(OBJ_DIR)\inet_ntop.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
@@ -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
$(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

View File

@@ -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 \
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 \
select.c
select.c gtls.c sslgen.c
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 \
@@ -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 \
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 \
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

View File

@@ -13,11 +13,11 @@ NDKBASE = c:/novell
endif
# 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.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.7d
OPENSSL_PATH = ../../openssl-0.9.7g
endif
ifndef INSTDIR
@@ -336,7 +336,14 @@ config.h: Makefile.netware
@echo $(DL)#define SIZEOF_CURL_OFF_T 4$(DL) >> $@
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
ifdef DISABLE_LDAP
@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
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
else

View File

@@ -12,7 +12,7 @@ objs = o.base64 o.connect o.cookie o.dict \
o.memdebug o.mprintf o.netrc o.parsedate o.progress \
o.security o.select o.sendf o.speedcheck o.ssluse \
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:
linkopts = -o libcurl
@@ -119,6 +119,12 @@ o.sendf: c.sendf
o.speedcheck: 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
gcc $(compileropts) -c -o ssluse.o c.ssluse

View File

@@ -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"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
CFLAGSLIB = /DCURL_STATICLIB
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo
@@ -99,7 +100,7 @@ LFLAGS = $(LFLAGS) $(WINDOWS_SDK_PATH)\lib\secur32.lib
TARGET = $(LIB_NAME).lib
DIROBJ = $(CFG)
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG)
CC = $(CCNODBG) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -111,7 +112,7 @@ TARGET = $(LIB_NAME).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSZLIB)
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -135,7 +136,7 @@ TARGET = $(LIB_NAME).lib
DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -160,7 +161,7 @@ DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -185,7 +186,7 @@ TARGET = $(LIB_NAME).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSZLIB)
CC = $(CCNODBG) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -198,7 +199,7 @@ DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -236,7 +237,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG)
CC = $(CCDEBUG) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -248,7 +249,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -260,7 +261,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSZLIB)
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -272,7 +273,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -285,7 +286,7 @@ DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(SSLLIBS) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -297,7 +298,7 @@ TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSZLIB)
CC = $(CCDEBUG) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -310,7 +311,7 @@ DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
@@ -428,6 +429,7 @@ X_OBJS= \
$(DIROBJ)\telnet.obj \
$(DIROBJ)\parsedate.obj \
$(DIROBJ)\getenv.obj \
$(DIROBJ)\gtls.obj \
$(DIROBJ)\inet_pton.obj \
$(DIROBJ)\hostip.obj \
$(DIROBJ)\hostasyn.obj \
@@ -443,6 +445,7 @@ X_OBJS= \
$(DIROBJ)\progress.obj \
$(DIROBJ)\sendf.obj \
$(DIROBJ)\speedcheck.obj \
$(DIROBJ)\sslgen.obj \
$(DIROBJ)\ssluse.obj \
$(DIROBJ)\timeval.obj \
$(DIROBJ)\url.obj \

17
lib/TODO.gnutls Normal file
View 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

View File

@@ -235,6 +235,10 @@
/* lber dynamic library 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 */
#define DL_LDAP_FILE "wldap32.dll"

View File

@@ -15,6 +15,7 @@
#define HAVE_BASENAME 1
#define HAVE_CLOSESOCKET 1
#define HAVE_FCNTL_H 1
#define HAVE_FIONBIO 1
#define HAVE_GETHOSTBYADDR 1
#define HAVE_GETHOSTNAME 1
#define HAVE_GETPASS 1
@@ -104,7 +105,10 @@
#define in_addr_t u_long
#define socklen_t int
#if __GNUC__ < 4 /* gcc 4.x built-in ? */
#define ssize_t int
#endif
#include <stdlib.h>
#include <string.h>

View File

@@ -133,6 +133,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */)
{
#undef SETBLOCK
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
/* most recent unix versions */
int flags;
@@ -142,46 +143,52 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
#undef SETBLOCK
#define SETBLOCK 1
#endif
#ifdef HAVE_FIONBIO
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#ifdef HAVE_IOCTLSOCKET
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
/* Windows? */
unsigned long flags;
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#ifdef HAVE_IOCTLSOCKET_CASE
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
/* presumably for Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif
#ifdef HAVE_SO_NONBLOCK
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING
return 0; /* returns success */
#undef SETBLOCK
#define SETBLOCK 6
#endif
#ifndef SETBLOCK
#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#endif
}
@@ -345,7 +352,8 @@ static CURLcode bindlocal(struct connectdata *conn,
if(!bindworked) {
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;
}
@@ -645,14 +653,14 @@ singleipconnect(struct connectdata *conn,
CURLcode res = bindlocal(conn, sockfd);
if(res) {
sclose(sockfd); /* close socket and bail out */
return res;
return CURL_SOCKET_BAD;
}
}
/* set socket non-blocking */
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) {
error = Curl_ourerrno();

View File

@@ -309,7 +309,7 @@ Curl_cookie_add(struct SessionHandle *data,
break;
}
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)) {
co->expirestr=strdup(whatptr);
@@ -317,7 +317,7 @@ Curl_cookie_add(struct SessionHandle *data,
badcookie = TRUE;
break;
}
co->expires = curl_getdate(what, &now);
co->expires = (long)curl_getdate(what, &now);
}
else if(!co->name) {
co->name = strdup(name);

View File

@@ -75,7 +75,7 @@
#include "urldata.h"
#include <curl/curl.h>
#include "transfer.h"
#include "ssluse.h"
#include "sslgen.h"
#include "url.h"
#include "getinfo.h"
#include "hostip.h"
@@ -201,7 +201,7 @@ CURLcode curl_global_init(long flags)
Curl_ccalloc = (curl_calloc_callback)calloc;
if (flags & CURL_GLOBAL_SSL)
if (!Curl_SSL_init())
if (!Curl_ssl_init())
return CURLE_FAILED_INIT;
if (flags & CURL_GLOBAL_WIN32)
@@ -266,7 +266,7 @@ void curl_global_cleanup(void)
Curl_global_host_cache_dtor();
if (init_flags & CURL_GLOBAL_SSL)
Curl_SSL_cleanup();
Curl_ssl_cleanup();
if (init_flags & CURL_GLOBAL_WIN32)
win32_cleanup();

View File

@@ -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
* 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;
else
current_form->namelength =
array_state?(long)array_value:va_arg(params, long);
array_state?(long)array_value:(long)va_arg(params, long);
break;
/*
@@ -1550,7 +1550,7 @@ char *Curl_FormBoundary(void)
if(!retstring)
return NULL; /* failed */
srand(time(NULL)+randomizer++); /* seed */
srand((unsigned int)time(NULL)+randomizer++); /* seed */
strcpy(retstring, "----------------------------");

View File

@@ -87,7 +87,7 @@
#include "strtoofft.h"
#include "strequal.h"
#include "ssluse.h"
#include "sslgen.h"
#include "connect.h"
#include "strerror.h"
#include "memory.h"
@@ -266,8 +266,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ptr=buf + ftp->nread_resp;
perline= ptr-ftp->linestart_resp; /* number of bytes in the current line,
so far */
perline= (int)(ptr-ftp->linestart_resp); /* number of bytes in the current
line, so far */
keepon=TRUE;
while((ftp->nread_resp<BUFSIZE) && (keepon && !result)) {
@@ -777,9 +777,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
/******************************************************************
* IPv6-specific section
*/
struct addrinfo *res, *ai;
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
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;
char hbuf[NI_MAXHOST];
struct sockaddr *sa=(struct sockaddr *)&ss;
@@ -866,13 +869,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
}
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;
}
sslen = sizeof(ss);
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;
}
@@ -1739,7 +1742,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
"%04d%02d%02d %02d:%02d:%02d GMT",
year, month, day, hour, minute, second);
/* 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,
@@ -2013,7 +2016,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
do the TLS stuff */
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
/* BLOCKING */
result = Curl_SSLConnect(conn, SECONDARYSOCKET);
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
if(result)
return result;
}
@@ -2086,7 +2089,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
char *bytes;
bytes=strstr(buf, " bytes");
if(bytes--) {
long in=bytes-buf;
long in=(long)(bytes-buf);
/* this is a hint there is size information in there! ;-) */
while(--in) {
/* 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
do the TLS stuff */
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)
return result;
}
@@ -2148,7 +2151,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
state(conn, FTP_STOP); /* this phase is over */
}
else {
failf(data, "%s", buf+4);
failf(data, "RETR response: %03d", ftpcode);
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)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
infof(data, "We have successfully logged in\n");
#ifdef HAVE_KRB4
if(data->set.krb4) {
if(conn->data->set.krb4) {
/* We are logged in, asked to use Kerberos. Set the requested
* protection level
*/
@@ -2276,7 +2277,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
static const char * const ftpauth[] = {
"SSL", "TLS"
};
size_t nread;
size_t nread = 0;
if(ftp->sendleft) {
/* 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)) {
/* Curl_SSLConnect is BLOCKING */
result = Curl_SSLConnect(conn, FIRSTSOCKET);
/* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) {
conn->protocol |= PROT_FTPS;
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! */
infof(data, "protocol connect phase DONE\n");
DEBUGF(infof(data, "protocol connect phase DONE\n"));
break;
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 */
ftp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
timeout_ms);
(int)timeout_ms);
if(rc == -1) {
failf(data, "select error");
@@ -2748,7 +2749,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
/* BLOCKING */
/* FTPS is simply ftp with SSL for the control channel */
/* now, perform the SSL initialization for this socket */
result = Curl_SSLConnect(conn, FIRSTSOCKET);
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(result)
return result;
}
@@ -2820,7 +2821,8 @@ CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
if(data->set.upload) {
if((-1 != data->set.infilesize) &&
(data->set.infilesize != *ftp->bytecountp) &&
!data->set.crlf) {
!data->set.crlf &&
!ftp->no_transfer) {
failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
" out of %" FORMAT_OFF_T " bytes)",
*ftp->bytecountp, data->set.infilesize);
@@ -3025,7 +3027,6 @@ static CURLcode ftp_range(struct connectdata *conn)
curl_off_t totalsize=-1;
char *ptr;
char *ptr2;
struct SessionHandle *data = conn->data;
struct FTP *ftp = conn->proto.ftp;
if(conn->bits.use_range && conn->range) {
@@ -3040,26 +3041,29 @@ static CURLcode ftp_range(struct connectdata *conn)
if((-1 == to) && (from>=0)) {
/* X - */
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) {
/* -Y */
totalsize = -from;
conn->maxdownload = -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 {
/* X-Y */
totalsize = to-from;
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
conn->resume_from = from;
infof(data, "FTP RANGE from %" FORMAT_OFF_T
" getting %" FORMAT_OFF_T " bytes\n", from, conn->maxdownload);
DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
" getting %" FORMAT_OFF_T " bytes\n",
from, conn->maxdownload));
}
infof(data, "range-download from %" FORMAT_OFF_T
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
from, to, conn->maxdownload);
DEBUGF(infof(conn->data, "range-download from %" FORMAT_OFF_T
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
from, to, conn->maxdownload));
ftp->dont_check = TRUE; /* dont check for successful transfer */
}
return CURLE_OK;
@@ -3081,7 +3085,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
/* the ftp struct is inited in Curl_ftp_connect() */
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) {
/* 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);
/* end of transfer */
infof(data, "DO-MORE phase ends\n");
DEBUGF(infof(data, "DO-MORE phase ends\n"));
return result;
}
@@ -3140,9 +3144,8 @@ CURLcode ftp_perform(struct connectdata *conn,
{
/* this is FTP and no proxy */
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 */
@@ -3161,7 +3164,7 @@ CURLcode ftp_perform(struct connectdata *conn,
*connected = conn->bits.tcpconnect;
if(*dophase_done)
infof(data, "DO phase is comlete\n");
DEBUGF(infof(conn->data, "DO phase is comlete\n"));
return result;
}
@@ -3818,7 +3821,7 @@ CURLcode Curl_ftp_doing(struct connectdata *conn,
if(*dophase_done) {
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;
}

View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -33,7 +33,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include "memory.h"
#include "ssluse.h"
#include "sslgen.h"
/* Make this the last #include */
#include "memdebug.h"
@@ -182,7 +182,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
*param_longp = data->info.numconnects;
break;
case CURLINFO_SSL_ENGINES:
*param_slistp = Curl_SSL_engines_list(data);
*param_slistp = Curl_ssl_engines_list(data);
break;
default:
return CURLE_BAD_FUNCTION_ARGUMENT;

490
lib/gtls.c Normal file
View 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
View 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

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else

View File

@@ -26,8 +26,6 @@
#include <string.h>
#include <errno.h>
#define _REENTRANT
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <malloc.h>
#else
@@ -550,7 +548,7 @@ CURLcode Curl_resolv_fdset(struct connectdata *conn,
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
FD_SET(td->dummy_sock,write_fd_set);
*max_fdp = td->dummy_sock;
*max_fdp = (int)td->dummy_sock;
}
(void) read_fd_set;
return CURLE_OK;

View File

@@ -85,7 +85,7 @@
#include "base64.h"
#include "cookie.h"
#include "strequal.h"
#include "ssluse.h"
#include "sslgen.h"
#include "http_digest.h"
#include "http_ntlm.h"
#include "http_negotiate.h"
@@ -416,7 +416,7 @@ Curl_http_output_auth(struct connectdata *conn,
/* Send proxy authentication header if needed */
if (conn->bits.httpproxy &&
(conn->bits.tunnel_proxy == proxytunnel)) {
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
#ifdef USE_NTLM
if(authproxy->picked == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
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
host due to a location-follow, we do some weirdo checks here */
if(!data->state.this_is_a_follow ||
conn->bits.netrc ||
!data->state.first_host ||
curl_strequal(data->state.first_host, conn->host.name) ||
data->set.http_disable_hostname_check_before_authentication) {
@@ -484,7 +485,7 @@ Curl_http_output_auth(struct connectdata *conn,
}
else
#endif
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
#ifdef USE_NTLM
if(authhost->picked == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, FALSE);
@@ -597,7 +598,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
}
else
#endif
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
#ifdef USE_NTLM
/* NTLM support requires the SSL crypto libs */
if(checkprefix("NTLM", start)) {
*availp |= CURLAUTH_NTLM;
@@ -810,6 +811,8 @@ struct send_buffer {
};
typedef struct send_buffer send_buffer;
static CURLcode add_custom_headers(struct connectdata *conn,
send_buffer *req_buffer);
static CURLcode
add_buffer(send_buffer *in, const void *inptr, size_t size);
@@ -884,34 +887,47 @@ CURLcode add_buffer_send(send_buffer *in,
*bytes_written += amount;
if((size_t)amount != size) {
/* The whole request could not be sent in one system call. We must queue
it up and send it later when we get the chance. We must not loop here
and wait until it might work again. */
if(http) {
if((size_t)amount != size) {
/* The whole request could not be sent in one system call. We must
queue it up and send it later when we get the chance. We must not
loop here and wait until it might work again. */
size -= amount;
size -= amount;
ptr = in->buffer + amount;
ptr = in->buffer + amount;
/* backup the currently set pointers */
http->backup.fread = conn->fread;
http->backup.fread_in = conn->fread_in;
http->backup.postdata = http->postdata;
http->backup.postsize = http->postsize;
/* backup the currently set pointers */
http->backup.fread = conn->fread;
http->backup.fread_in = conn->fread_in;
http->backup.postdata = http->postdata;
http->backup.postsize = http->postsize;
/* set the new pointers for the request-sending */
conn->fread = (curl_read_callback)readmoredata;
conn->fread_in = (void *)conn;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
/* set the new pointers for the request-sending */
conn->fread = (curl_read_callback)readmoredata;
conn->fread_in = (void *)conn;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
http->send_buffer = in;
http->sending = HTTPSEND_REQUEST;
http->send_buffer = in;
http->sending = HTTPSEND_REQUEST;
return CURLE_OK;
return CURLE_OK;
}
http->sending = HTTPSEND_BODY;
/* 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;
}
http->sending = HTTPSEND_BODY;
/* the full buffer was sent, clean up and return */
}
if(in->buffer)
free(in->buffer);
@@ -1037,9 +1053,15 @@ Curl_compareheader(char *headerline, /* line to check */
}
/*
* ConnectHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
* function will issue the necessary commands to get a seamless tunnel through
* this proxy. After that, the socket can be used just as a normal socket.
* ConnectHTTPProxyTunnel() requires that we're connected to a HTTP
* proxy. This function will issue the necessary commands to get a seamless
* 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,
@@ -1062,6 +1084,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
char *line_start;
char *host_port;
curl_socket_t tunnelsocket = conn->sock[sockindex];
send_buffer *req_buffer;
#define SELECT_OK 0
#define SELECT_ERROR 1
@@ -1079,26 +1102,66 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
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);
if(!host_port)
return CURLE_OUT_OF_MEMORY;
/* Setup the proxy-authorization header, if any */
result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
if(CURLE_OK == result) {
/* OK, now send the connect request to the proxy */
result =
Curl_sendf(tunnelsocket, conn,
"CONNECT %s:%d HTTP/1.0\015\012"
"%s"
"%s"
"\r\n",
hostname, remote_port,
conn->allocptr.proxyuserpwd?
conn->allocptr.proxyuserpwd:"",
data->set.useragent?conn->allocptr.uagent:""
);
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 =
add_bufferf(req_buffer,
"CONNECT %s:%d HTTP/1.0\r\n"
"%s" /* Host: */
"%s" /* Proxy-Authorization */
"%s" /* User-Agent */
"%s", /* Proxy-Connection */
hostname, remote_port,
host,
conn->allocptr.proxyuserpwd?
conn->allocptr.proxyuserpwd:"",
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)
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) {
/* now, perform the SSL initialization for this socket */
result = Curl_SSLConnect(conn, FIRSTSOCKET);
/* perform SSL initialization for this socket */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(result)
return result;
}
@@ -1347,6 +1410,62 @@ CURLcode Curl_http_done(struct connectdata *conn,
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
* 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 = "Pragma: no-cache\r\n";
http->p_pragma =
(!checkheaders(data, "Pragma:") &&
(conn->bits.httpproxy && !conn->bits.tunnel_proxy) )?
"Pragma: no-cache\r\n":NULL;
if(!checkheaders(data, "Accept:"))
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";
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 */
/* initialize a dynamic send-buffer */
@@ -1728,6 +1848,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
"%s" /* accept */
"%s" /* accept-encoding */
"%s" /* referer */
"%s" /* Proxy-Connection */
"%s",/* transfer-encoding */
request,
@@ -1746,6 +1867,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
conn->allocptr.accept_encoding:"",
(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
);
@@ -1852,33 +1975,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
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;
}
result = add_custom_headers(conn, req_buffer);
if(result)
return result;
http->postdata = NULL; /* nothing to post at this point */
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
@@ -1928,18 +2027,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
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)
return result;
data->set.expect100header = TRUE;
}
result = expect100(data, req_buffer);
if(result)
return result;
if(!checkheaders(data, "Content-Type:")) {
/* Get Content-Type: line from Curl_formpostheader.
@@ -2002,18 +2092,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
!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)
return result;
data->set.expect100header = TRUE;
}
result = expect100(data, req_buffer);
if(result)
return result;
result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */
if(result)
@@ -2121,21 +2202,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
!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) */
add_bufferf(req_buffer,
"Expect: 100-continue\r\n");
data->set.expect100header = TRUE;
}
result = expect100(data, req_buffer);
if(result)
return result;
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
}
}
else {
result = expect100(data, req_buffer);
if(result)
return result;
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
if(data->set.postfieldsize) {

View File

@@ -30,8 +30,7 @@
*/
#ifndef CURL_DISABLE_HTTP
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
#ifdef USE_NTLM
/* -- WIN32 approved -- */
#include <stdio.h>
@@ -769,5 +768,5 @@ Curl_ntlm_cleanup(struct connectdata *conn)
#endif
}
#endif /* USE_SSLEAY */
#endif /* USE_NTLM */
#endif /* !CURL_DISABLE_HTTP */

View File

@@ -39,6 +39,9 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
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 */

View File

@@ -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;
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);
}

View File

@@ -114,7 +114,7 @@ inet_pton4(const char *src, unsigned char *dst)
const char *pch;
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)
return (0);

View File

@@ -1,10 +1,10 @@
#ifndef __KRB4_H
#define __KRB4_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -12,7 +12,7 @@
* 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.

View File

@@ -43,6 +43,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
$(TMP_DIR)/ftp.o \
$(TMP_DIR)/getenv.o \
$(TMP_DIR)/getinfo.o \
$(TMP_DIR)/gtls.o \
$(TMP_DIR)/hash.o \
$(TMP_DIR)/hostares.o \
$(TMP_DIR)/hostasyn.o \
@@ -73,6 +74,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
$(TMP_DIR)/sendf.o \
$(TMP_DIR)/share.o \
$(TMP_DIR)/speedcheck.o \
$(TMP_DIR)/sslgen.o \
$(TMP_DIR)/ssluse.o \
$(TMP_DIR)/strequal.o \
$(TMP_DIR)/strerror.o \

View File

@@ -10,16 +10,15 @@ ATCPSDKI= /GG/netinclude
CC = gcc
CFLAGS = -I$(ATCPSDKI) -m68020-60 -noixemul -I. -I../include -W -Wall
OBJS = \
amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c \
easy.c escape.c file.c formdata.c ftp.c getenv.c \
getinfo.c hash.c hostip.c hostip4.c hostsyn.c http.c http_chunks.c \
http_digest.c http_negotiate.c http_ntlm.c if2ip.c inet_ntop.c \
inet_pton.c krb4.c ldap.c \
llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
progress.c security.c select.c sendf.c share.c speedcheck.c \
ssluse.c strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c
OBJS = amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c easy.c \
escape.c file.c formdata.c ftp.c getenv.c getinfo.c hash.c hostip.c \
hostip4.c hostsyn.c http.c http_chunks.c http_digest.c \
http_negotiate.c http_ntlm.c if2ip.c inet_ntop.c inet_pton.c krb4.c \
ldap.c llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
progress.c security.c select.c sendf.c share.c speedcheck.c ssluse.c \
strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c \
sslgen.c gtls.c
all: $(OBJS:.c=.o)
ar cru libcurl.a $(OBJS:.c=.o)
ranlib libcurl.a

View File

@@ -32,243 +32,264 @@ realclean vclean: clean
# DO NOT DELETE THIS LINE
$(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/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 \
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 \
../include/curl/mprintf.h memdebug.h
file.h speedcheck.h getinfo.h transfer.h url.h memory.h parsedate.h \
../include/curl/mprintf.h memdebug.h memory.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 \
../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 \
../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 \
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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 sendf.h progress.h \
../include/curl/mprintf.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 \
sendf.h progress.h ../include/curl/mprintf.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/multi.h formdata.h strequal.h memory.h \
../include/curl/mprintf.h memdebug.h
../include/curl/multi.h ../include/curl/curl.h formdata.h strequal.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 \
../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 \
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 \
../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 \
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.h \
base64.h strequal.h ssluse.h http_digest.h http_ntlm.h http_negotiate.h \
url.h share.h http.h memory.h select.h ../include/curl/mprintf.h \
memdebug.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 parsedate.h \
../include/curl/mprintf.h memdebug.h memory.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/multi.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 sendf.h connect.h \
../include/curl/mprintf.h memory.h strerror.h memdebug.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 \
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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 sendf.h if2ip.h progress.h \
transfer.h escape.h http.h ftp.h strtoofft.h strequal.h ssluse.h \
connect.h strerror.h memory.h inet_ntop.h select.h \
../include/curl/mprintf.h memdebug.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 \
sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h strtoofft.h \
strequal.h sslgen.h connect.h strerror.h memory.h inet_ntop.h select.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 \
../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 \
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 \
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 \
ca-bundle.h ../include/curl/mprintf.h memory.h memdebug.h
multiif.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h connect.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 \
../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 \
http_chunks.h hostip.h hash.h llist.h transfer.h sendf.h progress.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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h memdebug.h
$(OBJ_DIR)/if2ip.o: if2ip.c setup.h config.h if2ip.h inet_ntop.h memory.h \
../include/curl/curl.h ../include/curl/curlver.h ../include/curl/easy.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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 sendf.h speedcheck.h
$(OBJ_DIR)/ldap.o: ldap.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 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
../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 \
sendf.h speedcheck.h
$(OBJ_DIR)/ldap.o: ldap.c setup.h config.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/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 \
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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 ../include/curl/mprintf.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 \
sslgen.h ../include/curl/mprintf.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/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 \
../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 \
../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 \
../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 \
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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h netrc.h strequal.h strtok.h memory.h \
../include/curl/mprintf.h memdebug.h
../include/curl/multi.h ../include/curl/curl.h netrc.h strequal.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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 getinfo.h memory.h memdebug.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 \
getinfo.h memory.h sslgen.h memdebug.h memory.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/multi.h strequal.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 netrc.h content_encoding.h \
transfer.h sendf.h speedcheck.h progress.h http.h url.h getinfo.h \
ssluse.h http_digest.h http_ntlm.h http_negotiate.h share.h memory.h \
select.h ../include/curl/mprintf.h memdebug.h
../include/curl/multi.h ../include/curl/curl.h strequal.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 \
netrc.h content_encoding.h transfer.h sendf.h speedcheck.h progress.h \
http.h url.h getinfo.h sslgen.h http_digest.h http_ntlm.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 \
../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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 transfer.h ssluse.h url.h \
getinfo.h share.h memory.h progress.h ../include/curl/mprintf.h \
memdebug.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 \
transfer.h sslgen.h url.h getinfo.h share.h memory.h progress.h \
easyif.h ../include/curl/mprintf.h memdebug.h memory.h
$(OBJ_DIR)/security.o: security.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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h ../include/curl/mprintf.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 \
memory.h memdebug.h
../include/curl/multi.h ../include/curl/curl.h \
../include/curl/mprintf.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 memory.h memdebug.h memory.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/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 \
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)/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/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 \
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 \
../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 \
../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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 transfer.h url.h connect.h \
progress.h memory.h memdebug.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 \
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 \
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/easy.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 content_encoding.h \
memory.h memdebug.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 \
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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.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 share.h memory.h memdebug.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 \
share.h memory.h memdebug.h memory.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/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 \
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 \
memdebug.h
memdebug.h memory.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_ntlm.o: http_ntlm.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 \
../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 \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h strerror.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 ../include/curl/mprintf.h
../include/curl/multi.h ../include/curl/curl.h strerror.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 \
../include/curl/mprintf.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/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 \
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 \
../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 \
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 \
../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 \
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 \
../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 \
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 \
../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 \
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 \
../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 \
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)/parsedate.o: parsedate.c setup.h config.h ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/easy.h \
../include/curl/multi.h
$(OBJ_DIR)/select.o: select.c setup.h config.h select.h
../include/curl/multi.h ../include/curl/curl.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

View File

@@ -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
* 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_Init(&ctx);
MD5_Update(&ctx, input, strlen((char *)input));
MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
MD5_Final(outbuffer, &ctx);
}

View File

@@ -759,8 +759,8 @@ static int dprintf_formatf(
*w-- = digits[num % base];
num /= base;
}
width -= workend - w;
prec -= workend - w;
width -= (long)(workend - w);
prec -= (long)(workend - w);
if (alt && base == 8 && prec <= 0) {
*w-- = '0';
@@ -839,7 +839,7 @@ static int dprintf_formatf(
if (prec != -1 && (size_t) prec < len)
len = prec;
width -= len;
width -= (long)len;
if (p->flags & FLAGS_ALT)
OUTCHAR('"');
@@ -869,7 +869,7 @@ static int dprintf_formatf(
base = 16;
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
alt = 1;
num = (unsigned long) ptr;
num = (size_t) ptr;
is_neg = 0;
goto number;
}

View File

@@ -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
* 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");
if (override) {
printf("NETRC: overridden " NETRC " file: %s\n", home);
fprintf(stderr, "NETRC: overridden " NETRC " file: %s\n", override);
netrcfile = override;
netrc_alloc = TRUE;
}
@@ -171,7 +171,7 @@ int Curl_parsenetrc(char *host,
/* and yes, this is our host! */
state=HOSTVALID;
#ifdef _NETRC_DEBUG
printf("HOST: %s\n", tok);
fprintf(stderr, "HOST: %s\n", tok);
#endif
retcode=0; /* we did find our host */
}
@@ -188,7 +188,7 @@ int Curl_parsenetrc(char *host,
else {
strncpy(login, tok, LOGINSIZE-1);
#ifdef _NETRC_DEBUG
printf("LOGIN: %s\n", login);
fprintf(stderr, "LOGIN: %s\n", login);
#endif
}
state_login=0;
@@ -197,7 +197,7 @@ int Curl_parsenetrc(char *host,
if (state_our_login || !specific_login) {
strncpy(password, tok, PASSWORDSIZE-1);
#ifdef _NETRC_DEBUG
printf("PASSWORD: %s\n", password);
fprintf(stderr, "PASSWORD: %s\n", password);
#endif
}
state_password=0;

View File

@@ -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
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))
return -1; /* time_t overflow */

View File

@@ -151,7 +151,7 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
}
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));
if (r < 0)
@@ -236,7 +236,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
}
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));
if (r < 0)

View File

@@ -44,13 +44,18 @@
#include "urldata.h"
#include "sendf.h"
#include "connect.h" /* for the Curl_ourerrno() proto */
#include "sslgen.h"
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h>
#ifdef HAVE_KRB4
#include "krb4.h"
#else
#define Curl_sec_write(a,b,c,d) -1
#define Curl_sec_read(a,b,c,d) -1
#endif
#include <string.h>
#include "memory.h"
#include "strerror.h"
@@ -233,63 +238,18 @@ CURLcode Curl_write(struct connectdata *conn,
{
ssize_t bytes_written;
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]);
/* 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) {
err = SSL_get_error(conn->ssl[num].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. */
*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;
}
if (conn->ssl[num].use)
/* only TRUE if SSL enabled */
bytes_written = Curl_ssl_send(conn, num, mem, len);
else {
#else
(void)conn;
#endif
#ifdef HAVE_KRB4
if(conn->sec_complete) {
if(conn->sec_complete)
/* only TRUE if krb4 enabled */
bytes_written = Curl_sec_write(conn, sockfd, mem, len);
}
else
#endif /* HAVE_KRB4 */
{
bytes_written = (ssize_t)swrite(sockfd, mem, len);
}
if(-1 == bytes_written) {
int err = Curl_ourerrno();
@@ -311,10 +271,7 @@ CURLcode Curl_write(struct connectdata *conn,
failf(conn->data, "Send failure: %s",
Curl_strerror(conn, err));
}
#ifdef USE_SSLEAY
}
#endif
*written = bytes_written;
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 nread;
#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. */
@@ -384,45 +341,17 @@ int Curl_read(struct connectdata *conn, /* connection data */
*n=0; /* reset amount to zero */
if (conn->ssl[num].use) {
nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, (int)buffersize);
if(conn->ssl[num].use) {
nread = Curl_ssl_recv(conn, num, buf, buffersize);
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() */
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;
}
}
if(nread == -1)
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
}
else {
#else
(void)conn;
#endif
*n=0; /* reset amount to zero */
#ifdef HAVE_KRB4
if(conn->sec_complete)
nread = Curl_sec_read(conn, sockfd, buf, buffersize);
else
#endif
nread = sread(sockfd, buf, buffersize);
if(-1 == nread) {
@@ -434,10 +363,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
#endif
return -1;
}
#ifdef USE_SSLEAY
}
#endif /* USE_SSLEAY */
*n = nread;
return CURLE_OK;
}

View File

@@ -30,10 +30,14 @@
#define CURL_DISABLE_DICT
#define CURL_DISABLE_FILE
#define CURL_DISABLE_GOPHER
#endif
#endif /* HTTP_ONLY */
#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
#endif
@@ -46,9 +50,9 @@
#ifdef WIN32
/* hand-modified win32 config.h! */
#include "config-win32.h"
#endif
#endif
#endif
#endif /* WIN32 */
#endif /* WIN32_WCE */
#endif /* HAVE_CONFIG_H */
#ifdef macintosh
/* hand-modified MacOS config.h! */
@@ -78,7 +82,7 @@ typedef unsigned char bool;
#ifdef _MSC_VER
#define LONG_LONG __int64
#define ENABLE_64BIT
#endif
#endif /* _MSC_VER */
#endif /* HAVE_LONGLONG */
#ifndef SIZEOF_CURL_OFF_T
@@ -93,15 +97,15 @@ typedef unsigned char bool;
#define FORMAT_OFF_T "lld"
#else
#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
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
need it. */
#define _REENTRANT
/*#endif */
#endif
#include <stdio.h>
#ifdef HAVE_ASSERT_H
@@ -131,7 +135,7 @@ typedef unsigned char bool;
#define HAVE_MSG_NOSIGNAL 1 /* we have MSG_NOSIGNAL */
#else
#define SEND_4TH_ARG 0
#endif
#endif /* MSG_NOSIGNAL */
/* To make large file support transparent even on Windows */
#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
@@ -143,7 +147,7 @@ typedef unsigned char bool;
#define fstat(fd,st) _fstati64(fd,st)
#else
#define struct_stat struct stat
#endif
#endif /* Win32 with large file support */
/* Below we define four functions. They should
1. close a socket
@@ -158,7 +162,7 @@ typedef unsigned char bool;
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
#endif
#endif /* WIN32_LEAN_AND_MEAN */
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h> /* required by telnet.c */
@@ -170,8 +174,11 @@ typedef unsigned char bool;
#if !defined(__GNUC__) || defined(__MINGW32__)
#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
#else
/* 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 swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
#define HAVE_ALARM
#endif
#endif /* !GNU or mingw */
#define DIR_CHAR "\\"
#define DOT_CHAR "_"
#else
#else /* WIN32 */
#ifdef DJGPP
#define sclose(x) close_s(x)
@@ -197,21 +204,21 @@ typedef unsigned char bool;
#undef word
#endif
#else
#else /* DJGPP */
#ifdef __BEOS__
#define sclose(x) closesocket(x)
#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)
#else
#else /* __BEOS__ */
#define sclose(x) close(x)
#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
#endif
#endif /* __BEOS__ */
#define HAVE_ALARM
#endif
#endif /* DJGPP */
#ifdef _AMIGASF
#undef HAVE_ALARM
@@ -231,7 +238,7 @@ typedef unsigned char bool;
int fileno( FILE *stream);
#endif
#endif
#endif /* WIN32 */
/* now typedef our socket type */
#ifdef WIN32
@@ -280,4 +287,18 @@ typedef int curl_socket_t;
#define HAVE_INET_NTOA_R_2_ARGS 1
#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 */

541
lib/sslgen.c Normal file
View 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
View 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

View File

@@ -22,8 +22,13 @@
***************************************************************************/
/*
* The original SSL code for curl was written by
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
* Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
* 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"
@@ -47,6 +52,7 @@
#include "connect.h" /* Curl_ourerrno() proto */
#include "strequal.h"
#include "select.h"
#include "sslgen.h"
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h>
@@ -447,8 +453,8 @@ int cert_stuff(struct connectdata *conn,
#endif
case SSL_FILETYPE_PKCS12:
if(!cert_done) {
failf(data, "file type P12 for private key not supported\n");
return 0;
failf(data, "file type P12 for private key not supported\n");
return 0;
}
break;
default:
@@ -519,27 +525,20 @@ static char *SSL_strerror(unsigned long error, char *buf, size_t size)
return (buf);
}
/* "global" init done? */
static int init_ssl=0;
/* we have the "SSL is seeded" boolean global for the application to
prevent multiple time-consuming seedings in vain */
static bool ssl_seeded = FALSE;
#endif /* USE_SSLEAY */
#ifdef USE_SSLEAY
/**
* Global SSL init
*
* @retval 0 error initializing SSL
* @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
ENGINE_load_builtin_engines();
#endif
@@ -551,57 +550,39 @@ int Curl_SSL_init(void)
if (!SSLeay_add_ssl_algorithms())
return 0;
init_ssl++; /* never again */
#else
/* SSL disabled, do nothing */
#endif
return 1;
}
/* Global cleanup */
void Curl_SSL_cleanup(void)
{
#endif /* USE_SSLEAY */
#ifdef USE_SSLEAY
if(init_ssl) {
/* only cleanup if we did a previous init */
/* Free the SSL error strings */
ERR_free_strings();
/* Global cleanup */
void Curl_ossl_cleanup(void)
{
/* Free the SSL error strings */
ERR_free_strings();
/* EVP_cleanup() removes all ciphers and digests from the
table. */
EVP_cleanup();
/* EVP_cleanup() removes all ciphers and digests from the
table. */
EVP_cleanup();
#ifdef HAVE_ENGINE_cleanup
ENGINE_cleanup();
ENGINE_cleanup();
#endif
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
/* this function was not present in 0.9.6b, but was added sometimes
later */
CRYPTO_cleanup_all_ex_data();
#endif
init_ssl=0; /* not inited any more */
}
#else
/* SSL disabled, do nothing */
/* this function was not present in 0.9.6b, but was added sometimes
later */
CRYPTO_cleanup_all_ex_data();
#endif
}
#ifndef USE_SSLEAY
void Curl_SSL_Close(struct connectdata *conn)
{
(void)conn;
}
#endif
#endif /* USE_SSLEAY */
/* 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)
ENGINE *e = ENGINE_by_id(engine);
@@ -633,11 +614,12 @@ CURLcode Curl_SSL_set_engine(struct SessionHandle *data, const char *engine)
#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 (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
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
(void) data;
#endif
return (CURLE_OK);
return CURLE_OK;
}
#endif /* USE_SSLEAY */
/* 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;
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
@@ -674,217 +657,62 @@ struct curl_slist *Curl_SSL_engines_list(struct SessionHandle *data)
/*
* 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;
/*
ERR_remove_state() frees the error queue associated with
thread pid. If pid == 0, the current thread will have its
error queue removed.
int i;
/*
ERR_remove_state() frees the error queue associated with
thread pid. If pid == 0, the current thread will have its
error queue removed.
Since error queue data structures are allocated
automatically for new threads, they must be freed when
threads are terminated in oder to avoid memory leaks.
*/
ERR_remove_state(0);
Since error queue data structures are allocated
automatically for new threads, they must be freed when
threads are terminated in oder to avoid memory leaks.
*/
ERR_remove_state(0);
for(i=0; i<2; i++) {
struct ssl_connect_data *connssl = &conn->ssl[i];
for(i=0; i<2; i++) {
struct ssl_connect_data *connssl = &conn->ssl[i];
if(connssl->handle) {
(void)SSL_shutdown(connssl->handle);
SSL_set_connect_state(connssl->handle);
if(connssl->handle) {
(void)SSL_shutdown(connssl->handle);
SSL_set_connect_state(connssl->handle);
SSL_free (connssl->handle);
connssl->handle = NULL;
}
if(connssl->ctx) {
SSL_CTX_free (connssl->ctx);
connssl->ctx = NULL;
}
connssl->use = FALSE; /* get back to ordinary socket usage */
SSL_free (connssl->handle);
connssl->handle = NULL;
}
}
}
/*
* 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;
if(connssl->ctx) {
SSL_CTX_free (connssl->ctx);
connssl->ctx = NULL;
}
connssl->use = FALSE; /* get back to ordinary socket usage */
}
*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)
void Curl_ossl_session_free(void *ptr)
{
if(session->sessionid) {
/* defensive check */
/* free the ID */
SSL_SESSION_free(session->sessionid);
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;
/* free the ID */
SSL_SESSION_free(ptr);
}
/*
* This function is called when the 'data' struct is going away. Close
* 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
if(data->state.engine) {
ENGINE_finish(data->state.engine);
ENGINE_free(data->state.engine);
data->state.engine = NULL;
}
#else
(void)data;
#endif
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,
const char *prefix,
ASN1_UTCTIME *tm)
@@ -1280,28 +1108,25 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
}
#endif
#ifdef USE_SSLEAY
/* ====================================================== */
CURLcode
Curl_SSLConnect(struct connectdata *conn,
int sockindex)
Curl_ossl_connect(struct connectdata *conn,
int sockindex)
{
CURLcode retcode = CURLE_OK;
#ifdef USE_SSLEAY
struct SessionHandle *data = conn->data;
int err;
long lerr;
int what;
char * str;
SSL_METHOD *req_method;
SSL_SESSION *ssl_sessionid=NULL;
void *ssl_sessionid=NULL;
ASN1_TIME *certdate;
curl_socket_t sockfd = conn->sock[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) {
/* Make funny stuff to get random input */
random_the_seed(data);
@@ -1447,19 +1272,16 @@ Curl_SSLConnect(struct connectdata *conn,
connssl->server_cert = 0x0;
if(!conn->bits.reuse) {
/* We're not re-using a connection, check if there's a cached ID we
can/should use here! */
if(!Get_SSL_Session(conn, &ssl_sessionid)) {
/* we got a session id, use it! */
if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
failf(data, "SSL: SSL_set_session failed: %s",
ERR_error_string(ERR_get_error(),NULL));
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
infof (data, "SSL re-using session ID\n");
/* Check if there's a cached ID we can/should use here! */
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
/* we got a session id, use it! */
if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
failf(data, "SSL: SSL_set_session failed: %s",
ERR_error_string(ERR_get_error(),NULL));
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
infof (data, "SSL re-using session ID\n");
}
/* pass the raw socket into the SSL layers */
@@ -1473,16 +1295,13 @@ Curl_SSLConnect(struct connectdata *conn,
int writefd;
int readfd;
long timeout_ms;
long has_passed;
/* Find out if any timeout is set. If not, use 300 seconds.
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
allow for the connect call */
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 */
if(data->set.timeout &&
@@ -1490,20 +1309,22 @@ Curl_SSLConnect(struct connectdata *conn,
timeout_ms = data->set.timeout*1000;
else
timeout_ms = data->set.connecttimeout*1000;
/* 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;
}
}
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 */
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;
}
readfd = CURL_SOCKET_BAD;
writefd = CURL_SOCKET_BAD;
@@ -1586,12 +1407,7 @@ Curl_SSLConnect(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
else {
#if !defined(WIN32) && defined(EINTR)
/* 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 */
/* anything that gets here is fatally bad */
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
return CURLE_SSL_CONNECT_ERROR;
}
@@ -1605,9 +1421,30 @@ Curl_SSLConnect(struct connectdata *conn,
if(!ssl_sessionid) {
/* Since this is not a cached session ID, then we want to stach this one
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) {
failf(data,"failure to store ssl session");
failf(data, "failed to store ssl session");
return retcode;
}
}
@@ -1686,9 +1523,145 @@ Curl_SSLConnect(struct connectdata *conn,
X509_free(connssl->server_cert);
connssl->server_cert = NULL;
#else /* USE_SSLEAY */
(void)conn;
(void)sockindex;
#endif
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 */

View File

@@ -22,27 +22,43 @@
*
* $Id$
***************************************************************************/
/*
* This header should only be needed to get included by sslgen.c and ssluse.c
*/
#include "urldata.h"
CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex);
int Curl_SSL_init(void); /* Global SSL init */
void Curl_SSL_cleanup(void); /* Global SSL cleanup */
/* 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);
CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
/* tell OpenSSL to close down all open information regarding connections (and
thus session ID caching etc) */
int Curl_ossl_close_all(struct SessionHandle *data);
/* 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 */
CURLcode Curl_SSL_set_engine_default(struct SessionHandle *data);
/* function provided for the generic SSL-layer, called when a session id
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 */
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

View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -25,14 +25,6 @@
#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 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
#define strlcat(x,y,z) Curl_strlcat(x,y,z)
size_t Curl_strlcat(char *dst, const char *src, size_t siz);
#endif
size_t strlcat(char *dst, const char *src, size_t siz);
#endif

View File

@@ -571,7 +571,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
else {
if (!get_winsock_error(err, buf, max) &&
!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);
}
#endif

View File

@@ -94,7 +94,7 @@
#include "http.h"
#include "url.h"
#include "getinfo.h"
#include "ssluse.h"
#include "sslgen.h"
#include "http_digest.h"
#include "http_ntlm.h"
#include "http_negotiate.h"
@@ -243,6 +243,7 @@ CURLcode Curl_readrewind(struct connectdata *conn)
}
#ifdef USE_SSLEAY
/* FIX: this is nasty OpenSSL-specific code that really shouldn't be here */
static int data_pending(struct connectdata *conn)
{
if(conn->ssl[FIRSTSOCKET].handle)
@@ -269,9 +270,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
ssize_t nread; /* number of bytes read */
int didwhat=0;
int fd_read;
int fd_write;
int select_res;
curl_socket_t fd_read;
curl_socket_t fd_write;
curl_socket_t select_res;
curl_off_t contentlength;
@@ -286,6 +287,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
fd_write = CURL_SOCKET_BAD;
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 {
/* 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 */
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 */
@@ -519,8 +524,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(result)
return result;
data->info.header_size += headerlen;
conn->headerbytecount += headerlen;
data->info.header_size += (long)headerlen;
conn->headerbytecount += (long)headerlen;
conn->deductheadercount =
(100 == k->httpcode)?conn->headerbytecount:0;
@@ -696,6 +701,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
* fields. */
conn->size=0;
conn->maxdownload=0;
k->ignorecl = TRUE; /* ignore Content-Length headers */
break;
default:
/* nothing */
@@ -712,7 +718,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
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
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)) {
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
if (data->set.max_filesize &&
@@ -898,7 +904,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
&secs);
if(data->set.get_filetime)
data->info.filetime = k->timeofdoc;
data->info.filetime = (long)k->timeofdoc;
}
else if((checkprefix("WWW-Authenticate:", k->p) &&
(401 == k->httpcode)) ||
@@ -961,8 +967,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(result)
return result;
data->info.header_size += k->hbuflen;
conn->headerbytecount += k->hbuflen;
data->info.header_size += (long)k->hbuflen;
conn->headerbytecount += (long)k->hbuflen;
/* reset hbufp pointer && hbuflen */
k->hbufp = data->state.headerbuff;
@@ -1385,7 +1391,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
conn->size - k->bytecount);
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)) {
/*
* 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 */
if(conn->keep.keepon & KEEP_READ) {
FD_SET(conn->sockfd, read_fd_set);
*max_fd = conn->sockfd;
*max_fd = (int)conn->sockfd;
}
if(conn->keep.keepon & KEEP_WRITE) {
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
to compare it nicely */
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
warnings! */
@@ -1551,8 +1558,8 @@ Transfer(struct connectdata *conn)
return CURLE_OK;
while (!done) {
int fd_read;
int fd_write;
curl_socket_t fd_read;
curl_socket_t fd_write;
int interval_ms;
interval_ms = 1 * 1000;
@@ -1597,20 +1604,17 @@ Transfer(struct connectdata *conn)
*/
CURLcode Curl_pretransfer(struct SessionHandle *data)
{
CURLcode res;
if(!data->change.url)
/* we can't do anything wihout URL */
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 before any transfer takes place. */
CURLcode res = Curl_SSL_InitSessions(data, data->set.ssl.numsessions);
if(res)
return res;
}
#endif
/* 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
before any transfer takes place. */
res = Curl_ssl_initsessions(data, data->set.ssl.numsessions);
if(res)
return res;
data->set.followlocation=0; /* reset the location-follow counter */
data->state.this_is_a_follow = FALSE; /* reset this */

Some files were not shown because too many files have changed in this diff Show More