Compare commits

...

206 Commits

Author SHA1 Message Date
Daniel Stenberg
874fc8228a stand clear for release time 2005-03-04 13:41:46 +00:00
Daniel Stenberg
6f752c64bc Dave Dribin made it possible to set CURLOPT_COOKIEFILE to "" to activate
the cookie "engine" without having to provide an empty or non-existing file.
2005-03-04 00:26:50 +00:00
Daniel Stenberg
ccb7950c4c killed trailing whitespace 2005-03-04 00:24:52 +00:00
Daniel Stenberg
750e771376 killed trailing whitespace 2005-03-04 00:14:45 +00:00
Daniel Stenberg
7012a4a291 Rene Rebe fixed a -# crash when more data than expected was retrieved. 2005-03-04 00:12:02 +00:00
Daniel Stenberg
40ab20a252 new VB binding 2005-03-03 23:27:09 +00:00
Daniel Stenberg
6af315e50c VB binding, updated the .NET info 2005-03-03 23:25:13 +00:00
Daniel Stenberg
861b5e608b mention buffer overflows fixed 2005-03-03 13:13:21 +00:00
Daniel Stenberg
f61917594e fix the distribution files 2005-03-03 06:51:31 +00:00
Dan Fandrich
0ddab51ad8 Fix for a base64 decode heap buffer overflow vulnerability. 2005-02-28 23:54:17 +00:00
Dan Fandrich
9798432f56 Fixed some compiler warnings. Fixed a low incidence memory leak in the test server. 2005-02-24 18:54:23 +00:00
Daniel Stenberg
5faf52619d Updated as suggested by Samuel Daz Garca 2005-02-22 18:39:40 +00:00
Daniel Stenberg
f8b4ba80e0 krb4 fixed 2005-02-22 12:20:30 +00:00
Daniel Stenberg
527f70e540 Curl_base64_decode() now returns an allocated buffer 2005-02-22 12:10:30 +00:00
Daniel Stenberg
19f66c7575 Thanks for the notification iDEFENCE. We are the "initial vendor" and we sure
got no notification, no mail, no nothing.

You didn't even bother to mail us when you went public with this. Cool.

NTLM buffer overflow fix, as reported here:

http://www.securityfocus.com/archive/1/391042
2005-02-22 07:44:14 +00:00
Daniel Stenberg
b7721deb02 added test case 234 which is like 233 but uses --location-trusted instead so
thus the second request to the new host will use authentication fine
2005-02-19 22:33:06 +00:00
Daniel Stenberg
5ba188ab2d Ralph Mitchell reported a flaw when you used a proxy with auth, and you
requested data from a host and then followed a redirect to another
host. libcurl then didn't use the proxy-auth properly in the second request,
due to the host-only check for original host name wrongly being extended to
the proxy auth as well. Added test case 233 to verify the flaw and that the
fix removed the problem.
2005-02-18 23:53:07 +00:00
Daniel Stenberg
eadfd78c2e socket leak, mingw build 2005-02-18 11:54:52 +00:00
Daniel Stenberg
4d815c9990 Based on Mike Dobbs' report, BUILDING_LIBCURL is now defined in here if it
runs to build with mingw.
2005-02-18 08:24:53 +00:00
Daniel Stenberg
176981b529 close the socket properly when returning error due to failing localbind
Bug report #1124588 by David
2005-02-17 14:45:03 +00:00
Daniel Stenberg
85baebd0d4 mention filename= for the -F 2005-02-17 07:47:32 +00:00
Daniel Stenberg
ac022b2e30 Christopher R. Palmer reported a problem with HTTP-POSTing using "anyauth"
that picks NTLM. Thanks to David Byron letting me test NTLM against his
servers, I could quickly repeat and fix the problem. It turned out to be:

When libcurl POSTs without knowing/using an authentication and it gets back a
list of types from which it picks NTLM, it needs to either continue sending
its data if it keeps the connection alive, or not send the data but close the
connection. Then do the first step in the NTLM auth. libcurl didn't send the
data nor close the connection but simply read the response-body and then sent
the first negotiation step. Which then failed miserably of course. The fixed
version forces a connection if there is more than 2000 bytes left to send.
2005-02-16 14:31:23 +00:00
Daniel Stenberg
f169b750b8 check for ENGINE_load_builtin_engines() as well if engine is around 2005-02-14 23:50:29 +00:00
Marty Kuhrt
86295eef13 changed config-vms info 2005-02-14 22:37:59 +00:00
Marty Kuhrt
32d60b2714 changed curlmsg.* entries to see if CVS would ignore it now 2005-02-14 22:36:21 +00:00
Daniel Stenberg
0a3065a2f2 Rename Curl_pretransfersec() to *_second_connect() since it does not just
do pretransfer stuff like Curl_pretransfer().
2005-02-14 09:30:40 +00:00
Daniel Stenberg
b98faaa8c0 Fixed bad krb4 code. It always tried to use krb4 if built enabled. 2005-02-11 22:50:57 +00:00
Marty Kuhrt
73772323c9 rename amigaos.c and nwlib.c if they exist before building 2005-02-11 22:42:16 +00:00
Daniel Stenberg
98389066e2 Removed per Marty's request: The .h_* files aren't needed anymore, I
consolidated them into one file called config-vms.h.  The curlmsg.h and .sdl
files are generated from the curlmsg.msg file and, thus, shouldn't be in the
dist.
2005-02-11 22:05:04 +00:00
Marty Kuhrt
fb53ed4c1f re-sync'd with curlmsg.msg 2005-02-11 21:17:23 +00:00
Marty Kuhrt
e719eb5b81 ignore curlmsg.h and .sdl as they are generated by curlmsg.msg 2005-02-11 21:07:35 +00:00
Marty Kuhrt
3858063bcd sync'd error codes with include/curl.h 2005-02-11 21:01:52 +00:00
Marty Kuhrt
d4f5fea840 Added $Id$ and pre-exisiting logical check 2005-02-11 20:17:21 +00:00
Daniel Stenberg
22c1d48cb2 remove the check for strftime(), we don't need it 2005-02-11 19:34:05 +00:00
Daniel Stenberg
e7cefd684b Removed all uses of strftime() since it uses the localised version of the
week day names and month names and servers don't like that.
2005-02-11 00:03:49 +00:00
Daniel Stenberg
d2485e4f20 valgrind stuff for test suite, vms build and more 2005-02-10 08:57:23 +00:00
Daniel Stenberg
160d6b26b0 Moved out the valgrind report parser to valgrind.pm, to make it easier to
test it outside the test suite. Now we also disable valgrind usage if libcurl
was built shared, as then valgrind is only testing the wrapper-script running
shell which is pointless.
2005-02-10 08:50:33 +00:00
Daniel Stenberg
17d61e4f29 typecast assign to ftpport from int to prevent warnings 2005-02-10 07:45:26 +00:00
Daniel Stenberg
446b9467da init fix for non-SSL builds 2005-02-10 07:45:08 +00:00
Marty Kuhrt
3970a7056c Reduced the two config-vms.h_* files into this one. 2005-02-10 01:54:11 +00:00
Daniel Stenberg
74068a6d1b David Byron fixed his SSL problems, initially mentioned here:
http://curl.haxx.se/mail/lib-2005-01/0240.html. It turned out we didn't use
SSL_pending() as we should.

This was TODO-RELEASE issue #59.
2005-02-09 23:16:03 +00:00
Daniel Stenberg
8c83422fe2 David Byron identified the lack of SSL_pending() use, and this is my take
at fixing this issue.
2005-02-09 23:09:12 +00:00
Daniel Stenberg
61a1e3cd01 better error checking and SSL init by David Byron 2005-02-09 23:04:51 +00:00
Daniel Stenberg
89cac6f25c prevent a compiler warning 2005-02-09 22:47:57 +00:00
Gisle Vanem
62082293c5 Some functions are static here, but extern in libxml's
SAX.h. gcc doesn't like that. Rename.
2005-02-09 15:15:01 +00:00
Daniel Stenberg
153fd2752c the new ftp code and Gisle's DICT fix 2005-02-09 14:34:46 +00:00
Daniel Stenberg
e649a40f5d issue #54 done 2005-02-09 14:29:57 +00:00
Gisle Vanem
32d76a5b57 Set 'bits.close' in case of malloc fail.
Don't free 'lud_dn' twice in case curl_unescape()
fails.
2005-02-09 14:28:35 +00:00
Daniel Stenberg
14aa3fa258 add missing error codes 2005-02-09 14:13:21 +00:00
Gisle Vanem
f5394cccb1 Use CURL_SOCKET_BAD. 2005-02-09 14:01:15 +00:00
Gisle Vanem
64dd9c7656 Handle CURLE_LOGIN_DENIED in strerror.c.
For ftp only?
2005-02-09 13:59:40 +00:00
Daniel Stenberg
16ae0c6466 FD_SET can be big macro, use braces 2005-02-09 13:47:35 +00:00
Daniel Stenberg
6a2e21ec8c FTP code turned into state machine. Not completely yet, but a good start.
The tag 'before_ftp_statemachine' was set just before this commit in case
of future need.
2005-02-09 13:06:40 +00:00
Gisle Vanem
120f17ce04 Replace LF with CRLF. Ref RFC-2229, sec 2.3:
"Each command line must be terminated by a CRLF".
2005-02-09 11:50:41 +00:00
Daniel Stenberg
ab938bb9bd -O clarification 2005-02-08 23:39:47 +00:00
Daniel Stenberg
33820cd2ac inflate and out of memory fixes 2005-02-08 19:07:28 +00:00
Daniel Stenberg
41def21f91 ares_gethostbyname wants a 'ares_host_callback' in the 4th argument 2005-02-08 19:03:27 +00:00
Gisle Vanem
d118312922 Curl_addrinfo?_callback() and addrinfo_callback() now returns
CURLE_OK or CURLE_OUT_OF_MEMORY.
Add typecast in hostares.c.
2005-02-08 12:36:13 +00:00
Gisle Vanem
82b93e4945 Don't free too much in freedirs() if realloc() fails. 2005-02-08 12:32:28 +00:00
Daniel Stenberg
e36fb1ecda Curl_wait_for_resolv() no longer disconnects on failure, but leaves that
operation to the caller. Disconnecting has the disadvantage that the conn
pointer gets completely invalidated and this is not handled on lots of places
in the code.
2005-02-08 07:36:57 +00:00
Dan Fandrich
e4a1788614 Fix for a bug report that compressed files that are exactly 64 KiB long
produce a zlib error.
2005-02-07 19:12:37 +00:00
Gisle Vanem
7b23eff9cf Preserve previous status in Curl_http_done(). 2005-02-06 12:43:40 +00:00
Daniel Stenberg
67ff8e3ea3 valgrind errors occur too often when 'make test' is used. It is because too
many third-party libs and tools have problems. When curl is built without
--disable-shared, the testing is done with a front-end script which makes the
valgrind testing include (ba)sh as well and that often causes valgrind
errors. Either we improve the valgrind error scanner a lot to better identify
(lib)curl errors only, or we disable valgrind checking by default
2005-02-05 10:25:20 +00:00
Daniel Stenberg
2248599ae1 fix type 2005-02-04 23:53:12 +00:00
Daniel Stenberg
29350b363b Eric Vergnaud found a use of an uninitialized variable 2005-02-04 23:43:44 +00:00
Daniel Stenberg
83c470a443 David Byron pointed out that this -1 on the buffer size is pointless since
the buffer is already BUFSIZE +1 one big to fit the extra trailing zero. This
change is reported to fix David's weird SSL problem...
2005-02-04 13:42:41 +00:00
Daniel Stenberg
ab96e2d6e9 another example 2005-02-02 19:25:49 +00:00
Daniel Stenberg
6b81cf4bc9 HTML parsing example with libtidy, by Jeff Pohlmeyer 2005-02-02 19:25:37 +00:00
Daniel Stenberg
0d9301539e and we start over again 2005-02-01 08:46:06 +00:00
Daniel Stenberg
4a9e12542d 7.13 coming up 2005-02-01 07:54:36 +00:00
Daniel Stenberg
21b4105454 somewhat nicer libcurl usage 2005-01-31 20:03:01 +00:00
Daniel Stenberg
d7648d94ca htmltitle 2005-01-31 18:23:42 +00:00
Daniel Stenberg
883343ba63 HTML <head> parsing (with libxml) example code by Lars Nilsson. 2005-01-31 18:22:40 +00:00
Daniel Stenberg
16b5dc710f four changes 2005-01-30 22:57:19 +00:00
Daniel Stenberg
686d767053 if the DO operation returns failure, bail out and close down nicely to
prevent memory leakage
2005-01-30 22:54:06 +00:00
Daniel Stenberg
ed3176dd6b Let's add a cookie interface in 7.14 2005-01-30 13:26:12 +00:00
Daniel Stenberg
6a99ab098c Bugfixed the parser that scans the valgrind report outputs. I noticed that it
previously didn't detect and report the "Conditional jump or move depends on
uninitialised value(s)" error.

When I fixed this, I caught a few curl bugs with it. And then I had to spend
time to make the test suite IGNORE these errors when OpenSSL is used since it
produce massive amounts of valgrind warnings (but only of the "Conditional..."
kind it seems).

So, if a test that requires SSL is run, it ignores the "Conditional..."
errors, and you'll get a "valgrind PARTIAL" output instead of "valgrind OK".
2005-01-30 12:56:36 +00:00
Daniel Stenberg
b03adde546 properly mark tests as requiring feature 'SSL' 2005-01-30 12:53:05 +00:00
Daniel Stenberg
e6034ea299 Use calloc() to save us the memset() call and terminate conn->host.name
properly, to avoid reading uninited variables when using file:// (valgrind)
2005-01-30 12:42:15 +00:00
Daniel Stenberg
c7f51ebeab Clear the urlglob struct when allocated, since we might otherwise use
uninitialized variables. Pointed out to us by the friendly Valgrind.
2005-01-29 23:46:27 +00:00
Daniel Stenberg
9a820d7a98 include "url.h" for the Curl_safefree() proto 2005-01-29 22:38:45 +00:00
Daniel Stenberg
8dbaf534c8 Using the multi interface, and doing a requsted a re-used connection that
gets closed just after the request has been sent failed and did not re-issue
a request on a fresh reconnect like the easy interface did. Now it does!
(define CURL_MULTIEASY, run test case 160)
2005-01-29 22:31:06 +00:00
Daniel Stenberg
91f483c591 Define CURL_MULTIEASY when building this, to use my new curl_easy_perform()
that uses the multi interface to run the request. It is a great testbed for
the multi interface and I believe we shall do it this way for real in the
future when we have a successor to curl_multi_fdset().
2005-01-29 22:26:38 +00:00
Daniel Stenberg
c5b448038f corrected the URL 2005-01-29 13:54:15 +00:00
Daniel Stenberg
c4ff5eb0ca conn->ip_addr MUST NOT be used on re-used connections 2005-01-29 13:07:16 +00:00
Daniel Stenberg
0859cd2444 when using valgrind, include a much longer stack trace 2005-01-29 13:06:31 +00:00
Daniel Stenberg
59b45a90cc multi interface: when a request is denied due to "Maximum redirects followed"
libcurl leaked the last Location: URL.
2005-01-29 12:01:20 +00:00
Daniel Stenberg
f661475962 Connect failures with the multi interface was often returned as "connect()
timed out" even though the reason was different. Fixed this problem by not
setting this timeout to zero when using multi.
2005-01-28 23:21:24 +00:00
Daniel Stenberg
54b02ecf09 adjusted to the moved unlock of the DNS entry 2005-01-28 22:22:59 +00:00
Daniel Stenberg
4551e7ce49 KNOWN_BUGS #17 fixed. A DNS cache entry may not remain locked between two
curl_easy_perform() invokes. It was previously unlocked at disconnect, which
could mean that it remained locked between multiple transfers. The DNS cache
may not live as long as the connection cache does, as they are separate.

To deal with the lack of DNS (host address) data availability in re-used
connections, libcurl now keeps a copy of the IP adress as a string, to be able
to show it even on subsequent requests on the same connection.
2005-01-28 22:14:48 +00:00
Daniel Stenberg
064bc3ecbc Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work
when built ipv6-enabled. I've now made a fix for it. Writing test cases for
custom port strings turned too tricky so unfortunately there's none.
2005-01-28 08:26:36 +00:00
Daniel Stenberg
cf38a4c470 test the EPRT/LPRT/PORT somewhat more 2005-01-27 23:03:02 +00:00
Daniel Stenberg
aacc79a3a3 Use the same work-around for the memdebug stuff as in the command line client,
to allow the contents of the env var decide the file name.
2005-01-27 22:40:56 +00:00
Daniel Stenberg
9864bf703d a slightly involved work-around to prevent the debug-tracing from logging
a free-without-alloc as the first call
2005-01-27 15:59:01 +00:00
Daniel Stenberg
289a42f050 Make the debug build get the debug dump file path from the environment
variable to allow the test suite to better control where it ends up.
2005-01-27 15:51:03 +00:00
Daniel Stenberg
ade1e79b37 verify a part of the PORT line 2005-01-27 12:59:40 +00:00
Daniel Stenberg
2415724d5f Make the server ignore the given PORT address, to make it possible to test
curl's -P option easier.
2005-01-26 23:18:31 +00:00
Daniel Stenberg
5463177f1f added more official web and download mirrors 2005-01-26 12:05:33 +00:00
Daniel Stenberg
4efd751eda new curlpp URL 2005-01-26 11:53:49 +00:00
Daniel Stenberg
2337efc3b1 fixed sort, mention C, the java binding is now maintained by Vic Hanson 2005-01-26 11:53:12 +00:00
Daniel Stenberg
b942a25a45 add number to the bugs to make them easier to refer to 2005-01-25 23:40:35 +00:00
Daniel Stenberg
beab9a9696 two known bugs 2005-01-25 22:21:42 +00:00
Daniel Stenberg
177dbc7be0 Ian Ford asked about support for the FTP command ACCT, and I discovered it is
present in RFC959... so now (lib)curl supports it as well. --ftp-account and
CURLOPT_FTP_ACCOUNT set the account string. (The server may ask for an account
string after PASS have been sent away. The client responds with "ACCT [account
string]".) Added test case 228 and 229 to verify the functionality. Updated
the test FTP server to support ACCT somewhat.
2005-01-25 22:13:12 +00:00
Daniel Stenberg
f2e71edcbd A minor "syntax error" in numerous test files corrected 2005-01-25 21:45:03 +00:00
Daniel Stenberg
fad6e5a5bc new web mirror 2005-01-25 13:59:48 +00:00
Daniel Stenberg
52f6c437fe --protocols is added in 7.13.0 2005-01-25 12:06:12 +00:00
Daniel Stenberg
80a8be6319 David Shaw contributed a fairly complete and detailed autoconf macro you can
use to detect libcurl and setup variables for the protocols the installed
libcurl supports: docs/libcurl/libcurl.m4
2005-01-25 09:29:05 +00:00
Daniel Stenberg
043d70fcdf Use plain structs and not typedef'ed ones in the hash and linked-list code. 2005-01-25 00:06:29 +00:00
Daniel Stenberg
4f7e958969 two options less 2005-01-23 00:08:56 +00:00
Daniel Stenberg
53143910a1 \fI marked \fP more function calls etc. 2005-01-22 22:43:04 +00:00
Daniel Stenberg
95656cd7f3 If you're using libcurl as a win32 DLL, you MUST use the CURLOPT_WRITEFUNCTION
if you set CURLOPT_WRITEDATA - or you will experience crashes.
2005-01-22 22:24:17 +00:00
Daniel Stenberg
d8f79b263d next release will be 7.13.0 2005-01-22 19:26:37 +00:00
Daniel Stenberg
51da8552c3 added a few items I plan to do 2005-01-22 09:03:55 +00:00
Daniel Stenberg
7e42cb61f7 FTP third transfer support overhaul. See CHANGES for details. 2005-01-21 09:32:32 +00:00
Daniel Stenberg
6c038680f9 clarify the struct name for CURLOPT_HTTPPOST 2005-01-21 08:56:04 +00:00
Daniel Stenberg
291a908f19 Added support for "verify" => "stripfile" to strip contents of the file that
is being checked.

Also made the server retrying sleep only one second instead of three, to reduce
some waiting when fooling around with the servers.
2005-01-20 22:48:43 +00:00
Daniel Stenberg
b264a03f89 Support file names passed to RETR that don't start with a number. In that
case, all non-numeric prefixing letters are cut off to figure out the test
number.
2005-01-20 22:47:31 +00:00
Daniel Stenberg
7472ede32a Philippe Hameau found out that -Q "+[command]" didn't work, although some code
was written for it. I fixed and added test case 227 to verify it.  The curl.1
man page didn't mention the '+' so I added it.
2005-01-20 22:22:12 +00:00
Daniel Stenberg
b5065e462b add support for NOOP 2005-01-20 22:05:44 +00:00
Daniel Stenberg
8dd799b4bd If you give a *_LARGE option you MUST make sure that the type of the passed-in
argument is a curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you
must make sure that to pass in a type 'long' argument. */
2005-01-20 14:24:56 +00:00
Daniel Stenberg
a38520c90d added test226 too 2005-01-19 22:00:54 +00:00
Daniel Stenberg
3050ae57c0 Stephan Bergmann made libcurl return CURLE_URL_MALFORMAT if an FTP URL
contains %0a or %0d in the user, password or CWD parts. (A future fix would
include doing it for %00 as well - see KNOWN_BUGS for details.) Test case 225
and 226 were added to verify this
2005-01-19 21:56:02 +00:00
Daniel Stenberg
01205f772c today's proxy fixes 2005-01-19 18:05:56 +00:00
Gisle Vanem
06ad5be3af Don't copy 'stderr' for Win-CE in IPv6 code. Don't call
GetCurrentProcess() twice; use a local variable.
2005-01-19 10:20:55 +00:00
Daniel Stenberg
2fe3829e5e add a URL to an article about making Apache support PUT 2005-01-19 10:09:15 +00:00
Daniel Stenberg
a0c8b9bc68 Stephan Bergmann pointed out two flaws in libcurl built with HTTP disabled:
1) the proxy environment variables are still read and used to set HTTP proxy

2) you couldn't disable http proxy with CURLOPT_PROXY (since the option was
   disabled)
2005-01-19 09:36:44 +00:00
Daniel Stenberg
0406b1facf skip sys/socket.h on windows CE 2005-01-18 15:13:23 +00:00
Daniel Stenberg
65dbee01e5 check for errno.h 2005-01-18 14:34:50 +00:00
Daniel Stenberg
b1080f7c9a Cody Jones' enhanced version of Samuel Daz Garca's MSVC makefile patch. 2005-01-18 10:17:34 +00:00
Daniel Stenberg
7bfd58d41f Add support for server 'ftp2' which is a second FTP server. Useful for 3rd
party transfer tests or tests that need two FTP servers.
2005-01-17 20:20:34 +00:00
Daniel Stenberg
3851c6aae2 support the new --id command line option, that allows a second (or third or
whatever) instance to run without overwriting the previous' logfiles
2005-01-17 19:49:12 +00:00
Daniel Stenberg
ae03fa7d8e mention the name-prefix protocol guess thing 2005-01-17 14:57:21 +00:00
Daniel Stenberg
8a14dd25a9 updated the wording for -B/--use-ascii 2005-01-17 09:18:04 +00:00
Daniel Stenberg
e0bea7d541 Alex aka WindEagle pointed out that when doing "curl -v dictionary.com", curl
assumed this used the DICT protocol. While guessing protocols will remain
fuzzy, I've now made sure that the host names must start with "[protocol]."
for them to be a valid guessable name. I also removed "https" as a prefix that
indicates HTTPS, since we hardly ever see any host names using that.
2005-01-16 08:51:52 +00:00
Daniel Stenberg
534a8a05f3 mention --netrc in the -u description 2005-01-16 08:34:18 +00:00
Gisle Vanem
f5b8a26d9a errrno can by freak accident become EINTR on DOS or
Windows (unrelated to select). select() can never set errno
to EINTR on Windows.
2005-01-15 09:26:07 +00:00
Daniel Stenberg
cf51f7fb65 output better error detection, like when ipv6 can't resolve 2005-01-15 09:21:51 +00:00
Daniel Stenberg
4d1f3d3cd0 Added README.hostip 2005-01-14 13:43:29 +00:00
Daniel Stenberg
f70b87b4c5 verify the protocol too 2005-01-14 09:39:20 +00:00
Daniel Stenberg
0e26355348 Inspired by Martijn Koster's patch and example source at
http://www.greenhills.co.uk/mak/gentoo/curl-eintr-bug.c, I now made the
select() and poll() calls properly loop if they return -1 and errno is
EINTR. glibc docs for this is found here:
http://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html

This last link says BSD doesn't have this "effect". Will there be a problem
if we do this unconditionally?
S: ----------------------------------------------------------------------
2005-01-13 21:51:48 +00:00
Gisle Vanem
246ea56eab Added dependencies. 2005-01-12 15:32:41 +00:00
Gisle Vanem
7c1bba315b Added '-bd' option; target is a DLL.
Added dependencies.
2005-01-12 15:32:26 +00:00
Daniel Stenberg
9395cad379 support for retrieving used IP addresses 2005-01-11 22:26:00 +00:00
Daniel Stenberg
c5b2e85b47 Dan Torop cleaned up a few no longer used variables from David Phillips'
select() overhaul fix.
2005-01-11 20:22:44 +00:00
Gisle Vanem
38f8087281 Removed CURLTOOLDEBUG. It caused libcurl_wc.dll
to fail in mysterious ways.
2005-01-11 17:08:47 +00:00
Daniel Stenberg
e3fa7d021e Renamed easy.h and multi.h to easyif.h and multiif.h to make sure they don't
shadow our public headers with the former names.
2005-01-11 15:25:29 +00:00
Gisle Vanem
a1813e2b2d ".\lib\easy.h" shadows for <curl/easy.h> in Watcom.
Force including ../include/curl/easy.h.
2005-01-11 14:59:24 +00:00
Gisle Vanem
2e62458eef Fix '!if' expression. 2005-01-11 14:52:42 +00:00
Gisle Vanem
bb9e5565f2 ".\lib\multi.h" shadows for <curl/multi.h> in Watcom.
Force including ../include/curl/multi.h.
2005-01-11 14:32:09 +00:00
Daniel Stenberg
29102befa6 Cyrill Osterwalder posted a detailed analysis about a bug that occurs when
using a custom Host: header and curl fails to send a request on a re-used
persistent connection and thus creates a new connection and resends it. It
then sent two Host: headers. Cyrill's analysis was posted here:
http://curl.haxx.se/mail/archive-2005-01/0022.html
2005-01-11 14:00:45 +00:00
Daniel Stenberg
9d1145598a Bruce Mitchener identified (bug report #1099640) the never-ending SOCKS5
problem with the version byte and the check for bad versions. Bruce has lots
of clues on this, and based on his suggestion I've now removed the check of
that byte since it seems to be able to contain 1 or 5.
2005-01-10 23:32:14 +00:00
Daniel Stenberg
065e466f1a Use Curl_easy_addmulti() to clear associations from easy handles to multi
handles. Include multi.h to get proto.
2005-01-10 11:42:20 +00:00
Daniel Stenberg
3ac00f32af edited wording 2005-01-10 11:27:02 +00:00
Daniel Stenberg
21bb852750 Pavel Orehov reported memory problems with the multi interface in bug report
#1098843. In short, a shared DNS cache was setup for a multi handle and when
the shared cache was deleted before the individual easy handles, the latter
cleanups caused read/writes to already freed memory.
2005-01-10 10:07:07 +00:00
Daniel Stenberg
83bab78bda Hzhijun reported a memory leak in the SSL certificate code, that leaked the
remote certificate name when it didn't match the used host name.
2005-01-10 09:48:39 +00:00
Gisle Vanem
894ec46ef4 Note about the static lib requirement; -DCURL_STATICLIB. 2005-01-08 16:35:03 +00:00
Gisle Vanem
4eb1d3eb1b Watcom additions. 2005-01-08 16:15:06 +00:00
Gisle Vanem
945423e83a Added Watcom targets. 2005-01-08 16:12:27 +00:00
Gisle Vanem
9fd33c0b96 New file. 2005-01-08 16:06:37 +00:00
Gisle Vanem
3c09f2d2bd Added Makefile.Watcom to EXTRA_DIST. 2005-01-08 16:03:45 +00:00
Daniel Stenberg
7b4bf6a22c three recent bug fixes 2005-01-07 21:14:57 +00:00
Daniel Stenberg
b5b77f6367 disable the valgrind log checking 2005-01-07 21:11:24 +00:00
Daniel Stenberg
5a8097a4d5 fixed the valgrind log check and make it possible to disable it for a specific
test, see test 509
2005-01-07 21:11:13 +00:00
Daniel Stenberg
9cdf6fb64b added test 199 2005-01-07 21:09:50 +00:00
Daniel Stenberg
a137223b4f prevent a single byte read outside the string in test case 39 2005-01-06 22:54:37 +00:00
Daniel Stenberg
52e1ce9518 fixed #1097019, multiple GET posts (-G) error 2005-01-06 22:25:35 +00:00
Daniel Stenberg
8127a34f98 recent events 2005-01-05 14:12:06 +00:00
Gisle Vanem
2dcb8b674f Changed curl.dll to libcurl.dll. 2005-01-04 16:16:03 +00:00
Gisle Vanem
1e3b1b6e47 Minor comment fix. 2005-01-04 16:13:58 +00:00
Daniel Stenberg
9cdaae94cc just narrowed some text to fit within 80 cols 2005-01-04 16:01:34 +00:00
Gisle Vanem
316e74be74 Removed _WIN32_WINNT to support IPv6 under Win-2K. 2005-01-04 16:00:14 +00:00
Daniel Stenberg
af69c4f4f7 Marty Kuhrt's VMS update 2005-01-03 19:17:10 +00:00
Daniel Stenberg
ad9648a215 reverted the bad naming of the implib names 2005-01-02 21:15:29 +00:00
Daniel Stenberg
1576f3319e Alex Neblett's minor update 2005-01-02 19:19:32 +00:00
Daniel Stenberg
8ac90316d9 nah, don't use the system's getpass() function since it too often is limited
to 8(!) or similar lengths passwords
2004-12-26 09:17:38 +00:00
Daniel Stenberg
35ba5c826d issue 54 - this takes sweat 2004-12-25 23:15:45 +00:00
Daniel Stenberg
4f4ffa98b5 Test case 241 fails on all systems that support IPv6 but that don't have the
host name 'ip6-localhost' in /etc/hosts (or similar) since the test case uses
that host name to test the IPv6 name to address resolver.
2004-12-25 22:51:37 +00:00
Daniel Stenberg
b7d92c3e03 --protocols, license, src/config.h.in 2004-12-25 22:30:31 +00:00
Daniel Stenberg
4ecf939452 ./src/config.h.in is now removed from CVS. It is copied from the
lib/config.h.in file by buildconf
2004-12-25 22:10:38 +00:00
Daniel Stenberg
7ef6b05ef1 My reimplementation and cleanup of the getpass source code. We officially no
longer use Angus Mackay's getpass code due to the weirdo license his code was
donated to us under.
2004-12-25 22:08:02 +00:00
Daniel Stenberg
695f95aad1 mention the new --protocols 2004-12-24 09:02:23 +00:00
Daniel Stenberg
2a6ea6d7a7 David Shaw added --protocols, and thus the --feature no longer mentions what
protocols that are disabled.
2004-12-24 08:59:44 +00:00
Dan Fandrich
f5e0ff2170 Added LDAP library issue. 2004-12-23 22:34:00 +00:00
Daniel Stenberg
814d176b86 recent changes
and Merry Christmas!
2004-12-23 22:31:39 +00:00
Daniel Stenberg
3955b31362 David Shaw fixed the disable variables so that curl-config --feature works
correctly!
2004-12-23 08:48:59 +00:00
Daniel Stenberg
4b3fb5a01c issue 47 in next release? 2004-12-22 22:46:05 +00:00
Daniel Stenberg
67abd4cd47 Rune Kleveland fixed a minor memory leak for received cookies with the (rare)
version attribute set.
2004-12-22 22:33:31 +00:00
Daniel Stenberg
58f4af7973 Marcin Konicki provided two configure fixes and a source fix to make curl
build out-of-the-box on BeOS.
2004-12-22 22:28:10 +00:00
Dan Fandrich
99befd3a15 C ensures that static variables are initialized to 0 2004-12-22 20:12:15 +00:00
Daniel Stenberg
3acda85c2b added CURLINFO_HTTP_CONNECTCODE 2004-12-22 12:31:55 +00:00
Daniel Stenberg
dbb69797cf uh, fixed! 2004-12-22 09:21:04 +00:00
Daniel Stenberg
2910880b15 Added: 4 protocols we _could_ support and the CONNECT HTTP/1.0 detail we might
fix one day.
2004-12-22 09:19:29 +00:00
Daniel Stenberg
8b5f0abef1 more about error codes 2004-12-21 21:35:00 +00:00
Daniel Stenberg
10b5327b19 test enforced chunked encoding with PUT on a local file 2004-12-21 20:19:05 +00:00
Daniel Stenberg
4ba1eb26fa Added test case 217 that verified CURLINFO_HTTP_CONNECTCODE, and I made the
-w option support 'http_connect' to make it easier to verify!
2004-12-21 19:59:35 +00:00
Daniel Stenberg
444f6427b8 oops, variables first then code 2004-12-21 14:33:37 +00:00
Daniel Stenberg
a173e07eec Prevent failf() from using the va_list variable more than once.
See bug report #1088962 and  Single Unix Specification:
http://www.opengroup.org/onlinepubs/007908799/xsh/vfprintf.html
2004-12-21 14:22:10 +00:00
Daniel Stenberg
3de85777de mention how the FTP code should be fixed one day 2004-12-21 10:54:21 +00:00
Daniel Stenberg
f4c5314890 include sys/types.h before sys/select.h 2004-12-21 10:11:07 +00:00
Daniel Stenberg
1225ad58bd set debug curl too when -c is used 2004-12-21 10:10:40 +00:00
Daniel Stenberg
951fdeba67 How do I list the root dir of an FTP server? 2004-12-21 09:37:55 +00:00
Dan Fandrich
327b46cced Fixed a compile warning introduced by making the protocol table const. This
involves a binary-compatible change to the API struct curl_version_info_data
2004-12-20 21:14:45 +00:00
Dan Fandrich
80d301257c Make some more arrays of pointers const. 2004-12-20 18:23:43 +00:00
Dan Fandrich
0e59182945 gcc 2.7 can't handle a few warning options that gcc 2.95 can. 2004-12-20 18:20:17 +00:00
Daniel Stenberg
7270d5ce26 start working on 7.12.4 2004-12-20 13:09:38 +00:00
Daniel Stenberg
a142d419d2 and we start all over again 2004-12-20 12:51:14 +00:00
301 changed files with 7856 additions and 3791 deletions

371
CHANGES
View File

@@ -7,6 +7,369 @@
Changelog Changelog
Version 7.13.1 (4 March 2005)
Daniel (4 March 2005)
- Dave Dribin made it possible to set CURLOPT_COOKIEFILE to "" to activate
the cookie "engine" without having to provide an empty or non-existing file.
- Rene Rebe fixed a -# crash when more data than expected was retrieved.
Daniel (22 February 2005)
- NTLM and ftp-krb4 buffer overflow fixed, as reported here:
http://www.securityfocus.com/archive/1/391042 and the CAN report here:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0490
If these security guys were serious, we'd been notified in advance and we
could've saved a few of you a little surprise, but now we weren't.
Daniel (19 February 2005)
- Ralph Mitchell reported a flaw when you used a proxy with auth, and you
requested data from a host and then followed a redirect to another
host. libcurl then didn't use the proxy-auth properly in the second request,
due to the host-only check for original host name wrongly being extended to
the proxy auth as well. Added test case 233 to verify the flaw and that the
fix removed the problem.
Daniel (18 February 2005)
- Mike Dobbs reported a mingw build failure due to the lack of
BUILDING_LIBCURL being defined when libcurl is built. Now this is defined by
configure when mingw is used.
Daniel (17 February 2005)
- David in bug report #1124588 found and fixed a socket leak when libcurl
didn't close the socket properly when returning error due to failing
localbind
Daniel (16 February 2005)
- Christopher R. Palmer reported a problem with HTTP-POSTing using "anyauth"
that picks NTLM. Thanks to David Byron letting me test NTLM against his
servers, I could quickly repeat and fix the problem. It turned out to be:
When libcurl POSTs without knowing/using an authentication and it gets back
a list of types from which it picks NTLM, it needs to either continue
sending its data if it keeps the connection alive, or not send the data but
close the connection. Then do the first step in the NTLM auth. libcurl
didn't send the data nor close the connection but simply read the
response-body and then sent the first negotiation step. Which then failed
miserably of course. The fixed version forces a connection if there is more
than 2000 bytes left to send.
Daniel (14 February 2005)
- The configure script didn't check for ENGINE_load_builtin_engines() so it
was never used.
Daniel (11 February 2005)
- Removed all uses of strftime() since it uses the localised version of the
week day names and month names and servers don't like that.
Daniel (10 February 2005)
- Now the test script disables valgrind-testing when the test suite runs if
libcurl is built shared. Otherwise valgrind only tests the shell that runs
the wrapper-script named 'curl' that is a front-end to curl in this case.
This should also fix the huge amount of reports of false positives when
valgrind has identified leaks in (ba)sh and not in curl and people report
that as curl bugs. Bug report #1116672 is one example.
Also, the valgrind report parser has been adapted to check that at least one
of the sources in a stack strace is one of (lib)curl's source files or
otherwise it will not consider the problem to concern (lib)curl.
- Marty Kuhrt streamlined the VMS build.
Daniel (9 February 2005)
- David Byron fixed his SSL problems, initially mentioned here:
http://curl.haxx.se/mail/lib-2005-01/0240.html. It turned out we didn't use
SSL_pending() as we should.
- Converted lots of FTP code to a statemachine, so that the multi interface
doesn't block while communicating commands-responses with an FTP server.
I've added a comment like BLOCKING in the code on all spots I could find
where we still have blocking operations. When we change curl_easy_perform()
to use the multi interface, we'll also be able to simplify the code since
there will only be one "internal interface".
While doing this, I've now made CURLE_FTP_ACCESS_DENIED separate from the
new CURLE_LOGIN_DENIED. The first one is now access denied to a function,
like changing directory or retrieving a file, while the second means that we
were denied login.
The CVS tag 'before_ftp_statemachine' was set just before this went in, in
case of future need.
- Gisle made the DICT code send CRLF and not just LF as the spec says so.
Daniel (8 February 2005)
- Gisle fixed problems when libcurl runs out of memory, and worked on making
sure the proper error code is returned for those occations.
Daniel (7 February 2005)
- Maruko pointed out a problem with inflate decompressing exactly 64K
contents.
Daniel (5 February 2005)
- Eric Vergnaud found a use of an uninitialised variable in the ftp when doing
PORT on ipv6-enabled hosts.
- David Byron pointed out we could use BUFSIZE to read data (in
lib/transfer.c) instead of using BUFSIZE -1.
Version 7.13.0 (1 February 2005)
Daniel (31 January 2005)
- Added Lars Nilsson's htmltitle.cc example
Daniel (30 January 2005)
- Fixed a memory leak when using the multi interface and the DO operation
failed (as in test case 205).
- Fixed a valgrind warning for file:// operations.
- Fixed a valgrind report in the url globbing code for the curl command line
tool.
- Bugfixed the parser that scans the valgrind report outputs (in runtests.pl).
I noticed that it previously didn't detect and report the "Conditional jump
or move depends on uninitialised value(s)" error. When I fixed this, I
caught a few curl bugs with it. And then I had to spend time to make the
test suite IGNORE these errors when OpenSSL is used since it produce massive
amounts of valgrind warnings (but only of the "Conditional..." kind it
seems). So, if a test that requires SSL is run, it ignores the
"Conditional..." errors, and you'll get a "valgrind PARTIAL" output instead
of "valgrind OK".
Daniel (29 January 2005)
- Using the multi interface, and doing a requsted a re-used connection that
gets closed just after the request has been sent failed and did not re-issue
a request on a fresh reconnect like the easy interface did. Now it does!
- Define CURL_MULTIEASY when building libcurl (lib/easy.c to be exact), to use
my new curl_easy_perform() that uses the multi interface to run the
request. It is a great testbed for the multi interface and I believe we
shall do it this way for real in the future when we have a successor to
curl_multi_fdset(). I've used this approach to detect and fix several of the
recent multi-interfaces issues.
- Adjusted the KNOWN_BUGS #17 fix a bit more since the FTP code also did some
bad assumptions.
- multi interface: when a request is denied due to "Maximum redirects
followed" libcurl leaked the last Location: URL.
- Connect failures with the multi interface was often returned as "connect()
timed out" even though the reason was different.
Daniel (28 January 2005)
- KNOWN_BUGS #17 fixed. A DNS cache entry may not remain locked between two
curl_easy_perform() invokes. It was previously unlocked at disconnect, which
could mean that it remained locked between multiple transfers. The DNS cache
may not live as long as the connection cache does, as they are separate.
To deal with the lack of DNS (host address) data availability in re-used
connections, libcurl now keeps a copy of the IP adress as a string, to be
able to show it even on subsequent requests on the same connection.
The problem could be made to appear with this stunt:
1. create a multi handle
2. add an easy handle
3. fetch a URL that is persistent (leaves the connection alive)
4. remove the easy handle from the multi
5. kill the multi handle
6. create a multi handle
7. add the same easy handle to the new multi handle
8. fetch a URL from the same server as before (re-using the connection)
- Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work
when built ipv6-enabled. I've now made a fix for it. Writing test cases for
custom port hosts turned too tricky so unfortunately there's none.
Daniel (25 January 2005)
- Ian Ford asked about support for the FTP command ACCT, and I discovered it
is present in RFC959... so now (lib)curl supports it as well. --ftp-account
and CURLOPT_FTP_ACCOUNT set the account string. (The server may ask for an
account string after PASS have been sent away. The client responds
with "ACCT [account string]".) Added test case 228 and 229 to verify the
functionality. Updated the test FTP server to support ACCT somewhat.
- David Shaw contributed a fairly complete and detailed autoconf test you can
use to detect libcurl and setup variables for the protocols the installed
libcurl supports: docs/libcurl/libcurl.m4
Daniel (21 January 2005)
- Major FTP third party transfer overhaul.
These four options are now obsolete: CURLOPT_SOURCE_HOST,
CURLOPT_SOURCE_PATH, CURLOPT_SOURCE_PORT (this option didn't work before)
and CURLOPT_PASV_HOST.
These two options are added: CURLOPT_SOURCE_URL and CURLOPT_SOURCE_QUOTE.
The target-side didn't use the proper path with RETR, and thus this only
worked correctly in the login path (i.e without doing any CWD). The source-
side still uses a wrong path, but the fix for this will need to wait. Verify
the flaw by using a source URL with included %XX-codes.
Made CURLOPT_FTPPORT control weather the target operation should use PORT
(or not). The other side thus uses passive (PASV) mode.
Updated the ftp3rdparty.c example source to use the updated options.
Added support for a second FTP server in the test suite. Named... ftp2.
Added test cases 230, 231 and 232 as a few first basic tests of very simple
3rd party transfers.
Changed the debug output to include 'target' and 'source' when a 3rd party
is being made, to make it clearer what commands/responses came on what
connection.
Added three new command line options: --3p-url, --3p-user and --3p-quote.
Documented the command line options and the curl_easy_setopt options related
to third party transfers.
(Temporarily) disabled the ability to re-use an existing connection for the
source connection. This is because it needs to force a new in case the
source and target is the same host, and the host name check is trickier now
when the source is identified with a full URL instead of a plain host name
like before.
TODO (short-term) for 3rd party transfers: quote support. The options are
there, we need to add test cases to verify their functionality.
TODO (long-term) for 3rd party transfers: IPv6 support (EPRT and EPSV etc)
and SSL/TSL support.
Daniel (20 January 2005)
- Philippe Hameau found out that -Q "+[command]" didn't work, although some
code was written for it. I fixed and added test case 227 to verify it.
The curl.1 man page didn't mention the '+' so I added it.
Daniel (19 January 2005)
- Stephan Bergmann made libcurl return CURLE_URL_MALFORMAT if an FTP URL
contains %0a or %0d in the user, password or CWD parts. (A future fix would
include doing it for %00 as well - see KNOWN_BUGS for details.) Test case
225 and 226 were added to verify this
- Stephan Bergmann pointed out two flaws in libcurl built with HTTP disabled:
1) the proxy environment variables are still read and used to set HTTP proxy
2) you couldn't disable http proxy with CURLOPT_PROXY (since the option was
disabled). This is important since apps may want to disable HTTP proxy
without actually knowing if libcurl was built to disable HTTP or not.
Based on Stephan's patch, both these issues should now be fixed.
Daniel (18 January 2005)
- Cody Jones' enhanced version of Samuel D<>az Garc<72>a's MSVC makefile patch was
applied.
Daniel (16 January 2005)
- Alex aka WindEagle pointed out that when doing "curl -v dictionary.com", curl
assumed this used the DICT protocol. While guessing protocols will remain
fuzzy, I've now made sure that the host names must start with "[protocol]."
for them to be a valid guessable name. I also removed "https" as a prefix
that indicates HTTPS, since we hardly ever see any host names using that.
Daniel (13 January 2005)
- Inspired by Martijn Koster's patch and example source at
http://www.greenhills.co.uk/mak/gentoo/curl-eintr-bug.c, I now made the
select() and poll() calls properly loop if they return -1 and errno is
EINTR. glibc docs for this is found here:
http://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html
This last link says BSD doesn't have this "effect". Will there be a problem
if we do this unconditionally?
Daniel (11 January 2005)
- Dan Torop cleaned up a few no longer used variables from David Phillips'
select() overhaul fix.
- Cyrill Osterwalder posted a detailed analysis about a bug that occurs when
using a custom Host: header and curl fails to send a request on a re-used
persistent connection and thus creates a new connection and resends it. It
then sent two Host: headers. Cyrill's analysis was posted here:
http://curl.haxx.se/mail/archive-2005-01/0022.html
- Bruce Mitchener identified (bug report #1099640) the never-ending SOCKS5
problem with the version byte and the check for bad versions. Bruce has lots
of clues on this, and based on his suggestion I've now removed the check of
that byte since it seems to be able to contain 1 or 5.
Daniel (10 January 2005)
- Pavel Orehov reported memory problems with the multi interface in bug report
#1098843. In short, a shared DNS cache was setup for a multi handle and when
the shared cache was deleted before the individual easy handles, the latter
cleanups caused read/writes to already freed memory.
- Hzhijun reported a memory leak in the SSL certificate code, that leaked the
remote certificate name when it didn't match the used host name.
Gisle (8 January 2005)
- Added Makefile.Watcom files (src/lib). Updated Makefile.dist.
Daniel (7 January 2005)
- Improved the test script's valgrind log parser to actually work! Also added
the ability to disable the log scanner for specific test cases. Test case
509 results in numerous problems and leaks in OpenSSL and has to get it
disabled.
Daniel (6 January 2005)
- Fixed a single-byte read out of bounds in test case 39 in the curl tool code
(i.e not in the library).
- Bug report #1097019 identified a problem when doing -d "data" with -G and
sending it to two URLs with {}. Added test 199 to verify the fix.
Daniel (4 January 2005)
- Marty Kuhrt adjusted a VMS build script slightly
- Kai Sommerfeld and Gisle Vanem fixed libcurl to build with IPv6 support on
Win2000.
Daniel (2 January 2005)
- Alex Neblett updated the MSVC makefiles slightly.
Daniel (25 December 2004)
- Removed src/config.h.in from CVS, it is now copied from the (generated)
lib/config.h.in instead, as they can very well be the same. This removes a
"manual hassle". You may want to re-run buildconf now.
- Werner Koch filed Debian bug report #286794, mentioning that curl contained
non-free (by Debian's view) source code. This was Angus Mackay's
src/getpass.c source code. I tried to contact him about it to quickly solve
this issue, but his email addresses bounce and I got some time "over" and
reimplemented the functionality once brought by Angus. We no longer use any
of Angus' original code and the new function is much simpler (IMO). Issue
solved.
Daniel (24 December 2004)
- David Shaw added --protocols to curl-config, so that it now lists all
protocols libcurl was built to support. --feature no longer lists disabled
protocols.
Daniel (23 December 2004)
- David Shaw fixed the configure --disable-[protocol] variables so that
curl-config --feature now works correctly!
Daniel (22 December 2004)
- Rune Kleveland fixed a minor memory leak for received cookies with the
(rare) version attribute set.
- Marcin Konicki provided two configure fixes and a source fix to make curl
build out-of-the-box on BeOS.
Daniel (21 December 2004)
- Added test case 217 that verified CURLINFO_HTTP_CONNECTCODE, and I made the
-w option support 'http_connect' to make it easier to verify!
- Fixed lib/select.c include order to build fine on FreeBSD
- Fixed failf()'s reuse of the va_list variable that crashed on FreeBSD.
Pointed out by Peter Pentchev.
Version 7.12.3 (20 December 2004) Version 7.12.3 (20 December 2004)
Daniel (19 December 2004) Daniel (19 December 2004)
@@ -23,7 +386,7 @@ Daniel (18 December 2004)
- Samuel Listopad added support for PKCS12 formatted certificates. - Samuel Listopad added support for PKCS12 formatted certificates.
- Samuel Listopad fixed -E to support "C:/path" (with forward slash) as well. - Samuel Listopad fixed -E to support "C:/path" (with forward slash) as well.
Daniel (16 December 2004) Daniel (16 December 2004)
- Gisle found and fixed a problem in the directory re-use for FTP. - Gisle found and fixed a problem in the directory re-use for FTP.
@@ -88,7 +451,7 @@ Daniel (9 December 2004)
- Bryan Henderson pointed out in bug report #1081788 that the curl-config - Bryan Henderson pointed out in bug report #1081788 that the curl-config
--vernum output wasn't zero prefixed properly (as claimed in documentation). --vernum output wasn't zero prefixed properly (as claimed in documentation).
This is fixed in maketgz now. This is fixed in maketgz now.
Daniel (8 December 2004) Daniel (8 December 2004)
- Matt Veenstra updated the mach-O framework files for Mac OS X. - Matt Veenstra updated the mach-O framework files for Mac OS X.
@@ -196,7 +559,7 @@ Daniel (15 November 2004)
- Wojciech Zwiefka found out that CURLINFO_REDIRECT_TIME didn't work as - Wojciech Zwiefka found out that CURLINFO_REDIRECT_TIME didn't work as
documented. documented.
Daniel (12 November 2004) Daniel (12 November 2004)
- Gisle Vanem modigied the MSVC and Netware makefiles to build without - Gisle Vanem modigied the MSVC and Netware makefiles to build without
libcurl.def libcurl.def
@@ -296,7 +659,7 @@ Daniel (27 October 2004)
instead of storing it on the stack. The allocation/free is done for every instead of storing it on the stack. The allocation/free is done for every
incoming packet, which is suboptimal, but should be dwarfed by the actual incoming packet, which is suboptimal, but should be dwarfed by the actual
decompression computation. decompression computation.
I've also factored out some common code between deflate and gzip to reduce I've also factored out some common code between deflate and gzip to reduce
the code footprint somewhat. I've tested the gzip code on a few test files the code footprint somewhat. I've tested the gzip code on a few test files
and I tried deflate using the freshmeat.net server, and it all looks OK. I and I tried deflate using the freshmeat.net server, and it all looks OK. I

View File

@@ -53,6 +53,18 @@ borland-clean:
cd ..\src cd ..\src
make -f Makefile.b32 clean make -f Makefile.b32 clean
watcom:
cd lib
wmake -f Makefile.Watcom
cd ..\src
wmake -f Makefile.Watcom
watcom-clean:
cd lib
wmake -f Makefile.Watcom clean
cd ..\src
wmake -f Makefile.Watcom clean
mingw32: mingw32:
$(MAKE) -C lib -f Makefile.m32 ZLIB=1 $(MAKE) -C lib -f Makefile.m32 ZLIB=1
$(MAKE) -C src -f Makefile.m32 ZLIB=1 $(MAKE) -C src -f Makefile.m32 ZLIB=1
@@ -65,6 +77,37 @@ mingw32-clean:
$(MAKE) -C lib -f Makefile.m32 clean $(MAKE) -C lib -f Makefile.m32 clean
$(MAKE) -C src -f Makefile.m32 clean $(MAKE) -C src -f Makefile.m32 clean
vc-clean:
cd lib
nmake -f Makefile.vc6 clean
cd ..\src
nmake -f Makefile.vc6 clean
vc-all:
cd lib
nmake -f Makefile.vc6 cfg=release
nmake -f Makefile.vc6 cfg=release-ssl
nmake -f Makefile.vc6 cfg=release-zlib
nmake -f Makefile.vc6 cfg=release-ssl-zlib
nmake -f Makefile.vc6 cfg=release-ssl-dll
nmake -f Makefile.vc6 cfg=release-zlib-dll
nmake -f Makefile.vc6 cfg=release-ssl-dll-zlib-dll
nmake -f Makefile.vc6 cfg=release-dll
nmake -f Makefile.vc6 cfg=release-dll-ssl-dll
nmake -f Makefile.vc6 cfg=release-dll-zlib-dll
nmake -f Makefile.vc6 cfg=release-dll-ssl-dll-zlib-dll
nmake -f Makefile.vc6 cfg=debug
nmake -f Makefile.vc6 cfg=debug-ssl
nmake -f Makefile.vc6 cfg=debug-zlib
nmake -f Makefile.vc6 cfg=debug-ssl-zlib
nmake -f Makefile.vc6 cfg=debug-ssl-dll
nmake -f Makefile.vc6 cfg=debug-zlib-dll
nmake -f Makefile.vc6 cfg=debug-ssl-dll-zlib-dll
nmake -f Makefile.vc6 cfg=debug-dll
nmake -f Makefile.vc6 cfg=debug-dll-ssl-dll
nmake -f Makefile.vc6 cfg=debug-dll-zlib-dll
nmake -f Makefile.vc6 cfg=debug-dll-ssl-dll-zlib-dll
vc: vc:
cd lib cd lib
nmake /f Makefile.vc6 cfg=release nmake /f Makefile.vc6 cfg=release
@@ -93,13 +136,43 @@ vc-ssl-dll:
cd lib cd lib
nmake /f Makefile.vc6 cfg=release-ssl-dll nmake /f Makefile.vc6 cfg=release-ssl-dll
cd ..\src cd ..\src
nmake /f Makefile.vc6 nmake /f Makefile.vc6 cfg=release-ssl-dll
vc-libcurl-ssl-dll: vc-dll-ssl-dll:
cd lib cd lib
nmake /f Makefile.vc6 cfg=release-libcurl-ssl-dll nmake /f Makefile.vc6 cfg=release-dll-ssl-dll
cd ..\src cd ..\src
nmake /f Makefile.vc6 nmake /f Makefile.vc6 cfg=release-dll-ssl-dll
vc-dll:
cd lib
nmake /f Makefile.vc6 cfg=release-dll
cd ..\src
nmake /f Makefile.vc6 cfg=release-dll
vc-dll-zlib-dll:
cd lib
nmake /f Makefile.vc6 cfg=release-dll-zlib-dll
cd ..\src
nmake /f Makefile.vc6 cfg=release-dll-zlib-dll
vc-dll-ssl-dll-zlib-dll:
cd lib
nmake /f Makefile.vc6 cfg=release-dll-ssl-dll-zlib-dll
cd ..\src
nmake /f Makefile.vc6 cfg=release-dll-ssl-dll-zlib-dll
vc-ssl-dll-zlib-dll:
cd lib
nmake /f Makefile.vc6 cfg=release-ssl-dll-zlib-dll
cd ..\src
nmake /f Makefile.vc6 cfg=release-ssl-dll-zlib-dll
vc-zlib-dll:
cd lib
nmake /f Makefile.vc6 cfg=release-zlib-dll
cd ..\src
nmake /f Makefile.vc6 cfg=release-zlib-dll
djgpp: djgpp:
$(MAKE) -C lib -f Makefile.dj $(MAKE) -C lib -f Makefile.dj

13
README
View File

@@ -34,20 +34,27 @@ WEB SITE
Sweden -- http://curl.haxx.se/ Sweden -- http://curl.haxx.se/
Australia -- http://curl.planetmirror.com/ Australia -- http://curl.planetmirror.com/
Austria -- http://curl.gds.tuwien.ac.at/
Denmark -- http://curl.cofman.dk/ Denmark -- http://curl.cofman.dk/
Estonia -- http://curl.wildyou.net/ Estonia -- http://curl.wildyou.net/
France -- http://curl.mirror.internet.tp/
Germany -- http://curl.kgt.org/
Germany -- http://curl.mirror.at.stealer.net/ Germany -- http://curl.mirror.at.stealer.net/
Germany -- http://curl.netmirror.org/ Germany -- http://curl.netmirror.org/
Russia -- http://curl.tsuren.net/ Russia -- http://curl.tsuren.net/
Taiwan -- http://curl.cs.pu.edu.tw/
Thailand -- http://curl.siamu.ac.th/ Thailand -- http://curl.siamu.ac.th/
US (CA) -- http://curl.mirror.redwire.net/ US (CA) -- http://curl.mirror.redwire.net/
US -- http://curl.signal42.com/ US (CA) -- http://curl.mirrormonster.com/
US (CA) -- http://curl.signal42.com/
US (TX) -- http://curl.109k.com/
DOWNLOAD DOWNLOAD
The official download mirror sites are: The official download mirror sites are:
Australia -- http://curl.planetmirror.com/download.html Australia -- http://curl.planetmirror.com/download.html
Austria -- http://curl.gds.tuwien.ac.at/download.html
Estonia -- http://curl.wildyou.net/download.html Estonia -- http://curl.wildyou.net/download.html
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/ Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
Germany -- http://curl.mirror.at.stealer.net/download.html Germany -- http://curl.mirror.at.stealer.net/download.html
@@ -57,8 +64,12 @@ DOWNLOAD
Russia -- http://curl.tsuren.net/download.html Russia -- http://curl.tsuren.net/download.html
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/ Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Sweden -- http://cool.haxx.se/curl/ Sweden -- http://cool.haxx.se/curl/
Taiwan -- http://curl.cs.pu.edu.tw/download.html
Thailand -- http://curl.siamu.ac.th/download.html Thailand -- http://curl.siamu.ac.th/download.html
US (CA) -- http://curl.mirror.redwire.net/download.html US (CA) -- http://curl.mirror.redwire.net/download.html
US (CA) -- http://curl.mirrormonster.com/download.html
US (CA) -- http://curl.signal42.com/download.html
US (TX) -- http://curl.109k.com/download.html
CVS CVS

View File

@@ -1,81 +1,47 @@
Curl and libcurl 7.12.3 Curl and libcurl 7.13.1
Public curl release number: 84 Public curl release number: 86
Releases counted from the very beginning: 111 Releases counted from the very beginning: 113
Available command line options: 100 Available command line options: 104
Available curl_easy_setopt() options: 123 Available curl_easy_setopt() options: 122
Number of public functions in libcurl: 46 Number of public functions in libcurl: 46
Amount of public web site mirrors: 14 Amount of public web site mirrors: 18
Number of known libcurl bindings: 29 Number of known libcurl bindings: 30
This release includes the following changes: This release includes the following changes:
o PKCS12 certificate support added o CURLOPT_COOKIEFILE set to "" is now activating the cookie engine
o added CURLINFO_SSL_ENGINES (and "--engine list") o FTP code overhaul => multi interface much less blocking
o new configure options: --disable-cookies, --disable-crypto-auth and o Added CURLE_LOGIN_DENIED to be returned when curl is denied login to FTP
--disable-verbose servers
o persistent ftp request improvements
o CURLOPT_IOCTLFUNCTION and CURLOPT_IOCTLDATA added. If your app uses HTTP
Digest, NTLM or Negotiate authentication, you will most likely want to use
these
o -w time_redirect and num_redirects
o no longer uses libcurl.def for building on Windows, OS/2 and Netware
o builds on Windows CE
o request retrying, --retry and family added
o FTP 3rd party transfers with source and dest on the same host now works
o added CURLINFO_NUM_CONNECTS
This release includes the following bugfixes: This release includes the following bugfixes:
o curl -E on windows accepts "c:/path" with forward-slash o -# crash when more data than expected was retrieved
o several improvements for large file support on windows o NTLM/krb4 buffer overflow fixed (CAN-2005-0490)
o file handle leak in aborted multipart formpost file upload o proxy auth bug when following redirects to another host
o -T upload multiple files with backslashes in file names o socket leak when local bind failed
o modified credentials between two requests on a persistent http connection o HTTP POST with --anyauth picking NTLM
o large file file:// resumes on Windows o SSL problems when downloading exactly 16KB data
o URLs with username and IPv6 numerical addresses o out of memory conditions preserve error codes better
o configure works better with SSL libs in a "non-standard ld.so dir" o a few crashes at out of memory
o curl-config --vernum zero prefixed o inflate buffer usage bugfix
o bad memory access in the NTLM code o better DICT protocol adherence
o EPSV on multi-homed servers now works correctly o disable valgrind-checking while testing if libcurl is built shared
o chunked-encoded transfers could get closed pre-maturely without error o locale names in some date strings
o proxy CONNECT now default timeouts after 3600 seconds
o disabling EPSV or EPRT is ignored when connecting to an IPv6 FTP server
o no extra progress meter newline output after each Location: followed
o HTTP PUT/POST with Digest, NTLM or Negotiate no longer uses HEAD
o works with or gracefully bails out when exceeding FD_SETSIZE file
descriptors
o CURLINFO_REDIRECT_TIME works
o building with gssapi libs and hdeaders in the default dirs
o curl_getdate() parsing of dates later than year 2037 with 32 bit time_t
o curl -v when stderr is closed wrote debug messages to the network socket
o build failure with libidn 0.3.X or older
o huge POSTs on VMS
o configure no longer uses pkg-config on cross-compiles
o potential gzip decompress memory leak
o "-C - --fail" on a HTTP page already downloaded
o formposting a zero byte file
o use setlocale() for better IDN functionality by default
Other curl-related news since the previous public release: Other curl-related news since the previous public release:
o pycurl 7.12.2: http://pycurl.sf.net/ o libcurl-vb 1.0 http://sf.net/projects/libcurl-vb/
o TclCurl 0.12.2: http://personal1.iddeo.es/andresgarci/tclcurl/english/ o pycurl 7.13.0: http://pycurl.sf.net/
o libcurl.NET 1.2: http://www.seasideresearch.com/downloads.html o new german mirror: http://curl.mons-new-media.de
o RCurl 0.5.1: http://www.omegahat.org/RCurl/ o new US mirror: http://curl.islandofpoker.com
o libcurl.mono 1.0:
http://forge.novell.com/modules/xfmod/project/?libcurl-mono
o new German curl mirror: http://curl.kgt.org/
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Peter Wullinger, Guillaume Arluison, Alexander Krasnostavsky, Mohun Biswas, Gisle Vanem, David Byron, Marty Kuhrt, Maruko, Eric Vergnaud, Christopher
Tomas Pospisek, Gisle Vanem, Dan Fandrich, Paul Nolan, Andres Garcia, Tim R. Palmer, Mike Dobbs, David in bug report #1124588, Ralph Mitchell,
Sneddon, Ian Gulliver, Jean-Philippe Barrette-LaPierre, Jeff Phillips, Rene Rebe, Dave Dribin, Dan Fandrich
Wojciech Zwiefka, David Phillips, Reinout van Schouwen, Maurice Barnum,
Richard Atterer, Rene Bernhardt, Matt Veenstra, Bryan Henderson, Ton Voon,
Kai Sommerfeld, David Byron, Harshal Pradhan, Tom Lee, Dinar, Jean-Marc
Ranger, Samuel Listopad
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,8 +1,34 @@
Issues not sorted in any particular order. Issues not sorted in any particular order.
To get fixed in 7.12.3 (planned release: December 2004) To get fixed in 7.13.2 (planned release: April 2005)
====================== ======================
58 - Fix KNOWN_BUGS #19: "FTP 3rd party transfers with the multi interface
doesn't work"
47 - Peter Sylvester's patch for SRP on the TLS layer 47 - Peter Sylvester's patch for SRP on the TLS layer
Awaits OpenSSL support for this, no need to support this in libcurl before Awaits OpenSSL support for this, no need to support this in libcurl before
there's an OpenSSL release that does it. there's an OpenSSL release that does it.
58 - SSPI for libcurl on Windows
59 - --form-string and --form-file as discussed on curl-users list
To get fixed in 7.14.0
======================
55 - Add a function to the multi interface that gets file descriptors, as an
alternative to the curl_multi_fdset(). This is necessary to allow apps to
properly avoid the FD_SETSIZE problem.
56 - Make curl_easy_perform() a wrapper-function that simply creates a multi
handle, adds the easy handle to it, runs curl_multi_perform() until the
transfer is done, then detach the easy handle, destroy the multi handle
and return the easy handle's return code. This will thus make everything
internally use and assume the multi interface. The select()-loop should
use the new function from (55).
57 - Add an interface to libcurl for getting and setting cookies from an easy
handle. One idea: http://curl.haxx.se/mail/lib-2004-12/0195.html the
older idea: http://curl.haxx.se/dev/COOKIES. We need to settle on some
middle ground I guess.

View File

@@ -87,9 +87,7 @@ AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1, [use Ioctlsocket() for non-blocking sockets]
dnl Ioctlsocket didnt compile, do test 5! dnl Ioctlsocket didnt compile, do test 5!
AC_TRY_COMPILE([ AC_TRY_COMPILE([
/* headers for SO_NONBLOCK test (BeOS) */ /* headers for SO_NONBLOCK test (BeOS) */
#include <sys/types.h> #include <socket.h>
#include <unistd.h>
#include <fcntl.h>
],[ ],[
/* SO_NONBLOCK source code */ /* SO_NONBLOCK source code */
long b = 1; long b = 1;
@@ -695,15 +693,15 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
dnl -Wcast-align is a bit too annoying on all gcc versions ;-) dnl -Wcast-align is a bit too annoying on all gcc versions ;-)
if test "$gccnum" -ge "207"; then if test "$gccnum" -ge "207"; then
dnl gcc 2.7 or later (well, they don't work on 2.2.2) dnl gcc 2.7 or later
WARN="$WARN -Wno-long-long -Wmissing-declarations -Wsign-compare" WARN="$WARN -Wmissing-declarations"
fi fi
if test "$gccnum" -gt "295"; then if test "$gccnum" -gt "295"; then
dnl only if the compiler is newer than 2.95 since we got lots of dnl only if the compiler is newer than 2.95 since we got lots of
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
dnl gcc 2.95.4 on FreeBSD 4.9! dnl gcc 2.95.4 on FreeBSD 4.9!
WARN="$WARN -Wundef" WARN="$WARN -Wundef -Wno-long-long -Wsign-compare"
fi fi
if test "$gccnum" -ge "296"; then if test "$gccnum" -ge "296"; then

View File

@@ -185,24 +185,24 @@ SOURCE=..\..\getopt.c
!IF "$(CFG)" == "adig - Win32 Release" !IF "$(CFG)" == "adig - Win32 Release"
"areslib - Win32 Release" : "areslib - Win32 Release" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release"
cd "..\adig" cd "..\adig"
"areslib - Win32 ReleaseCLEAN" : "areslib - Win32 ReleaseCLEAN" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN
cd "..\adig" cd "..\adig"
!ELSEIF "$(CFG)" == "adig - Win32 Debug" !ELSEIF "$(CFG)" == "adig - Win32 Debug"
"areslib - Win32 Debug" : "areslib - Win32 Debug" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug"
cd "..\adig" cd "..\adig"
"areslib - Win32 DebugCLEAN" : "areslib - Win32 DebugCLEAN" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN
cd "..\adig" cd "..\adig"

View File

@@ -195,24 +195,24 @@ SOURCE=..\..\ahost.c
!IF "$(CFG)" == "ahost - Win32 Release" !IF "$(CFG)" == "ahost - Win32 Release"
"areslib - Win32 Release" : "areslib - Win32 Release" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release"
cd "..\ahost" cd "..\ahost"
"areslib - Win32 ReleaseCLEAN" : "areslib - Win32 ReleaseCLEAN" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN
cd "..\ahost" cd "..\ahost"
!ELSEIF "$(CFG)" == "ahost - Win32 Debug" !ELSEIF "$(CFG)" == "ahost - Win32 Debug"
"areslib - Win32 Debug" : "areslib - Win32 Debug" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug"
cd "..\ahost" cd "..\ahost"
"areslib - Win32 DebugCLEAN" : "areslib - Win32 DebugCLEAN" :
cd "\ARES-1.1.1\vc\areslib" cd ".\areslib"
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN $(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN
cd "..\ahost" cd "..\ahost"

View File

@@ -168,6 +168,8 @@ echo "buildconf: running aclocal hack to convert all mv to mv -f"
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
echo "buildconf: running autoheader" echo "buildconf: running autoheader"
${AUTOHEADER:-autoheader} || die "The autoheader command failed" ${AUTOHEADER:-autoheader} || die "The autoheader command failed"
echo "buildconf: cp lib/config.h.in src/config.h.in"
cp lib/config.h.in src/config.h.in
echo "buildconf: running autoconf" echo "buildconf: running autoconf"
${AUTOCONF:-autoconf} || die "The autoconf command failed" ${AUTOCONF:-autoconf} || die "The autoconf command failed"

View File

@@ -116,6 +116,17 @@ esac
AC_MSG_RESULT($mimpure) AC_MSG_RESULT($mimpure)
AM_CONDITIONAL(MIMPURE, test x$mimpure = xyes) AM_CONDITIONAL(MIMPURE, test x$mimpure = xyes)
AC_MSG_CHECKING([if we need BUILDING_LIBCURL])
case $host in
*-*-mingw*)
AC_DEFINE(BUILDING_LIBCURL, 1, [when building libcurl itself])
AC_MSG_RESULT(yes)
;;
*)
AC_MSG_RESULT(no)
;;
esac
dnl The install stuff has already been taken care of by the automake stuff dnl The install stuff has already been taken care of by the automake stuff
dnl AC_PROG_INSTALL dnl AC_PROG_INSTALL
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
@@ -133,8 +144,8 @@ AC_HELP_STRING([--disable-http],[Disable HTTP support]),
AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP]) AC_DEFINE(CURL_DISABLE_HTTP, 1, [to disable HTTP])
AC_MSG_WARN([disable HTTP disables FTP over proxy and GOPHER too]) AC_MSG_WARN([disable HTTP disables FTP over proxy and GOPHER too])
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER]) AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
AC_SUBST(CURL_DISABLE_HTTP) AC_SUBST(CURL_DISABLE_HTTP, [1])
AC_SUBST(CURL_DISABLE_GOPHER) AC_SUBST(CURL_DISABLE_GOPHER, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -149,7 +160,7 @@ AC_HELP_STRING([--disable-ftp],[Disable FTP support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP]) AC_DEFINE(CURL_DISABLE_FTP, 1, [to disable FTP])
AC_SUBST(CURL_DISABLE_FTP) AC_SUBST(CURL_DISABLE_FTP, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -164,7 +175,7 @@ AC_HELP_STRING([--disable-gopher],[Disable GOPHER support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER]) AC_DEFINE(CURL_DISABLE_GOPHER, 1, [to disable GOPHER])
AC_SUBST(CURL_DISABLE_GOPHER) AC_SUBST(CURL_DISABLE_GOPHER, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -179,7 +190,7 @@ AC_HELP_STRING([--disable-file],[Disable FILE support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE]) AC_DEFINE(CURL_DISABLE_FILE, 1, [to disable FILE])
AC_SUBST(CURL_DISABLE_FILE) AC_SUBST(CURL_DISABLE_FILE, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -194,7 +205,7 @@ AC_HELP_STRING([--disable-ldap],[Disable LDAP support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP]) AC_DEFINE(CURL_DISABLE_LDAP, 1, [to disable LDAP])
AC_SUBST(CURL_DISABLE_LDAP) AC_SUBST(CURL_DISABLE_LDAP, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -209,7 +220,7 @@ AC_HELP_STRING([--disable-dict],[Disable DICT support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_DICT, 1, [to disable DICT]) AC_DEFINE(CURL_DISABLE_DICT, 1, [to disable DICT])
AC_SUBST(CURL_DISABLE_DICT) AC_SUBST(CURL_DISABLE_DICT, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -224,7 +235,7 @@ AC_HELP_STRING([--disable-telnet],[Disable TELNET support]),
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET]) AC_DEFINE(CURL_DISABLE_TELNET, 1, [to disable TELNET])
AC_SUBST(CURL_DISABLE_TELNET) AC_SUBST(CURL_DISABLE_TELNET, [1])
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
;; ;;
@@ -314,6 +325,16 @@ then
) )
fi fi
if test "$HAVE_GETHOSTBYNAME" != "1"
then
dnl gethostbyname in the net lib - for BeOS
AC_CHECK_LIB(net, gethostbyname,
[HAVE_GETHOSTBYNAME="1"
LIBS="$LIBS -lnet"
])
fi
if test "$HAVE_GETHOSTBYNAME" = "1"; then if test "$HAVE_GETHOSTBYNAME" = "1"; then
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname]) AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
else else
@@ -828,8 +849,12 @@ dnl **********************************************************************
if test X"$OPENSSL_ENABLED" = X"1"; then if test X"$OPENSSL_ENABLED" = X"1"; then
dnl If the ENGINE library seems to be around, check for the OpenSSL engine dnl If the ENGINE library seems to be around, check for the OpenSSL engine
dnl header, it is kind of "separated" from the main SSL check dnl stuff, it is kind of "separated" from the main SSL check
AC_CHECK_FUNC(ENGINE_init, [ AC_CHECK_HEADERS(openssl/engine.h) ]) AC_CHECK_FUNC(ENGINE_init,
[
AC_CHECK_HEADERS(openssl/engine.h)
AC_CHECK_FUNCS( ENGINE_load_builtin_engines )
])
AC_MSG_CHECKING([CA cert bundle install path]) AC_MSG_CHECKING([CA cert bundle install path])
@@ -1171,6 +1196,7 @@ AC_CHECK_HEADERS(
sys/resource.h \ sys/resource.h \
libgen.h \ libgen.h \
locale.h \ locale.h \
errno.h \
setjmp.h, setjmp.h,
dnl to do if not found dnl to do if not found
[], [],
@@ -1243,7 +1269,6 @@ AC_CHECK_FUNCS( strtoll \
strdup \ strdup \
strstr \ strstr \
strtok_r \ strtok_r \
strftime \
uname \ uname \
strcasecmp \ strcasecmp \
stricmp \ stricmp \
@@ -1253,8 +1278,6 @@ AC_CHECK_FUNCS( strtoll \
inet_addr \ inet_addr \
inet_ntoa \ inet_ntoa \
inet_pton \ inet_pton \
tcsetattr \
tcgetattr \
perror \ perror \
closesocket \ closesocket \
siginterrupt \ siginterrupt \

View File

@@ -19,7 +19,8 @@ Available values for OPTION include:
--ca ca bundle install path --ca ca bundle install path
--cc compiler --cc compiler
--cflags pre-processor and compiler flags --cflags pre-processor and compiler flags
--feature newline separated list of enabled features --features newline separated list of enabled features
--protocols newline separated list of enabled protocols
--help display this help and exit --help display this help and exit
--libs library linking information --libs library linking information
--prefix curl install prefix --prefix curl install prefix
@@ -56,7 +57,7 @@ while test $# -gt 0; do
echo "$prefix" echo "$prefix"
;; ;;
--feature) --feature|--features)
if test "@USE_SSLEAY@" = "1"; then if test "@USE_SSLEAY@" = "1"; then
echo "SSL" echo "SSL"
fi fi
@@ -69,32 +70,40 @@ while test $# -gt 0; do
if test "@HAVE_LIBZ@" = "1"; then if test "@HAVE_LIBZ@" = "1"; then
echo "libz" echo "libz"
fi fi
if test "@CURL_DISABLE_HTTP@" = "1"; then
echo "HTTP-disabled"
fi
if test "@CURL_DISABLE_FTP@" = "1"; then
echo "FTP-disabled"
fi
if test "@CURL_DISABLE_GOPHER@" = "1"; then
echo "GOPHER-disabled"
fi
if test "@CURL_DISABLE_FILE@" = "1"; then
echo "FILE-disabled"
fi
if test "@CURL_DISABLE_TELNET@" = "1"; then
echo "TELNET-disabled"
fi
if test "@CURL_DISABLE_LDAP@" = "1"; then
echo "LDAP-disabled"
fi
if test "@CURL_DISABLE_DICT@" = "1"; then
echo "DICT-disabled"
fi
if test "@HAVE_ARES@" = "1"; then if test "@HAVE_ARES@" = "1"; then
echo "AsynchDNS" echo "AsynchDNS"
fi fi
;; ;;
--protocols)
if test "@CURL_DISABLE_HTTP@" != "1"; then
echo "HTTP"
if test "@USE_SSLEAY@" = "1"; then
echo "HTTPS"
fi
fi
if test "@CURL_DISABLE_FTP@" != "1"; then
echo "FTP"
if test "@USE_SSLEAY@" = "1"; then
echo "FTPS"
fi
fi
if test "@CURL_DISABLE_GOPHER@" != "1"; then
echo "GOPHER"
fi
if test "@CURL_DISABLE_FILE@" != "1"; then
echo "FILE"
fi
if test "@CURL_DISABLE_TELNET@" != "1"; then
echo "TELNET"
fi
if test "@CURL_DISABLE_LDAP@" != "1"; then
echo "LDAP"
fi
if test "@CURL_DISABLE_DICT@" != "1"; then
echo "DICT"
fi
;;
--version) --version)
echo libcurl @VERSION@ echo libcurl @VERSION@
exit 0 exit 0
@@ -123,8 +132,7 @@ while test $# -gt 0; do
*) *)
echo "unknown option: $1" echo "unknown option: $1"
usage usage 1
exit 1
;; ;;
esac esac
shift shift

View File

@@ -25,10 +25,14 @@ Basic
ScriptBasic bindings to libcurl. Writtten by Peter Verhas ScriptBasic bindings to libcurl. Writtten by Peter Verhas
http://scriptbasic.com/ http://scriptbasic.com/
C
libcurl is a C library in itself!
http://curl.haxx.se/libcurl/
C++ C++
Written by Jean-Philippe Barrette-LaPierre Written by Jean-Philippe Barrette-LaPierre
http://www.sourceforge.net/projects/curlpp http://rrette.com/curlpp.html
Ch Ch
@@ -68,7 +72,7 @@ glib/GTK+
Java Java
Written by Daniel Stenberg Maintained by Vic Hanson
http://curl.haxx.se/libcurl/java/ http://curl.haxx.se/libcurl/java/
Lua Lua
@@ -76,16 +80,16 @@ Lua
Written by Steve Dekorte Written by Steve Dekorte
http://curl.haxx.se/libcurl/lua/ http://curl.haxx.se/libcurl/lua/
.NET
Written by Jeffrey Phillips
http://www.seasideresearch.com/downloads.html
Mono Mono
Written by Jeffrey Phillips Written by Jeffrey Phillips
http://forge.novell.com/modules/xfmod/project/?libcurl-mono http://forge.novell.com/modules/xfmod/project/?libcurl-mono
.NET
libcurl-net Written by Jeffrey Phillips
http://sourceforge.net/projects/libcurl-net/
Object-Pascal Object-Pascal
Free Pascal, Delphi and Kylix binding written by Christophe Espern. Free Pascal, Delphi and Kylix binding written by Christophe Espern.
@@ -146,6 +150,11 @@ Tcl
Tclcurl is written by Andr<64>s Garc<72>a Tclcurl is written by Andr<64>s Garc<72>a
http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html
Visual Basic
libcurl-vb is written by Jeffrey Phillips
http://sourceforge.net/projects/libcurl-vb/
Q Q
http://q-lang.sourceforge.net/ http://q-lang.sourceforge.net/

View File

@@ -1,4 +1,4 @@
Updated: August 18, 2004 (http://curl.haxx.se/docs/faq.html) Updated: December 21, 2004 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
@@ -42,6 +42,7 @@ FAQ
3.14 Does curl support javascript or pac (automated proxy config)? 3.14 Does curl support javascript or pac (automated proxy config)?
3.15 Can I do recursive fetches with curl? 3.15 Can I do recursive fetches with curl?
3.16 What certificates do I need when I use SSL? 3.16 What certificates do I need when I use SSL?
3.17 How do I list the root dir of an FTP server?
4. Running Problems 4. Running Problems
4.1 Problems connecting to SSL servers. 4.1 Problems connecting to SSL servers.
@@ -520,6 +521,18 @@ FAQ
that was signed by one of the authorities in the bundle. curl comes with a that was signed by one of the authorities in the bundle. curl comes with a
default CA cert bundle. You can override the default. default CA cert bundle. You can override the default.
3.17 How do I list the root dir of an FTP server?
There are two ways. The way defined in the RFC is to use an encoded slash
in the first path part. List the "/tmp" dir like this:
curl ftp://ftp.sunet.se/%2ftmp/
or the not-quite-kosher-but-more-readable way, by simply starting the path
section of the URL with a slash:
curl ftp://ftp.sunet.se//tmp/
4. Running Problems 4. Running Problems
@@ -623,7 +636,10 @@ FAQ
4.6 Can you tell me what error code 142 means? 4.6 Can you tell me what error code 142 means?
All error codes that are larger than the highest documented error code means All curl error codes are described at the end of the man page, in the
section called "EXIT CODES".
Error codes that are larger than the highest documented error code means
that curl has exited due to a crash. This is a serious error, and we that curl has exited due to a crash. This is a serious error, and we
appreciate a detailed bug report from you that describes how we could go appreciate a detailed bug report from you that describes how we could go
ahead and repeat this! ahead and repeat this!
@@ -806,13 +822,13 @@ FAQ
When building an application that uses the static libcurl library, you must When building an application that uses the static libcurl library, you must
add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for
dynamic import symbols. If you get linker error like "unknown symbol dynamic import symbols. If you get linker error like "unknown symbol
__imp__curl_easy_init ..." you have linked against the wrong (static) library. __imp__curl_easy_init ..." you have linked against the wrong (static)
If you want to use the curl.dll and import lib, you don't need any extra CFLAGS, library. If you want to use the libcurl.dll and import lib, you don't need
but use one of the import libraries below. These are the libraries produced by any extra CFLAGS, but use one of the import libraries below. These are the
the various lib/Makefile.* files: libraries produced by the various lib/Makefile.* files:
Target: static lib. import lib for curl*.dll. Target: static lib. import lib for libcurl*.dll.
-------------------------------------------------------- -----------------------------------------------------------
MingW: libcurl.a libcurldll.a MingW: libcurl.a libcurldll.a
MSVC (release): libcurl.lib libcurl_imp.lib MSVC (release): libcurl.lib libcurl_imp.lib
MSVC (debug): libcurld.lib libcurld_imp.lib MSVC (debug): libcurld.lib libcurld_imp.lib

View File

@@ -1,7 +1,7 @@
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
| (__| |_| | _ <| |___ | (__| |_| | _ <| |___
\___|\___/|_| \_\_____| \___|\___/|_| \_\_____|
How To Compile How To Compile
@@ -75,7 +75,7 @@ UNIX
./configure ./configure
(with csh, tcsh and their clones): (with csh, tcsh and their clones):
env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \ env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
./configure ./configure
@@ -131,7 +131,7 @@ UNIX
Win32 Win32
===== =====
Without SSL: Without SSL:
MingW32 (GCC-2.95) style MingW32 (GCC-2.95) style
@@ -199,8 +199,8 @@ Win32
Then run 'nmake vc' in curl's root directory. Then run 'nmake vc' in curl's root directory.
If you want to compile with zlib support, you will need to build If you want to compile with zlib support, you will need to build
zlib (http://www.gzip.org/zlib/) as well. Please read the zlib zlib (http://www.gzip.org/zlib/) as well. Please read the zlib
documentation on how to compile zlib. Define the ZLIB_PATH environment documentation on how to compile zlib. Define the ZLIB_PATH environment
variable to the location of zlib.h and zlib.lib, for example: variable to the location of zlib.h and zlib.lib, for example:
set ZLIB_PATH=c:\zlib-1.2.1 set ZLIB_PATH=c:\zlib-1.2.1
@@ -229,7 +229,7 @@ Win32
'nmake vc-ssl-dll' creates the libcurl dynamic library and 'nmake vc-ssl-dll' creates the libcurl dynamic library and
links curl.exe against libcurl and OpenSSL dynamically. links curl.exe against libcurl and OpenSSL dynamically.
This executable requires libcurl.dll and the OpenSSL DLLs This executable requires libcurl.dll and the OpenSSL DLLs
at runtime. at runtime.
Run 'nmake vc-ssl-zlib' to build with both ssl and zlib support. Run 'nmake vc-ssl-zlib' to build with both ssl and zlib support.
Microsoft / Borland style Microsoft / Borland style
@@ -241,27 +241,27 @@ Win32
Using Borland C++ compiler version 5.5.1 (available as free download Using Borland C++ compiler version 5.5.1 (available as free download
from Borland's site) from Borland's site)
--------------------------------------------------------------------- ---------------------------------------------------------------------
compile openssl compile openssl
Make sure you include the paths to curl/include and openssl/inc32 in Make sure you include the paths to curl/include and openssl/inc32 in
your bcc32.cnf file your bcc32.cnf file
eg : -I"c:\Bcc55\include;c:\path_curl\include;c:\path_openssl\inc32" eg : -I"c:\Bcc55\include;c:\path_curl\include;c:\path_openssl\inc32"
Check to make sure that all of the sources listed in lib/Makefile.b32 Check to make sure that all of the sources listed in lib/Makefile.b32
are present in the /path_to_curl/lib directory. (Check the src are present in the /path_to_curl/lib directory. (Check the src
directory for missing ones.) directory for missing ones.)
Make sure the environment variable "BCCDIR" is set to the install Make sure the environment variable "BCCDIR" is set to the install
location for the compiler eg : c:\Borland\BCC55 location for the compiler eg : c:\Borland\BCC55
command line: command line:
make -f /path_to_curl/lib/Makefile-ssl.b32 make -f /path_to_curl/lib/Makefile-ssl.b32
compile simplessl.c with appropriate links compile simplessl.c with appropriate links
c:\curl\docs\examples\> bcc32 -L c:\path_to_curl\lib\libcurl.lib c:\curl\docs\examples\> bcc32 -L c:\path_to_curl\lib\libcurl.lib
-L c:\borland\bcc55\lib\psdk\ws2_32.lib -L c:\borland\bcc55\lib\psdk\ws2_32.lib
-L c:\openssl\out32\libeay32.lib -L c:\openssl\out32\libeay32.lib
@@ -293,6 +293,13 @@ Win32
- Add defines to Project/Settings/C/C++/General/Preprocessor Definitions - Add defines to Project/Settings/C/C++/General/Preprocessor Definitions
in the curllib.dsw/curllib.dsp Visual C++ 6 IDE project. in the curllib.dsw/curllib.dsp Visual C++ 6 IDE project.
Important (with SSL or not):
When building an application that uses the static libcurl library, you
must add '-DCURL_STATICLIB' to your CFLAGS. Otherwise the linker will
look for dynamic import symbols.
IBM OS/2 IBM OS/2
======== ========
@@ -373,7 +380,7 @@ VMS
1 = Success 1 = Success
2 = Error 2 = Error
3 = Information 3 = Information
4 = Fatal 4 = Fatal
<5-7> reserved. <5-7> reserved.
This all presents itself with: This all presents itself with:
@@ -449,10 +456,10 @@ NetWare
- either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later. - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later.
- gnu make and awk running on the platform you compile on; - gnu make and awk running on the platform you compile on;
native Win32 versions can be downloaded from: native Win32 versions can be downloaded from:
http://www.gknw.com/development/prgtools/ http://www.gknw.com/development/prgtools/
- recent Novell LibC SDK available from: - recent Novell LibC SDK available from:
http://developer.novell.com/ndk/libc.htm http://developer.novell.com/ndk/libc.htm
- optional zlib sources (at the moment only dynamic linking with zlib.imp); - optional zlib sources (at the moment only dynamic linking with zlib.imp);
sources with NetWare Makefile can be obtained from: sources with NetWare Makefile can be obtained from:
http://www.gknw.com/mirror/zlib/ http://www.gknw.com/mirror/zlib/
@@ -464,7 +471,7 @@ NetWare
a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it
with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...; with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...;
other options are currently not supported, although partly prepared. other options are currently not supported, although partly prepared.
The Ares lib builds arlready fine, and both test tools work fine at least The Ares lib builds arlready fine, and both test tools work fine at least
when build with CodeWarrior...; don't know yet why they fail when build with when build with CodeWarrior...; don't know yet why they fail when build with
gcc though; if you want to compile with Ares support then set an env var gcc though; if you want to compile with Ares support then set an env var
WITH_ARES=1; I've not tested yet including libares into curl. WITH_ARES=1; I've not tested yet including libares into curl.
@@ -604,7 +611,7 @@ PORTS
- m68k Linux - m68k Linux
- m68k OpenBSD - m68k OpenBSD
- m88k dg-dgux5.4R3.00 - m88k dg-dgux5.4R3.00
- s390 Linux - s390 Linux
- XScale/PXA250 Linux 2.4 - XScale/PXA250 Linux 2.4
Useful URLs Useful URLs

View File

@@ -3,58 +3,86 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems changelog of the current development status, as one or more of these problems
may have been fixed since this was written! may have been fixed since this was written!
* Test case 165 might fail on system which has libidn present, but with an 20. valgrind errors occur too often when 'make test' is used. It is because
too many third-party libs and tools have problems. When curl is built
without --disable-shared, the testing is done with a front-end script which
makes the valgrind testing include (ba)sh as well and that often causes
valgrind errors. Either we improve the valgrind error scanner a lot to
better identify (lib)curl errors only, or we disable valgrind checking by
default.
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
18. test case 57 has </test> that should be </client> but when corrected, the
test case fails!
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
<password>, and <fpath> components, encoded as "%00". The problem is that
curl_unescape does not detect this, but instead returns a shortened C
string. From a strict FTP protocol standpoint, NUL is a valid character
within RFC 959 <string>, so the way to handle this correctly in curl would
be to use a data structure other than a plain C string, one that can handle
embedded NUL characters. From a practical standpoint, most FTP servers
would not meaningfully support NUL characters within RFC 959 <string>,
anyway (e.g., UNIX pathnames may not contain NUL).
15. Test case 241 fails on all systems that support IPv6 but that don't have
the host name 'ip6-localhost' in /etc/hosts (or similar) since the test case
uses that host name to test the IPv6 name to address resolver.
14. Test case 165 might fail on system which has libidn present, but with an
old iconv version (2.1.3 is a known bad version), since it doesn't recognize old iconv version (2.1.3 is a known bad version), since it doesn't recognize
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
test pass, but instead makes it fail on Solaris hosts that use its native test pass, but instead makes it fail on Solaris hosts that use its native
iconv. iconv.
* curl version 7.12.2 fails on AIX if compiled with --enable-ares. 13. curl version 7.12.2 fails on AIX if compiled with --enable-ares.
The workaround is to combine --enable-ares with --disable-shared The workaround is to combine --enable-ares with --disable-shared
* When connecting to a SOCKS proxy, the (connect) timeout is not properly 12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
acknowledged after the actual TCP connect (during the SOCKS "negotiate" acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase). Pointed out by Lucas. Fix: need to select() and timeout properly. phase). Pointed out by Lucas. Fix: need to select() and timeout properly.
* Using configure --disable-[protocol] may cause 'make test' to fail for 11. Using configure --disable-[protocol] may cause 'make test' to fail for
tests using the disabled protocol(s). tests using the disabled protocol(s).
* To get HTTP Negotiate authentication to work fine, you need to provide a 10. To get HTTP Negotiate authentication to work fine, you need to provide a
(fake) user name (this concerns both curl and the lib) because the code (fake) user name (this concerns both curl and the lib) because the code
wrongly only considers authentication if there's a user name provided. wrongly only considers authentication if there's a user name provided.
Bug report #1004841. How? http://curl.haxx.se/mail/lib-2004-08/0182.html Bug report #1004841. How? http://curl.haxx.se/mail/lib-2004-08/0182.html
* --limit-rate using -d or -F does not work. This is because the limit logic 9. --limit-rate using -d or -F does not work. This is because the limit logic
is provided by the curl app in its read/write callbacks, and when doing is provided by the curl app in its read/write callbacks, and when doing
-d/-F the callbacks aren't used! Bug report #921395. -d/-F the callbacks aren't used! Bug report #921395.
* Doing resumed upload over HTTP does not work with '-C -', because curl 8. Doing resumed upload over HTTP does not work with '-C -', because curl
doesn't do a HEAD first to get the initial size. This needs to be done doesn't do a HEAD first to get the initial size. This needs to be done
manually for HTTP PUT resume to work, and then '-C [index]'. manually for HTTP PUT resume to work, and then '-C [index]'.
* CURLOPT_USERPWD and CURLOPT_PROXYUSERPWD have no way of providing user names 7. CURLOPT_USERPWD and CURLOPT_PROXYUSERPWD have no way of providing user names
that contain a colon. This can't be fixed easily in a backwards compatible that contain a colon. This can't be fixed easily in a backwards compatible
way without adding new options (and then, they should most probably allow way without adding new options (and then, they should most probably allow
setting user name and password separately). setting user name and password separately).
* libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that 6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
such parts should be sent to the server as 'CWD ' (without an argument). such parts should be sent to the server as 'CWD ' (without an argument).
The only exception to this rule, is that we knowingly break this if the The only exception to this rule, is that we knowingly break this if the
empty part is first in the path, as then we use the double slashes to empty part is first in the path, as then we use the double slashes to
indicate that the user wants to reach the root dir (this exception SHALL indicate that the user wants to reach the root dir (this exception SHALL
remain even when this bug is fixed). remain even when this bug is fixed).
* libcurl doesn't treat the content-length of compressed data properly, as 5. libcurl doesn't treat the content-length of compressed data properly, as
it seems HTTP servers send the *uncompressed* length in that header and it seems HTTP servers send the *uncompressed* length in that header and
libcurl thinks of it as the *compressed* lenght. Some explanations are here: libcurl thinks of it as the *compressed* length. Some explanations are here:
http://curl.haxx.se/mail/lib-2003-06/0146.html http://curl.haxx.se/mail/lib-2003-06/0146.html
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage 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. struct. It has been reported to work on AIX 5.1 though.
* GOPHER transfers seem broken 3. GOPHER transfers seem broken
* If a HTTP server responds to a HEAD request and includes a body (thus 2. If a HTTP server responds to a HEAD request and includes a body (thus
violating the RFC2616), curl won't wait to read the response but just stop violating the RFC2616), curl won't wait to read the response but just stop
reading and return back. If a second request (let's assume a GET) is then reading and return back. If a second request (let's assume a GET) is then
immediately made to the same server again, the connection will be re-used immediately made to the same server again, the connection will be re-used
@@ -63,3 +91,7 @@ may have been fixed since this was written!
and havoc is what happens. and havoc is what happens.
More details on this is found in this libcurl mailing list thread: More details on this is found in this libcurl mailing list thread:
http://curl.haxx.se/mail/lib-2002-08/0000.html http://curl.haxx.se/mail/lib-2002-08/0000.html
1. LDAP support requires that not only the OpenLDAP shared libraries be
present at run time, but the development libraries (liblber.so and
libldap.so) as well (not applicable to Windows).

View File

@@ -36,6 +36,9 @@ TODO
* Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and * Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete. SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
* 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 LIBCURL - multi interface
* Add a curl_multi_fdset() alternative that returns only two arrays with file * Add a curl_multi_fdset() alternative that returns only two arrays with file
@@ -62,6 +65,12 @@ TODO
FTP FTP
* 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 * Support GSS/Kerberos 5 for ftp file transfer. This will allow user
authentication and file encryption. Possible libraries and example clients authentication and file encryption. Possible libraries and example clients
are available from MIT or Heimdal. Requsted by Markus Moeller. are available from MIT or Heimdal. Requsted by Markus Moeller.
@@ -96,6 +105,10 @@ TODO
This could possibly be implemented using the multi interface to queue This could possibly be implemented using the multi interface to queue
requests and the response data. requests and the response data.
* When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
never been reported as causing trouble to anyone, but should be considered
to use the HTTP version the user has chosen.
TELNET TELNET
* Reading input (to send to the remote server) on stdin is a crappy solution * Reading input (to send to the remote server) on stdin is a crappy solution
@@ -148,6 +161,22 @@ TODO
lib/ldap.c source file and get moved to the main network code so that the lib/ldap.c source file and get moved to the main network code so that the
multi interface and friends will work for LDAP as well. multi interface and friends will work for LDAP as well.
NEW PROTOCOLS
* TFTP - RFC1350 (protocol) and RFC3617 (URI format)
Dan Fandrich: I wrote a tftp protocol module as part of the I-Boot
bootloader under a BSD-style license with attribution clause
http://download.intrinsyc.com/supported/tools/i-boot-lite/i-boot-lite-1.8/src/libs/net/tftp.c
* RTSP - RFC2326 (protocol - very HTTP-like, also contains URL description)
* SFTP/SCP/SSH (no RFCs for protocol nor URI/URL format). An implementation
should most probably use an existing ssh library, such as OpenSSH.
* RSYNC (no RFCs for protocol nor URI/URL format). An implementation should
most probably use an existing rsync library, such as librsync.
CLIENT CLIENT
* "curl --sync http://example.com/feed[1-100].rss" or * "curl --sync http://example.com/feed[1-100].rss" or
@@ -210,7 +239,7 @@ TODO
* Consider extending 'roffit' to produce decent ASCII output, and use that * Consider extending 'roffit' to produce decent ASCII output, and use that
instead of (g)nroff when building src/hugehelp.c instead of (g)nroff when building src/hugehelp.c
TEST SUITE TEST SUITE
* Make the test servers able to serve multiple running test suites. Like if * Make the test servers able to serve multiple running test suites. Like if

View File

@@ -1,4 +1,4 @@
Online: http://curl.haxx.se/docs/httpscripting.shtml Online: http://curl.haxx.se/docs/httpscripting.html
Date: December 9, 2004 Date: December 9, 2004
The Art Of Scripting HTTP Requests Using Curl The Art Of Scripting HTTP Requests Using Curl

View File

@@ -1,8 +1,27 @@
.\" You can view this file with: .\" **************************************************************************
.\" nroff -man curl-config.1 .\" * _ _ ____ _
.\" Written by Daniel Stenberg .\" * 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$
.\" **************************************************************************
.\" .\"
.TH curl-config 1 "11 Dec 2004" "Curl 7.10" "curl-config manual" .TH curl-config 1 "25 Jan 2004" "Curl 7.13.0" "curl-config manual"
.SH NAME .SH NAME
curl-config \- Get information about a libcurl installation curl-config \- Get information about a libcurl installation
.SH SYNOPSIS .SH SYNOPSIS
@@ -32,6 +51,12 @@ to link your application with libcurl.
This is the prefix used when libcurl was installed. Libcurl is then installed This is the prefix used when libcurl was installed. Libcurl is then installed
in $prefix/lib and its header files are installed in $prefix/include and so in $prefix/lib and its header files are installed in $prefix/include and so
on. The prefix is set with "configure --prefix". on. The prefix is set with "configure --prefix".
.IP "--protocols"
Lists what particular protocols the installed libcurl was built to support. At
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, GOPHER,
FILE, TELNET, LDAP, DICT. Do not assume any particular order. The protocols
will be listed using uppercase and are separated by newlines. There may be
none, one or several protocols in the list. (Added in 7.13.0)
.IP "--version" .IP "--version"
Outputs version information about the installed libcurl. Outputs version information about the installed libcurl.
.IP "--vernum" .IP "--vernum"

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 .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl 1 "7 Dec 2004" "Curl 7.12.3" "Curl Manual" .TH curl 1 "25 Jan 2005" "Curl 7.13.0" "Curl Manual"
.SH NAME .SH NAME
curl \- transfer a URL curl \- transfer a URL
.SH SYNOPSIS .SH SYNOPSIS
@@ -120,9 +120,9 @@ using \fI-D/--dump-header\fP!
If this option is set more than once, the last one will be the one that's If this option is set more than once, the last one will be the one that's
used. used.
.IP "-B/--use-ascii" .IP "-B/--use-ascii"
Use ASCII transfer when getting an FTP file or LDAP info. For FTP, this can Enable ASCII transfer when using FTP or LDAP. For FTP, this can also be
also be enforced by using an URL that ends with ";type=A". This option causes enforced by using an URL that ends with ";type=A". This option causes data
data sent to stdout to be in text mode for win32 systems. sent to stdout to be in text mode for win32 systems.
If this option is used twice, the second one will disable ASCII usage. If this option is used twice, the second one will disable ASCII usage.
.IP "--basic" .IP "--basic"
@@ -330,6 +330,12 @@ document stating so (which often also describes why and more). This flag will
prevent curl from outputting that and fail silently instead. prevent curl from outputting that and fail silently instead.
If this option is used twice, the second will again disable silent failure. If this option is used twice, the second will again disable silent failure.
.IP "--ftp-account [data]"
(FTP) When an FTP server asks for "account data" after user name and password
has been provided, this data is sent off using the ACCT command. (Added in
7.13.0)
If this option is used twice, the second will override the previous use.
.IP "--ftp-create-dirs" .IP "--ftp-create-dirs"
(FTP) When an FTP URL/operation uses a path that doesn't currently exist on (FTP) When an FTP URL/operation uses a path that doesn't currently exist on
the server, the standard behavior of curl is to fail. Using this option, curl the server, the standard behavior of curl is to fail. Using this option, curl
@@ -374,6 +380,11 @@ or
\fBcurl\fP -F "name=daniel;type=text/foo" url.com \fBcurl\fP -F "name=daniel;type=text/foo" url.com
You can also explicitly change the name field of an file upload part by
setting filename=, like this:
\fBcurl\fP -F "file=@localfile;filename=nameinpost" url.com
See further examples and details in the MANUAL. See further examples and details in the MANUAL.
This option can be used multiple times. This option can be used multiple times.
@@ -622,6 +633,9 @@ dynamically.
Write output to a local file named like the remote file we get. (Only the file Write output to a local file named like the remote file we get. (Only the file
part of the remote file is used, the path is cut off.) part of the remote file is used, the path is cut off.)
The remote file name to use for saving is extracted from the given URL.
Nothing else
You may use this option as many times as you have number of URLs. You may use this option as many times as you have number of URLs.
.IP "--pass <phrase>" .IP "--pass <phrase>"
(SSL) Pass phrase for the private key (SSL) Pass phrase for the private key
@@ -677,9 +691,11 @@ 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. file will not be read and used as a config file.
.IP "-Q/--quote <comand>" .IP "-Q/--quote <comand>"
(FTP) Send an arbitrary command to the remote FTP server. Quote commands are (FTP) Send an arbitrary command to the remote FTP server. Quote commands are
sent BEFORE the transfer is taking place. To make commands take place after a sent BEFORE the transfer is taking place (just after the initial PWD command
successful transfer, prefix them with a dash '-'. You may specify any amount to be exact). To make commands take place after a successful transfer, prefix
of commands to be run before and after the transfer. If the server returns them with a dash '-'. To make commands get sent after libcurl has changed
working directory, just before the transfer command(s), prefix the command
with '+'. You may specify any amount of commands. If the server returns
failure for one of the commands, the entire operation will be aborted. You failure for one of the commands, the entire operation will be aborted. You
must send syntactically correct FTP commands as RFC959 defines. must send syntactically correct FTP commands as RFC959 defines.
@@ -842,7 +858,8 @@ to read for untrained humans.
If this option is used several times, the last one will be used. (Added in If this option is used several times, the last one will be used. (Added in
7.9.7) 7.9.7)
.IP "-u/--user <user:password>" .IP "-u/--user <user:password>"
Specify user and password to use for server authentication. Specify user and password to use for server authentication. Overrides
\fI-n/--netrc\fP and \fI--netrc-optional\fP.
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-U/--proxy-user <user:password>" .IP "-U/--proxy-user <user:password>"
@@ -931,6 +948,10 @@ to follow location: headers.
.B http_code .B http_code
The numerical code that was found in the last retrieved HTTP(S) page. The numerical code that was found in the last retrieved HTTP(S) page.
.TP .TP
.B http_connect
The numerical code that was found in the last response (from a proxy) to a
curl CONNECT request. (Added in 7.12.4)
.TP
.B time_total .B time_total
The total time, in seconds, that the full operation lasted. The time will be The total time, in seconds, that the full operation lasted. The time will be
displayed with millisecond resolution. displayed with millisecond resolution.
@@ -1058,6 +1079,17 @@ Forces curl to use SSL version 2 when negotiating with a remote SSL server.
.IP "-3/--sslv3" .IP "-3/--sslv3"
(HTTPS) (HTTPS)
Forces curl to use SSL version 3 when negotiating with a remote SSL server. Forces curl to use SSL version 3 when negotiating with a remote SSL server.
.IP "--3p-quote"
(FTP) Specify arbitrary commands to send to the source server. See the
\fI-Q/--quote\fP option for details. (Added in 7.13.0)
.IP "--3p-url"
(FTP) Activates a FTP 3rd party transfer. Specifies the source URL to get a
file from, while the "normal" URL will be used as target URL, the file that
will be written/created.
Note that not all FTP server allow 3rd party transfers. (Added in 7.13.0)
.IP "--3p-user"
(FTP) Specify user:password for the source URL transfer. (Added in 7.13.0)
.IP "-4/--ipv4" .IP "-4/--ipv4"
If libcurl is capable of resolving an address to multiple IP versions (which If libcurl is capable of resolving an address to multiple IP versions (which
it is if it is ipv6-capable), this option tells libcurl to resolve names to it is if it is ipv6-capable), this option tells libcurl to resolve names to

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 \ post-callback.c multi-app.c multi-double.c multi-single.c \
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \ multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \ multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
anyauthput.c anyauthput.c htmltitle.cc htmltidy.c
all: all:
@echo "done" @echo "done"

View File

@@ -44,6 +44,8 @@ ftpgetresp.c - get the response strings from the FTP server
ftpupload.c - upload a file to a FTP server ftpupload.c - upload a file to a FTP server
getinfo.c - get the Content-Type from the recent transfer getinfo.c - get the Content-Type from the recent transfer
getinmemory.c - download a file to memory only getinmemory.c - download a file to memory only
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
page using libxml
http-post.c - HTTP POST http-post.c - HTTP POST
httpput.c - HTTP PUT a local file httpput.c - HTTP PUT a local file
https.c - simple HTTPS transfer https.c - simple HTTPS transfer

View File

@@ -1,8 +1,8 @@
/***************************************************************************** /*****************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* $Id$ * $Id$
@@ -16,22 +16,20 @@
/* /*
* This is an example showing how to transfer a file between two remote hosts. * This is an example showing how to transfer a file between two remote hosts.
* 7.13.0 or later required.
*/ */
int main(void) int main(void)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
char sourceFileName[] = "/tmp/file"; char source_url[] = "ftp://remotehost.com/path/to/source";
char targetFileName[] = "/tmp/curlTargetTest.dat"; char target_url[] = "ftp://aotherserver.com/path/to/dest";
char sourceHost[] = "source";
char targetHost[] = "target";
char sourceUserPass[] = "user:pass"; char sourceUserPass[] = "user:pass";
char targetUserPass[] = "user:pass"; char targetUserPass[] = "user:pass";
char url[100]; char url[100];
struct curl_slist *source_pre_cmd = NULL; struct curl_slist *source_pre_cmd = NULL;
struct curl_slist *target_pre_cmd = NULL; struct curl_slist *target_pre_cmd = NULL;
struct curl_slist *source_post_cmd = NULL; struct curl_slist *source_post_cmd = NULL;
@@ -39,24 +37,25 @@ int main(void)
char cmd[] = "PWD"; /* just to test */ char cmd[] = "PWD"; /* just to test */
curl_global_init(CURL_GLOBAL_DEFAULT); curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init(); curl = curl_easy_init();
if (curl) { if (curl) {
sprintf(url, "ftp://%s@%s/%s", targetUserPass, targetHost, targetFileName); /* The ordinary URL is the target when speaking 3rd party transfers */
printf("%s\n", url); curl_easy_setopt(curl, CURLOPT_URL, target_url);
curl_easy_setopt(curl, CURLOPT_URL, url);
/* Set a proxy host */ /* Set a source URL */
curl_easy_setopt(curl, CURLOPT_SOURCE_HOST, sourceHost); curl_easy_setopt(curl, CURLOPT_SOURCE_URL, source_url);
/* Set a proxy user and password */ /* Set target user and password */
curl_easy_setopt(curl, CURLOPT_USERPWD, targetUserPass);
/* Set source user and password */
curl_easy_setopt(curl, CURLOPT_SOURCE_USERPWD, sourceUserPass); curl_easy_setopt(curl, CURLOPT_SOURCE_USERPWD, sourceUserPass);
/* Set a proxy full file name */ #if 0
curl_easy_setopt(curl, CURLOPT_SOURCE_PATH, sourceFileName); /* FTPPORT enables PORT on the target side, instead of PASV. */
curl_easy_setopt(curl, CURLOPT_FTPPORT, ""); /* optional */
/* Set a proxy passive host */ #endif
curl_easy_setopt(curl, CURLOPT_PASV_HOST, 0); /* optional */
/* build a list of commands to pass to libcurl */ /* build a list of commands to pass to libcurl */
source_pre_cmd = curl_slist_append(source_pre_cmd, cmd); source_pre_cmd = curl_slist_append(source_pre_cmd, cmd);
@@ -77,7 +76,7 @@ int main(void)
target_post_cmd = curl_slist_append(target_post_cmd, cmd); target_post_cmd = curl_slist_append(target_post_cmd, cmd);
/* Set a post-quote command */ /* Set a post-quote command */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, target_post_cmd); curl_easy_setopt(curl, CURLOPT_POSTQUOTE, target_post_cmd);
/* Switch on full protocol/debug output */ /* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

View File

@@ -78,8 +78,12 @@ int main(int argc, char **argv)
DLL may not use the variable's memory when passed in to it from an app DLL may not use the variable's memory when passed in to it from an app
like this. */ like this. */
/* and give the size of the upload (optional) */ /* Set the size of the file to upload (optional). If you give a *_LARGE
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_info.st_size); option you MUST make sure that the type of the passed-in argument is a
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
make sure that to pass in a type 'long' argument. */
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
/* Now run off and do what you've been told! */ /* Now run off and do what you've been told! */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);

View File

@@ -37,7 +37,7 @@ void *myrealloc(void *ptr, size_t size)
size_t size_t
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{ {
register int realsize = size * nmemb; size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data; struct MemoryStruct *mem = (struct MemoryStruct *)data;
mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1); mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);

118
docs/examples/htmltidy.c Normal file
View File

@@ -0,0 +1,118 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Download a document and use libtidy to parse the HTML.
* Written by Jeff Pohlmeyer
*
* LibTidy => http://tidy.sourceforge.net
*
* gcc -Wall -I/usr/local/include tidycurl.c -lcurl -ltidy -o tidycurl
*
*/
#include <stdio.h>
#include <tidy/tidy.h>
#include <tidy/buffio.h>
#include <curl/curl.h>
/* curl write callback, to fill tidy's input buffer... */
uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
{
uint r;
r = size * nmemb;
tidyBufAppend( out, in, r );
return(r);
}
/* Traverse the document tree */
void dumpNode(TidyDoc doc, TidyNode tnod, int indent )
{
TidyNode child;
for ( child = tidyGetChild(tnod); child; child = tidyGetNext(child) )
{
ctmbstr name = tidyNodeGetName( child );
if ( name )
{
/* if it has a name, then it's an HTML tag ... */
TidyAttr attr;
printf( "%*.*s%s ", indent, indent, "<", name);
/* walk the attribute list */
for ( attr=tidyAttrFirst(child); attr; attr=tidyAttrNext(attr) ) {
printf(tidyAttrName(attr));
tidyAttrValue(attr)?printf("=\"%s\" ",
tidyAttrValue(attr)):printf(" ");
}
printf( ">\n");
}
else {
/* if it doesn't have a name, then it's probably text, cdata, etc... */
TidyBuffer buf;
tidyBufInit(&buf);
tidyNodeGetText(doc, child, &buf);
printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
tidyBufFree(&buf);
}
dumpNode( doc, child, indent + 4 ); /* recursive */
}
}
int main(int argc, char **argv )
{
CURL *curl;
char curl_errbuf[CURL_ERROR_SIZE];
TidyDoc tdoc;
TidyBuffer docbuf = {0};
TidyBuffer tidy_errbuf = {0};
int err;
if ( argc == 2) {
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, no);
curl_easy_setopt(curl, CURLOPT_VERBOSE, yes);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
tdoc = tidyCreate();
tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
tidyOptSetInt(tdoc, TidyWrapLen, 4096);
tidySetErrorBuffer( tdoc, &tidy_errbuf );
tidyBufInit(&docbuf);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
err=curl_easy_perform(curl);
if ( !err ) {
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
if ( err >= 0 ) {
err = tidyCleanAndRepair(tdoc); /* fix any problems */
if ( err >= 0 ) {
err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
if ( err >= 0 ) {
dumpNode( tdoc, tidyGetRoot(tdoc), 0 ); /* walk the tree */
fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
}
}
}
}
else
fprintf(stderr, "%s\n", curl_errbuf);
/* clean-up */
curl_easy_cleanup(curl);
tidyBufFree(&docbuf);
tidyBufFree(&tidy_errbuf);
tidyRelease(tdoc);
return(err);
}
else
printf( "usage: %s <url>\n", argv[0] );
return(0);
}

301
docs/examples/htmltitle.cc Normal file
View File

@@ -0,0 +1,301 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
// Get a web page, parse it with libxml.
//
// Written by Lars Nilsson
//
// GNU C++ compile command line suggestion (edit paths accordingly):
//
// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cc \
// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <curl/curl.h>
#include <libxml/HTMLparser.h>
//
// Case-insensitive string comparison
//
#ifdef _MSC_VER
#define COMPARE(a, b) (!stricmp((a), (b)))
#else
#define COMPARE(a, b) (!strcasecmp((a), (b)))
#endif
//
// libxml callback context structure
//
struct Context
{
Context(): addTitle(false) { }
bool addTitle;
std::string title;
};
//
// libcurl variables for error strings and returned data
static char errorBuffer[CURL_ERROR_SIZE];
static std::string buffer;
//
// libcurl write callback function
//
static int writer(char *data, size_t size, size_t nmemb,
std::string *writerData)
{
if (writerData == NULL)
return 0;
writerData->append(data, size*nmemb);
return size * nmemb;
}
//
// libcurl connection initialization
//
static bool init(CURL *&conn, char *url)
{
CURLcode code;
conn = curl_easy_init();
if (conn == NULL)
{
fprintf(stderr, "Failed to create CURL connection\n");
exit(EXIT_FAILURE);
}
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set error buffer [%d]\n", code);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_URL, url);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
return false;
}
return true;
}
//
// libxml start element callback function
//
static void StartElement(void *voidContext,
const xmlChar *name,
const xmlChar **attributes)
{
Context *context = (Context *)voidContext;
if (COMPARE((char *)name, "TITLE"))
{
context->title = "";
context->addTitle = true;
}
}
//
// libxml end element callback function
//
static void EndElement(void *voidContext,
const xmlChar *name)
{
Context *context = (Context *)voidContext;
if (COMPARE((char *)name, "TITLE"))
context->addTitle = false;
}
//
// Text handling helper function
//
static void handleCharacters(Context *context,
const xmlChar *chars,
int length)
{
if (context->addTitle)
context->title.append((char *)chars, length);
}
//
// libxml PCDATA callback function
//
static void Characters(void *voidContext,
const xmlChar *chars,
int length)
{
Context *context = (Context *)voidContext;
handleCharacters(context, chars, length);
}
//
// libxml CDATA callback function
//
static void cdata(void *voidContext,
const xmlChar *chars,
int length)
{
Context *context = (Context *)voidContext;
handleCharacters(context, chars, length);
}
//
// libxml SAX callback structure
//
static htmlSAXHandler saxHandler =
{
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
StartElement,
EndElement,
NULL,
Characters,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
cdata,
NULL
};
//
// Parse given (assumed to be) HTML text and return the title
//
static void parseHtml(const std::string &html,
std::string &title)
{
htmlParserCtxtPtr ctxt;
Context context;
ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
XML_CHAR_ENCODING_NONE);
htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
htmlParseChunk(ctxt, "", 0, 1);
htmlFreeParserCtxt(ctxt);
title = context.title;
}
int main(int argc, char *argv[])
{
CURL *conn = NULL;
CURLcode code;
std::string title;
// Ensure one argument is given
if (argc != 2)
{
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
exit(EXIT_FAILURE);
}
curl_global_init(CURL_GLOBAL_DEFAULT);
// Initialize CURL connection
if (!init(conn, argv[1]))
{
fprintf(stderr, "Connection initializion failed\n");
exit(EXIT_FAILURE);
}
// Retrieve content for the URL
code = curl_easy_perform(conn);
curl_easy_cleanup(conn);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
exit(EXIT_FAILURE);
}
// Parse the (assumed) HTML code
parseHtml(buffer, title);
// Display the extracted title
printf("Title: %s\n", title.c_str());
return EXIT_SUCCESS;
}

View File

@@ -19,6 +19,9 @@
* line argument to the URL also given on the command line. * line argument to the URL also given on the command line.
* *
* This example also uses its own read callback. * This example also uses its own read callback.
*
* Here's an article on how to setup a PUT handler for Apache:
* http://www.apacheweek.com/features/put
*/ */
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)

View File

@@ -52,7 +52,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
CLEANFILES = $(HTMLPAGES) $(PDFPAGES) CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4
MAN2HTML= roffit --mandir=. < $< >$@ MAN2HTML= roffit --mandir=. < $< >$@

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_easy_getinfo 3 "14 Dec 2004" "libcurl 7.12.3" "libcurl Manual" .TH curl_easy_getinfo 3 "22 Dec 2004" "libcurl 7.12.3" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_getinfo - extract information from a curl handle curl_easy_getinfo - extract information from a curl handle
.SH SYNOPSIS .SH SYNOPSIS
@@ -27,7 +27,13 @@ The following information can be extracted:
Pass a pointer to a 'char *' to receive the last used effective URL. Pass a pointer to a 'char *' to receive the last used effective URL.
.IP CURLINFO_RESPONSE_CODE .IP CURLINFO_RESPONSE_CODE
Pass a pointer to a long to receive the last received HTTP or FTP code. This Pass a pointer to a long to receive the last received HTTP or FTP code. This
option was known as CURLINFO_HTTP_CODE in libcurl 7.10.7 and earlier. option was known as CURLINFO_HTTP_CODE in libcurl 7.10.7 and earlier. This
will be zero if no server response code has been received. Note that a proxy's
CONNECT response should be read with \fICURLINFO_HTTP_CONNECTCODE\fP and not
this.
.IP CURLINFO_HTTP_CONNECTCODE
Pass a pointer to a long to receive the last received proxy response code to a
CONNECT request.
.IP CURLINFO_FILETIME .IP CURLINFO_FILETIME
Pass a pointer to a long to receive the remote time of the retrieved Pass a pointer to a long to receive the remote time of the retrieved
document. If you get -1, it can be because of many reasons (unknown, the document. If you get -1, it can be because of many reasons (unknown, the

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 .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl_easy_setopt 3 "29 Nov 2004" "libcurl 7.12.3" "libcurl Manual" .TH curl_easy_setopt 3 "25 Jan 2005" "libcurl 7.13.0" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_setopt - set options for a curl easy handle curl_easy_setopt - set options for a curl easy handle
.SH SYNOPSIS .SH SYNOPSIS
@@ -543,11 +543,10 @@ data to figure out the size. This is the large file version of the
.IP CURLOPT_HTTPPOST .IP CURLOPT_HTTPPOST
Tells libcurl you want a multipart/formdata HTTP POST to be made and you Tells libcurl you want a multipart/formdata HTTP POST to be made and you
instruct what data to pass on to the server. Pass a pointer to a linked list instruct what data to pass on to the server. Pass a pointer to a linked list
of HTTP post structs as parameter. The linked list should be a fully valid of curl_httppost structs as parameter. . The easiest way to create such a
list of 'struct HttpPost' structs properly filled in. The best and most list, is to use \fIcurl_formadd(3)\fP as documented. The data in this list
elegant way to do this, is to use \fIcurl_formadd(3)\fP as documented. The must remain intact until you close this curl handle again with
data in this list must remain intact until you close this curl handle again \fIcurl_easy_cleanup(3)\fP.
with \fIcurl_easy_cleanup(3)\fP.
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual. You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
@@ -618,9 +617,9 @@ name of your file holding cookie data to read. The cookie data may be in
Netscape / Mozilla cookie data format or just regular HTTP-style headers Netscape / Mozilla cookie data format or just regular HTTP-style headers
dumped to a file. dumped to a file.
Given an empty or non-existing file, this option will enable cookies for this Given an empty or non-existing file or by passing the empty string (""), this
curl handle, making it understand and parse received cookies and then use option will enable cookies for this curl handle, making it understand and
matching cookies in future request. parse received cookies and then use matching cookies in future request.
.IP CURLOPT_COOKIEJAR .IP CURLOPT_COOKIEJAR
Pass a file name as char *, zero terminated. This will make libcurl write all Pass a file name as char *, zero terminated. This will make libcurl write all
internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP
@@ -752,6 +751,22 @@ Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
.IP CURLFTPAUTH_TLS .IP CURLFTPAUTH_TLS
Try "AUTH TLS" first, and only if that fails try "AUTH SSL" Try "AUTH TLS" first, and only if that fails try "AUTH SSL"
.RE .RE
.IP CURLOPT_SOURCE_URL
When set, it enables a FTP third party transfer, using the set URL as source,
while \fICURLOPT_URL\fP is the target.
.IP CURLOPT_SOURCE_USERPWD
Set "username:password" to use for the source connection when doing FTP third
party transfers.
.IP CURLOPT_SOURCE_QUOTE
Exactly like \fICURLOPT_QUOTE\fP, but for the source host.
.IP CURLOPT_SOURCE_PREQUOTE
Exactly like \fICURLOPT_PREQUOTE\fP, but for the source host.
.IP CURLOPT_SOURCE_POSTQUOTE
Exactly like \fICURLOPT_POSTQUOTE\fP, but for the source host.
.IP CURLOPT_FTP_ACCOUNT
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP
server asks for "account data" after user name and password has been provided,
this data is sent off using the ACCT command. (Added in 7.13.0)
.SH PROTOCOL OPTIONS .SH PROTOCOL OPTIONS
.IP CURLOPT_TRANSFERTEXT .IP CURLOPT_TRANSFERTEXT
A non-zero parameter tells the library to use ASCII mode for ftp transfers, A non-zero parameter tells the library to use ASCII mode for ftp transfers,

View File

@@ -16,13 +16,9 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
.SH DESCRIPTION .SH DESCRIPTION
This function extracts file descriptor information from a given multi_handle. This function extracts file descriptor information from a given multi_handle.
libcurl returns its fd_set sets. The application can use these to select() libcurl returns its fd_set sets. The application can use these to select()
on. The \fIcurl_multi_perform(3)\fI function should be called as soon as one 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. of them are ready to be read from or written to.
NOTE that once this call is made, you must not remove the sets you point to,
as libcurl will need to be able to read them. It needs them after select()
calls, to know if certain sockets are readable or writable.
You should also be aware that when doing select(), you should consider using a You should also be aware that when doing select(), you should consider using a
rather small (single-digit number of seconds) timeout and call rather small (single-digit number of seconds) timeout and call
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the \fIcurl_multi_perform\fP regularly - even if no activity has been seen on the

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH libcurl-errors 3 "27 Apr 2004" "libcurl 7.12" "libcurl errors" .TH libcurl-errors 3 "9 Feb 2005" "libcurl 7.13.1" "libcurl errors"
.SH NAME .SH NAME
libcurl-errors \- error codes in libcurl libcurl-errors \- error codes in libcurl
.SH DESCRIPTION .SH DESCRIPTION
@@ -187,6 +187,13 @@ Invalid LDAP URL
Maximum file size exceeded Maximum file size exceeded
.IP "CURLE_FTP_SSL_FAILED (64)" .IP "CURLE_FTP_SSL_FAILED (64)"
Requested FTP SSL level failed Requested FTP SSL level failed
.IP "CURLE_SEND_FAIL_REWIND (65)"
When doing a send operation curl had to rewind the data to retransmit, but the
rewinding operation failed
.IP "CURLE_SSL_ENGINE_INITFAILED (66)"
Initiating the SSL Engine failed
.IP "CURLE_LOGIN_DENIED (67)"
The remote server denied curl to login (Added in 7.13.1)
.SH "CURLMcode" .SH "CURLMcode"
This is the generic return code used by functions in the libcurl multi This is the generic return code used by functions in the libcurl multi
interface. Also consider \fIcurl_multi_strerror(3)\fI. interface. Also consider \fIcurl_multi_strerror(3)\fI.

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 .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH libcurl-tutorial 3 "18 Jun 2004" "libcurl" "libcurl programming" .TH libcurl-tutorial 3 "25 Jan 2005" "libcurl" "libcurl programming"
.SH NAME .SH NAME
libcurl-tutorial \- libcurl programming tutorial libcurl-tutorial \- libcurl programming tutorial
.SH "Objective" .SH "Objective"
@@ -76,6 +76,11 @@ possibly together with a few other features that can be on and off on
different libcurls. different libcurls.
See also the "Features libcurl Provides" further down. See also the "Features libcurl Provides" further down.
.IP "autoconf macro"
When you write your configure script to detect libcurl and setup variables
accordingly, we offer a prewritten macro that probably does everything you
need in this area. See docs/libcurl/libcurl.m4 file - it includes docs on how
to use it.
.SH "Portable Code in a Portable World" .SH "Portable Code in a Portable World"
The people behind libcurl have put a considerable effort to make libcurl work The people behind libcurl have put a considerable effort to make libcurl work
@@ -94,9 +99,9 @@ use the library. Once for your program's entire life time. This is done using
curl_global_init() curl_global_init()
and it takes one parameter which is a bit pattern that tells libcurl what to and it takes one parameter which is a bit pattern that tells libcurl what to
initialize. Using CURL_GLOBAL_ALL will make it initialize all known internal initialize. Using \fICURL_GLOBAL_ALL\fP will make it initialize all known
sub modules, and might be a good default option. The current two bits that internal sub modules, and might be a good default option. The current two bits
are specified are: that are specified are:
.RS .RS
.IP "CURL_GLOBAL_WIN32" .IP "CURL_GLOBAL_WIN32"
which only does anything on Windows machines. When used on which only does anything on Windows machines. When used on
@@ -113,17 +118,19 @@ application so if your program or another library already does this, this
bit should not be needed. bit should not be needed.
.RE .RE
libcurl has a default protection mechanism that detects if curl_global_init() libcurl has a default protection mechanism that detects if
hasn't been called by the time curl_easy_perform() is called and if that is \fIcurl_global_init(3)\fP hasn't been called by the time
the case, libcurl runs the function itself with a guessed bit pattern. Please \fIcurl_easy_perform(3)\fP is called and if that is the case, libcurl runs the
note that depending solely on this is not considered nice nor very good. function itself with a guessed bit pattern. Please note that depending solely
on this is not considered nice nor very good.
When the program no longer uses libcurl, it should call curl_global_cleanup(), When the program no longer uses libcurl, it should call
which is the opposite of the init call. It will then do the reversed \fIcurl_global_cleanup(3)\fP, which is the opposite of the init call. It will
operations to cleanup the resources the curl_global_init() call initialized. then do the reversed operations to cleanup the resources the
\fIcurl_global_init(3)\fP call initialized.
Repeated calls to curl_global_init() and curl_global_cleanup() should be Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP
avoided. They should only be called once each. should be avoided. They should only be called once each.
.SH "Features libcurl Provides" .SH "Features libcurl Provides"
It is considered best-practice to determine libcurl features run-time rather It is considered best-practice to determine libcurl features run-time rather
@@ -153,17 +160,18 @@ It returns an easy handle. Using that you proceed to the next step: setting
up your preferred actions. A handle is just a logic entity for the upcoming up your preferred actions. A handle is just a logic entity for the upcoming
transfer or series of transfers. transfer or series of transfers.
You set properties and options for this handle using curl_easy_setopt(). They You set properties and options for this handle using
control how the subsequent transfer or transfers will be made. Options remain \fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or
set in the handle until set again to something different. Alas, multiple transfers will be made. Options remain set in the handle until set again to
requests using the same handle will use the same options. something different. Alas, multiple requests using the same handle will use
the same options.
Many of the options you set in libcurl are "strings", pointers to data Many of the options you set in libcurl are "strings", pointers to data
terminated with a zero byte. Keep in mind that when you set strings with terminated with a zero byte. Keep in mind that when you set strings with
curl_easy_setopt(), libcurl will not copy the data. It will merely point to \fIcurl_easy_setopt(3)\fP, libcurl will not copy the data. It will merely
the data. You MUST make sure that the data remains available for libcurl to point to the data. You MUST make sure that the data remains available for
use until finished or until you use the same option again to point to libcurl to use until finished or until you use the same option again to point
something else. to something else.
One of the most basic properties to set in the handle is the URL. You set One of the most basic properties to set in the handle is the URL. You set
your preferred URL to transfer with CURLOPT_URL in a manner similar to: your preferred URL to transfer with CURLOPT_URL in a manner similar to:
@@ -188,41 +196,44 @@ similar to this:
You can control what data your function get in the forth argument by setting You can control what data your function get in the forth argument by setting
another property: another property:
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct); curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
Using that property, you can easily pass local data between your application Using that property, you can easily pass local data between your application
and the function that gets invoked by libcurl. libcurl itself won't touch the and the function that gets invoked by libcurl. libcurl itself won't touch the
data you pass with CURLOPT_WRITEDATA. data you pass with \fICURLOPT_WRITEDATA\fP.
libcurl offers its own default internal callback that'll take care of the data libcurl offers its own default internal callback that'll take care of the data
if you don't set the callback with CURLOPT_WRITEFUNCTION. It will then simply if you don't set the callback with \fICURLOPT_WRITEFUNCTION\fP. It will then
output the received data to stdout. You can have the default callback write simply output the received data to stdout. You can have the default callback
the data to a different file handle by passing a 'FILE *' to a file opened for write the data to a different file handle by passing a 'FILE *' to a file
writing with the CURLOPT_WRITEDATA option. opened for writing with the \fICURLOPT_WRITEDATA\fP option.
Now, we need to take a step back and have a deep breath. Here's one of those Now, we need to take a step back and have a deep breath. Here's one of those
rare platform-dependent nitpicks. Did you spot it? On some platforms[2], rare platform-dependent nitpicks. Did you spot it? On some platforms[2],
libcurl won't be able to operate on files opened by the program. Thus, if you libcurl won't be able to operate on files opened by the program. Thus, if you
use the default callback and pass in a an open file with CURLOPT_WRITEDATA, it use the default callback and pass in a an open file with
will crash. You should therefore avoid this to make your program run fine \fICURLOPT_WRITEDATA\fP, it will crash. You should therefore avoid this to
virtually everywhere. make your program run fine virtually everywhere.
(CURLOPT_WRITEDATA was formerly known as CURLOPT_FILE. Both names still work (\fICURLOPT_WRITEDATA\fP was formerly known as \fICURLOPT_FILE\fP. Both names
and do the same thing). still work and do the same thing).
If you're using libcurl as a win32 DLL, you MUST use the
\fICURLOPT_WRITEFUNCTION\fP if you set \fICURLOPT_WRITEDATA\fP - or you will
experience crashes.
There are of course many more options you can set, and we'll get back to a few There are of course many more options you can set, and we'll get back to a few
of them later. Let's instead continue to the actual transfer: of them later. Let's instead continue to the actual transfer:
success = curl_easy_perform(easyhandle); success = curl_easy_perform(easyhandle);
The \fIcurl_easy_perform(3)\fP will connect to the remote site, do the \fIcurl_easy_perform(3)\fP will connect to the remote site, do the necessary
necessary commands and receive the transfer. Whenever it receives data, it commands and receive the transfer. Whenever it receives data, it calls the
calls the callback function we previously set. The function may get one byte callback function we previously set. The function may get one byte at a time,
at a time, or it may get many kilobytes at once. libcurl delivers as much as or it may get many kilobytes at once. libcurl delivers as much as possible as
possible as often as possible. Your callback function should return the number often as possible. Your callback function should return the number of bytes it
of bytes it "took care of". If that is not the exact same amount of bytes that \&"took care of". If that is not the exact same amount of bytes that was
was passed to it, libcurl will abort the operation and return with an error passed to it, libcurl will abort the operation and return with an error code.
code.
When the transfer is complete, the function returns a return code that informs When the transfer is complete, the function returns a return code that informs
you if it succeeded in its mission or not. If a return code isn't enough for you if it succeeded in its mission or not. If a return code isn't enough for
@@ -236,12 +247,12 @@ previous
.SH "Multi-threading Issues" .SH "Multi-threading Issues"
libcurl is completely thread safe, except for two issues: signals and alarm libcurl is completely thread safe, except for two issues: signals and alarm
handlers. Signals are needed for a SIGPIPE handler, and the alarm() Bacall handlers. Signals are needed for a SIGPIPE handler, and the alarm() call is
is used to catch timeouts (mostly during ENS lookup). used to deal with timeouts (during DNS lookup).
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
then of course using OpenSSL multi-threaded and it has itself a few then of course using OpenSSL multi-threaded and it has itself a few
requirements on this. Basilio, you need to provide one or two functions to requirements on this. Basically, you need to provide one or two functions to
allow it to function properly. For all details, see this: allow it to function properly. For all details, see this:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
@@ -322,12 +333,12 @@ CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]:
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size); curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
.fi .fi
When you call curl_easy_perform() this time, it'll perform all the necessary When you call \fIcurl_easy_perform(3)\fP this time, it'll perform all the
operations and when it has invoked the upload it'll call your supplied necessary operations and when it has invoked the upload it'll call your
callback to get the data to upload. The program should return as much data as supplied callback to get the data to upload. The program should return as much
possible in every invoke, as that is likely to make the upload perform as data as possible in every invoke, as that is likely to make the upload perform
fast as possible. The callback should return the number of bytes it wrote in as fast as possible. The callback should return the number of bytes it wrote
the buffer. Returning 0 will signal the end of the upload. in the buffer. Returning 0 will signal the end of the upload.
.SH "Passwords" .SH "Passwords"
Many protocols use or even require that user name and password are provided Many protocols use or even require that user name and password are provided
@@ -466,15 +477,14 @@ then passing that list to libcurl.
While the simple examples above cover the majority of all cases where HTTP While the simple examples above cover the majority of all cases where HTTP
POST operations are required, they don't do multi-part formposts. Multi-part POST operations are required, they don't do multi-part formposts. Multi-part
formposts were introduced as a better way to post (possibly large) binary formposts were introduced as a better way to post (possibly large) binary data
data and was first documented in the RFC1867. They're called multi-part and was first documented in the RFC1867. They're called multi-part because
because they're built by a chain of parts, each being a single unit. Each they're built by a chain of parts, each being a single unit. Each part has its
part has its own name and contents. You can in fact create and post a own name and contents. You can in fact create and post a multi-part formpost
multi-part formpost with the regular libcurl POST support described above, but with the regular libcurl POST support described above, but that would require
that would require that you build a formpost yourself and provide to that you build a formpost yourself and provide to libcurl. To make that
libcurl. To make that easier, libcurl provides curl_formadd(). Using this easier, libcurl provides \fIcurl_formadd(3)\fP. Using this function, you add
function, you add parts to the form. When you're done adding parts, you post parts to the form. When you're done adding parts, you post the whole form.
the whole form.
The following example sets two simple text parts with plain textual contents, The following example sets two simple text parts with plain textual contents,
and then a file with binary contents and upload the whole thing. and then a file with binary contents and upload the whole thing.
@@ -527,10 +537,10 @@ post handle:
.fi .fi
Since all options on an easyhandle are "sticky", they remain the same until Since all options on an easyhandle are "sticky", they remain the same until
changed even if you do call curl_easy_perform(), you may need to tell curl to changed even if you do call \fIcurl_easy_perform(3)\fP, you may need to tell
go back to a plain GET request if you intend to do such a one as your next curl to go back to a plain GET request if you intend to do such a one as your
request. You force an easyhandle to back to GET by using the CURLOPT_HTTPGET next request. You force an easyhandle to back to GET by using the
option: CURLOPT_HTTPGET option:
curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, TRUE); curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, TRUE);
@@ -719,7 +729,7 @@ Mozilla javascript engine in the past.
Re-cycling the same easy handle several times when doing multiple requests is Re-cycling the same easy handle several times when doing multiple requests is
the way to go. the way to go.
After each single curl_easy_perform() operation, libcurl will keep the After each single \fIcurl_easy_perform(3)\fP operation, libcurl will keep the
connection alive and open. A subsequent request using the same easy handle to connection alive and open. A subsequent request using the same easy handle to
the same host might just be able to use the already open connection! This the same host might just be able to use the already open connection! This
reduces network impact a lot. reduces network impact a lot.
@@ -903,8 +913,8 @@ A little example that deletes a given file before an operation:
.fi .fi
If you would instead want this operation (or chain of operations) to happen If you would instead want this operation (or chain of operations) to happen
_after_ the data transfer took place the option to curl_easy_setopt() would _after_ the data transfer took place the option to \fIcurl_easy_setopt(3)\fP
instead be called CURLOPT_POSTQUOTE and used the exact same way. would instead be called CURLOPT_POSTQUOTE and used the exact same way.
The custom FTP command will be issued to the server in the same order they are The custom FTP command will be issued to the server in the same order they are
added to the list, and if a command gets an error code returned back from the added to the list, and if a command gets an error code returned back from the
@@ -973,9 +983,9 @@ The perhaps most advanced cookie operation libcurl offers, is saving the
entire internal cookie state back into a Netscape/Mozilla formatted cookie entire internal cookie state back into a Netscape/Mozilla formatted cookie
file. We call that the cookie-jar. When you set a file name with file. We call that the cookie-jar. When you set a file name with
CURLOPT_COOKIEJAR, that file name will be created and all received cookies CURLOPT_COOKIEJAR, that file name will be created and all received cookies
will be stored in it when curl_easy_cleanup() is called. This enabled cookies will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enabled
to get passed on properly between multiple handles without any information cookies to get passed on properly between multiple handles without any
getting lost. information getting lost.
.SH "FTP Peculiarities We Need" .SH "FTP Peculiarities We Need"
@@ -1103,46 +1113,47 @@ of how to use the easy interface. The multi interface is simply a way to make
multiple transfers at the same time, by adding up multiple easy handles in to multiple transfers at the same time, by adding up multiple easy handles in to
a "multi stack". a "multi stack".
You create the easy handles you want and you set all the options just like You create the easy handles you want and you set all the options just like you
you have been told above, and then you create a multi handle with have been told above, and then you create a multi handle with
curl_multi_init() and add all those easy handles to that multi handle with \fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle
curl_multi_add_handle(). with \fIcurl_multi_add_handle(3)\fP.
When you've added the handles you have for the moment (you can still add new When you've added the handles you have for the moment (you can still add new
ones at any time), you start the transfers by call curl_multi_perform(). ones at any time), you start the transfers by call
\fIcurl_multi_perform(3)\fP.
curl_multi_perform() is asynchronous. It will only execute as little as \fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as
possible and then return back control to your program. It is designed to possible and then return back control to your program. It is designed to never
never block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again soon,
soon, as that is a signal that it still has local data to send or remote data as that is a signal that it still has local data to send or remote data to
to receive. receive.
The best usage of this interface is when you do a select() on all possible The best usage of this interface is when you do a select() on all possible
file descriptors or sockets to know when to call libcurl again. This also file descriptors or sockets to know when to call libcurl again. This also
makes it easy for you to wait and respond to actions on your own makes it easy for you to wait and respond to actions on your own application's
application's sockets/handles. You figure out what to select() for by using sockets/handles. You figure out what to select() for by using
curl_multi_fdset(), that fills in a set of fd_set variables for you with the \fIcurl_multi_fdset(3)\fP, that fills in a set of fd_set variables for you
particular file descriptors libcurl uses for the moment. with the particular file descriptors libcurl uses for the moment.
When you then call select(), it'll return when one of the file handles signal When you then call select(), it'll return when one of the file handles signal
action and you then call curl_multi_perform() to allow libcurl to do what it action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
wants to do. Take note that libcurl does also feature some time-out code so what it wants to do. Take note that libcurl does also feature some time-out
we advice you to never use very long timeouts on select() before you call code so we advice you to never use very long timeouts on select() before you
curl_multi_perform(), which thus should be called unconditionally every now call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally
and then even if none of its file descriptors have signaled ready. Another every now and then even if none of its file descriptors have signaled
precaution you should use: always call curl_multi_fdset() immediately before ready. Another precaution you should use: always call
the select() call since the current set of file descriptors may change when \fIcurl_multi_fdset(3)\fP immediately before the select() call since the
calling a curl function. current set of file descriptors may change when calling a curl function.
If you want to stop the transfer of one of the easy handles in the stack, you If you want to stop the transfer of one of the easy handles in the stack, you
can use curl_multi_remove_handle() to remove individual easy can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy
handles. Remember that easy handles should be curl_easy_cleanup()ed. handles. Remember that easy handles should be \fIcurl_easy_cleanup(3)\fPed.
When a transfer within the multi stack has finished, the counter of running When a transfer within the multi stack has finished, the counter of running
transfers (as filled in by curl_multi_perform()) will decrease. When the transfers (as filled in by \fIcurl_multi_perform(3)\fP) will decrease. When
number reaches zero, all transfers are done. the number reaches zero, all transfers are done.
curl_multi_info_read() can be used to get information about completed \fIcurl_multi_info_read(3)\fP can be used to get information about completed
transfers. It then returns the CURLcode for each easy transfer, to allow you transfers. It then returns the CURLcode for each easy transfer, to allow you
to figure out success on each individual transfer. to figure out success on each individual transfer.

209
docs/libcurl/libcurl.m4 Normal file
View File

@@ -0,0 +1,209 @@
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
# [ACTION-IF-YES], [ACTION-IF-NO])
# ----------------------------------------------------------
# David Shaw <dshaw@jabberwocky.com> Jan-23-2005
#
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
# specify whether to default to --with-libcurl or --without-libcurl.
# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the
# minimum version of libcurl to accept. Pass the version as a regular
# version number like 7.10.1. If not supplied, any version is
# accepted. ACTION-IF-YES is a list of shell commands to run if
# libcurl was successfully found and passed the various tests.
# ACTION-IF-NO is a list of shell commands that are run otherwise.
# Note that using --without-libcurl does run ACTION-IF-NO.
#
# This macro defines HAVE_LIBCURL if a working libcurl setup is found,
# and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary values.
# Other useful defines are LIBCURL_FEATURE_xxx where xxx are the
# various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
# where yyy are the various protocols supported by libcurl. Both xxx
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
# the macro for the complete list of possible defines. Shell
# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
# defined to 'yes' for those features and protocols that were found.
# Note that xxx and yyy keep the same capitalization as in the
# curl-config list (e.g. it's "HTTP" and not "http").
#
# Users may override the detected values by doing something like:
# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
#
# For the sake of sanity, this macro assumes that any libcurl that is
# found is after version 7.7.2, the first version that included the
# curl-config script. Note that it is very important for people
# packaging binary versions of libcurl to include this script!
# Without curl-config, we can only make educated guesses as to what
# protocols are available. Specifically, we assume that all of HTTP,
# FTP, GOPHER, FILE, TELNET, LDAP, and DICT exist, and (if SSL exists)
# HTTPS is present. All of these protocols existed when libcurl was
# first created in version 7, so this is a safe assumption. If the
# version is 7.11.0 or later, FTPS is assumed to be present as well.
# FTPS existed before then, but was not yet fully standards compliant.
AC_DEFUN([LIBCURL_CHECK_CONFIG],
[
AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_GOPHER],[Defined if libcurl supports GOPHER])
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
AC_ARG_WITH(libcurl,
AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]),
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
if test "$_libcurl_with" != "no" ; then
AC_PROG_AWK
_libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
_libcurl_try_link=yes
if test -d "$_libcurl_with" ; then
CPPFLAGS="${CPPFLAGS} -I$withval/include"
LDFLAGS="${LDFLAGS} -L$withval/lib"
fi
AC_PATH_PROG([_libcurl_config],[curl-config])
if test x$_libcurl_config != "x" ; then
AC_CACHE_CHECK([for the version of libcurl],
[libcurl_cv_lib_curl_version],
[libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
_libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
_libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
if test $_libcurl_wanted -gt 0 ; then
AC_CACHE_CHECK([for libcurl >= version $2],
[libcurl_cv_lib_version_ok],
[
if test $_libcurl_version -ge $_libcurl_wanted ; then
libcurl_cv_lib_version_ok=yes
else
libcurl_cv_lib_version_ok=no
fi
])
fi
if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
if test x"$LIBCURL_CPPFLAGS" = "x" ; then
LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
fi
if test x"$LIBCURL" = "x" ; then
LIBCURL=`$_libcurl_config --libs`
fi
# All curl-config scripts support --feature
_libcurl_features=`$_libcurl_config --feature`
# Is it modern enough to have --protocols? (7.12.4)
if test $_libcurl_version -ge 461828 ; then
_libcurl_protocols=`$_libcurl_config --protocols`
fi
else
_libcurl_try_link=no
fi
unset _libcurl_wanted
fi
if test $_libcurl_try_link = yes ; then
# we didn't find curl-config, so let's see if the user-supplied
# link line (or failing that, "-lcurl") is enough.
LIBCURL=${LIBCURL-"-lcurl"}
AC_CACHE_CHECK([whether libcurl is usable],
[libcurl_cv_lib_curl_usable],
[
_libcurl_save_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
_libcurl_save_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS $LIBCURL"
AC_LINK_IFELSE(AC_LANG_PROGRAM([#include <curl/curl.h>],[
/* Try and use a few common options to force a failure if we are
missing symbols or can't link. */
int x;
curl_easy_setopt(NULL,CURLOPT_URL,NULL);
x=CURL_ERROR_SIZE;
x=CURLOPT_WRITEFUNCTION;
x=CURLOPT_FILE;
x=CURLOPT_ERRORBUFFER;
x=CURLOPT_STDERR;
x=CURLOPT_VERBOSE;
]),libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
CPPFLAGS=$_libcurl_save_cppflags
LDFLAGS=$_libcurl_save_ldflags
unset _libcurl_save_cppflags
unset _libcurl_save_ldflags
])
if test $libcurl_cv_lib_curl_usable = yes ; then
AC_DEFINE(HAVE_LIBCURL,1,
[Define to 1 if you have a functional curl library.])
AC_SUBST(LIBCURL_CPPFLAGS)
AC_SUBST(LIBCURL)
for _libcurl_feature in $_libcurl_features ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
done
if test "x$_libcurl_protocols" = "x" ; then
# We don't have --protocols, so just assume that all
# protocols are available
_libcurl_protocols="HTTP FTP GOPHER FILE TELNET LDAP DICT"
if test x$libcurl_feature_SSL = xyes ; then
_libcurl_protocols="$_libcurl_protocols HTTPS"
# FTPS wasn't standards-compliant until version
# 7.11.0
if test $_libcurl_version -ge 461568; then
_libcurl_protocols="$_libcurl_protocols FTPS"
fi
fi
fi
for _libcurl_protocol in $_libcurl_protocols ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
done
fi
fi
unset _libcurl_try_link
unset _libcurl_version_parse
unset _libcurl_config
unset _libcurl_feature
unset _libcurl_features
unset _libcurl_protocol
unset _libcurl_protocols
unset _libcurl_version
fi
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
# This is the IF-NO path
ifelse([$4],,:,[$4])
else
# This is the IF-YES path
ifelse([$3],,:,[$3])
fi
unset _libcurl_with
])dnl

View File

@@ -245,7 +245,9 @@ typedef enum {
CURLE_COULDNT_RESOLVE_HOST, /* 6 */ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
CURLE_COULDNT_CONNECT, /* 7 */ CURLE_COULDNT_CONNECT, /* 7 */
CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
CURLE_FTP_ACCESS_DENIED, /* 9 */ CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
due to lack of access - when login fails
this is not returned. */
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 */ CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 */
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */ CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
@@ -305,6 +307,8 @@ typedef enum {
CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
that failed */ that failed */
CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
accepted and we failed to login */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;
@@ -712,7 +716,7 @@ typedef enum {
CINIT(SSLENGINE_DEFAULT, LONG, 90), CINIT(SSLENGINE_DEFAULT, LONG, 90),
/* Non-zero value means to use the global dns cache */ /* Non-zero value means to use the global dns cache */
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To becomeO BSOLETE soon */
/* DNS cache timeout */ /* DNS cache timeout */
CINIT(DNS_CACHE_TIMEOUT, LONG, 92), CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
@@ -842,25 +846,15 @@ typedef enum {
/* Enable/disable the TCP Nagle algorithm */ /* Enable/disable the TCP Nagle algorithm */
CINIT(TCP_NODELAY, LONG, 121), CINIT(TCP_NODELAY, LONG, 121),
/* When doing 3rd party transfer, set the source host name with this */ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
CINIT(SOURCE_HOST, OBJECTPOINT, 122),
/* When doing 3rd party transfer, set the source user and password with /* When doing 3rd party transfer, set the source user and password with
this */ this */
CINIT(SOURCE_USERPWD, OBJECTPOINT, 123), CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
/* When doing 3rd party transfer, set the source file path with this */ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
CINIT(SOURCE_PATH, OBJECTPOINT, 124), /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* When doing 3rd party transfer, set the source server's port number
with this */
CINIT(SOURCE_PORT, LONG, 125),
/* When doing 3rd party transfer, decide which server that should get the
PASV command (and the other gets the PORT).
0 (default) - The target host issues PASV.
1 - The source host issues PASV */
CINIT(PASV_HOST, LONG, 126),
/* When doing 3rd party transfer, set the source pre-quote linked list /* When doing 3rd party transfer, set the source pre-quote linked list
of commands with this */ of commands with this */
@@ -885,6 +879,17 @@ typedef enum {
CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
CINIT(IOCTLDATA, OBJECTPOINT, 131), CINIT(IOCTLDATA, OBJECTPOINT, 131),
/* To make a 3rd party transfer, set the source URL with this */
CINIT(SOURCE_URL, OBJECTPOINT, 132),
/* When doing 3rd party transfer, set the source quote linked list of
commands with this */
CINIT(SOURCE_QUOTE, OBJECTPOINT, 133),
/* zero terminated string for pass on to the FTP server when asked for
"account" info */
CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
CURLOPT_LASTENTRY /* the last unused */ CURLOPT_LASTENTRY /* the last unused */
} CURLoption; } CURLoption;
@@ -910,6 +915,11 @@ typedef enum {
#define CURLOPT_PASSWDDATA -4 #define CURLOPT_PASSWDDATA -4
#define CURLOPT_CLOSEFUNCTION -5 #define CURLOPT_CLOSEFUNCTION -5
#define CURLOPT_SOURCE_HOST -6
#define CURLOPT_SOURCE_PATH -7
#define CURLOPT_SOURCE_PORT -8
#define CURLOPT_PASV_HOST -9
#else #else
/* This is set if CURL_NO_OLDIES is defined at compile-time */ /* This is set if CURL_NO_OLDIES is defined at compile-time */
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ #undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
@@ -1337,7 +1347,7 @@ typedef enum {
/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by /* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
basicly all programs ever, that want to get version information. It is basicly all programs ever, that want to get version information. It is
meant to be a built-in version number for what kind of struct the caller meant to be a built-in version number for what kind of struct the caller
expects. If the struct ever changes, we redfine the NOW to another enum expects. If the struct ever changes, we redefine the NOW to another enum
from above. */ from above. */
#define CURLVERSION_NOW CURLVERSION_THIRD #define CURLVERSION_NOW CURLVERSION_THIRD
@@ -1347,11 +1357,11 @@ typedef struct {
unsigned int version_num; /* LIBCURL_VERSION_NUM */ unsigned int version_num; /* LIBCURL_VERSION_NUM */
const char *host; /* OS/host/cpu/machine when configured */ const char *host; /* OS/host/cpu/machine when configured */
int features; /* bitmask, see defines below */ int features; /* bitmask, see defines below */
char *ssl_version; /* human readable string */ const char *ssl_version; /* human readable string */
long ssl_version_num; /* number */ long ssl_version_num; /* number */
const char *libz_version; /* human readable string */ const char *libz_version; /* human readable string */
/* protocols is terminated by an entry with a NULL protoname */ /* protocols is terminated by an entry with a NULL protoname */
const char **protocols; const char * const *protocols;
/* The fields below this were added in CURLVERSION_SECOND */ /* The fields below this were added in CURLVERSION_SECOND */
const char *ares; const char *ares;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -28,7 +28,7 @@
/* This is the version number of the libcurl package from which this header /* This is the version number of the libcurl package from which this header
file origins: */ file origins: */
#define LIBCURL_VERSION "7.12.3-CVS" #define LIBCURL_VERSION "7.13.1-CVS"
/* This is the numeric version of the libcurl version number, meant for easier /* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -44,12 +44,12 @@
always a greater number in a more recent release. It makes comparisons with always a greater number in a more recent release. It makes comparisons with
greater than and less than work. greater than and less than work.
*/ */
#define LIBCURL_VERSION_NUM 0x070c03 #define LIBCURL_VERSION_NUM 0x070d01
/* The numeric version number is also available "in parts" by using these /* The numeric version number is also available "in parts" by using these
defines: */ defines: */
#define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 12 #define LIBCURL_VERSION_MINOR 13
#define LIBCURL_VERSION_PATCH 3 #define LIBCURL_VERSION_PATCH 1
#endif /* __CURL_CURLVER_H */ #endif /* __CURL_CURLVER_H */

View File

@@ -67,7 +67,9 @@
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#ifndef _WIN32_WCE
#include <sys/socket.h> #include <sys/socket.h>
#endif
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#endif #endif

357
lib/Makefile.Watcom Normal file
View File

@@ -0,0 +1,357 @@
#
# Watcom / OpenWatcom / Win32 makefile for libcurl.
# G. Vanem <giva@bgnett.no>
#
# $Id$
TARGETS = libcurl_wc.lib libcurl_wc.dll libcurl_wc_imp.lib
CC = wcc386
CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -s -fr=con -w2 -fpi -oilrtfm -bt=nt -bd &
-d+ -dWIN32 -dHAVE_LONGLONG -dCURL_CA_BUNDLE=getenv("CURL_CA_BUNDLE") &
-dBUILDING_LIBCURL -dWITHOUT_MM_LIB -dHAVE_SPNEGO=1 -dENABLE_IPV6 &
-dDEBUG_THREADING_GETADDRINFO -dDEBUG=1 -dCURLDEBUG -I. -I..\include
OBJ_DIR = Watcom_obj
LIB_ARG = $(OBJ_DIR)\wlib.arg
LINK_ARG = $(OBJ_DIR)\wlink.arg
OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
$(OBJ_DIR)\strequal.obj $(OBJ_DIR)\timeval.obj &
$(OBJ_DIR)\easy.obj $(OBJ_DIR)\base64.obj &
$(OBJ_DIR)\security.obj $(OBJ_DIR)\hostip.obj &
$(OBJ_DIR)\krb4.obj $(OBJ_DIR)\progress.obj &
$(OBJ_DIR)\memdebug.obj $(OBJ_DIR)\formdata.obj &
$(OBJ_DIR)\http_chunks.obj $(OBJ_DIR)\cookie.obj &
$(OBJ_DIR)\strtok.obj $(OBJ_DIR)\http.obj &
$(OBJ_DIR)\connect.obj $(OBJ_DIR)\sendf.obj &
$(OBJ_DIR)\llist.obj $(OBJ_DIR)\ftp.obj &
$(OBJ_DIR)\hash.obj $(OBJ_DIR)\url.obj &
$(OBJ_DIR)\multi.obj $(OBJ_DIR)\dict.obj &
$(OBJ_DIR)\content_encoding.obj $(OBJ_DIR)\if2ip.obj &
$(OBJ_DIR)\share.obj $(OBJ_DIR)\speedcheck.obj &
$(OBJ_DIR)\http_digest.obj $(OBJ_DIR)\ldap.obj &
$(OBJ_DIR)\md5.obj $(OBJ_DIR)\ssluse.obj &
$(OBJ_DIR)\http_negotiate.obj $(OBJ_DIR)\version.obj &
$(OBJ_DIR)\http_ntlm.obj $(OBJ_DIR)\getenv.obj &
$(OBJ_DIR)\inet_pton.obj $(OBJ_DIR)\escape.obj &
$(OBJ_DIR)\strtoofft.obj $(OBJ_DIR)\mprintf.obj &
$(OBJ_DIR)\strerror.obj $(OBJ_DIR)\telnet.obj &
$(OBJ_DIR)\hostares.obj $(OBJ_DIR)\netrc.obj &
$(OBJ_DIR)\hostasyn.obj $(OBJ_DIR)\getinfo.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
RESOURCE = $(OBJ_DIR)\libcurl.res
all: $(OBJ_DIR) $(TARGETS) .SYMBOLIC
@echo Welcome to libcurl
$(OBJ_DIR):
mkdir $(OBJ_DIR)
libcurl_wc.lib: $(OBJS) $(LIB_ARG)
wlib -q -b -c $@ @$(LIB_ARG)
libcurl_wc.dll: $(OBJS) $(RESOURCE) $(LINK_ARG)
wlink name libcurl_wc.dll @$(LINK_ARG)
clean: .SYMBOLIC
- rm -f $(OBJS) $(RESOURCE)
vclean realclean: clean .SYMBOLIC
- rm -f $(TARGETS) $(LIB_ARG) $(LINK_ARG) libcurl_wc.map
- rmdir $(OBJ_DIR)
.ERASE
$(RESOURCE): libcurl.rc
wrc -dCURLDEBUG=1 -q -r -zm -I..\include -fo=$@ libcurl.rc
.ERASE
.c{$(OBJ_DIR)}.obj:
$(CC) $[@ $(CFLAGS) -fo=$@
@echo .
$(LIB_ARG): $(__MAKEFILES__)
%create $^@
for %f in ($(OBJS)) do @%append $^@ +- %f
$(LINK_ARG): $(__MAKEFILES__)
%create $^@
@%append $^@ system nt dll
@%append $^@ file { $(OBJS) }
@%append $^@ option quiet, map, caseexact, eliminate, implib=libcurl_wc_imp.lib,
@%append $^@ res=$(RESOURCE) libpath $(%watcom)\lib386;$(%watcom)\lib386\nt
@%append $^@ library clib3r.lib, ws2_32.lib
#
# Dependencies based on "gcc -MM .."
#
$(OBJ_DIR)\file.obj: file.c setup.h config-win32.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 &
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
$(OBJ_DIR)\timeval.obj: timeval.c timeval.h setup.h config-win32.h
$(OBJ_DIR)\base64.obj: base64.c setup.h config-win32.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 ..\include\curl\curl.h &
memdebug.h
$(OBJ_DIR)\hostip.obj: hostip.c setup.h config-win32.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 &
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
$(OBJ_DIR)\progress.obj: progress.c setup.h config-win32.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 http_chunks.h &
hostip.h hash.h llist.h sendf.h progress.h ..\include\curl\mprintf.h
$(OBJ_DIR)\formdata.obj: formdata.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h strequal.h &
memory.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\cookie.obj: cookie.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h strequal.h strtok.h sendf.h &
memory.h memdebug.h
$(OBJ_DIR)\http.obj: http.c setup.h config-win32.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 &
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
$(OBJ_DIR)\sendf.obj: sendf.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h sendf.h connect.h &
..\include\curl\mprintf.h memory.h strerror.h memdebug.h
$(OBJ_DIR)\ftp.obj: ftp.c setup.h config-win32.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 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
$(OBJ_DIR)\url.obj: url.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h netrc.h base64.h ssluse.h if2ip.h &
transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h &
share.h content_encoding.h http_digest.h http_negotiate.h select.h multiif.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
$(OBJ_DIR)\dict.obj: dict.c setup.h config-win32.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 &
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.obj: if2ip.c setup.h config-win32.h
$(OBJ_DIR)\speedcheck.obj: speedcheck.c setup.h config-win32.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 http_chunks.h hostip.h hash.h llist.h sendf.h &
speedcheck.h
$(OBJ_DIR)\ldap.obj: ldap.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h sendf.h escape.h transfer.h &
strequal.h strtok.h ldap.h memory.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\ssluse.obj: ssluse.c setup.h config-win32.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 &
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
$(OBJ_DIR)\version.obj: version.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h ..\include\curl\mprintf.h
$(OBJ_DIR)\getenv.obj: getenv.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memory.h memdebug.h
$(OBJ_DIR)\escape.obj: escape.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memory.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\mprintf.obj: mprintf.c setup.h config-win32.h ..\include\curl\mprintf.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h memory.h ..\include\curl\curl.h memdebug.h
$(OBJ_DIR)\telnet.obj: telnet.c setup.h config-win32.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 &
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
$(OBJ_DIR)\netrc.obj: netrc.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h netrc.h strequal.h &
strtok.h memory.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\getinfo.obj: getinfo.c setup.h config-win32.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 http_chunks.h hostip.h hash.h llist.h &
getinfo.h memory.h ssluse.h memdebug.h
$(OBJ_DIR)\transfer.obj: transfer.c setup.h config-win32.h strtoofft.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h strequal.h urldata.h &
cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
netrc.h content_encoding.h transfer.h sendf.h speedcheck.h progress.h &
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
$(OBJ_DIR)\strequal.obj: strequal.c setup.h config-win32.h strequal.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\easy.obj: easy.c setup.h config-win32.h strequal.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 http_chunks.h hostip.h hash.h llist.h &
transfer.h ssluse.h url.h getinfo.h share.h memory.h progress.h &
easyif.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\security.obj: security.c setup.h config-win32.h
$(OBJ_DIR)\krb4.obj: krb4.c setup.h config-win32.h
$(OBJ_DIR)\memdebug.obj: memdebug.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h ..\include\curl\multi.h &
..\include\curl\curl.h ..\include\curl\mprintf.h urldata.h cookie.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h memory.h memdebug.h
$(OBJ_DIR)\http_chunks.obj: http_chunks.c setup.h config-win32.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 http_chunks.h hostip.h hash.h llist.h sendf.h &
content_encoding.h http.h memory.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\strtok.obj: strtok.c setup.h config-win32.h strtok.h
$(OBJ_DIR)\connect.obj: connect.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h sendf.h if2ip.h strerror.h connect.h &
memory.h select.h memdebug.h
$(OBJ_DIR)\llist.obj: llist.c setup.h config-win32.h llist.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
$(OBJ_DIR)\hash.obj: hash.c setup.h config-win32.h hash.h llist.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
$(OBJ_DIR)\multi.obj: multi.c setup.h config-win32.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 http_chunks.h hostip.h hash.h llist.h &
transfer.h url.h connect.h progress.h memory.h easyif.h multiif.h &
memdebug.h
$(OBJ_DIR)\content_encoding.obj: content_encoding.c setup.h config-win32.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 http_chunks.h hostip.h hash.h llist.h sendf.h &
content_encoding.h memory.h memdebug.h
$(OBJ_DIR)\share.obj: share.c setup.h config-win32.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 &
http_chunks.h hostip.h hash.h llist.h share.h memory.h memdebug.h
$(OBJ_DIR)\http_digest.obj: http_digest.c setup.h config-win32.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 &
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
$(OBJ_DIR)\md5.obj: md5.c setup.h config-win32.h md5.h
$(OBJ_DIR)\http_negotiate.obj: http_negotiate.c setup.h config-win32.h
$(OBJ_DIR)\http_ntlm.obj: http_ntlm.c setup.h config-win32.h
$(OBJ_DIR)\inet_pton.obj: inet_pton.c setup.h config-win32.h inet_pton.h
$(OBJ_DIR)\strtoofft.obj: strtoofft.c setup.h config-win32.h strtoofft.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\strerror.obj: strerror.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h strerror.h urldata.h &
cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
..\include\curl\mprintf.h
$(OBJ_DIR)\hostares.obj: hostares.c setup.h config-win32.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 &
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
$(OBJ_DIR)\hostasyn.obj: hostasyn.c setup.h config-win32.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 &
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
$(OBJ_DIR)\hostip4.obj: hostip4.c setup.h config-win32.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 &
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
$(OBJ_DIR)\hostip6.obj: hostip6.c setup.h config-win32.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 &
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
$(OBJ_DIR)\hostsyn.obj: hostsyn.c setup.h config-win32.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 &
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
$(OBJ_DIR)\hostthre.obj: hostthre.c setup.h config-win32.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 &
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
$(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h config-win32.h ..\include\curl\mprintf.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h inet_ntop.h
$(OBJ_DIR)\parsedate.obj: parsedate.c setup.h config-win32.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h select.h

View File

@@ -30,7 +30,7 @@ EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos $(DSP) \
README.ares README.curlx makefile.dj config.dj libcurl.framework.make \ README.ares README.curlx makefile.dj config.dj libcurl.framework.make \
libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \ libcurl.plist libcurl.rc config-amigaos.h amigaos.c amigaos.h makefile.amiga \
Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \ Makefile.netware nwlib.c libcurl.imp msvcproj.head msvcproj.foot \
config-win32ce.h README.httpauth config-win32ce.h README.httpauth Makefile.Watcom README.hostip
CLEANFILES = $(DSP) CLEANFILES = $(DSP)

View File

@@ -17,4 +17,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h \ http_chunks.h strtok.h connect.h llist.h hash.h content_encoding.h \
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \ share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \ inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
setup.h transfer.h select.h setup.h transfer.h select.h easyif.h multiif.h parsedate.h

View File

@@ -35,7 +35,7 @@ IMPLIB_NAME = libcurl_imp
IMPLIB_NAME_DEBUG = libcurld_imp IMPLIB_NAME_DEBUG = libcurld_imp
!IFNDEF OPENSSL_PATH !IFNDEF OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.7d OPENSSL_PATH = ../../openssl-0.9.7e
!ENDIF !ENDIF
!IFNDEF ZLIB_PATH !IFNDEF ZLIB_PATH
@@ -58,6 +58,8 @@ LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib LNKLIB = link.exe /lib
LFLAGS = /nologo LFLAGS = /nologo
SSLLIBS = libeay32.lib ssleay32.lib SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL= zdll.lib
ZLIBLIBS = zlib.lib
!IFDEF USEMM_LIBS !IFDEF USEMM_LIBS
WINLIBS = wsock32.lib winmm.lib WINLIBS = wsock32.lib winmm.lib
!ELSE !ELSE
@@ -72,8 +74,8 @@ CFGSET = FALSE
!IF "$(CFG)" == "release" !IF "$(CFG)" == "release"
TARGET = $(LIB_NAME).lib TARGET = $(LIB_NAME).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LNK = $(LNKLIB) /out:$(TARGET) LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) CC = $(CCNODBG)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
@@ -83,9 +85,9 @@ CFGSET = TRUE
!IF "$(CFG)" == "release-zlib" !IF "$(CFG)" == "release-zlib"
TARGET = $(LIB_NAME).lib TARGET = $(LIB_NAME).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)" LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(TARGET) LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSZLIB) CC = $(CCNODBG) $(CFLAGSZLIB)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
@@ -95,8 +97,8 @@ CFGSET = TRUE
!IF "$(CFG)" == "release-dll" !IF "$(CFG)" == "release-dll"
TARGET = $(LIB_NAME).dll TARGET = $(LIB_NAME).dll
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LNK = $(LNKDLL) $(WINLIBS) /out:$(TARGET) /IMPLIB:$(IMPLIB_NAME).lib LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
CC = $(CCNODBG) CC = $(CCNODBG)
CFGSET = TRUE CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res RESOURCE = $(DIROBJ)\libcurl.res
@@ -107,9 +109,9 @@ RESOURCE = $(DIROBJ)\libcurl.res
!IF "$(CFG)" == "release-ssl" !IF "$(CFG)" == "release-ssl"
TARGET = $(LIB_NAME).lib TARGET = $(LIB_NAME).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32" LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
@@ -118,81 +120,123 @@ CFGSET = TRUE
# release-ssl-dll # release-ssl-dll
!IF "$(CFG)" == "release-ssl-dll" !IF "$(CFG)" == "release-ssl-dll"
TARGET = $(LIB_NAME).dll TARGET = $(LIB_NAME).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll" LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKDLL) $(SSLLIBS) $(WINLIBS) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:$(IMPLIB_NAME).lib LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF !ENDIF
###################### ######################
# release-ssl-zlib # release-ssl-zlib
!IF "$(CFG)" == "release-ssl-zlib" !IF "$(CFG)" == "release-ssl-zlib"
TARGET = $(LIB_NAME).lib TARGET = $(LIB_NAME).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32" LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)" LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(TARGET) LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB) CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
###################### ######################
# release-libcurl-ssl-dll # release-dll-ssl-dll
!IF "$(CFG)" == "release-libcurl-ssl-dll"
TARGET = $(LIB_NAME).lib !IF "$(CFG)" == "release-dll-ssl-dll"
DIROBJ = .\$(CFG) TARGET = $(LIB_NAME).dll
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll" DIROBJ = $(CFG)
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(TARGET) LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
CC = $(CCNODBG) $(CFLAGSSSL) CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF !ENDIF
######################
# release-zlib-dll
!IF "$(CFG)" == "release-zlib-dll"
TARGET = $(LIB_NAME).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(CFLAGSZLIB)
CFGSET = TRUE
!ENDIF
######################
# release-ssl-dll-zlib-dll
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
TARGET = $(LIB_NAME).lib
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)
CFGSET = TRUE
!ENDIF
######################
# release-dll-zlib-dll
!IF "$(CFG)" == "release-dll-zlib-dll"
TARGET = $(LIB_NAME).dll
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
CC = $(CCNODBG) $(CFLAGSZLIB)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
######################
# release-dll-ssl-dll-zlib-dll
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
TARGET = $(LIB_NAME).dll
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
###################### ######################
# debug # debug
!IF "$(CFG)" == "debug" !IF "$(CFG)" == "debug"
TARGET = $(LIB_NAME_DEBUG).lib TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LNK = $(LNKLIB) /out:$(TARGET) LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) CC = $(CCDEBUG)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
######################
# debug-dll
!IF "$(CFG)" == "debug-dll"
TARGET = $(LIB_NAME_DEBUG).dll
DIROBJ = .\$(CFG)
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(TARGET) /IMPLIB:$(IMPLIB_NAME_DEBUG).lib /PDB:$(IMPLIB_NAME_DEBUG).pdb
CC = $(CCDEBUG)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
###################### ######################
# debug-ssl # debug-ssl
#todo
!IF "$(CFG)" == "debug-ssl" !IF "$(CFG)" == "debug-ssl"
TARGET = $(LIB_NAME_DEBUG).lib TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET) LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL) CC = $(CCDEBUG) $(CFLAGSSSL)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
###################### ######################
# debug-zlib # debug-zlib
!IF "$(CFG)" == "debug-zlib" !IF "$(CFG)" == "debug-zlib"
TARGET = $(LIB_NAME_DEBUG).lib TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)" LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(TARGET) LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSZLIB) CC = $(CCDEBUG) $(CFLAGSZLIB)
CFGSET = TRUE CFGSET = TRUE
!ENDIF !ENDIF
@@ -201,38 +245,151 @@ CFGSET = TRUE
# debug-ssl-dll # debug-ssl-dll
!IF "$(CFG)" == "debug-ssl-dll" !IF "$(CFG)" == "debug-ssl-dll"
TARGET = $(LIB_NAME_DEBUG).dll TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = .\$(CFG) DIROBJ = $(CFG)
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)/out32dll LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
LNK = $(LNKDLL) $(WINLIBS) $(LFLAGSSSL) /DEBUG /out:$(TARGET) /IMPLIB:$(IMPLIB_NAME_DEBUG).lib /PDB:$(IMPLIB_NAME_DEBUG).pdb LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL) CC = $(CCDEBUG) $(CFLAGSSSL)
CFGSET = TRUE CFGSET = TRUE
!ENDIF
######################
# debug-ssl-zlib
!IF "$(CFG)" == "debug-ssl-zlib"
TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
LNK = $(LNKLIB) $(SSLLIBS) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
CFGSET = TRUE
!ENDIF
######################
# debug-zlib-dll
!IF "$(CFG)" == "debug-zlib-dll"
TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCDEBUG) $(CFLAGSZLIB)
CFGSET = TRUE
!ENDIF
######################
# debug-ssl-dll-zlib-dll
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
TARGET = $(LIB_NAME_DEBUG).lib
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)
CFGSET = TRUE
!ENDIF
######################
# debug-dll
!IF "$(CFG)" == "debug-dll"
TARGET = $(LIB_NAME_DEBUG).dll
DIROBJ = $(CFG)
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
CC = $(CCDEBUG)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
######################
# debug-dll-ssl-dll
!IF "$(CFG)" == "debug-dll-ssl-dll"
TARGET = $(LIB_NAME_DEBUG).dll
DIROBJ = $(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
CC = $(CCDEBUG) $(CFLAGSSSL)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
######################
# debug-dll-zlib-dll
!IF "$(CFG)" == "debug-dll-zlib-dll"
TARGET = $(LIB_NAME_DEBUG).dll
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
CC = $(CCDEBUG) $(CFLAGSZLIB)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF
######################
# debug-dll-ssl-dll-zlib-dll
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
TARGET = $(LIB_NAME_DEBUG).dll
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
CC = $(CCDEBUG) $(CFLAGSSSL) $(CFLAGSZLIB)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF !ENDIF
####################### #######################
# Usage # Usage
# #
!IF "$(CFGSET)" == "FALSE" !IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target> !MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
!MESSAGE where <config> is one of: !MESSAGE where <config> is one of:
!MESSAGE release - release static library !MESSAGE release - release static library
!MESSAGE release-dll - release dll !MESSAGE release-ssl - release static library with ssl
!MESSAGE release-zlib - release static library with zlib !MESSAGE release-zlib - release static library with zlib
!MESSAGE release-ssl - release static library with ssl !MESSAGE release-ssl-zlib - release static library with ssl and zlib
!MESSAGE release-ssl-zlib - release static library with ssl and zlib !MESSAGE release-ssl-dll - release static library with dynamic ssl
!MESSAGE release-ssl-dll - release dll library with ssl !MESSAGE release-zlib-dll - release static library with dynamic zlib
!MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl !MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
!MESSAGE debug - debug static library !MESSAGE release-dll - release dynamic library
!MESSAGE debug-dll - debug dll !MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
!MESSAGE debug-zlib - debug static library with zlib !MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
!MESSAGE debug-ssl - debug static library with ssl !MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
!MESSAGE debug-ssl-dll - debug dll library with ssl !MESSAGE debug - debug static library
!MESSAGE debug-ssl - debug static library with ssl
!MESSAGE debug-zlib - debug static library with zlib
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
!MESSAGE debug-dll - debug dynamic library
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
!MESSAGE <target> can be left blank in which case all is assumed !MESSAGE <target> can be left blank in which case all is assumed
!ERROR please choose a valid configuration "$(CFG)" !ERROR please choose a valid configuration "$(CFG)"
!ENDIF !ENDIF
####################### #######################
# Only the clean target can be used if a config was not provided.
#
!IF "$(CFGSET)" == "FALSE"
clean:
@-erase /s *.dll 2> NUL
@-erase /s *.exp 2> NUL
@-erase /s *.idb 2> NUL
@-erase /s *.lib 2> NUL
@-erase /s *.obj 2> NUL
@-erase /s *.pch 2> NUL
@-erase /s *.pdb 2> NUL
@-erase /s *.res 2> NUL
!ELSE
# A config was provided, so the library can be built.
# #
X_OBJS= \ X_OBJS= \
$(DIROBJ)\base64.obj \ $(DIROBJ)\base64.obj \
@@ -290,9 +447,16 @@ X_OBJS= \
all : $(TARGET) all : $(TARGET)
$(TARGET): $(X_OBJS) $(TARGET): $(X_OBJS)
$(LNK) $(LFLAGS) $(X_OBJS) $(LNK) $(LFLAGS) $(X_OBJS)
-xcopy $(DIROBJ)\$(LIB_NAME).dll . /y
-xcopy $(DIROBJ)\$(LIB_NAME).lib . /y
-xcopy $(DIROBJ)\$(LIB_NAME_DEBUG).dll . /y
-xcopy $(DIROBJ)\$(LIB_NAME_DEBUG).lib . /y
-xcopy $(DIROBJ)\$(IMPLIB_NAME).lib . /y
-xcopy $(DIROBJ)\$(IMPLIB_NAME).lib . /y
-xcopy $(DIROBJ)\*.exp . /y
-xcopy $(DIROBJ)\*.pdb . /y
$(X_OBJS): $(DIROBJ) $(X_OBJS): $(DIROBJ)
@@ -305,18 +469,14 @@ $(DIROBJ):
$(CC) $(CFLAGS) /Fo"$@" $< $(CC) $(CFLAGS) /Fo"$@" $<
debug-dll\libcurl.res \ debug-dll\libcurl.res \
debug-ssl-dll\libcurl.res \ debug-dll-ssl-dll\libcurl.res \
release-libcurl-ssl-dll\libcurl.res: libcurl.rc debug-dll-zlib-dll\libcurl.res \
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
rc /dCURLDEBUG=1 /Fo $@ libcurl.rc rc /dCURLDEBUG=1 /Fo $@ libcurl.rc
release-dll\libcurl.res \ release-dll\libcurl.res \
release-ssl-dll\libcurl.res \ release-dll-ssl-dll\libcurl.res \
release-libcurl-ssl-dll\libcurl.res: libcurl.rc release-dll-zlib-dll\libcurl.res \
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
rc /dCURLDEBUG=0 /Fo $@ libcurl.rc rc /dCURLDEBUG=0 /Fo $@ libcurl.rc
!ENDIF # End of case where a config was provided.
clean:
-@erase $(DIROBJ)\*.obj
-@erase $(DIROBJ)\*.res
-@erase vc60.idb
-@erase vc60.pch

35
lib/README.hostip Normal file
View File

@@ -0,0 +1,35 @@
hostip.c explained
==================
The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
source file are these:
CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
that. The host may not be able to resolve IPv6, but we don't really have to
take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
defined.
CURLRES_ARES - is defined if libcurl is built to use c-ares for asynchronous
name resolves. It cannot have ENABLE_IPV6 defined at the same time, as c-ares
has no ipv6 support. This can be Windows or *nix.
CURLRES_THREADED - is defined if libcurl is built to run under (native)
Windows, and then the name resolve will be done in a new thread, and the
supported asynch API will be the same as for ares-builds.
If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
defined.
The host*.c sources files are split up like this:
hostip.c - method-independent resolver functions and utility functions
hostasyn.c - functions for asynchronous name resolves
hostsyn.c - functions for synchronous name resolves
hostares.c - functions for ares-using name resolves
hostthre.c - functions for threaded name resolves
hostip4.c - ipv4-specific functions
hostip6.c - ipv6-specific functions
The hostip.h is the single united header file for all this. It defines the
CURLRES_* defines based on the config*.h and setup.h defines.

View File

@@ -39,7 +39,7 @@
/* /*
* The telnet options represented as strings * The telnet options represented as strings
*/ */
static const char *telnetoptions[]= static const char * const telnetoptions[]=
{ {
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
"NAME", "STATUS", "TIMING MARK", "RCTE", "NAME", "STATUS", "TIMING MARK", "RCTE",
@@ -78,7 +78,7 @@ static const char *telnetoptions[]=
/* /*
* Then those numbers represented as strings: * Then those numbers represented as strings:
*/ */
static const char *telnetcmds[]= static const char * const telnetcmds[]=
{ {
"EOF", "SUSP", "ABORT", "EOR", "SE", "EOF", "SUSP", "ABORT", "EOR", "SE",
"NOP", "DMARK", "BRK", "IP", "AO", "NOP", "DMARK", "BRK", "IP", "AO",

View File

@@ -76,10 +76,10 @@ static void decodeQuantum(unsigned char *dest, const char *src)
/* /*
* Curl_base64_decode() * Curl_base64_decode()
* *
* Given a base64 string at src, decode it into the memory pointed to by * Given a base64 string at src, decode it and return an allocated memory in
* dest. Returns the length of the decoded data. * the *outptr. Returns the length of the decoded data.
*/ */
size_t Curl_base64_decode(const char *src, char *dest) size_t Curl_base64_decode(const char *src, unsigned char **outptr)
{ {
int length = 0; int length = 0;
int equalsTerm = 0; int equalsTerm = 0;
@@ -87,25 +87,49 @@ size_t Curl_base64_decode(const char *src, char *dest)
int numQuantums; int numQuantums;
unsigned char lastQuantum[3]; unsigned char lastQuantum[3];
size_t rawlen=0; size_t rawlen=0;
unsigned char *newstr;
*outptr = NULL;
while((src[length] != '=') && src[length]) while((src[length] != '=') && src[length])
length++; length++;
while(src[length+equalsTerm] == '=') /* A maximum of two = padding characters is allowed */
if(src[length] == '=') {
equalsTerm++; equalsTerm++;
if(src[length+equalsTerm] == '=')
equalsTerm++;
}
numQuantums = (length + equalsTerm) / 4; numQuantums = (length + equalsTerm) / 4;
/* Don't allocate a buffer if the decoded length is 0 */
if (numQuantums <= 0)
return 0;
rawlen = (numQuantums * 3) - equalsTerm; rawlen = (numQuantums * 3) - equalsTerm;
/* The buffer must be large enough to make room for the last quantum
(which may be partially thrown out) and the zero terminator. */
newstr = malloc(rawlen+4);
if(!newstr)
return 0;
*outptr = newstr;
/* Decode all but the last quantum (which may not decode to a
multiple of 3 bytes) */
for(i = 0; i < numQuantums - 1; i++) { for(i = 0; i < numQuantums - 1; i++) {
decodeQuantum((unsigned char *)dest, src); decodeQuantum((unsigned char *)newstr, src);
dest += 3; src += 4; newstr += 3; src += 4;
} }
/* This final decode may actually read slightly past the end of the buffer
if the input string is missing pad bytes. This will almost always be
harmless. */
decodeQuantum(lastQuantum, src); decodeQuantum(lastQuantum, src);
for(i = 0; i < 3 - equalsTerm; i++) for(i = 0; i < 3 - equalsTerm; i++)
dest[i] = lastQuantum[i]; newstr[i] = lastQuantum[i];
newstr[i] = 0; /* zero terminate */
return rawlen; return rawlen;
} }

View File

@@ -23,5 +23,5 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
size_t Curl_base64_encode(const char *input, size_t size, char **str); size_t Curl_base64_encode(const char *input, size_t size, char **str);
size_t Curl_base64_decode(const char *source, char *dest); size_t Curl_base64_decode(const char *source, unsigned char **outptr);
#endif #endif

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -98,6 +98,7 @@
#include "connect.h" #include "connect.h"
#include "memory.h" #include "memory.h"
#include "select.h" #include "select.h"
#include "url.h" /* for Curl_safefree() */
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
@@ -429,6 +430,25 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
return rc; return rc;
} }
CURLcode Curl_store_ip_addr(struct connectdata *conn)
{
char addrbuf[256];
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
/* save the string */
Curl_safefree(conn->ip_addr_str);
conn->ip_addr_str = strdup(addrbuf);
if(!conn->ip_addr_str)
return CURLE_OUT_OF_MEMORY; /* FAIL */
#ifdef PF_INET6
if(conn->ip_addr->ai_family == PF_INET6)
conn->bits.ipv6 = TRUE;
#endif
return CURLE_OK;
}
/* Used within the multi interface. Try next IP address, return TRUE if no /* Used within the multi interface. Try next IP address, return TRUE if no
more address exists */ more address exists */
static bool trynextip(struct connectdata *conn, static bool trynextip(struct connectdata *conn,
@@ -450,6 +470,8 @@ static bool trynextip(struct connectdata *conn,
/* store the new socket descriptor */ /* store the new socket descriptor */
conn->sock[sockindex] = sockfd; conn->sock[sockindex] = sockfd;
conn->ip_addr = ai; conn->ip_addr = ai;
Curl_store_ip_addr(conn);
return FALSE; return FALSE;
} }
ai = ai->ai_next; ai = ai->ai_next;
@@ -618,8 +640,10 @@ singleipconnect(struct connectdata *conn,
/* user selected to bind the outgoing socket to a specified "device" /* user selected to bind the outgoing socket to a specified "device"
before doing connect */ before doing connect */
CURLcode res = bindlocal(conn, sockfd); CURLcode res = bindlocal(conn, sockfd);
if(res) if(res) {
sclose(sockfd); /* close socket and bail out */
return res; return res;
}
} }
/* set socket non-blocking */ /* set socket non-blocking */
@@ -754,7 +778,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(data->state.used_interface == Curl_if_multi) if(data->state.used_interface == Curl_if_multi)
/* don't hang when doing multi */ /* don't hang when doing multi */
timeout_per_addr = timeout_ms = 0; timeout_per_addr = 0;
/* /*
* Connecting with a Curl_addrinfo chain * Connecting with a Curl_addrinfo chain

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -39,6 +39,8 @@ CURLcode Curl_connecthost(struct connectdata *conn,
int Curl_ourerrno(void); int Curl_ourerrno(void);
CURLcode Curl_store_ip_addr(struct connectdata *conn);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
#endif #endif

View File

@@ -128,7 +128,7 @@ inflate_stream(struct SessionHandle *data,
} }
/* Done with these bytes, exit */ /* Done with these bytes, exit */
if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) { if (status == Z_OK && z->avail_in == 0) {
free(decomp); free(decomp);
return result; return result;
} }

View File

@@ -113,6 +113,8 @@ static void freecookie(struct Cookie *co)
free(co->value); free(co->value);
if(co->maxage) if(co->maxage)
free(co->maxage); free(co->maxage);
if(co->version)
free(co->version);
free(co); free(co);
} }
@@ -649,6 +651,10 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
fp = stdin; fp = stdin;
fromfile=FALSE; fromfile=FALSE;
} }
else if(file && !*file) {
/* points to a "" string */
fp = NULL;
}
else else
fp = file?fopen(file, "r"):NULL; fp = file?fopen(file, "r"):NULL;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -85,7 +85,7 @@
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
CURLcode Curl_dict(struct connectdata *conn) CURLcode Curl_dict(struct connectdata *conn, bool *done)
{ {
char *word; char *word;
char *ppath; char *ppath;
@@ -100,6 +100,8 @@ CURLcode Curl_dict(struct connectdata *conn)
char *path = conn->path; char *path = conn->path;
curl_off_t *bytecount = &conn->bytecount; curl_off_t *bytecount = &conn->bytecount;
*done = TRUE; /* unconditionally */
if(conn->bits.user_passwd) { if(conn->bits.user_passwd) {
/* AUTH is missing */ /* AUTH is missing */
} }
@@ -136,12 +138,12 @@ CURLcode Curl_dict(struct connectdata *conn)
} }
result = Curl_sendf(sockfd, conn, result = Curl_sendf(sockfd, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"MATCH " "MATCH "
"%s " /* database */ "%s " /* database */
"%s " /* strategy */ "%s " /* strategy */
"%s\n" /* word */ "%s\r\n" /* word */
"QUIT\n", "QUIT\r\n",
database, database,
strategy, strategy,
@@ -180,11 +182,11 @@ CURLcode Curl_dict(struct connectdata *conn)
} }
result = Curl_sendf(sockfd, conn, result = Curl_sendf(sockfd, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"DEFINE " "DEFINE "
"%s " /* database */ "%s " /* database */
"%s\n" /* word */ "%s\r\n" /* word */
"QUIT\n", "QUIT\r\n",
database, database,
word); word);
if(result) if(result)
@@ -209,9 +211,9 @@ CURLcode Curl_dict(struct connectdata *conn)
ppath[i] = ' '; ppath[i] = ' ';
} }
result = Curl_sendf(sockfd, conn, result = Curl_sendf(sockfd, conn,
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n" "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"%s\n" "%s\r\n"
"QUIT\n", ppath); "QUIT\r\n", ppath);
if(result) if(result)
failf(data, "Failed sending DICT request"); failf(data, "Failed sending DICT request");
else else

View File

@@ -2,18 +2,18 @@
#define __DICT_H #define __DICT_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -24,7 +24,7 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_DICT #ifndef CURL_DISABLE_DICT
CURLcode Curl_dict(struct connectdata *conn); CURLcode Curl_dict(struct connectdata *conn, bool *done);
CURLcode Curl_dict_done(struct connectdata *conn); CURLcode Curl_dict_done(struct connectdata *conn);
#endif #endif
#endif #endif

View File

@@ -82,6 +82,7 @@
#include "share.h" #include "share.h"
#include "memory.h" #include "memory.h"
#include "progress.h" #include "progress.h"
#include "easyif.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -165,8 +166,8 @@ static void idna_init (void)
#endif /* USE_LIBIDN */ #endif /* USE_LIBIDN */
/* true globals -- for curl_global_init() and curl_global_cleanup() */ /* true globals -- for curl_global_init() and curl_global_cleanup() */
static unsigned int initialized = 0; static unsigned int initialized;
static long init_flags = 0; static long init_flags;
/* /*
* If a memory-using function (like curl_getenv) is used before * If a memory-using function (like curl_getenv) is used before
@@ -200,7 +201,8 @@ CURLcode curl_global_init(long flags)
Curl_ccalloc = (curl_calloc_callback)calloc; Curl_ccalloc = (curl_calloc_callback)calloc;
if (flags & CURL_GLOBAL_SSL) if (flags & CURL_GLOBAL_SSL)
Curl_SSL_init(); if (!Curl_SSL_init())
return CURLE_FAILED_INIT;
if (flags & CURL_GLOBAL_WIN32) if (flags & CURL_GLOBAL_WIN32)
if (win32_init() != CURLE_OK) if (win32_init() != CURLE_OK)
@@ -354,6 +356,89 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
return ret; return ret;
} }
#ifdef CURL_MULTIEASY
/***************************************************************************
* This function is still only for testing purposes. It makes a great way
* to run the full test suite on the multi interface instead of the easy one.
***************************************************************************
*
* The *new* curl_easy_perform() is the external interface that performs a
* transfer previously setup.
*
* Wrapper-function that: creates a multi handle, adds the easy handle to it,
* runs curl_multi_perform() until the transfer is done, then detaches the
* easy handle, destroys the multi handle and returns the easy handle's return
* code. This will make everything internally use and assume multi interface.
*/
CURLcode curl_easy_perform(CURL *easy)
{
CURLM *multi;
CURLMcode mcode;
CURLcode code = CURLE_OK;
int still_running;
struct timeval timeout;
int rc;
CURLMsg *msg;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
if(!easy)
return CURLE_BAD_FUNCTION_ARGUMENT;
multi = curl_multi_init();
if(!multi)
return CURLE_OUT_OF_MEMORY;
mcode = curl_multi_add_handle(multi, easy);
if(mcode) {
curl_multi_cleanup(multi);
return CURLE_FAILED_INIT;
}
/* we start some action by calling perform right away */
do {
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi, &still_running));
if(!still_running)
break;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* timeout once per second */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
if(rc == -1)
/* select error */
break;
/* timeout or data to send/receive => loop! */
} while(still_running);
msg = curl_multi_info_read(multi, &rc);
if(msg)
code = msg->data.result;
mcode = curl_multi_remove_handle(multi, easy);
/* what to do if it fails? */
mcode = curl_multi_cleanup(multi);
/* what to do if it fails? */
return code;
}
#else
/* /*
* curl_easy_perform() is the external interface that performs a transfer * curl_easy_perform() is the external interface that performs a transfer
* previously setup. * previously setup.
@@ -388,6 +473,7 @@ CURLcode curl_easy_perform(CURL *curl)
return Curl_perform(data); return Curl_perform(data);
} }
#endif
/* /*
* curl_easy_cleanup() is the external interface to cleaning/freeing the given * curl_easy_cleanup() is the external interface to cleaning/freeing the given
@@ -403,6 +489,15 @@ void curl_easy_cleanup(CURL *curl)
Curl_close(data); Curl_close(data);
} }
/*
* Store a pointed to the multi handle within the easy handle's data struct.
*/
void Curl_easy_addmulti(struct SessionHandle *data,
void *multi)
{
data->multi = multi;
}
/* /*
* curl_easy_getinfo() is an external interface that allows an app to retrieve * curl_easy_getinfo() is an external interface that allows an app to retrieve
* information from a performed transfer and similar. * information from a performed transfer and similar.

31
lib/easyif.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef __EASYIF_H
#define __EASYIF_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/*
* Prototypes for library-wide functions provided by easy.c
*/
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
#endif /* __EASYIF_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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -87,6 +87,7 @@
#include "transfer.h" #include "transfer.h"
#include "url.h" #include "url.h"
#include "memory.h" #include "memory.h"
#include "parsedate.h" /* for the week day and month names */
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -266,7 +267,7 @@ static CURLcode file_upload(struct connectdata *conn)
* opposed to sockets) we instead perform the whole do-operation in this * opposed to sockets) we instead perform the whole do-operation in this
* function. * function.
*/ */
CURLcode Curl_file(struct connectdata *conn) CURLcode Curl_file(struct connectdata *conn, bool *done)
{ {
/* This implementation ignores the host name in conformance with /* This implementation ignores the host name in conformance with
RFC 1738. Only local files (reachable via the standard file system) RFC 1738. Only local files (reachable via the standard file system)
@@ -286,6 +287,8 @@ CURLcode Curl_file(struct connectdata *conn)
int fd; int fd;
struct timeval now = Curl_tvnow(); struct timeval now = Curl_tvnow();
*done = TRUE; /* unconditionally */
Curl_readwrite_init(conn); Curl_readwrite_init(conn);
Curl_initinfo(data); Curl_initinfo(data);
Curl_pgrsStartNow(data); Curl_pgrsStartNow(data);
@@ -319,7 +322,6 @@ CURLcode Curl_file(struct connectdata *conn)
if(result) if(result)
return result; return result;
#ifdef HAVE_STRFTIME
if(fstated) { if(fstated) {
struct tm *tm; struct tm *tm;
time_t clock = (time_t)statbuf.st_mtime; time_t clock = (time_t)statbuf.st_mtime;
@@ -330,11 +332,17 @@ CURLcode Curl_file(struct connectdata *conn)
tm = gmtime(&clock); tm = gmtime(&clock);
#endif #endif
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", snprintf(buf, BUFSIZE-1,
tm); "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
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);
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
} }
#endif
return result; return result;
} }

View File

@@ -2,18 +2,18 @@
#define __FILE_H #define __FILE_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -24,7 +24,7 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_FILE #ifndef CURL_DISABLE_FILE
CURLcode Curl_file(struct connectdata *); CURLcode Curl_file(struct connectdata *, bool *done);
CURLcode Curl_file_done(struct connectdata *, CURLcode); CURLcode Curl_file_done(struct connectdata *, CURLcode);
CURLcode Curl_file_connect(struct connectdata *); CURLcode Curl_file_connect(struct connectdata *);
#endif #endif

View File

@@ -1539,7 +1539,7 @@ void curl_formfree(struct curl_httppost *form)
char *Curl_FormBoundary(void) char *Curl_FormBoundary(void)
{ {
char *retstring; char *retstring;
static int randomizer=0; /* this is just so that two boundaries within static int randomizer; /* this is just so that two boundaries within
the same form won't be identical */ the same form won't be identical */
size_t i; size_t i;

4092
lib/ftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
#ifndef __FTP_H #ifndef __FTP_H
#define __FTP_H #define __FTP_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -24,14 +24,21 @@
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
CURLcode Curl_ftp(struct connectdata *conn); CURLcode Curl_ftp(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode); CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
CURLcode Curl_ftp_connect(struct connectdata *conn); CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_disconnect(struct connectdata *conn); CURLcode Curl_ftp_disconnect(struct connectdata *conn);
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
CURLcode Curl_nbftpsendf(struct connectdata *, const char *fmt, ...);
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
int *ftpcode); int *ftpcode);
CURLcode Curl_ftp_nextconnect(struct connectdata *conn); CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
#endif CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
CURLcode Curl_ftp_fdset(struct connectdata *conn,
#endif fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp);
CURLcode Curl_ftp_doing(struct connectdata *conn,
bool *dophase_done);
#endif /* CURL_DISABLE_FTP */
#endif /* __FTP_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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -50,12 +50,11 @@ hash_str(const char *key, size_t key_length)
static void static void
hash_element_dtor(void *user, void *element) hash_element_dtor(void *user, void *element)
{ {
curl_hash *h = (curl_hash *) user; struct curl_hash *h = (struct curl_hash *) user;
curl_hash_element *e = (curl_hash_element *) element; struct curl_hash_element *e = (struct curl_hash_element *) element;
if (e->key) { if (e->key)
free(e->key); free(e->key);
}
h->dtor(e->ptr); h->dtor(e->ptr);
@@ -64,7 +63,7 @@ hash_element_dtor(void *user, void *element)
/* return 1 on error, 0 is fine */ /* return 1 on error, 0 is fine */
int int
Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor)
{ {
int i; int i;
@@ -72,7 +71,7 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
h->size = 0; h->size = 0;
h->slots = slots; h->slots = slots;
h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); h->table = (struct curl_llist **) malloc(slots * sizeof(struct curl_llist *));
if(h->table) { if(h->table) {
for (i = 0; i < slots; ++i) { for (i = 0; i < slots; ++i) {
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
@@ -89,12 +88,12 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
return 1; /* failure */ return 1; /* failure */
} }
curl_hash * struct curl_hash *
Curl_hash_alloc(int slots, curl_hash_dtor dtor) Curl_hash_alloc(int slots, curl_hash_dtor dtor)
{ {
curl_hash *h; struct curl_hash *h;
h = (curl_hash *) malloc(sizeof(curl_hash)); h = (struct curl_hash *) malloc(sizeof(struct curl_hash));
if (h) { if (h) {
if(Curl_hash_init(h, slots, dtor)) { if(Curl_hash_init(h, slots, dtor)) {
/* failure */ /* failure */
@@ -118,11 +117,11 @@ hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len)
return 0; return 0;
} }
static curl_hash_element * static struct curl_hash_element *
mk_hash_element(char *key, size_t key_len, const void *p) mk_hash_element(char *key, size_t key_len, const void *p)
{ {
curl_hash_element *he = struct curl_hash_element *he =
(curl_hash_element *) malloc(sizeof(curl_hash_element)); (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
if(he) { if(he) {
char *dup = strdup(key); char *dup = strdup(key);
@@ -147,14 +146,14 @@ mk_hash_element(char *key, size_t key_len, const void *p)
/* Return the data in the hash. If there already was a match in the hash, /* Return the data in the hash. If there already was a match in the hash,
that data is returned. */ that data is returned. */
void * void *
Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p)
{ {
curl_hash_element *he; struct curl_hash_element *he;
curl_llist_element *le; struct curl_llist_element *le;
curl_llist *l = FETCH_LIST(h, key, key_len); struct curl_llist *l = FETCH_LIST(h, key, key_len);
for (le = l->head; le; le = le->next) { for (le = l->head; le; le = le->next) {
he = (curl_hash_element *) le->ptr; he = (struct curl_hash_element *) le->ptr;
if (hash_key_compare(he->key, he->key_len, key, key_len)) { if (hash_key_compare(he->key, he->key_len, key, key_len)) {
h->dtor(p); /* remove the NEW entry */ h->dtor(p); /* remove the NEW entry */
return he->ptr; /* return the EXISTING entry */ return he->ptr; /* return the EXISTING entry */
@@ -181,11 +180,11 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p)
} }
void * void *
Curl_hash_pick(curl_hash *h, char *key, size_t key_len) Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
{ {
curl_llist_element *le; struct curl_llist_element *le;
curl_hash_element *he; struct curl_hash_element *he;
curl_llist *l = FETCH_LIST(h, key, key_len); struct curl_llist *l = FETCH_LIST(h, key, key_len);
for (le = l->head; for (le = l->head;
le; le;
@@ -204,7 +203,7 @@ void
Curl_hash_apply(curl_hash *h, void *user, Curl_hash_apply(curl_hash *h, void *user,
void (*cb)(void *user, void *ptr)) void (*cb)(void *user, void *ptr))
{ {
curl_llist_element *le; struct curl_llist_element *le;
int i; int i;
for (i = 0; i < h->slots; ++i) { for (i = 0; i < h->slots; ++i) {
@@ -219,7 +218,7 @@ Curl_hash_apply(curl_hash *h, void *user,
#endif #endif
void void
Curl_hash_clean(curl_hash *h) Curl_hash_clean(struct curl_hash *h)
{ {
int i; int i;
@@ -231,19 +230,19 @@ Curl_hash_clean(curl_hash *h)
} }
void void
Curl_hash_clean_with_criterium(curl_hash *h, void *user, Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
int (*comp)(void *, void *)) int (*comp)(void *, void *))
{ {
curl_llist_element *le; struct curl_llist_element *le;
curl_llist_element *lnext; struct curl_llist_element *lnext;
curl_llist *list; struct curl_llist *list;
int i; int i;
for (i = 0; i < h->slots; ++i) { for (i = 0; i < h->slots; ++i) {
list = h->table[i]; list = h->table[i];
le = list->head; /* get first list entry */ le = list->head; /* get first list entry */
while(le) { while(le) {
curl_hash_element *he = le->ptr; struct curl_hash_element *he = le->ptr;
lnext = le->next; lnext = le->next;
/* ask the callback function if we shall remove this entry or not */ /* ask the callback function if we shall remove this entry or not */
if (comp(user, he->ptr)) { if (comp(user, he->ptr)) {
@@ -256,7 +255,7 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user,
} }
void void
Curl_hash_destroy(curl_hash *h) Curl_hash_destroy(struct curl_hash *h)
{ {
if (!h) if (!h)
return; return;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -31,30 +31,31 @@
typedef void (*curl_hash_dtor)(void *); typedef void (*curl_hash_dtor)(void *);
typedef struct _curl_hash { struct curl_hash {
curl_llist **table; struct curl_llist **table;
curl_hash_dtor dtor; curl_hash_dtor dtor;
int slots; int slots;
size_t size; size_t size;
} curl_hash; };
typedef struct _curl_hash_element { struct curl_hash_element {
void *ptr; void *ptr;
char *key; char *key;
size_t key_len; size_t key_len;
} curl_hash_element; };
int Curl_hash_init(curl_hash *, int, curl_hash_dtor); int Curl_hash_init(struct curl_hash *, int, curl_hash_dtor);
curl_hash *Curl_hash_alloc(int, curl_hash_dtor); struct curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
void *Curl_hash_add(curl_hash *, char *, size_t, void *); void *Curl_hash_add(struct curl_hash *, char *, size_t, void *);
int Curl_hash_delete(curl_hash *h, char *key, size_t key_len); int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len);
void *Curl_hash_pick(curl_hash *, char *, size_t); void *Curl_hash_pick(struct curl_hash *, char *, size_t);
void Curl_hash_apply(curl_hash *h, void *user, void Curl_hash_apply(struct curl_hash *h, void *user,
void (*cb)(void *user, void *ptr)); void (*cb)(void *user, void *ptr));
int Curl_hash_count(curl_hash *h); int Curl_hash_count(struct curl_hash *h);
void Curl_hash_clean(curl_hash *h); void Curl_hash_clean(struct curl_hash *h);
void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)); void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
void Curl_hash_destroy(curl_hash *h); int (*comp)(void *, void *));
void Curl_hash_destroy(struct curl_hash *h);
#endif #endif

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -99,7 +99,7 @@
#ifdef CURLRES_ARES #ifdef CURLRES_ARES
/* /*
* Curl_fdset() is called when someone from the outside world (using * Curl_resolv_fdset() is called when someone from the outside world (using
* curl_multi_fdset()) wants to get our fd_set setup and we're talking with * curl_multi_fdset()) wants to get our fd_set setup and we're talking with
* ares. The caller must make sure that this function is only called when we * ares. The caller must make sure that this function is only called when we
* have a working ares channel. * have a working ares channel.
@@ -107,10 +107,10 @@
* Returns: CURLE_OK always! * Returns: CURLE_OK always!
*/ */
CURLcode Curl_fdset(struct connectdata *conn, CURLcode Curl_resolv_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
int *max_fdp) int *max_fdp)
{ {
int max = ares_fds(conn->data->state.areschannel, int max = ares_fds(conn->data->state.areschannel,
@@ -249,7 +249,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
/* close the connection, since we can't return failure here without /* close the connection, since we can't return failure here without
cleaning up this connection properly */ cleaning up this connection properly */
Curl_disconnect(conn); conn->bits.close = TRUE;
} }
return rc; return rc;
@@ -291,7 +291,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
/* areschannel is already setup in the Curl_open() function */ /* areschannel is already setup in the Curl_open() function */
ares_gethostbyname(data->state.areschannel, hostname, PF_INET, ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
Curl_addrinfo4_callback, conn); (ares_host_callback)Curl_addrinfo4_callback, conn);
*waitp = TRUE; /* please wait for the response */ *waitp = TRUE; /* please wait for the response */
} }

View File

@@ -67,11 +67,6 @@
#include <process.h> #include <process.h>
#endif #endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
@@ -108,12 +103,13 @@
* *
* The storage operation locks and unlocks the DNS cache. * The storage operation locks and unlocks the DNS cache.
*/ */
static void addrinfo_callback(void *arg, /* "struct connectdata *" */ static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
int status, int status,
void *addr) void *addr)
{ {
struct connectdata *conn = (struct connectdata *)arg; struct connectdata *conn = (struct connectdata *)arg;
struct Curl_dns_entry *dns = NULL; struct Curl_dns_entry *dns = NULL;
CURLcode rc = CURLE_OK;
conn->async.status = status; conn->async.status = status;
@@ -135,13 +131,17 @@ static void addrinfo_callback(void *arg, /* "struct connectdata *" */
dns = Curl_cache_addr(data, ai, dns = Curl_cache_addr(data, ai,
conn->async.hostname, conn->async.hostname,
conn->async.port); conn->async.port);
if(!dns) if(!dns) {
/* failed to store, cleanup and return error */ /* failed to store, cleanup and return error */
Curl_freeaddrinfo(ai); Curl_freeaddrinfo(ai);
rc = CURLE_OUT_OF_MEMORY;
}
if(data->share) if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS); Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
} }
else
rc = CURLE_OUT_OF_MEMORY;
} }
conn->async.dns = dns; conn->async.dns = dns;
@@ -153,21 +153,22 @@ static void addrinfo_callback(void *arg, /* "struct connectdata *" */
/* ipv4: The input hostent struct will be freed by ares when we return from /* ipv4: The input hostent struct will be freed by ares when we return from
this function */ this function */
return rc;
} }
void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */ CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
int status, int status,
struct hostent *hostent) struct hostent *hostent)
{ {
addrinfo_callback(arg, status, hostent); return addrinfo_callback(arg, status, hostent);
} }
#ifdef CURLRES_IPV6 #ifdef CURLRES_IPV6
void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */ CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
int status, int status,
struct addrinfo *ai) struct addrinfo *ai)
{ {
addrinfo_callback(arg, status, ai); return addrinfo_callback(arg, status, ai);
} }
#endif #endif

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -67,11 +67,6 @@
#include <process.h> #include <process.h>
#endif #endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
@@ -131,7 +126,7 @@
*/ */
/* These two symbols are for the global DNS cache */ /* These two symbols are for the global DNS cache */
static curl_hash hostname_cache; static struct curl_hash hostname_cache;
static int host_cache_initialized; static int host_cache_initialized;
static void freednsentry(void *freethis); static void freednsentry(void *freethis);
@@ -152,7 +147,7 @@ void Curl_global_host_cache_init(void)
/* /*
* Return a pointer to the global cache * Return a pointer to the global cache
*/ */
curl_hash *Curl_global_host_cache_get(void) struct curl_hash *Curl_global_host_cache_get(void)
{ {
return &hostname_cache; return &hostname_cache;
} }
@@ -244,7 +239,7 @@ hostcache_timestamp_remove(void *datap, void *hc)
* Prune the DNS cache. This assumes that a lock has already been taken. * Prune the DNS cache. This assumes that a lock has already been taken.
*/ */
static void static void
hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now) hostcache_prune(struct curl_hash *hostcache, int cache_timeout, time_t now)
{ {
struct hostcache_prune_data user; struct hostcache_prune_data user;
@@ -507,7 +502,7 @@ static void freednsentry(void *freethis)
/* /*
* Curl_mk_dnscache() creates a new DNS cache and returns the handle for it. * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
*/ */
curl_hash *Curl_mk_dnscache(void) struct curl_hash *Curl_mk_dnscache(void)
{ {
return Curl_hash_alloc(7, freednsentry); return Curl_hash_alloc(7, freednsentry);
} }

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -112,7 +112,7 @@ struct connectdata;
void Curl_global_host_cache_init(void); void Curl_global_host_cache_init(void);
void Curl_global_host_cache_dtor(void); void Curl_global_host_cache_dtor(void);
curl_hash *Curl_global_host_cache_get(void); struct curl_hash *Curl_global_host_cache_get(void);
#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache) #define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
@@ -159,13 +159,13 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
CURLcode Curl_wait_for_resolv(struct connectdata *conn, CURLcode Curl_wait_for_resolv(struct connectdata *conn,
struct Curl_dns_entry **dnsentry); struct Curl_dns_entry **dnsentry);
/* Curl_fdset() is a generic function that exists in multiple versions /* Curl_resolv_fdset() is a generic function that exists in multiple versions
depending on what name resolve technology we've built to use. The function depending on what name resolve technology we've built to use. The function
is called from the curl_multi_fdset() function */ is called from the curl_multi_fdset() function */
CURLcode Curl_fdset(struct connectdata *conn, CURLcode Curl_resolv_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
int *max_fdp); int *max_fdp);
/* unlock a previously resolved dns entry */ /* unlock a previously resolved dns entry */
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns); void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns);
@@ -176,7 +176,7 @@ void Curl_scan_cache_used(void *user, void *ptr);
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr); void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
/* make a new dns cache and return the handle */ /* make a new dns cache and return the handle */
curl_hash *Curl_mk_dnscache(void); struct curl_hash *Curl_mk_dnscache(void);
/* prune old entries from the DNS cache */ /* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct SessionHandle *data); void Curl_hostcache_prune(struct SessionHandle *data);
@@ -199,14 +199,14 @@ int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
/* This is the callback function that is used when we build with asynch /* This is the callback function that is used when we build with asynch
resolve, ipv4 */ resolve, ipv4 */
void Curl_addrinfo4_callback(void *arg, CURLcode Curl_addrinfo4_callback(void *arg,
int status, int status,
struct hostent *hostent); struct hostent *hostent);
/* This is the callback function that is used when we build with asynch /* This is the callback function that is used when we build with asynch
resolve, ipv6 */ resolve, ipv6 */
void Curl_addrinfo6_callback(void *arg, CURLcode Curl_addrinfo6_callback(void *arg,
int status, int status,
struct addrinfo *ai); struct addrinfo *ai);
/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP /* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP

View File

@@ -67,11 +67,6 @@
#include <process.h> #include <process.h>
#endif #endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -67,11 +67,6 @@
#include <process.h> #include <process.h>
#endif #endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
@@ -133,10 +128,10 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
* It is present here to keep #ifdefs out from multi.c * It is present here to keep #ifdefs out from multi.c
*/ */
CURLcode Curl_fdset(struct connectdata *conn, CURLcode Curl_resolv_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
int *max_fdp) int *max_fdp)
{ {
(void)conn; (void)conn;
(void)read_fd_set; (void)read_fd_set;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -155,7 +155,7 @@ struct thread_data {
HANDLE thread_hnd; HANDLE thread_hnd;
unsigned thread_id; unsigned thread_id;
DWORD thread_status; DWORD thread_status;
curl_socket_t dummy_sock; /* dummy for Curl_fdset() */ curl_socket_t dummy_sock; /* dummy for Curl_resolv_fdset() */
FILE *stderr_file; FILE *stderr_file;
HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */ HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */
HANDLE event_resolved; /* marks that the thread obtained the information */ HANDLE event_resolved; /* marks that the thread obtained the information */
@@ -184,11 +184,13 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
* due to a resolver timeout. * due to a resolver timeout.
*/ */
HANDLE mutex_waiting = NULL; HANDLE mutex_waiting = NULL;
if (!DuplicateHandle(GetCurrentProcess(), td->mutex_waiting, HANDLE curr_proc = GetCurrentProcess();
GetCurrentProcess(), &mutex_waiting, 0, FALSE,
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
curr_proc, &mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */ /* failed to duplicate the mutex, no point in continuing */
return 0; return -1;
} }
/* Sharing the same _iob[] element with our parent thread should /* Sharing the same _iob[] element with our parent thread should
@@ -212,12 +214,10 @@ static unsigned __stdcall gethostbyname_thread (void *arg)
SetEvent(td->event_resolved); SetEvent(td->event_resolved);
if (he) { if (he) {
Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he); rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
rc = 1;
} }
else { else {
Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL); rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
rc = 0;
} }
TRACE(("Winsock-error %d, addr %s\n", conn->async.status, TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
@@ -252,14 +252,18 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
* due to a resolver timeout. * due to a resolver timeout.
*/ */
HANDLE mutex_waiting = NULL; HANDLE mutex_waiting = NULL;
if (!DuplicateHandle(GetCurrentProcess(), td->mutex_waiting, HANDLE curr_proc = GetCurrentProcess();
GetCurrentProcess(), &mutex_waiting, 0, FALSE,
if (!DuplicateHandle(curr_proc, td->mutex_waiting,
curr_proc, &mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {
/* failed to duplicate the mutex, no point in continuing */ /* failed to duplicate the mutex, no point in continuing */
return 0; return -1;
} }
#ifndef _WIN32_WCE
*stderr = *td->stderr_file; *stderr = *td->stderr_file;
#endif
itoa(conn->async.port, service, 10); itoa(conn->async.port, service, 10);
@@ -280,10 +284,10 @@ static unsigned __stdcall getaddrinfo_thread (void *arg)
#ifdef DEBUG_THREADING_GETADDRINFO #ifdef DEBUG_THREADING_GETADDRINFO
dump_addrinfo (conn, res); dump_addrinfo (conn, res);
#endif #endif
Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res); rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
} }
else { else {
Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL); rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
TRACE(("Winsock-error %d, no address\n", conn->async.status)); TRACE(("Winsock-error %d, no address\n", conn->async.status));
} }
} }
@@ -383,7 +387,6 @@ static bool init_resolve_thread (struct connectdata *conn,
(LPTHREAD_START_ROUTINE) THREAD_FUNC, (LPTHREAD_START_ROUTINE) THREAD_FUNC,
conn, 0, &td->thread_id); conn, 0, &td->thread_id);
#else #else
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC, td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
conn, 0, &td->thread_id); conn, 0, &td->thread_id);
#endif #endif
@@ -401,9 +404,9 @@ static bool init_resolve_thread (struct connectdata *conn,
destroy_thread_data(&conn->async); destroy_thread_data(&conn->async);
return FALSE; return FALSE;
} }
/* This socket is only to keep Curl_fdset() and select() happy; should never /* This socket is only to keep Curl_resolv_fdset() and select() happy;
* become signalled for read/write since it's unbound but Windows needs * should never become signalled for read/write since it's unbound but
* atleast 1 socket in select(). * Windows needs atleast 1 socket in select().
*/ */
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
return TRUE; return TRUE;
@@ -488,7 +491,11 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
if (!conn->async.dns) { if (!conn->async.dns) {
/* a name was not resolved */ /* a name was not resolved */
if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) { if (td->thread_status == CURLE_OUT_OF_MEMORY) {
rc = CURLE_OUT_OF_MEMORY;
failf(data, "Could not resolve host: %s", curl_easy_strerror(rc));
}
else if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
failf(data, "Resolving host timed out: %s", conn->host.name); failf(data, "Resolving host timed out: %s", conn->host.name);
rc = CURLE_OPERATION_TIMEDOUT; rc = CURLE_OPERATION_TIMEDOUT;
} }
@@ -503,10 +510,8 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
destroy_thread_data(&conn->async); destroy_thread_data(&conn->async);
if(CURLE_OK != rc) if(!conn->async.dns)
/* close the connection, since we must not return failure from here conn->bits.close = TRUE;
without cleaning up this connection properly */
Curl_disconnect(conn);
return (rc); return (rc);
} }
@@ -536,10 +541,10 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
CURLcode Curl_fdset(struct connectdata *conn, CURLcode Curl_resolv_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
int *max_fdp) int *max_fdp)
{ {
const struct thread_data *td = const struct thread_data *td =
(const struct thread_data *) conn->async.os_specific; (const struct thread_data *) conn->async.os_specific;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -95,6 +95,7 @@
#include "http.h" #include "http.h"
#include "memory.h" #include "memory.h"
#include "select.h" #include "select.h"
#include "parsedate.h" /* for the week day and month names */
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -250,21 +251,31 @@ static CURLcode perhapsrewind(struct connectdata *conn)
if((expectsend == -1) || (expectsend > bytessent)) { if((expectsend == -1) || (expectsend > bytessent)) {
/* There is still data left to send */ /* There is still data left to send */
if((data->state.authproxy.picked == CURLAUTH_NTLM) ||/* using NTLM */ if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
(data->state.authhost.picked == CURLAUTH_NTLM) ) { (data->state.authhost.picked == CURLAUTH_NTLM)) {
conn->bits.close = FALSE; /* don't close, keep on sending */ if(((expectsend - bytessent) < 2000) ||
(conn->ntlm.state != NTLMSTATE_NONE)) {
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
data left to send, keep on sending. */
/* rewind data when completely done sending! */ /* rewind data when completely done sending! */
conn->bits.rewindaftersend = TRUE; if(!conn->bits.authneg)
return CURLE_OK; conn->bits.rewindaftersend = TRUE;
}
else { return CURLE_OK;
/* If there is more than just a little data left to send, close the }
* current connection by force. if(conn->bits.close)
*/ /* this is already marked to get closed */
conn->bits.close = TRUE; return CURLE_OK;
conn->size = 0; /* don't download any more than 0 bytes */
infof(data, "NTLM send, close instead of sending %ld bytes\n",
expectsend - bytessent);
} }
/* This is not NTLM or NTLM with many bytes left to send: close
*/
conn->bits.close = TRUE;
conn->size = 0; /* don't download any more than 0 bytes */
} }
if(bytessent) if(bytessent)
@@ -309,7 +320,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
conn->newurl = strdup(data->change.url); /* clone URL */ conn->newurl = strdup(data->change.url); /* clone URL */
if((data->set.httpreq != HTTPREQ_GET) && if((data->set.httpreq != HTTPREQ_GET) &&
(data->set.httpreq != HTTPREQ_HEAD)) { (data->set.httpreq != HTTPREQ_HEAD) &&
!conn->bits.rewindaftersend) {
code = perhapsrewind(conn); code = perhapsrewind(conn);
if(code) if(code)
return code; return code;
@@ -391,24 +403,17 @@ Curl_http_output_auth(struct connectdata *conn,
and if this is one single bit it'll be used instantly. */ and if this is one single bit it'll be used instantly. */
authproxy->picked = authproxy->want; authproxy->picked = authproxy->want;
/* To prevent the user+password to get sent to other than the original /* Send proxy authentication header if needed */
host due to a location-follow, we do some weirdo checks here */ if (conn->bits.httpproxy &&
if(!data->state.this_is_a_follow || (conn->bits.tunnel_proxy == proxytunnel)) {
!data->state.first_host ||
curl_strequal(data->state.first_host, conn->host.name) ||
data->set.http_disable_hostname_check_before_authentication) {
/* Send proxy authentication header if needed */
if (conn->bits.httpproxy &&
(conn->bits.tunnel_proxy == proxytunnel)) {
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
if(authproxy->want == CURLAUTH_NTLM) { if(authproxy->want == CURLAUTH_NTLM) {
auth=(char *)"NTLM"; auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, TRUE); result = Curl_output_ntlm(conn, TRUE);
if(result) if(result)
return result; return result;
} }
else else
#endif #endif
if(authproxy->want == CURLAUTH_BASIC) { if(authproxy->want == CURLAUTH_BASIC) {
/* Basic */ /* Basic */
@@ -442,10 +447,17 @@ Curl_http_output_auth(struct connectdata *conn,
else else
authproxy->multi = FALSE; authproxy->multi = FALSE;
} }
else else
/* we have no proxy so let's pretend we're done authenticating /* we have no proxy so let's pretend we're done authenticating
with it */ with it */
authproxy->done = TRUE; authproxy->done = TRUE;
/* 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 ||
!data->state.first_host ||
curl_strequal(data->state.first_host, conn->host.name) ||
data->set.http_disable_hostname_check_before_authentication) {
/* Send web authentication header if needed */ /* Send web authentication header if needed */
{ {
@@ -858,8 +870,7 @@ CURLcode add_buffer_send(send_buffer *in,
if(conn->data->set.verbose) if(conn->data->set.verbose)
/* this data _may_ contain binary stuff */ /* this data _may_ contain binary stuff */
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount, Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, amount, conn);
conn->host.dispname);
*bytes_written += amount; *bytes_written += amount;
@@ -1140,7 +1151,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
/* output debug if that is requested */ /* output debug if that is requested */
if(data->set.verbose) if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline, Curl_debug(data, CURLINFO_HEADER_IN, line_start, perline,
conn->host.dispname); conn);
/* send the header to the callback */ /* send the header to the callback */
writetype = CLIENTWRITE_HEADER; writetype = CLIENTWRITE_HEADER;
@@ -1223,7 +1234,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
* Curl_http_connect() performs HTTP stuff to do at connect-time, called from * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
* the generic Curl_connect(). * the generic Curl_connect().
*/ */
CURLcode Curl_http_connect(struct connectdata *conn) CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
{ {
struct SessionHandle *data; struct SessionHandle *data;
CURLcode result; CURLcode result;
@@ -1262,6 +1273,8 @@ CURLcode Curl_http_connect(struct connectdata *conn)
data->state.first_host = strdup(conn->host.name); data->state.first_host = strdup(conn->host.name);
} }
*done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
@@ -1275,7 +1288,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
{ {
struct SessionHandle *data; struct SessionHandle *data;
struct HTTP *http; struct HTTP *http;
(void)status; /* no use for us */
data=conn->data; data=conn->data;
http=conn->proto.http; http=conn->proto.http;
@@ -1292,7 +1304,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
free(buff->buffer); free(buff->buffer);
free(buff); free(buff);
http->send_buffer = NULL; /* cleaer the pointer */ http->send_buffer = NULL; /* clear the pointer */
} }
if(HTTPREQ_POST_FORM == data->set.httpreq) { if(HTTPREQ_POST_FORM == data->set.httpreq) {
@@ -1308,6 +1320,9 @@ CURLcode Curl_http_done(struct connectdata *conn,
else if(HTTPREQ_PUT == data->set.httpreq) else if(HTTPREQ_PUT == data->set.httpreq)
conn->bytecount = http->readbytecount + http->writebytecount; conn->bytecount = http->readbytecount + http->writebytecount;
if (status != CURLE_OK)
return (status);
if(!conn->bits.retry && if(!conn->bits.retry &&
((http->readbytecount + ((http->readbytecount +
conn->headerbytecount - conn->headerbytecount -
@@ -1327,7 +1342,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
* request is to be performed. This creates and sends a properly constructed * request is to be performed. This creates and sends a properly constructed
* HTTP request. * HTTP request.
*/ */
CURLcode Curl_http(struct connectdata *conn) CURLcode Curl_http(struct connectdata *conn, bool *done)
{ {
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
char *buf = data->state.buffer; /* this is a short cut to the buffer */ char *buf = data->state.buffer; /* this is a short cut to the buffer */
@@ -1341,6 +1356,11 @@ CURLcode Curl_http(struct connectdata *conn)
Curl_HttpReq httpreq = data->set.httpreq; Curl_HttpReq httpreq = data->set.httpreq;
char *addcookies = NULL; char *addcookies = NULL;
/* Always consider the DO phase done after this function call, even if there
may be parts of the request that is not yet sent, since we can deal with
the rest of the request in the PERFORM phase. */
*done = TRUE;
if(!conn->proto.http) { if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */ /* Only allocate this struct if we don't already have it! */
@@ -1775,7 +1795,7 @@ CURLcode Curl_http(struct connectdata *conn)
#endif #endif
if(data->set.timecondition) { if(data->set.timecondition) {
struct tm *thistime; struct tm *tm;
/* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since /* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since
* header family should have their times set in GMT as RFC2616 defines: * header family should have their times set in GMT as RFC2616 defines:
@@ -1787,18 +1807,22 @@ CURLcode Curl_http(struct connectdata *conn)
#ifdef HAVE_GMTIME_R #ifdef HAVE_GMTIME_R
/* thread-safe version */ /* thread-safe version */
struct tm keeptime; struct tm keeptime;
thistime = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime); tm = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
#else #else
thistime = gmtime(&data->set.timevalue); tm = gmtime(&data->set.timevalue);
#endif #endif
#ifdef HAVE_STRFTIME
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
strftime(buf, BUFSIZE-1, "%a, %d %b %Y %H:%M:%S GMT", thistime); snprintf(buf, BUFSIZE-1,
#else "%s, %02d %s %4d %02d:%02d:%02d GMT",
/* TODO: Right, we *could* write a replacement here */ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
strcpy(buf, "no strftime() support"); tm->tm_mday,
#endif Curl_month[tm->tm_mon],
tm->tm_year + 1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
switch(data->set.timecondition) { switch(data->set.timecondition) {
case CURL_TIMECOND_IFMODSINCE: case CURL_TIMECOND_IFMODSINCE:
default: default:

View File

@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -34,9 +34,9 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
char *hostname, int remote_port); char *hostname, int remote_port);
/* protocol-specific functions set up to be called by the main engine */ /* protocol-specific functions set up to be called by the main engine */
CURLcode Curl_http(struct connectdata *conn); CURLcode Curl_http(struct connectdata *conn, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode); CURLcode Curl_http_done(struct connectdata *, CURLcode);
CURLcode Curl_http_connect(struct connectdata *conn); CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
/* The following functions are defined in http_chunks.c */ /* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn);

View File

@@ -1,8 +1,8 @@
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -10,7 +10,7 @@
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -43,7 +43,7 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
/* /*
* Chunk format (simplified): * Chunk format (simplified):
* *
* <HEX SIZE>[ chunk extension ] CRLF * <HEX SIZE>[ chunk extension ] CRLF
@@ -188,7 +188,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
break; break;
case DEFLATE: case DEFLATE:
/* update conn->keep.str to point to the chunk data. */ /* update conn->keep.str to point to the chunk data. */
conn->keep.str = datap; conn->keep.str = datap;
result = Curl_unencode_deflate_write(conn->data, &conn->keep, result = Curl_unencode_deflate_write(conn->data, &conn->keep,

View File

@@ -1,10 +1,10 @@
#ifndef __HTTP_CHUNKS_H #ifndef __HTTP_CHUNKS_H
#define __HTTP_CHUNKS_H #define __HTTP_CHUNKS_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -12,7 +12,7 @@
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.

View File

@@ -166,12 +166,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
len = strlen(header); len = strlen(header);
if (len > 0) { if (len > 0) {
int rawlen; int rawlen = Curl_base64_decode(header, (unsigned char **)&input_token.value);
input_token.length = (len+3)/4 * 3;
input_token.value = malloc(input_token.length);
if (input_token.value == NULL)
return ENOMEM;
rawlen = Curl_base64_decode(header, input_token.value);
if (rawlen < 0) if (rawlen < 0)
return -1; return -1;
input_token.length = rawlen; input_token.length = rawlen;
@@ -211,7 +206,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
input_token.length = mechTokenLength; input_token.length = mechTokenLength;
free(mechToken); free(mechToken);
mechToken = NULL; mechToken = NULL;
infof(conn->data, "Parse SPNEGO Target Token succeded\n"); infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
} }
} }
#endif #endif
@@ -292,7 +287,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn)
neg_ctx->output_token.length = spnegoTokenLength; neg_ctx->output_token.length = spnegoTokenLength;
free(spnegoToken); free(spnegoToken);
spnegoToken = NULL; spnegoToken = NULL;
infof(conn->data, "Make SPNEGO Initial Token succeded\n"); infof(conn->data, "Make SPNEGO Initial Token succeeded\n");
} }
} }
#endif #endif

View File

@@ -103,7 +103,6 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
header++; header++;
if(checkprefix("NTLM", header)) { if(checkprefix("NTLM", header)) {
unsigned char buffer[256];
header += strlen("NTLM"); header += strlen("NTLM");
while(*header && isspace((int)*header)) while(*header && isspace((int)*header))
@@ -123,17 +122,22 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
(40) Target Information (optional) security buffer(*) (40) Target Information (optional) security buffer(*)
32 (48) start of data block 32 (48) start of data block
*/ */
size_t size;
size_t size = Curl_base64_decode(header, (char *)buffer); unsigned char *buffer;
size = Curl_base64_decode(header, &buffer);
if(!buffer)
return CURLNTLM_BAD;
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */ ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
if(size >= 48) if(size >= 48)
/* the nonce of interest is index [24 .. 31], 8 bytes */ /* the nonce of interest is index [24 .. 31], 8 bytes */
memcpy(ntlm->nonce, &buffer[24], 8); memcpy(ntlm->nonce, &buffer[24], 8);
/* FIX: add an else here! */
/* at index decimal 20, there's a 32bit NTLM flag field */ /* at index decimal 20, there's a 32bit NTLM flag field */
free(buffer);
} }
else { else {
if(ntlm->state >= NTLMSTATE_TYPE1) if(ntlm->state >= NTLMSTATE_TYPE1)

View File

@@ -199,7 +199,8 @@ krb4_auth(void *app_data, struct connectdata *conn)
{ {
int ret; int ret;
char *p; char *p;
int len; unsigned char *ptr;
size_t len;
KTEXT_ST adat; KTEXT_ST adat;
MSG_DAT msg_data; MSG_DAT msg_data;
int checksum; int checksum;
@@ -275,11 +276,17 @@ krb4_auth(void *app_data, struct connectdata *conn)
return AUTH_ERROR; return AUTH_ERROR;
} }
p += 5; p += 5;
len = Curl_base64_decode(p, (char *)adat.dat); len = Curl_base64_decode(p, &ptr);
if(len < 0) { if(len > sizeof(adat.dat)-1) {
free(ptr);
len=0;
}
if(!len || !ptr) {
Curl_failf(data, "Failed to decode base64 from server"); Curl_failf(data, "Failed to decode base64 from server");
return AUTH_ERROR; return AUTH_ERROR;
} }
memcpy((char *)adat.dat, ptr, len);
free(ptr);
adat.length = len; adat.length = len;
ret = krb_rd_safe(adat.dat, adat.length, &d->key, ret = krb_rd_safe(adat.dat, adat.length, &d->key,
(struct sockaddr_in *)hisctladdr, (struct sockaddr_in *)hisctladdr,
@@ -317,10 +324,11 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
char *name; char *name;
char *p; char *p;
char passwd[100]; char passwd[100];
int tmp; size_t tmp;
ssize_t nread; ssize_t nread;
int save; int save;
CURLcode result; CURLcode result;
unsigned char *ptr;
save = Curl_set_command_prot(conn, prot_private); save = Curl_set_command_prot(conn, prot_private);
@@ -346,12 +354,18 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
} }
p += 2; p += 2;
tmp = Curl_base64_decode(p, (char *)tkt.dat); tmp = Curl_base64_decode(p, &ptr);
if(tmp < 0) { if(tmp >= sizeof(tkt.dat)) {
free(ptr);
tmp=0;
}
if(!tmp || !ptr) {
Curl_failf(conn->data, "Failed to decode base64 in reply.\n"); Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
Curl_set_command_prot(conn, save); Curl_set_command_prot(conn, save);
return CURLE_FTP_WEIRD_SERVER_REPLY; return CURLE_FTP_WEIRD_SERVER_REPLY;
} }
memcpy((char *)tkt.dat, ptr, tmp);
free(ptr);
tkt.length = tmp; tkt.length = tmp;
tktcopy.length = tkt.length; tktcopy.length = tkt.length;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -224,7 +224,7 @@ static void (*ldap_free_urldesc)(LDAPURLDesc *) = _ldap_free_urldesc;
#endif #endif
CURLcode Curl_ldap(struct connectdata *conn) CURLcode Curl_ldap(struct connectdata *conn, bool *done)
{ {
CURLcode status = CURLE_OK; CURLcode status = CURLE_OK;
int rc = 0; int rc = 0;
@@ -256,6 +256,7 @@ CURLcode Curl_ldap(struct connectdata *conn)
int num = 0; int num = 0;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
*done = TRUE; /* unconditionally */
infof(data, "LDAP local: %s\n", data->change.url); infof(data, "LDAP local: %s\n", data->change.url);
if (!DynaOpen(&mod_name)) { if (!DynaOpen(&mod_name)) {
@@ -379,6 +380,7 @@ quit:
/* no data to transfer */ /* no data to transfer */
Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
conn->bits.close = TRUE;
return status; return status;
} }
@@ -473,9 +475,9 @@ static bool unescape_elements (LDAPURLDesc *ludp)
char *new_dn = curl_unescape(dn, 0); char *new_dn = curl_unescape(dn, 0);
free(dn); free(dn);
ludp->lud_dn = new_dn;
if (!new_dn) if (!new_dn)
return (FALSE); return (FALSE);
ludp->lud_dn = new_dn;
} }
return (TRUE); return (TRUE);
} }

View File

@@ -2,18 +2,18 @@
#define __LDAP_H #define __LDAP_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -24,6 +24,6 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_LDAP #ifndef CURL_DISABLE_LDAP
CURLcode Curl_ldap(struct connectdata *conn); CURLcode Curl_ldap(struct connectdata *conn, bool *done);
#endif #endif
#endif /* __LDAP_H */ #endif /* __LDAP_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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -33,7 +33,7 @@
#include "memdebug.h" #include "memdebug.h"
void void
Curl_llist_init(curl_llist *l, curl_llist_dtor dtor) Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
{ {
l->size = 0; l->size = 0;
l->dtor = dtor; l->dtor = dtor;
@@ -41,12 +41,12 @@ Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
l->tail = NULL; l->tail = NULL;
} }
curl_llist * struct curl_llist *
Curl_llist_alloc(curl_llist_dtor dtor) Curl_llist_alloc(curl_llist_dtor dtor)
{ {
curl_llist *list; struct curl_llist *list;
list = (curl_llist *)malloc(sizeof(curl_llist)); list = (struct curl_llist *)malloc(sizeof(struct curl_llist));
if(NULL == list) if(NULL == list)
return NULL; return NULL;
@@ -59,10 +59,11 @@ Curl_llist_alloc(curl_llist_dtor dtor)
* Curl_llist_insert_next() returns 1 on success and 0 on failure. * Curl_llist_insert_next() returns 1 on success and 0 on failure.
*/ */
int int
Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p) Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
const void *p)
{ {
curl_llist_element *ne = struct curl_llist_element *ne =
(curl_llist_element *) malloc(sizeof(curl_llist_element)); (struct curl_llist_element *) malloc(sizeof(struct curl_llist_element));
if(!ne) if(!ne)
return 0; return 0;
@@ -91,7 +92,8 @@ Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
} }
int int
Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user) Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
void *user)
{ {
if (e == NULL || list->size == 0) if (e == NULL || list->size == 0)
return 1; return 1;
@@ -119,7 +121,7 @@ Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
} }
void void
Curl_llist_destroy(curl_llist *list, void *user) Curl_llist_destroy(struct curl_llist *list, void *user)
{ {
if(list) { if(list) {
while (list->size > 0) while (list->size > 0)

View File

@@ -1,18 +1,18 @@
#ifndef __LLIST_H #ifndef __LLIST_H
#define __LLIST_H #define __LLIST_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -28,29 +28,33 @@
typedef void (*curl_llist_dtor)(void *, void *); typedef void (*curl_llist_dtor)(void *, void *);
typedef struct _curl_llist_element { struct curl_llist_element {
void *ptr; void *ptr;
struct _curl_llist_element *prev; struct curl_llist_element *prev;
struct _curl_llist_element *next; struct curl_llist_element *next;
} curl_llist_element; };
typedef struct _curl_llist { struct curl_llist {
curl_llist_element *head; struct curl_llist_element *head;
curl_llist_element *tail; struct curl_llist_element *tail;
curl_llist_dtor dtor; curl_llist_dtor dtor;
size_t size; size_t size;
} curl_llist; };
void Curl_llist_init(curl_llist *, curl_llist_dtor); void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
curl_llist *Curl_llist_alloc(curl_llist_dtor); struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
int Curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *); int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
int Curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *); const void *);
int Curl_llist_remove(curl_llist *, curl_llist_element *, void *); int Curl_llist_insert_prev(struct curl_llist *, struct curl_llist_element *,
int Curl_llist_remove_next(curl_llist *, curl_llist_element *, void *); const void *);
size_t Curl_llist_count(curl_llist *); int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
void Curl_llist_destroy(curl_llist *, void *); void *);
int Curl_llist_remove_next(struct curl_llist *, struct curl_llist_element *,
void *);
size_t Curl_llist_count(struct curl_llist *);
void Curl_llist_destroy(struct curl_llist *, void *);
#endif #endif

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -43,6 +43,9 @@
#include "connect.h" #include "connect.h"
#include "progress.h" #include "progress.h"
#include "memory.h" #include "memory.h"
#include "easyif.h"
#include "multiif.h"
#include "sendf.h"
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
@@ -54,11 +57,14 @@ struct Curl_message {
}; };
typedef enum { typedef enum {
CURLM_STATE_INIT, CURLM_STATE_INIT, /* start in this state */
CURLM_STATE_CONNECT, /* resolve/connect has been sent off */ CURLM_STATE_CONNECT, /* resolve/connect has been sent off */
CURLM_STATE_WAITRESOLVE, /* we're awaiting the resolve to finalize */ CURLM_STATE_WAITRESOLVE, /* awaiting the resolve to finalize */
CURLM_STATE_WAITCONNECT, /* we're awaiting the connect to finalize */ CURLM_STATE_WAITCONNECT, /* awaiting the connect to finalize */
CURLM_STATE_DO, /* send off the request (part 1) */ CURLM_STATE_PROTOCONNECT, /* completing the protocol-specific connect
phase */
CURLM_STATE_DO, /* start send off the request (part 1) */
CURLM_STATE_DOING, /* sending off the request (part 1) */
CURLM_STATE_DO_MORE, /* send off the request (part 2) */ CURLM_STATE_DO_MORE, /* send off the request (part 2) */
CURLM_STATE_PERFORM, /* transfer data */ CURLM_STATE_PERFORM, /* transfer data */
CURLM_STATE_DONE, /* post data transfer operation */ CURLM_STATE_DONE, /* post data transfer operation */
@@ -106,9 +112,36 @@ struct Curl_multi {
int num_msgs; /* total amount of messages in the easy handles */ int num_msgs; /* total amount of messages in the easy handles */
/* Hostname cache */ /* Hostname cache */
curl_hash *hostcache; struct curl_hash *hostcache;
}; };
/* always use this function to change state, to make debugging easier */
static void multistate(struct Curl_one_easy *easy, CURLMstate state)
{
#ifdef CURLDEBUG
const char *statename[]={
"INIT",
"CONNECT",
"WAITRESOLVE",
"WAITCONNECT",
"PROTOCONNECT",
"DO",
"DOING",
"DO_MORE",
"PERFORM",
"DONE",
"COMPLETED",
};
CURLMstate oldstate = easy->state;
#endif
easy->state = state;
#ifdef CURLDEBUG
infof(easy->easy_handle,
"STATE: %s => %s handle %p: \n",
statename[oldstate], statename[easy->state], (char *)easy);
#endif
}
CURLM *curl_multi_init(void) CURLM *curl_multi_init(void)
{ {
@@ -156,7 +189,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
/* set the easy handle */ /* set the easy handle */
easy->easy_handle = easy_handle; easy->easy_handle = easy_handle;
easy->state = CURLM_STATE_INIT; multistate(easy, CURLM_STATE_INIT);
/* for multi interface connections, we share DNS cache automaticly */ /* for multi interface connections, we share DNS cache automaticly */
easy->easy_handle->hostcache = multi->hostcache; easy->easy_handle->hostcache = multi->hostcache;
@@ -174,6 +207,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
if(easy->next) if(easy->next)
easy->next->prev = easy; easy->next->prev = easy;
Curl_easy_addmulti(easy_handle, multi_handle);
/* increase the node-counter */ /* increase the node-counter */
multi->num_easy++; multi->num_easy++;
@@ -207,6 +242,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
/* clear out the usage of the shared DNS cache */ /* clear out the usage of the shared DNS cache */
easy->easy_handle->hostcache = NULL; easy->easy_handle->hostcache = NULL;
Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association
to this multi handle */
/* make the previous node point to our next */ /* make the previous node point to our next */
if(easy->prev) if(easy->prev)
@@ -252,7 +289,22 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
break; break;
case CURLM_STATE_WAITRESOLVE: case CURLM_STATE_WAITRESOLVE:
/* waiting for a resolve to complete */ /* waiting for a resolve to complete */
Curl_fdset(easy->easy_conn, read_fd_set, write_fd_set, &this_max_fd); Curl_resolv_fdset(easy->easy_conn, read_fd_set, write_fd_set,
&this_max_fd);
if(this_max_fd > *max_fd)
*max_fd = this_max_fd;
break;
case CURLM_STATE_PROTOCONNECT:
Curl_protocol_fdset(easy->easy_conn, read_fd_set, write_fd_set,
&this_max_fd);
if(this_max_fd > *max_fd)
*max_fd = this_max_fd;
break;
case CURLM_STATE_DOING:
Curl_doing_fdset(easy->easy_conn, read_fd_set, write_fd_set,
&this_max_fd);
if(this_max_fd > *max_fd) if(this_max_fd > *max_fd)
*max_fd = this_max_fd; *max_fd = this_max_fd;
break; break;
@@ -312,6 +364,8 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
struct Curl_message *msg = NULL; struct Curl_message *msg = NULL;
bool connected; bool connected;
bool async; bool async;
bool protocol_connect;
bool dophase_done;
*running_handles = 0; /* bump this once for every living handle */ *running_handles = 0; /* bump this once for every living handle */
@@ -320,10 +374,6 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
easy=multi->easy.next; easy=multi->easy.next;
while(easy) { while(easy) {
#if 0
fprintf(stderr, "HANDLE %p: State: %x\n",
(char *)easy, easy->state);
#endif
do { do {
if (CURLM_STATE_WAITCONNECT <= easy->state && if (CURLM_STATE_WAITCONNECT <= easy->state &&
easy->state <= CURLM_STATE_DO && easy->state <= CURLM_STATE_DO &&
@@ -336,15 +386,15 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
gotourl = strdup(easy->easy_handle->change.url); gotourl = strdup(easy->easy_handle->change.url);
if(gotourl) { if(gotourl) {
easy->easy_handle->change.url_changed = FALSE; easy->easy_handle->change.url_changed = FALSE;
easy->result = Curl_follow(easy->easy_handle, gotourl); easy->result = Curl_follow(easy->easy_handle, gotourl, FALSE);
if(CURLE_OK == easy->result) if(CURLE_OK == easy->result)
easy->state = CURLM_STATE_CONNECT; multistate(easy, CURLM_STATE_CONNECT);
else else
free(gotourl); free(gotourl);
} }
else { else {
easy->result = CURLE_OUT_OF_MEMORY; easy->result = CURLE_OUT_OF_MEMORY;
easy->state = CURLM_STATE_COMPLETED; multistate(easy, CURLM_STATE_COMPLETED);
break; break;
} }
} }
@@ -359,7 +409,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
/* after init, go CONNECT */ /* after init, go CONNECT */
easy->state = CURLM_STATE_CONNECT; multistate(easy, CURLM_STATE_CONNECT);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
easy->easy_handle->state.used_interface = Curl_if_multi; easy->easy_handle->state.used_interface = Curl_if_multi;
@@ -370,16 +420,22 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
/* Connect. We get a connection identifier filled in. */ /* Connect. We get a connection identifier filled in. */
Curl_pgrsTime(easy->easy_handle, TIMER_STARTSINGLE); Curl_pgrsTime(easy->easy_handle, TIMER_STARTSINGLE);
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn, easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn,
&async); &async, &protocol_connect);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
if(async) if(async)
/* We're now waiting for an asynchronous name lookup */ /* We're now waiting for an asynchronous name lookup */
easy->state = CURLM_STATE_WAITRESOLVE; multistate(easy, CURLM_STATE_WAITRESOLVE);
else { else {
/* after the connect has been sent off, go WAITCONNECT */ /* after the connect has been sent off, go WAITCONNECT unless the
easy->state = CURLM_STATE_WAITCONNECT; protocol connect is already done and we can go directly to
DO! */
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
if(protocol_connect)
multistate(easy, CURLM_STATE_DO);
else
multistate(easy, CURLM_STATE_WAITCONNECT);
} }
} }
break; break;
@@ -395,14 +451,17 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(dns) { if(dns) {
/* Perform the next step in the connection phase, and then move on /* Perform the next step in the connection phase, and then move on
to the WAITCONNECT state */ to the WAITCONNECT state */
easy->result = Curl_async_resolved(easy->easy_conn); easy->result = Curl_async_resolved(easy->easy_conn,
&protocol_connect);
if(CURLE_OK != easy->result) if(CURLE_OK != easy->result)
/* if Curl_async_resolved() returns failure, the connection struct /* if Curl_async_resolved() returns failure, the connection struct
is already freed and gone */ is already freed and gone */
easy->easy_conn = NULL; /* no more connection */ easy->easy_conn = NULL; /* no more connection */
else {
easy->state = CURLM_STATE_WAITCONNECT; /* FIX: what if protocol_connect is TRUE here?! */
multistate(easy, CURLM_STATE_WAITCONNECT);
}
} }
if(CURLE_OK != easy->result) { if(CURLE_OK != easy->result) {
@@ -419,7 +478,8 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
easy->result = Curl_is_connected(easy->easy_conn, FIRSTSOCKET, easy->result = Curl_is_connected(easy->easy_conn, FIRSTSOCKET,
&connected); &connected);
if(connected) if(connected)
easy->result = Curl_protocol_connect(easy->easy_conn); easy->result = Curl_protocol_connect(easy->easy_conn,
&protocol_connect);
if(CURLE_OK != easy->result) { if(CURLE_OK != easy->result) {
/* failure detected */ /* failure detected */
@@ -429,39 +489,110 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
} }
if(connected) { if(connected) {
if(!protocol_connect) {
/* We have a TCP connection, but 'protocol_connect' may be false
and then we continue to 'STATE_PROTOCONNECT'. If protocol
connect is TRUE, we move on to STATE_DO. */
multistate(easy, CURLM_STATE_PROTOCONNECT);
fprintf(stderr, "WAITCONNECT => PROTOCONNECT\n");
}
else {
/* after the connect has completed, go DO */
multistate(easy, CURLM_STATE_DO);
result = CURLM_CALL_MULTI_PERFORM;
}
}
break;
case CURLM_STATE_PROTOCONNECT:
/* protocol-specific connect phase */
easy->result = Curl_protocol_connecting(easy->easy_conn,
&protocol_connect);
if(protocol_connect) {
/* after the connect has completed, go DO */ /* after the connect has completed, go DO */
easy->state = CURLM_STATE_DO; multistate(easy, CURLM_STATE_DO);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
else if(easy->result) {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
break; break;
case CURLM_STATE_DO: case CURLM_STATE_DO:
/* Do the fetch or put request */ /* Perform the protocol's DO action */
easy->result = Curl_do(&easy->easy_conn); easy->result = Curl_do(&easy->easy_conn, &dophase_done);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
/* after do, go PERFORM... or DO_MORE */ if(!dophase_done) {
if(easy->easy_conn->bits.do_more) { /* DO was not completed in one function call, we must continue
DOING... */
multistate(easy, CURLM_STATE_DOING);
result = CURLM_OK;
}
/* after DO, go PERFORM... or DO_MORE */
else if(easy->easy_conn->bits.do_more) {
/* we're supposed to do more, but we need to sit down, relax /* we're supposed to do more, but we need to sit down, relax
and wait a little while first */ and wait a little while first */
easy->state = CURLM_STATE_DO_MORE; multistate(easy, CURLM_STATE_DO_MORE);
result = CURLM_OK; result = CURLM_OK;
} }
else { else {
/* we're done with the DO, now PERFORM */ /* we're done with the DO, now PERFORM */
easy->result = Curl_readwrite_init(easy->easy_conn); easy->result = Curl_readwrite_init(easy->easy_conn);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_PERFORM; multistate(easy, CURLM_STATE_PERFORM);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
} }
} }
else {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
break;
case CURLM_STATE_DOING:
/* we continue DOING until the DO phase is complete */
easy->result = Curl_protocol_doing(easy->easy_conn, &dophase_done);
if(CURLE_OK == easy->result) {
if(dophase_done) {
/* after DO, go PERFORM... or DO_MORE */
if(easy->easy_conn->bits.do_more) {
/* we're supposed to do more, but we need to sit down, relax
and wait a little while first */
multistate(easy, CURLM_STATE_DO_MORE);
result = CURLM_OK;
}
else {
/* we're done with the DO, now PERFORM */
easy->result = Curl_readwrite_init(easy->easy_conn);
if(CURLE_OK == easy->result) {
multistate(easy, CURLM_STATE_PERFORM);
result = CURLM_CALL_MULTI_PERFORM;
}
}
} /* dophase_done */
}
else {
/* failure detected */
Curl_posttransfer(easy->easy_handle);
Curl_done(&easy->easy_conn, easy->result);
Curl_disconnect(easy->easy_conn); /* close the connection */
easy->easy_conn = NULL; /* no more connection */
}
break; break;
case CURLM_STATE_DO_MORE: case CURLM_STATE_DO_MORE:
/* /* Ready to do more? */
* First, check if we really are ready to do more.
*/
easy->result = Curl_is_connected(easy->easy_conn, SECONDARYSOCKET, easy->result = Curl_is_connected(easy->easy_conn, SECONDARYSOCKET,
&connected); &connected);
if(connected) { if(connected) {
@@ -474,7 +605,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
easy->result = Curl_readwrite_init(easy->easy_conn); easy->result = Curl_readwrite_init(easy->easy_conn);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_PERFORM; multistate(easy, CURLM_STATE_PERFORM);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
} }
@@ -500,26 +631,36 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
Curl_done(&easy->easy_conn, easy->result); Curl_done(&easy->easy_conn, easy->result);
} }
/* after the transfer is done, go DONE */
else if(TRUE == done) { else if(TRUE == done) {
char *newurl;
bool retry = Curl_retry_request(easy->easy_conn, &newurl);
/* call this even if the readwrite function returned error */ /* call this even if the readwrite function returned error */
Curl_posttransfer(easy->easy_handle); Curl_posttransfer(easy->easy_handle);
/* When we follow redirects, must to go back to the CONNECT state */ /* When we follow redirects, must to go back to the CONNECT state */
if(easy->easy_conn->newurl) { if(easy->easy_conn->newurl || retry) {
char *newurl = easy->easy_conn->newurl; if(!retry) {
easy->easy_conn->newurl = NULL; /* if the URL is a follow-location and not just a retried request
then figure out the URL here */
newurl = easy->easy_conn->newurl;
easy->easy_conn->newurl = NULL;
}
easy->result = Curl_done(&easy->easy_conn, CURLE_OK); easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
if(easy->result == CURLE_OK) if(easy->result == CURLE_OK)
easy->result = Curl_follow(easy->easy_handle, newurl); easy->result = Curl_follow(easy->easy_handle, newurl, retry);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
easy->state = CURLM_STATE_CONNECT; multistate(easy, CURLM_STATE_CONNECT);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
else
/* Since we "took it", we are in charge of freeing this on
failure */
free(newurl);
} }
else { else {
easy->state = CURLM_STATE_DONE; /* after the transfer is done, go DONE */
multistate(easy, CURLM_STATE_DONE);
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
} }
} }
@@ -530,7 +671,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
/* after we have DONE what we're supposed to do, go COMPLETED, and /* after we have DONE what we're supposed to do, go COMPLETED, and
it doesn't matter what the Curl_done() returned! */ it doesn't matter what the Curl_done() returned! */
easy->state = CURLM_STATE_COMPLETED; multistate(easy, CURLM_STATE_COMPLETED);
break; break;
case CURLM_STATE_COMPLETED: case CURLM_STATE_COMPLETED:
@@ -548,7 +689,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
/* /*
* If an error was returned, and we aren't in completed state now, * If an error was returned, and we aren't in completed state now,
* then we go to completed and consider this transfer aborted. */ * then we go to completed and consider this transfer aborted. */
easy->state = CURLM_STATE_COMPLETED; multistate(easy, CURLM_STATE_COMPLETED);
} }
else else
/* this one still lives! */ /* this one still lives! */
@@ -577,13 +718,19 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
multi->num_msgs++; /* increase message counter */ multi->num_msgs++; /* increase message counter */
} }
easy = easy->next; /* operate on next handle */ easy = easy->next; /* operate on next handle */
} }
return result; return result;
} }
/* This is called when an easy handle is cleanup'ed that is part of a multi
handle */
void Curl_multi_rmeasy(void *multi_handle, CURL *easy_handle)
{
curl_multi_remove_handle(multi_handle, easy_handle);
}
CURLMcode curl_multi_cleanup(CURLM *multi_handle) CURLMcode curl_multi_cleanup(CURLM *multi_handle)
{ {
struct Curl_multi *multi=(struct Curl_multi *)multi_handle; struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
@@ -600,6 +747,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
nexteasy=easy->next; nexteasy=easy->next;
/* clear out the usage of the shared DNS cache */ /* clear out the usage of the shared DNS cache */
easy->easy_handle->hostcache = NULL; easy->easy_handle->hostcache = NULL;
Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
if (easy->msg) if (easy->msg)
free(easy->msg); free(easy->msg);

30
lib/multiif.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef __MULTIIF_H
#define __MULTIIF_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/*
* Prototypes for library-wide functions provided by multi.c
*/
void Curl_multi_rmeasy(void *multi, CURL *data);
#endif /* __MULTIIF_H */

View File

@@ -86,11 +86,14 @@
static time_t Curl_parsedate(const char *date); static time_t Curl_parsedate(const char *date);
static const char *wkday[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; const char * const Curl_wkday[] =
static const char *weekday[] = { "Monday", "Tuesday", "Wednesday", "Thursday", {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
"Friday", "Saturday", "Sunday" }; static const char * const weekday[] =
static const char *month[]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", { "Monday", "Tuesday", "Wednesday", "Thursday",
"Aug", "Sep", "Oct", "Nov", "Dec" }; "Friday", "Saturday", "Sunday" };
const char * const Curl_month[]=
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
struct tzinfo { struct tzinfo {
const char *name; const char *name;
@@ -153,12 +156,12 @@ static const struct tzinfo tz[]= {
static int checkday(char *check, size_t len) static int checkday(char *check, size_t len)
{ {
int i; int i;
const char **what; const char * const *what;
bool found= FALSE; bool found= FALSE;
if(len > 3) if(len > 3)
what = &weekday[0]; what = &weekday[0];
else else
what = &wkday[0]; what = &Curl_wkday[0];
for(i=0; i<7; i++) { for(i=0; i<7; i++) {
if(curl_strequal(check, what[0])) { if(curl_strequal(check, what[0])) {
found=TRUE; found=TRUE;
@@ -172,10 +175,10 @@ static int checkday(char *check, size_t len)
static int checkmonth(char *check) static int checkmonth(char *check)
{ {
int i; int i;
const char **what; const char * const *what;
bool found= FALSE; bool found= FALSE;
what = &month[0]; what = &Curl_month[0];
for(i=0; i<12; i++) { for(i=0; i<12; i++) {
if(curl_strequal(check, what[0])) { if(curl_strequal(check, what[0])) {
found=TRUE; found=TRUE;

28
lib/parsedate.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef __PARSEDATE_H
#define __PARSEDATEL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
extern const char * const Curl_wkday[7];
extern const char * const Curl_month[12];
#endif

View File

@@ -297,13 +297,15 @@ int
Curl_sec_read_msg(struct connectdata *conn, char *s, int level) Curl_sec_read_msg(struct connectdata *conn, char *s, int level)
{ {
int len; int len;
char *buf; unsigned char *buf;
int code; int code;
buf = malloc(strlen(s)); len = Curl_base64_decode(s + 4, &buf); /* XXX */
len = Curl_base64_decode(s + 4, buf); /* XXX */ if(len > 0)
len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);
else
return -1;
len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);
if(len < 0) { if(len < 0) {
free(buf); free(buf);
return -1; return -1;
@@ -314,10 +316,10 @@ Curl_sec_read_msg(struct connectdata *conn, char *s, int level)
if(buf[3] == '-') if(buf[3] == '-')
code = 0; code = 0;
else else
sscanf(buf, "%d", &code); sscanf((char *)buf, "%d", &code);
if(buf[len-1] == '\n') if(buf[len-1] == '\n')
buf[len-1] = '\0'; buf[len-1] = '\0';
strcpy(s, buf); strcpy(s, (char *)buf);
free(buf); free(buf);
return code; return code;
} }

View File

@@ -23,13 +23,14 @@
#include "setup.h" #include "setup.h"
#ifdef HAVE_SYS_SELECT_H #include <errno.h>
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@@ -38,6 +39,15 @@
#error "We can't compile without select() support!" #error "We can't compile without select() support!"
#endif #endif
#ifdef __BEOS__
/* BeOS has FD_SET defined in socket.h */
#include <socket.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "connect.h"
#include "select.h" #include "select.h"
#ifdef WIN32 #ifdef WIN32
@@ -76,7 +86,9 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
num++; num++;
} }
r = poll(pfd, num, timeout_ms); do {
r = poll(pfd, num, timeout_ms);
} while((r == -1) && (errno == EINTR));
if (r < 0) if (r < 0)
return -1; return -1;
@@ -138,7 +150,9 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
maxfd = writefd; maxfd = writefd;
} }
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout); do {
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
} while((r == -1) && (Curl_ourerrno() == EINTR));
if (r < 0) if (r < 0)
return -1; return -1;
@@ -175,8 +189,11 @@ int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
*/ */
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
{ {
int r;
#ifdef HAVE_POLL_FINE #ifdef HAVE_POLL_FINE
return poll(ufds, nfds, timeout_ms); do {
r = poll(ufds, nfds, timeout_ms);
} while((r == -1) && (errno == EINTR));
#else #else
struct timeval timeout; struct timeval timeout;
struct timeval *ptimeout; struct timeval *ptimeout;
@@ -184,7 +201,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
fd_set fds_write; fd_set fds_write;
fd_set fds_err; fd_set fds_err;
curl_socket_t maxfd; curl_socket_t maxfd;
int r;
unsigned int i; unsigned int i;
FD_ZERO(&fds_read); FD_ZERO(&fds_read);
@@ -219,7 +235,9 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
ptimeout = &timeout; ptimeout = &timeout;
} }
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); do {
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
} while((r == -1) && (Curl_ourerrno() == EINTR));
if (r < 0) if (r < 0)
return -1; return -1;
@@ -240,7 +258,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
if (ufds[i].revents != 0) if (ufds[i].revents != 0)
r++; r++;
} }
return r;
#endif #endif
return r;
} }

View File

@@ -154,22 +154,22 @@ void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
void Curl_failf(struct SessionHandle *data, const char *fmt, ...) void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
{ {
va_list ap; va_list ap;
size_t len;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
if(data->set.errorbuffer && !data->state.errorbuf) { if(data->set.errorbuffer && !data->state.errorbuf) {
vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap); snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
data->state.errorbuf = TRUE; /* wrote error string */ data->state.errorbuf = TRUE; /* wrote error string */
} }
if(data->set.verbose) { if(data->set.verbose) {
size_t len; len = strlen(data->state.buffer);
if(len < BUFSIZE - 1) {
vsnprintf(data->state.buffer, BUFSIZE, fmt, ap); data->state.buffer[len] = '\n';
len = strlen(data->state.buffer); data->state.buffer[++len] = '\0';
}
if(len < BUFSIZE - 1) { Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
data->state.buffer[len] = '\n';
data->state.buffer[++len] = '\0';
}
Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
} }
va_end(ap); va_end(ap);
@@ -204,8 +204,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
break; break;
if(data->set.verbose) if(data->set.verbose)
Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written, Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written, conn);
conn->host.dispname);
if((size_t)bytes_written != write_len) { if((size_t)bytes_written != write_len) {
/* if not all was written at once, we must advance the pointer, decrease /* if not all was written at once, we must advance the pointer, decrease
@@ -468,18 +467,22 @@ static int showit(struct SessionHandle *data, curl_infotype type,
} }
int Curl_debug(struct SessionHandle *data, curl_infotype type, int Curl_debug(struct SessionHandle *data, curl_infotype type,
char *ptr, size_t size, char *host) char *ptr, size_t size,
struct connectdata *conn)
{ {
int rc; int rc;
if(data->set.printhost && host) { if(data->set.printhost && conn && conn->host.dispname) {
char buffer[160]; char buffer[160];
const char *t=NULL; const char *t=NULL;
const char *w="Data";
switch (type) { switch (type) {
case CURLINFO_HEADER_IN: case CURLINFO_HEADER_IN:
w = "Header";
case CURLINFO_DATA_IN: case CURLINFO_DATA_IN:
t = "from"; t = "from";
break; break;
case CURLINFO_HEADER_OUT: case CURLINFO_HEADER_OUT:
w = "Header";
case CURLINFO_DATA_OUT: case CURLINFO_DATA_OUT:
t = "to"; t = "to";
break; break;
@@ -488,7 +491,10 @@ int Curl_debug(struct SessionHandle *data, curl_infotype type,
} }
if(t) { if(t) {
snprintf(buffer, sizeof(buffer), "[Data %s %s]", t, host); snprintf(buffer, sizeof(buffer), "[%s %s %s%s]", w, t,
conn->xfertype==NORMAL?"":
(conn->xfertype==SOURCE3RD?"source ":"target "),
conn->host.dispname);
rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer)); rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
if(rc) if(rc)
return rc; return rc;

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -62,7 +62,8 @@ CURLcode Curl_write(struct connectdata *conn,
/* the function used to output verbose information */ /* the function used to output verbose information */
int Curl_debug(struct SessionHandle *handle, curl_infotype type, int Curl_debug(struct SessionHandle *handle, curl_infotype type,
char *data, size_t size, char *host); char *data, size_t size,
struct connectdata *conn);
#endif #endif

View File

@@ -160,17 +160,6 @@ typedef unsigned char bool;
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */ #define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
#endif #endif
#if (defined(ENABLE_IPV6) || defined(CURLDEBUG)) && defined(_MSC_VER) && \
(!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500)
/*
* Needed to pull in the real getaddrinfo() and not the inline version
* in <wspiAPI.H> which doesn't support IPv6 (IPv4 only). <wspiAPI.H> is
* included from <ws2tcpip.h> for <= 0x0500 SDKs.
*/
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#if HAVE_WINSOCK2_H #if HAVE_WINSOCK2_H
#include <winsock2.h> /* required by telnet.c */ #include <winsock2.h> /* required by telnet.c */
#endif #endif

View File

@@ -2,18 +2,18 @@
#define __CURL_SHARE_H #define __CURL_SHARE_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -32,24 +32,17 @@
struct Curl_share { struct Curl_share {
unsigned int specifier; unsigned int specifier;
volatile unsigned int dirty; volatile unsigned int dirty;
curl_lock_function lockfunc; curl_lock_function lockfunc;
curl_unlock_function unlockfunc; curl_unlock_function unlockfunc;
void *clientdata; void *clientdata;
curl_hash *hostcache; struct curl_hash *hostcache;
struct CookieInfo *cookies; struct CookieInfo *cookies;
}; };
CURLSHcode Curl_share_lock ( CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
struct SessionHandle *, curl_lock_access);
curl_lock_data, CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
curl_lock_access
);
CURLSHcode Curl_share_unlock (
struct SessionHandle *,
curl_lock_data
);
#endif /* __CURL_SHARE_H */ #endif /* __CURL_SHARE_H */

View File

@@ -169,7 +169,7 @@ int random_the_seed(struct SessionHandle *data)
/* let the option override the define */ /* let the option override the define */
nread += RAND_load_file((data->set.ssl.random_file? nread += RAND_load_file((data->set.ssl.random_file?
data->set.ssl.random_file:RANDOM_FILE), data->set.ssl.random_file:RANDOM_FILE),
16384); -1); /* -1 to read the entire file */
if(seed_enough(nread)) if(seed_enough(nread))
return nread; return nread;
} }
@@ -231,7 +231,7 @@ int random_the_seed(struct SessionHandle *data)
RAND_file_name(buf, BUFSIZE); RAND_file_name(buf, BUFSIZE);
if(buf[0]) { if(buf[0]) {
/* we got a file name to try */ /* we got a file name to try */
nread += RAND_load_file(buf, 16384); nread += RAND_load_file(buf, -1);
if(seed_enough(nread)) if(seed_enough(nread))
return nread; return nread;
} }
@@ -450,6 +450,11 @@ int cert_stuff(struct connectdata *conn,
} }
ssl=SSL_new(ctx); ssl=SSL_new(ctx);
if (NULL == ssl) {
failf(data,"unable to create an SSL structure\n");
return 0;
}
x509=SSL_get_certificate(ssl); x509=SSL_get_certificate(ssl);
/* This version was provided by Evan Jordan and is supposed to not /* This version was provided by Evan Jordan and is supposed to not
@@ -515,15 +520,18 @@ static int init_ssl=0;
static bool ssl_seeded = FALSE; static bool ssl_seeded = FALSE;
#endif /* USE_SSLEAY */ #endif /* USE_SSLEAY */
/* Global init */ /**
void Curl_SSL_init(void) * Global SSL init
*
* @retval 0 error initializing SSL
* @retval 1 SSL initialized successfully
*/
int Curl_SSL_init(void)
{ {
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
/* make sure this is only done once */ /* make sure this is only done once */
if(0 != init_ssl) if(init_ssl)
return; return 1;
init_ssl++; /* never again */
#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES #ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
ENGINE_load_builtin_engines(); ENGINE_load_builtin_engines();
@@ -533,10 +541,16 @@ void Curl_SSL_init(void)
SSL_load_error_strings(); SSL_load_error_strings();
/* Setup all the global SSL stuff */ /* Setup all the global SSL stuff */
SSLeay_add_ssl_algorithms(); if (!SSLeay_add_ssl_algorithms())
return 0;
init_ssl++; /* never again */
#else #else
/* SSL disabled, do nothing */ /* SSL disabled, do nothing */
#endif #endif
return 1;
} }
/* Global cleanup */ /* Global cleanup */
@@ -784,6 +798,7 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
/* free the cache data */ /* free the cache data */
free(data->state.session); free(data->state.session);
data->state.session = NULL;
} }
#ifdef HAVE_OPENSSL_ENGINE_H #ifdef HAVE_OPENSSL_ENGINE_H
if(data->state.engine) { if(data->state.engine) {
@@ -798,7 +813,7 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
/* /*
* Extract the session id and store it in the session cache. * Extract the session id and store it in the session cache.
*/ */
static int Store_SSL_Session(struct connectdata *conn, static CURLcode Store_SSL_Session(struct connectdata *conn,
struct ssl_connect_data *ssl) struct ssl_connect_data *ssl)
{ {
SSL_SESSION *ssl_sessionid; SSL_SESSION *ssl_sessionid;
@@ -810,7 +825,7 @@ static int Store_SSL_Session(struct connectdata *conn,
clone_host = strdup(conn->host.name); clone_host = strdup(conn->host.name);
if(!clone_host) if(!clone_host)
return -1; /* bail out */ return CURLE_OUT_OF_MEMORY; /* bail out */
/* ask OpenSSL, say please */ /* ask OpenSSL, say please */
@@ -857,9 +872,10 @@ static int Store_SSL_Session(struct connectdata *conn,
store->name = clone_host; /* clone host name */ store->name = clone_host; /* clone host name */
store->remote_port = conn->remote_port; /* port number */ store->remote_port = conn->remote_port; /* port number */
Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config); if (!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
return CURLE_OUT_OF_MEMORY;
return 0; return CURLE_OK;
} }
static int Curl_ASN1_UTCTIME_output(struct connectdata *conn, static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
@@ -1003,6 +1019,7 @@ static CURLcode verifyhost(struct connectdata *conn,
#else #else
struct in_addr addr; struct in_addr addr;
#endif #endif
CURLcode res = CURLE_OK;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip && if(conn->bits.ipv6_ip &&
@@ -1131,8 +1148,7 @@ static CURLcode verifyhost(struct connectdata *conn,
if(data->set.ssl.verifyhost > 1) { if(data->set.ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name '%s' does not match " failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", peer_CN, conn->host.dispname); "target host name '%s'", peer_CN, conn->host.dispname);
OPENSSL_free(peer_CN); res = CURLE_SSL_PEER_CERTIFICATE;
return CURLE_SSL_PEER_CERTIFICATE ;
} }
else else
infof(data, "\t common name: %s (does not match '%s')\n", infof(data, "\t common name: %s (does not match '%s')\n",
@@ -1140,10 +1156,11 @@ static CURLcode verifyhost(struct connectdata *conn,
} }
else { else {
infof(data, "\t common name: %s (matched)\n", peer_CN); infof(data, "\t common name: %s (matched)\n", peer_CN);
OPENSSL_free(peer_CN);
} }
if(peer_CN)
OPENSSL_free(peer_CN);
} }
return CURLE_OK; return res;
} }
#endif #endif
@@ -1312,9 +1329,16 @@ Curl_SSLConnect(struct connectdata *conn,
#ifdef SSL_CTRL_SET_MSG_CALLBACK #ifdef SSL_CTRL_SET_MSG_CALLBACK
if (data->set.fdebug) { if (data->set.fdebug) {
SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK, if (!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
ssl_tls_trace); ssl_tls_trace)) {
SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, conn); failf(data, "SSL: couldn't set callback!");
return CURLE_SSL_CONNECT_ERROR;
}
if (!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, conn)) {
failf(data, "SSL: couldn't set callback argument!");
return CURLE_SSL_CONNECT_ERROR;
}
} }
#endif #endif
@@ -1408,6 +1432,10 @@ Curl_SSLConnect(struct connectdata *conn,
/* Lets make an SSL structure */ /* Lets make an SSL structure */
connssl->handle = SSL_new(connssl->ctx); connssl->handle = SSL_new(connssl->ctx);
if (!connssl->handle) {
failf(data, "SSL: couldn't create a context (handle)!");
return CURLE_OUT_OF_MEMORY;
}
SSL_set_connect_state(connssl->handle); SSL_set_connect_state(connssl->handle);
connssl->server_cert = 0x0; connssl->server_cert = 0x0;
@@ -1417,14 +1445,22 @@ Curl_SSLConnect(struct connectdata *conn,
can/should use here! */ can/should use here! */
if(!Get_SSL_Session(conn, &ssl_sessionid)) { if(!Get_SSL_Session(conn, &ssl_sessionid)) {
/* we got a session id, use it! */ /* we got a session id, use it! */
SSL_set_session(connssl->handle, ssl_sessionid); 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 */ /* Informational message */
infof (data, "SSL re-using session ID\n"); infof (data, "SSL re-using session ID\n");
} }
} }
/* pass the raw socket into the SSL layers */ /* pass the raw socket into the SSL layers */
SSL_set_fd(connssl->handle, sockfd); if (!SSL_set_fd(connssl->handle, sockfd)) {
failf(data, "SSL: SSL_set_fd failed: %s",
ERR_error_string(ERR_get_error(),NULL));
return CURLE_SSL_CONNECT_ERROR;
}
while(1) { while(1) {
int writefd; int writefd;
@@ -1562,7 +1598,11 @@ Curl_SSLConnect(struct connectdata *conn,
if(!ssl_sessionid) { if(!ssl_sessionid) {
/* Since this is not a cached session ID, then we want to stach this one /* Since this is not a cached session ID, then we want to stach this one
in the cache! */ in the cache! */
Store_SSL_Session(conn, connssl); retcode = Store_SSL_Session(conn, connssl);
if(retcode) {
failf(data,"failure to store ssl session");
return retcode;
}
} }
@@ -1584,6 +1624,7 @@ Curl_SSLConnect(struct connectdata *conn,
if(!str) { if(!str) {
failf(data, "SSL: couldn't get X509-subject!"); failf(data, "SSL: couldn't get X509-subject!");
X509_free(connssl->server_cert); X509_free(connssl->server_cert);
connssl->server_cert = NULL;
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
infof(data, "\t subject: %s\n", str); infof(data, "\t subject: %s\n", str);
@@ -1599,6 +1640,7 @@ Curl_SSLConnect(struct connectdata *conn,
retcode = verifyhost(conn, connssl->server_cert); retcode = verifyhost(conn, connssl->server_cert);
if(retcode) { if(retcode) {
X509_free(connssl->server_cert); X509_free(connssl->server_cert);
connssl->server_cert = NULL;
return retcode; return retcode;
} }
} }
@@ -1636,6 +1678,7 @@ Curl_SSLConnect(struct connectdata *conn,
} }
X509_free(connssl->server_cert); X509_free(connssl->server_cert);
connssl->server_cert = NULL;
#else /* USE_SSLEAY */ #else /* USE_SSLEAY */
(void)conn; (void)conn;
(void)sockindex; (void)sockindex;

View File

@@ -25,7 +25,7 @@
#include "urldata.h" #include "urldata.h"
CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex); CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex);
void Curl_SSL_init(void); /* Global SSL init */ int Curl_SSL_init(void); /* Global SSL init */
void Curl_SSL_cleanup(void); /* Global SSL cleanup */ void Curl_SSL_cleanup(void); /* Global SSL cleanup */
/* init the SSL session ID cache */ /* init the SSL session ID cache */

View File

@@ -236,6 +236,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_SEND_FAIL_REWIND: case CURLE_SEND_FAIL_REWIND:
return "Send failed since rewinding of the data stream failed"; return "Send failed since rewinding of the data stream failed";
case CURLE_LOGIN_DENIED:
return "FTP: login denied";;
case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */ case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */
case CURLE_MALFORMAT_USER: /* not used by current libcurl */ case CURLE_MALFORMAT_USER: /* not used by current libcurl */
case CURLE_BAD_CALLING_ORDER: /* not used by current libcurl */ case CURLE_BAD_CALLING_ORDER: /* not used by current libcurl */

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -1065,7 +1065,7 @@ CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
return CURLE_OK; return CURLE_OK;
} }
CURLcode Curl_telnet(struct connectdata *conn) CURLcode Curl_telnet(struct connectdata *conn, bool *done)
{ {
CURLcode code; CURLcode code;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@@ -1093,6 +1093,8 @@ CURLcode Curl_telnet(struct connectdata *conn)
char *buf = data->state.buffer; char *buf = data->state.buffer;
struct TELNET *tn; struct TELNET *tn;
*done = TRUE; /* uncontionally */
code = init_telnet(conn); code = init_telnet(conn);
if(code) if(code)
return code; return code;

View File

@@ -2,18 +2,18 @@
#define __TELNET_H #define __TELNET_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
* / __| | | | |_) | | * / __| | | | |_) | |
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html. * are also available at http://curl.haxx.se/docs/copyright.html.
* *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell * 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 * copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file. * furnished to do so, under the terms of the COPYING file.
@@ -24,7 +24,7 @@
* $Id$ * $Id$
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_TELNET #ifndef CURL_DISABLE_TELNET
CURLcode Curl_telnet(struct connectdata *conn); CURLcode Curl_telnet(struct connectdata *conn, bool *done);
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode); CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
#endif #endif
#endif #endif

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -242,6 +242,19 @@ CURLcode Curl_readrewind(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
#ifdef USE_SSLEAY
static int data_pending(struct connectdata *conn)
{
if(conn->ssl[FIRSTSOCKET].handle)
/* SSL is in use */
return SSL_pending(conn->ssl[FIRSTSOCKET].handle);
return 0; /* nothing */
}
#else
/* non-SSL never have pending data */
#define data_pending(x) 0
#endif
/* /*
* Curl_readwrite() is the low-level function to be called when data is to * Curl_readwrite() is the low-level function to be called when data is to
@@ -285,7 +298,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
read or we get a EWOULDBLOCK */ read or we get a EWOULDBLOCK */
do { do {
size_t buffersize = data->set.buffer_size? size_t buffersize = data->set.buffer_size?
data->set.buffer_size:BUFSIZE -1; data->set.buffer_size:BUFSIZE;
/* receive data from the network! */ /* receive data from the network! */
int readrc = Curl_read(conn, conn->sockfd, k->buf, buffersize, &nread); int readrc = Curl_read(conn, conn->sockfd, k->buf, buffersize, &nread);
@@ -464,7 +477,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->write_after_100_header = FALSE; k->write_after_100_header = FALSE;
k->keepon |= KEEP_WRITE; k->keepon |= KEEP_WRITE;
k->wkeepfd = k->writefd;
} }
} }
else else
@@ -529,6 +541,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(result) if(result)
return result; return result;
if(conn->bits.rewindaftersend) {
/* We rewind after a complete send, so thus we continue
sending now */
infof(data, "Keep sending data to get tossed away!\n");
k->keepon |= KEEP_WRITE;
}
} }
#endif /* CURL_DISABLE_HTTP */ #endif /* CURL_DISABLE_HTTP */
@@ -936,7 +955,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose) if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN, Curl_debug(data, CURLINFO_HEADER_IN,
k->p, k->hbuflen, conn->host.dispname); k->p, k->hbuflen, conn);
result = Curl_client_write(data, writetype, k->p, k->hbuflen); result = Curl_client_write(data, writetype, k->p, k->hbuflen);
if(result) if(result)
@@ -1033,14 +1052,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose) { if(data->set.verbose) {
if(k->badheader) { if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
k->hbuflen, conn->host.dispname); k->hbuflen, conn);
if(k->badheader == HEADER_PARTHEADER) if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, conn);
conn->host.dispname);
} }
else else
Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, Curl_debug(data, CURLINFO_DATA_IN, k->str, nread, conn);
conn->host.dispname);
} }
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
@@ -1150,7 +1167,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
k->keepon &= ~KEEP_READ; k->keepon &= ~KEEP_READ;
} }
} while(0); } while(data_pending(conn));
} /* if( read from socket ) */ } /* if( read from socket ) */
@@ -1192,7 +1209,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
go into the Expect: 100 state and await such a header */ go into the Expect: 100 state and await such a header */
k->wait100_after_headers = FALSE; /* headers sent */ k->wait100_after_headers = FALSE; /* headers sent */
k->write_after_100_header = TRUE; /* wait for the header */ k->write_after_100_header = TRUE; /* wait for the header */
k->wkeepfd = k->writefd; /* set the keeper variable */
k->keepon &= ~KEEP_WRITE; /* disable writing */ k->keepon &= ~KEEP_WRITE; /* disable writing */
k->start100 = Curl_tvnow(); /* timeout count starts now */ k->start100 = Curl_tvnow(); /* timeout count starts now */
didwhat &= ~KEEP_WRITE; /* we didn't write anything actually */ didwhat &= ~KEEP_WRITE; /* we didn't write anything actually */
@@ -1272,7 +1288,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(data->set.verbose) if(data->set.verbose)
/* show the data before we change the pointer upload_fromhere */ /* show the data before we change the pointer upload_fromhere */
Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere, Curl_debug(data, CURLINFO_DATA_OUT, conn->upload_fromhere,
bytes_written, conn->host.dispname); bytes_written, conn);
if(conn->upload_present != bytes_written) { if(conn->upload_present != bytes_written) {
/* we only wrote a part of the buffer (if anything), deal with it! */ /* we only wrote a part of the buffer (if anything), deal with it! */
@@ -1336,7 +1352,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* we've waited long enough, continue anyway */ /* we've waited long enough, continue anyway */
k->write_after_100_header = FALSE; k->write_after_100_header = FALSE;
k->keepon |= KEEP_WRITE; k->keepon |= KEEP_WRITE;
k->wkeepfd = k->writefd;
} }
} }
} }
@@ -1463,12 +1478,6 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
k->keepon |= KEEP_WRITE; k->keepon |= KEEP_WRITE;
} }
} }
/* get these in backup variables to be able to restore them on each lap in
the select() loop */
k->rkeepfd = k->readfd;
k->wkeepfd = k->writefd;
} }
return CURLE_OK; return CURLE_OK;
@@ -1491,7 +1500,6 @@ void Curl_single_fdset(struct connectdata *conn,
if(conn->keep.keepon & KEEP_READ) { if(conn->keep.keepon & KEEP_READ) {
FD_SET(conn->sockfd, read_fd_set); FD_SET(conn->sockfd, read_fd_set);
*max_fd = conn->sockfd; *max_fd = conn->sockfd;
conn->keep.readfdp = read_fd_set; /* store the address of the set */
} }
if(conn->keep.keepon & KEEP_WRITE) { if(conn->keep.keepon & KEEP_WRITE) {
FD_SET(conn->writesockfd, write_fd_set); FD_SET(conn->writesockfd, write_fd_set);
@@ -1500,7 +1508,6 @@ void Curl_single_fdset(struct connectdata *conn,
to compare it nicely */ to compare it nicely */
if((int)conn->writesockfd > *max_fd) if((int)conn->writesockfd > *max_fd)
*max_fd = conn->writesockfd; *max_fd = conn->writesockfd;
conn->keep.writefdp = write_fd_set; /* store the address of the set */
} }
/* we don't use exceptions, only touch that one to prevent compiler /* we don't use exceptions, only touch that one to prevent compiler
warnings! */ warnings! */
@@ -1543,9 +1550,6 @@ Transfer(struct connectdata *conn)
if(!conn->bits.getheader && conn->bits.no_body) if(!conn->bits.getheader && conn->bits.no_body)
return CURLE_OK; return CURLE_OK;
k->writefdp = &k->writefd; /* store the address of the set */
k->readfdp = &k->readfd; /* store the address of the set */
while (!done) { while (!done) {
int fd_read; int fd_read;
int fd_write; int fd_write;
@@ -1742,9 +1746,11 @@ static void strcpy_url(char *output, char *url)
* as given by the remote server and set up the new URL to request. * as given by the remote server and set up the new URL to request.
*/ */
CURLcode Curl_follow(struct SessionHandle *data, CURLcode Curl_follow(struct SessionHandle *data,
char *newurl) /* this 'newurl' is the Location: string, char *newurl, /* this 'newurl' is the Location: string,
and it must be malloc()ed before passed and it must be malloc()ed before passed
here */ here */
bool retry) /* set TRUE if this is a request retry as
opposed to a real redirect following */
{ {
/* Location: redirect */ /* Location: redirect */
char prot[16]; /* URL protocol string storage */ char prot[16]; /* URL protocol string storage */
@@ -1758,8 +1764,9 @@ CURLcode Curl_follow(struct SessionHandle *data,
return CURLE_TOO_MANY_REDIRECTS; return CURLE_TOO_MANY_REDIRECTS;
} }
/* mark the next request as a followed location: */ if(!retry)
data->state.this_is_a_follow = TRUE; /* mark the next request as a followed location: */
data->state.this_is_a_follow = TRUE;
data->set.followlocation++; /* count location-followers */ data->set.followlocation++; /* count location-followers */
@@ -2040,9 +2047,11 @@ Curl_connect_host(struct SessionHandle *data,
do { do {
bool async; bool async;
bool protocol_done=TRUE; /* will be TRUE always since this is only used
within the easy interface */
Curl_pgrsTime(data, TIMER_STARTSINGLE); Curl_pgrsTime(data, TIMER_STARTSINGLE);
data->change.url_changed = FALSE; data->change.url_changed = FALSE;
res = Curl_connect(data, conn, &async); res = Curl_connect(data, conn, &async, &protocol_done);
if((CURLE_OK == res) && async) { if((CURLE_OK == res) && async) {
/* Now, if async is TRUE here, we need to wait for the name /* Now, if async is TRUE here, we need to wait for the name
@@ -2050,7 +2059,10 @@ Curl_connect_host(struct SessionHandle *data,
res = Curl_wait_for_resolv(*conn, NULL); res = Curl_wait_for_resolv(*conn, NULL);
if(CURLE_OK == res) if(CURLE_OK == res)
/* Resolved, continue with the connection */ /* Resolved, continue with the connection */
res = Curl_async_resolved(*conn); res = Curl_async_resolved(*conn, &protocol_done);
else
/* if we can't resolve, we kill this "connection" now */
(void)Curl_disconnect(*conn);
} }
if(res) if(res)
break; break;
@@ -2063,7 +2075,7 @@ Curl_connect_host(struct SessionHandle *data,
res = Curl_done(conn, res); res = Curl_done(conn, res);
if(CURLE_OK == res) { if(CURLE_OK == res) {
char *gotourl = strdup(data->change.url); char *gotourl = strdup(data->change.url);
res = Curl_follow(data, gotourl); res = Curl_follow(data, gotourl, FALSE);
if(res) if(res)
free(gotourl); free(gotourl);
} }
@@ -2073,7 +2085,32 @@ Curl_connect_host(struct SessionHandle *data,
return res; return res;
} }
/* Returns TRUE and sets '*url' if a request retry is wanted */
bool Curl_retry_request(struct connectdata *conn,
char **url)
{
bool retry = FALSE;
if((conn->keep.bytecount+conn->headerbytecount == 0) &&
conn->bits.reuse) {
/* We got no data and we attempted to re-use a connection. This might
happen if the connection was left alive when we were done using it
before, but that was closed when we wanted to read from it again. Bad
luck. Retry the same request on a fresh connect! */
infof(conn->data, "Connection died, retrying a fresh connect\n");
*url = strdup(conn->data->change.url);
conn->bits.close = TRUE; /* close this connection */
conn->bits.retry = TRUE; /* mark this as a connection we're about
to retry. Marking it this way should
prevent i.e HTTP transfers to return
error just because nothing has been
transfered! */
retry = TRUE;
}
return retry;
}
/* /*
* Curl_perform() is the internal high-level function that gets called by the * Curl_perform() is the internal high-level function that gets called by the
@@ -2086,6 +2123,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
CURLcode res2; CURLcode res2;
struct connectdata *conn=NULL; struct connectdata *conn=NULL;
char *newurl = NULL; /* possibly a new URL to follow to! */ char *newurl = NULL; /* possibly a new URL to follow to! */
bool retry = FALSE;
data->state.used_interface = Curl_if_easy; data->state.used_interface = Curl_if_easy;
@@ -2104,42 +2142,26 @@ CURLcode Curl_perform(struct SessionHandle *data)
res = Curl_connect_host(data, &conn); /* primary connection */ res = Curl_connect_host(data, &conn); /* primary connection */
if(res == CURLE_OK) { if(res == CURLE_OK) {
if (data->set.source_host) /* 3rd party transfer */ if (data->set.source_url) /* 3rd party transfer */
res = Curl_pretransfersec(conn); res = Curl_second_connect(conn);
else else
conn->sec_conn = NULL; conn->sec_conn = NULL;
} }
if(res == CURLE_OK) { if(res == CURLE_OK) {
bool do_done;
res = Curl_do(&conn); res = Curl_do(&conn, &do_done);
/* for non 3rd party transfer only */ /* for non 3rd party transfer only */
if(res == CURLE_OK && !data->set.source_host) { if(res == CURLE_OK && !data->set.source_url) {
res = Transfer(conn); /* now fetch that URL please */ res = Transfer(conn); /* now fetch that URL please */
if(res == CURLE_OK) { if(res == CURLE_OK) {
retry = Curl_retry_request(conn, &newurl);
if((conn->keep.bytecount+conn->headerbytecount == 0) && if(!retry)
conn->bits.reuse) {
/* We got no data and we attempted to re-use a connection. This
might happen if the connection was left alive when we were done
using it before, but that was closed when we wanted to read
from it again. Bad luck. Retry the same request on a fresh
connect! */
infof(data, "Connection died, retrying a fresh connect\n");
newurl = strdup(conn->data->change.url);
conn->bits.close = TRUE; /* close this connection */
conn->bits.retry = TRUE; /* mark this as a connection we're about
to retry. Marking it this way should
prevent i.e HTTP transfers to return
error just because nothing has been
transfered! */
}
else
/* /*
* We must duplicate the new URL here as the connection data * We must duplicate the new URL here as the connection data may
* may be free()ed in the Curl_done() function. * be free()ed in the Curl_done() function.
*/ */
newurl = conn->newurl?strdup(conn->newurl):NULL; newurl = conn->newurl?strdup(conn->newurl):NULL;
} }
@@ -2174,7 +2196,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
*/ */
if((res == CURLE_OK) && newurl) { if((res == CURLE_OK) && newurl) {
res = Curl_follow(data, newurl); res = Curl_follow(data, newurl, retry);
if(CURLE_OK == res) { if(CURLE_OK == res) {
newurl = NULL; newurl = NULL;
continue; continue;
@@ -2235,36 +2257,34 @@ Curl_Transfer(struct connectdata *c_conn, /* connection data */
} }
/* /*
* Curl_pretransfersec() prepares the secondary connection (used for 3rd party * Curl_second_connect() makes the secondary connection (used for 3rd party
* FTP transfers). * FTP transfers).
*/ */
CURLcode Curl_pretransfersec(struct connectdata *conn) CURLcode Curl_second_connect(struct connectdata *conn)
{ {
CURLcode status = CURLE_OK; CURLcode status = CURLE_OK;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct connectdata *sec_conn = NULL; /* secondary connection */ struct connectdata *sec_conn = NULL; /* secondary connection */
bool reuse_fresh_tmp = data->set.reuse_fresh; bool backup_reuse_fresh = data->set.reuse_fresh;
char *backup_userpwd = data->set.userpwd;
/* update data with source host options */
char *url = aprintf( "%s://%s/", conn->protostr, data->set.source_host);
if(!url)
return CURLE_OUT_OF_MEMORY;
if(data->change.url_alloc) if(data->change.url_alloc)
free(data->change.url); free(data->change.url);
data->change.url_alloc = TRUE; data->change.url_alloc = FALSE;
data->change.url = url; data->change.url = data->set.source_url;
data->set.ftpport = data->set.source_port;
data->set.userpwd = data->set.source_userpwd;
/* We must never actually alter 'data->set' properties, so we restore the
backed up values afterwards! */
#if 0
/* if both remote hosts are the same host - create new connection */ /* if both remote hosts are the same host - create new connection */
if (strequal(conn->host.dispname, data->set.source_host)) if (strequal(conn->host.dispname, data->set.source_host))
/* NOTE: this is restored back to the original value after the connect is #endif
done */
data->set.reuse_fresh = TRUE; data->set.reuse_fresh = TRUE;
data->set.userpwd = data->set.source_userpwd;
/* secondary connection */ /* secondary connection */
status = Curl_connect_host(data, &sec_conn); status = Curl_connect_host(data, &sec_conn);
if(CURLE_OK == status) { if(CURLE_OK == status) {
@@ -2274,7 +2294,8 @@ CURLcode Curl_pretransfersec(struct connectdata *conn)
conn->sec_conn = sec_conn; conn->sec_conn = sec_conn;
} }
data->set.reuse_fresh = reuse_fresh_tmp; data->set.reuse_fresh = backup_reuse_fresh;
data->set.userpwd = backup_userpwd;
return status; return status;
} }

View File

@@ -24,9 +24,9 @@
***************************************************************************/ ***************************************************************************/
CURLcode Curl_perform(struct SessionHandle *data); CURLcode Curl_perform(struct SessionHandle *data);
CURLcode Curl_pretransfer(struct SessionHandle *data); CURLcode Curl_pretransfer(struct SessionHandle *data);
CURLcode Curl_pretransfersec(struct connectdata *conn); CURLcode Curl_second_connect(struct connectdata *conn);
CURLcode Curl_posttransfer(struct SessionHandle *data); CURLcode Curl_posttransfer(struct SessionHandle *data);
CURLcode Curl_follow(struct SessionHandle *data, char *newurl); CURLcode Curl_follow(struct SessionHandle *data, char *newurl, bool retry);
CURLcode Curl_readwrite(struct connectdata *conn, bool *done); CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
void Curl_single_fdset(struct connectdata *conn, void Curl_single_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
@@ -36,7 +36,7 @@ void Curl_single_fdset(struct connectdata *conn,
CURLcode Curl_readwrite_init(struct connectdata *conn); CURLcode Curl_readwrite_init(struct connectdata *conn);
CURLcode Curl_readrewind(struct connectdata *conn); CURLcode Curl_readrewind(struct connectdata *conn);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp); CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
bool Curl_retry_request(struct connectdata *conn, char **url);
/* This sets up a forthcoming transfer */ /* This sets up a forthcoming transfer */
CURLcode CURLcode
Curl_Transfer (struct connectdata *data, Curl_Transfer (struct connectdata *data,

285
lib/url.c
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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -118,6 +118,7 @@ void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
#include "http_digest.h" #include "http_digest.h"
#include "http_negotiate.h" #include "http_negotiate.h"
#include "select.h" #include "select.h"
#include "multiif.h"
/* And now for the protocols */ /* And now for the protocols */
#include "ftp.h" #include "ftp.h"
@@ -196,6 +197,10 @@ void Curl_safefree(void *ptr)
CURLcode Curl_close(struct SessionHandle *data) CURLcode Curl_close(struct SessionHandle *data)
{ {
if(data->multi) {
/* this handle is still part of a multi handle, take care of this first */
Curl_multi_rmeasy(data->multi, data);
}
/* Loop through all open connections and kill them one by one */ /* Loop through all open connections and kill them one by one */
while(-1 != ConnectionKillOne(data)) while(-1 != ConnectionKillOne(data))
; /* empty loop */ ; /* empty loop */
@@ -774,7 +779,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/ */
data->set.cookiesession = (bool)va_arg(param, long); data->set.cookiesession = (bool)va_arg(param, long);
break; break;
#endif #endif /* CURL_DISABLE_COOKIES */
case CURLOPT_HTTPGET: case CURLOPT_HTTPGET:
/* /*
@@ -813,27 +818,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
and this just changes the actual request keyword */ and this just changes the actual request keyword */
break; break;
case CURLOPT_PROXY:
/*
* Set proxy server:port to use as HTTP proxy.
*
* If the proxy is set to "" we explicitly say that we don't want to use a
* proxy (even though there might be environment variables saying so).
*
* Setting it to NULL, means no proxy but allows the environment variables
* to decide for us.
*/
if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc=FALSE;;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
break;
case CURLOPT_PROXYPORT: case CURLOPT_PROXYPORT:
/* /*
* Explicitly set HTTP proxy port number. * Explicitly set HTTP proxy port number.
@@ -882,6 +866,27 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
break; break;
#endif /* CURL_DISABLE_HTTP */ #endif /* CURL_DISABLE_HTTP */
case CURLOPT_PROXY:
/*
* Set proxy server:port to use as HTTP proxy.
*
* If the proxy is set to "" we explicitly say that we don't want to use a
* proxy (even though there might be environment variables saying so).
*
* Setting it to NULL, means no proxy but allows the environment variables
* to decide for us.
*/
if(data->change.proxy_alloc) {
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc=FALSE;;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
break;
case CURLOPT_WRITEHEADER: case CURLOPT_WRITEHEADER:
/* /*
* Custom pointer to pass the header write callback function * Custom pointer to pass the header write callback function
@@ -1355,19 +1360,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
break; break;
/*********** 3rd party transfer options ***********/ /*********** 3rd party transfer options ***********/
case CURLOPT_SOURCE_HOST: case CURLOPT_SOURCE_URL:
/* /*
* Use SOURCE HOST * SOURCE URL
*/ */
data->set.source_host = va_arg(param, char *); data->set.source_url = va_arg(param, char *);
data->set.printhost = (data->set.source_host != NULL); data->set.printhost = (data->set.source_url != NULL);
break;
case CURLOPT_SOURCE_PORT:
/*
* Use SOURCE PORT
*/
data->set.source_port = va_arg(param, char *);
break; break;
case CURLOPT_SOURCE_USERPWD: case CURLOPT_SOURCE_USERPWD:
@@ -1377,18 +1375,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.source_userpwd = va_arg(param, char *); data->set.source_userpwd = va_arg(param, char *);
break; break;
case CURLOPT_SOURCE_PATH: case CURLOPT_SOURCE_QUOTE:
/* /*
* Use SOURCE PATH * List of RAW FTP commands to use after a connect
*/ */
data->set.source_path = va_arg(param, char *); data->set.source_quote = va_arg(param, struct curl_slist *);
break;
case CURLOPT_PASV_HOST:
/*
* Indicates whether source or target host is passive
*/
data->set.pasvHost = va_arg(param, long)?CURL_SOURCE_PASV:CURL_TARGET_PASV;
break; break;
case CURLOPT_SOURCE_PREQUOTE: case CURLOPT_SOURCE_PREQUOTE:
@@ -1405,6 +1396,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.source_postquote = va_arg(param, struct curl_slist *); data->set.source_postquote = va_arg(param, struct curl_slist *);
break; break;
case CURLOPT_FTP_ACCOUNT:
data->set.ftp_account = va_arg(param, char *);
break;
default: default:
/* unknown tag and its companion, just ignore: */ /* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */ result = CURLE_FAILED_INIT; /* correct this */
@@ -1422,9 +1417,6 @@ CURLcode Curl_disconnect(struct connectdata *conn)
data = conn->data; data = conn->data;
if(conn->dns_entry)
Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
/* scan for DNS cache entries still marked as in use */ /* scan for DNS cache entries still marked as in use */
Curl_hash_apply(data->hostcache, Curl_hash_apply(data->hostcache,
@@ -1505,6 +1497,7 @@ CURLcode Curl_disconnect(struct connectdata *conn)
Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.ref);
Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.host);
Curl_safefree(conn->allocptr.cookiehost); Curl_safefree(conn->allocptr.cookiehost);
Curl_safefree(conn->ip_addr_str);
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
defined(USE_THREADING_GETADDRINFO) defined(USE_THREADING_GETADDRINFO)
@@ -1821,8 +1814,8 @@ static int handleSock5Proxy(const char *proxy_name,
return 1; return 1;
} }
if ((socksreq[0] != 5) || /* version */ /* ignore the first (VER) byte */
(socksreq[1] != 0)) { /* status */ if (socksreq[1] != 0) { /* status */
failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).", failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]); socksreq[0], socksreq[1]);
return 1; return 1;
@@ -1966,6 +1959,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
conn->dns_entry = hostaddr; conn->dns_entry = hostaddr;
conn->ip_addr = addr; conn->ip_addr = addr;
Curl_store_ip_addr(conn);
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
return handleSock5Proxy(conn->proxyuser, return handleSock5Proxy(conn->proxyuser,
conn->proxypasswd, conn->proxypasswd,
@@ -1989,51 +1984,122 @@ static CURLcode ConnectPlease(struct connectdata *conn,
*/ */
static void verboseconnect(struct connectdata *conn) static void verboseconnect(struct connectdata *conn)
{ {
struct SessionHandle *data = conn->data; infof(conn->data, "Connected to %s (%s) port %d\n",
char addrbuf[256];
/* Get a printable version of the network address. */
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
infof(data, "Connected to %s (%s) port %d\n",
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
addrbuf[0] ? addrbuf : "??", conn->port); conn->ip_addr_str, conn->port);
}
CURLcode Curl_protocol_fdset(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp)
{
CURLcode res = CURLE_OK;
if(conn->curl_proto_fdset)
res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp);
return res;
}
CURLcode Curl_doing_fdset(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp)
{
CURLcode res = CURLE_OK;
if(conn && conn->curl_doing_fdset)
res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp);
return res;
}
/*
* We are doing protocol-specific connecting and this is being called over and
* over from the multi interface until the connection phase is done on
* protocol layer.
*/
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
{
CURLcode result=CURLE_OK;
if(conn && conn->curl_connecting) {
*done = FALSE;
result = conn->curl_connecting(conn, done);
}
else
*done = TRUE;
return result;
}
/*
* We are DOING this is being called over and over from the multi interface
* until the DOING phase is done on protocol layer.
*/
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
{
CURLcode result=CURLE_OK;
if(conn && conn->curl_doing) {
*done = FALSE;
result = conn->curl_doing(conn, done);
}
else
*done = TRUE;
return result;
} }
/* /*
* We have discovered that the TCP connection has been successful, we can now * We have discovered that the TCP connection has been successful, we can now
* proceed with some action. * proceed with some action.
* *
* If we're using the multi interface, this host address pointer is most
* likely NULL at this point as we can't keep the resolved info around. This
* may call for some reworking, like a reference counter in the struct or
* something.
*/ */
CURLcode Curl_protocol_connect(struct connectdata *conn) CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
if(conn->bits.tcpconnect) *protocol_done = FALSE;
if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
/* We already are connected, get back. This may happen when the connect /* We already are connected, get back. This may happen when the connect
worked fine in the first call, like when we connect to a local server worked fine in the first call, like when we connect to a local server
or proxy. */ or proxy. Note that we don't know if the protocol is actually done.
Unless this protocol doesn't have any protocol-connect callback, as
then we know we're done. */
if(!conn->curl_connecting)
*protocol_done = TRUE;
return CURLE_OK; return CURLE_OK;
}
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ if(!conn->bits.tcpconnect) {
if(data->set.verbose) Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
verboseconnect(conn);
if(conn->curl_connect) { if(data->set.verbose)
/* is there a protocol-specific connect() procedure? */ verboseconnect(conn);
}
/* set start time here for timeout purposes in the if(!conn->bits.protoconnstart) {
* connect procedure, it is later set again for the if(conn->curl_connect) {
* progress meter purpose */ /* is there a protocol-specific connect() procedure? */
conn->now = Curl_tvnow();
/* Call the protocol-specific connect function */ /* Set start time here for timeout purposes in the connect procedure, it
result = conn->curl_connect(conn); is later set again for the progress meter purpose */
conn->now = Curl_tvnow();
/* Call the protocol-specific connect function */
result = conn->curl_connect(conn, protocol_done);
}
else
*protocol_done = TRUE;
/* it has started, possibly even completed but that knowledge isn't stored
in this bit! */
conn->bits.protoconnstart = TRUE;
} }
return result; /* pass back status */ return result; /* pass back status */
@@ -2192,7 +2258,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
to not have to modify everything at once, we allocate a temporary to not have to modify everything at once, we allocate a temporary
connection data struct and fill in for comparison purposes. */ connection data struct and fill in for comparison purposes. */
conn = (struct connectdata *)malloc(sizeof(struct connectdata)); conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
if(!conn) { if(!conn) {
*in_connect = NULL; /* clear the pointer */ *in_connect = NULL; /* clear the pointer */
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -2202,9 +2268,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
any failure */ any failure */
*in_connect = conn; *in_connect = conn;
/* we have to init the struct */
memset(conn, 0, sizeof(struct connectdata));
/* and we setup a few fields in case we end up actually using this struct */ /* and we setup a few fields in case we end up actually using this struct */
conn->data = data; /* remember our daddy */ conn->data = data; /* remember our daddy */
conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
@@ -2259,6 +2322,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(NULL == conn->host.rawalloc) if(NULL == conn->host.rawalloc)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
conn->host.name = conn->host.rawalloc; conn->host.name = conn->host.rawalloc;
conn->host.name[0] = 0;
/************************************************************* /*************************************************************
* Parse the URL. * Parse the URL.
@@ -2348,21 +2412,19 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/* Note: if you add a new protocol, please update the list in /* Note: if you add a new protocol, please update the list in
* lib/version.c too! */ * lib/version.c too! */
if(checkprefix("GOPHER", conn->host.name)) if(checkprefix("GOPHER.", conn->host.name))
strcpy(conn->protostr, "gopher"); strcpy(conn->protostr, "gopher");
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
else if(checkprefix("HTTPS", conn->host.name))
strcpy(conn->protostr, "https");
else if(checkprefix("FTPS", conn->host.name)) else if(checkprefix("FTPS", conn->host.name))
strcpy(conn->protostr, "ftps"); strcpy(conn->protostr, "ftps");
#endif /* USE_SSLEAY */ #endif /* USE_SSLEAY */
else if(checkprefix("FTP", conn->host.name)) else if(checkprefix("FTP.", conn->host.name))
strcpy(conn->protostr, "ftp"); strcpy(conn->protostr, "ftp");
else if(checkprefix("TELNET", conn->host.name)) else if(checkprefix("TELNET.", conn->host.name))
strcpy(conn->protostr, "telnet"); strcpy(conn->protostr, "telnet");
else if (checkprefix("DICT", conn->host.name)) else if (checkprefix("DICT.", conn->host.name))
strcpy(conn->protostr, "DICT"); strcpy(conn->protostr, "DICT");
else if (checkprefix("LDAP", conn->host.name)) else if (checkprefix("LDAP.", conn->host.name))
strcpy(conn->protostr, "LDAP"); strcpy(conn->protostr, "LDAP");
else { else {
strcpy(conn->protostr, "http"); strcpy(conn->protostr, "http");
@@ -2433,6 +2495,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
#ifndef CURL_DISABLE_HTTP
/************************************************************* /*************************************************************
* Detect what (if any) proxy to use * Detect what (if any) proxy to use
*************************************************************/ *************************************************************/
@@ -2597,6 +2660,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(no_proxy) if(no_proxy)
free(no_proxy); free(no_proxy);
} /* if not using proxy */ } /* if not using proxy */
#endif /* CURL_DISABLE_HTTP */
/************************************************************* /*************************************************************
* No protocol part in URL was used, add it! * No protocol part in URL was used, add it!
@@ -2745,6 +2809,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->curl_do_more = Curl_ftp_nextconnect; conn->curl_do_more = Curl_ftp_nextconnect;
conn->curl_done = Curl_ftp_done; conn->curl_done = Curl_ftp_done;
conn->curl_connect = Curl_ftp_connect; conn->curl_connect = Curl_ftp_connect;
conn->curl_connecting = Curl_ftp_multi_statemach;
conn->curl_doing = Curl_ftp_doing;
conn->curl_proto_fdset = Curl_ftp_fdset;
conn->curl_doing_fdset = Curl_ftp_fdset;
conn->curl_disconnect = Curl_ftp_disconnect; conn->curl_disconnect = Curl_ftp_disconnect;
} }
@@ -3397,17 +3465,21 @@ static CURLcode CreateConnection(struct SessionHandle *data,
*/ */
static CURLcode SetupConnection(struct connectdata *conn, static CURLcode SetupConnection(struct connectdata *conn,
struct Curl_dns_entry *hostaddr) struct Curl_dns_entry *hostaddr,
bool *protocol_done)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
Curl_pgrsTime(data, TIMER_NAMELOOKUP); Curl_pgrsTime(data, TIMER_NAMELOOKUP);
if(conn->protocol & PROT_FILE) if(conn->protocol & PROT_FILE) {
/* There's nothing in this function to setup if we're only doing /* There's nothing in this function to setup if we're only doing
a file:// transfer */ a file:// transfer */
*protocol_done = TRUE;
return result; return result;
}
*protocol_done = FALSE; /* default to not done */
/************************************************************* /*************************************************************
* Send user-agent to HTTP proxies even if the target protocol * Send user-agent to HTTP proxies even if the target protocol
@@ -3428,13 +3500,13 @@ static CURLcode SetupConnection(struct connectdata *conn,
conn->headerbytecount = 0; conn->headerbytecount = 0;
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
bool connected; bool connected = FALSE;
/* Connect only if not already connected! */ /* Connect only if not already connected! */
result = ConnectPlease(conn, hostaddr, &connected); result = ConnectPlease(conn, hostaddr, &connected);
if(connected) { if(connected) {
result = Curl_protocol_connect(conn); result = Curl_protocol_connect(conn, protocol_done);
if(CURLE_OK == result) if(CURLE_OK == result)
conn->bits.tcpconnect = TRUE; conn->bits.tcpconnect = TRUE;
} }
@@ -3448,6 +3520,7 @@ static CURLcode SetupConnection(struct connectdata *conn,
else { else {
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
conn->bits.tcpconnect = TRUE; conn->bits.tcpconnect = TRUE;
*protocol_done = TRUE;
if(data->set.verbose) if(data->set.verbose)
verboseconnect(conn); verboseconnect(conn);
} }
@@ -3472,7 +3545,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
CURLcode Curl_connect(struct SessionHandle *data, CURLcode Curl_connect(struct SessionHandle *data,
struct connectdata **in_connect, struct connectdata **in_connect,
bool *asyncp) bool *asyncp,
bool *protocol_done)
{ {
CURLcode code; CURLcode code;
struct Curl_dns_entry *dns; struct Curl_dns_entry *dns;
@@ -3488,7 +3562,7 @@ CURLcode Curl_connect(struct SessionHandle *data,
/* If an address is available it means that we already have the name /* If an address is available it means that we already have the name
resolved, OR it isn't async. resolved, OR it isn't async.
If so => continue connecting from here */ If so => continue connecting from here */
code = SetupConnection(*in_connect, dns); code = SetupConnection(*in_connect, dns, protocol_done);
/* else /* else
response will be received and treated async wise */ response will be received and treated async wise */
} }
@@ -3506,12 +3580,16 @@ CURLcode Curl_connect(struct SessionHandle *data,
} }
/* Call this function after Curl_connect() has returned async=TRUE and /* Call this function after Curl_connect() has returned async=TRUE and
then a successful name resolve has been received */ then a successful name resolve has been received.
CURLcode Curl_async_resolved(struct connectdata *conn)
Note: this function disconnects and frees the conn data in case of
resolve failure */
CURLcode Curl_async_resolved(struct connectdata *conn,
bool *protocol_done)
{ {
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
defined(USE_THREADING_GETADDRINFO) defined(USE_THREADING_GETADDRINFO)
CURLcode code = SetupConnection(conn, conn->async.dns); CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
if(code) if(code)
/* We're not allowed to return failure with memory left allocated /* We're not allowed to return failure with memory left allocated
@@ -3521,6 +3599,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn)
return code; return code;
#else #else
(void)conn; (void)conn;
(void)protocol_done;
return CURLE_OK; return CURLE_OK;
#endif #endif
} }
@@ -3535,12 +3614,16 @@ CURLcode Curl_done(struct connectdata **connp,
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
/* cleanups done even if the connection is re-used */ /* cleanups done even if the connection is re-used */
if(conn->bits.rangestringalloc) { if(conn->bits.rangestringalloc) {
free(conn->range); free(conn->range);
conn->bits.rangestringalloc = FALSE; conn->bits.rangestringalloc = FALSE;
} }
if(conn->dns_entry) {
Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
conn->dns_entry = NULL;
}
/* Cleanup possible redirect junk */ /* Cleanup possible redirect junk */
if(conn->newurl) { if(conn->newurl) {
free(conn->newurl); free(conn->newurl);
@@ -3581,7 +3664,7 @@ CURLcode Curl_done(struct connectdata **connp,
return result; return result;
} }
CURLcode Curl_do(struct connectdata **connp) CURLcode Curl_do(struct connectdata **connp, bool *done)
{ {
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
struct connectdata *conn = *connp; struct connectdata *conn = *connp;
@@ -3591,7 +3674,7 @@ CURLcode Curl_do(struct connectdata **connp)
if(conn->curl_do) { if(conn->curl_do) {
/* generic protocol-specific function pointer set in curl_connect() */ /* generic protocol-specific function pointer set in curl_connect() */
result = conn->curl_do(conn); result = conn->curl_do(conn, done);
/* This was formerly done in transfer.c, but we better do it here */ /* This was formerly done in transfer.c, but we better do it here */
@@ -3611,8 +3694,10 @@ CURLcode Curl_do(struct connectdata **connp)
if(CURLE_OK == result) { if(CURLE_OK == result) {
bool async; bool async;
bool protocol_done = TRUE;
/* Now, redo the connect and get a new connection */ /* Now, redo the connect and get a new connection */
result = Curl_connect(data, connp, &async); result = Curl_connect(data, connp, &async, &protocol_done);
if(CURLE_OK == result) { if(CURLE_OK == result) {
/* We have connected or sent away a name resolve query fine */ /* We have connected or sent away a name resolve query fine */
@@ -3625,13 +3710,13 @@ CURLcode Curl_do(struct connectdata **connp)
return result; return result;
/* Resolved, continue with the connection */ /* Resolved, continue with the connection */
result = Curl_async_resolved(conn); result = Curl_async_resolved(conn, &protocol_done);
if(result) if(result)
return result; return result;
} }
/* ... finally back to actually retry the DO phase */ /* ... finally back to actually retry the DO phase */
result = conn->curl_do(conn); result = conn->curl_do(conn, done);
} }
} }
} }

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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -31,17 +31,28 @@ CURLcode Curl_open(struct SessionHandle **curl);
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...); CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */ CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **, CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
bool *async); bool *async, bool *protocol_connect);
CURLcode Curl_async_resolved(struct connectdata *conn); CURLcode Curl_async_resolved(struct connectdata *conn,
CURLcode Curl_do(struct connectdata **); bool *protocol_connect);
CURLcode Curl_do(struct connectdata **, bool *done);
CURLcode Curl_do_more(struct connectdata *); CURLcode Curl_do_more(struct connectdata *);
CURLcode Curl_done(struct connectdata **, CURLcode); CURLcode Curl_done(struct connectdata **, CURLcode);
CURLcode Curl_disconnect(struct connectdata *); CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn); CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
bool Curl_ssl_config_matches(struct ssl_config_data* data, bool Curl_ssl_config_matches(struct ssl_config_data* data,
struct ssl_config_data* needle); struct ssl_config_data* needle);
bool Curl_clone_ssl_config(struct ssl_config_data* source, bool Curl_clone_ssl_config(struct ssl_config_data* source,
struct ssl_config_data* dest); struct ssl_config_data* dest);
void Curl_free_ssl_config(struct ssl_config_data* sslc); void Curl_free_ssl_config(struct ssl_config_data* sslc);
void Curl_safefree(void *ptr); void Curl_safefree(void *ptr);
CURLcode Curl_protocol_fdset(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp);
CURLcode Curl_doing_fdset(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp);
#endif #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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -188,12 +188,6 @@ typedef enum {
NTLMSTATE_LAST NTLMSTATE_LAST
} curlntlm; } curlntlm;
/* for 3rd party transfers to decide which side that issues PASV */
typedef enum {
CURL_TARGET_PASV,
CURL_SOURCE_PASV
} curl_pasv_side;
/* Struct used for NTLM challenge-response authentication */ /* Struct used for NTLM challenge-response authentication */
struct ntlmdata { struct ntlmdata {
curlntlm state; curlntlm state;
@@ -249,6 +243,42 @@ struct HTTP {
/**************************************************************************** /****************************************************************************
* FTP unique setup * FTP unique setup
***************************************************************************/ ***************************************************************************/
typedef enum {
FTP_STOP, /* do nothing state, stops the state machine */
FTP_WAIT220, /* waiting for the inintial 220 response immediately after
a connect */
FTP_AUTH,
FTP_USER,
FTP_PASS,
FTP_ACCT,
FTP_PBSZ,
FTP_PROT,
FTP_PWD,
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
FTP_RETR_PREQUOTE,
FTP_STOR_PREQUOTE,
FTP_POSTQUOTE,
FTP_CWD, /* change dir */
FTP_MKD, /* if the dir didn't exist */
FTP_MDTM, /* to figure out the datestamp */
FTP_TYPE, /* to set type when doing a head-like request */
FTP_LIST_TYPE, /* set type when about to do a dir list */
FTP_RETR_TYPE, /* set type when about to RETR a file */
FTP_STOR_TYPE, /* set type when about to STOR a file */
FTP_SIZE, /* get the remote file's size for head-like request */
FTP_RETR_SIZE, /* get the remote file's size for RETR */
FTP_STOR_SIZE, /* get the size for (resumed) STOR */
FTP_REST, /* when used to check if the server supports it in head-like */
FTP_RETR_REST, /* when asking for "resume" in for RETR */
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
FTP_PASV, /* generic state for PASV and EPSV, check count1 */
FTP_LIST, /* generic state for LIST, NLST or a custom list command */
FTP_RETR,
FTP_STOR, /* generic state for STOR and APPE */
FTP_QUIT,
FTP_LAST /* never used */
} ftpstate;
struct FTP { struct FTP {
curl_off_t *bytecountp; curl_off_t *bytecountp;
char *user; /* user name string */ char *user; /* user name string */
@@ -277,6 +307,18 @@ struct FTP {
bool cwddone; /* if it has been determined that the proper CWD combo bool cwddone; /* if it has been determined that the proper CWD combo
already has been done */ already has been done */
char *prevpath; /* conn->path from the previous transfer */ char *prevpath; /* conn->path from the previous transfer */
size_t nread_resp; /* number of bytes currently read of a server response */
int count1; /* general purpose counter for the state machine */
int count2; /* general purpose counter for the state machine */
int count3; /* general purpose counter for the state machine */
char *sendthis; /* allocated pointer to a buffer that is to be sent to the
ftp server */
size_t sendleft; /* number of bytes left to send from the sendthis buffer */
size_t sendsize; /* total size of the sendthis buffer */
struct timeval response; /* set to Curl_tvnow() when a command has been sent
off, used to time-out response reading */
ftpstate state; /* always use ftp.c:state() to change state! */
curl_off_t downloadsize;
}; };
/**************************************************************************** /****************************************************************************
@@ -299,8 +341,9 @@ struct ConnectBits {
bool httpproxy; /* if set, this transfer is done through a http proxy */ bool httpproxy; /* if set, this transfer is done through a http proxy */
bool user_passwd; /* do we use user+password for this connection? */ bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */ bool proxy_user_passwd; /* user+password for the proxy? */
bool ipv6_ip; /* we communicate with a remove site specified with pure IPv6 bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
IP address */ IP address */
bool ipv6; /* we communicate with a site using an IPv6 address */
bool use_range; bool use_range;
bool rangestringalloc; /* the range string is malloc()'ed */ bool rangestringalloc; /* the range string is malloc()'ed */
@@ -314,9 +357,12 @@ struct ConnectBits {
bool forbidchunk; /* used only to explicitly forbid chunk-upload for bool forbidchunk; /* used only to explicitly forbid chunk-upload for
specific upload buffers. See readmoredata() in specific upload buffers. See readmoredata() in
http.c for details. */ http.c for details. */
bool tcpconnect; /* the tcp stream (or simimlar) is connected, this
is set the first time on the first connect function bool tcpconnect; /* the TCP layer (or simimlar) is connected, this is set
call */ the first time on the first connect function call */
bool protoconnstart;/* the protocol layer has STARTED its operation after
the TCP layer connect */
bool retry; /* this connection is about to get closed and then bool retry; /* this connection is about to get closed and then
re-attempted at another connection. */ re-attempted at another connection. */
bool no_body; /* CURLOPT_NO_BODY (or similar) was set */ bool no_body; /* CURLOPT_NO_BODY (or similar) was set */
@@ -410,15 +456,6 @@ struct Curl_transfer_keeper {
char *uploadbuf; char *uploadbuf;
curl_socket_t maxfd; curl_socket_t maxfd;
/* pointers to the actual descriptors we check */
fd_set *readfdp;
fd_set *writefdp;
/* the file descriptors to play with */
fd_set readfd;
fd_set writefd;
fd_set rkeepfd;
fd_set wkeepfd;
int keepon; int keepon;
bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
@@ -465,9 +502,21 @@ struct connectdata {
#define PROT_FTPS (1<<9) #define PROT_FTPS (1<<9)
#define PROT_SSL (1<<10) /* protocol requires SSL */ #define PROT_SSL (1<<10) /* protocol requires SSL */
/* the particular host we use, in two different ways */ /* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
Curl_done() */
struct Curl_dns_entry *dns_entry; struct Curl_dns_entry *dns_entry;
Curl_addrinfo *ip_addr; /* the particular IP we connected to */
/* 'ip_addr' is the particular IP we connected to. It points to a struct
within the DNS cache, so this pointer is only valid as long as the DNS
cache entry remains locked. It gets unlocked in Curl_done() */
Curl_addrinfo *ip_addr;
/* 'ip_addr_str' is the ip_addr data as a human readable malloc()ed string.
It remains available as long as the connection does, which is longer than
the ip_addr itself. Set with Curl_store_ip_addr() when ip_addr has been
set. */
char *ip_addr_str;
char protostr[16]; /* store the protocol string in this buffer */ char protostr[16]; /* store the protocol string in this buffer */
@@ -512,7 +561,7 @@ struct connectdata {
/* These two functions MUST be set by the curl_connect() function to be /* These two functions MUST be set by the curl_connect() function to be
be protocol dependent */ be protocol dependent */
CURLcode (*curl_do)(struct connectdata *); CURLcode (*curl_do)(struct connectdata *, bool *done);
CURLcode (*curl_done)(struct connectdata *, CURLcode); CURLcode (*curl_done)(struct connectdata *, CURLcode);
/* If the curl_do() function is better made in two halves, this /* If the curl_do() function is better made in two halves, this
@@ -523,8 +572,29 @@ struct connectdata {
/* This function *MAY* be set to a protocol-dependent function that is run /* This function *MAY* be set to a protocol-dependent function that is run
* after the connect() and everything is done, as a step in the connection. * after the connect() and everything is done, as a step in the connection.
* The 'done' pointer points to a bool that should be set to TRUE if the
* function completes before return. If it doesn't complete, the caller
* should call the curl_connecting() function until it is.
*/ */
CURLcode (*curl_connect)(struct connectdata *); CURLcode (*curl_connect)(struct connectdata *, bool *done);
/* See above. Currently only used for FTP. */
CURLcode (*curl_connecting)(struct connectdata *, bool *done);
CURLcode (*curl_doing)(struct connectdata *, bool *done);
/* Called from the multi interface during the PROTOCONNECT phase, and it
should then return a proper fd set */
CURLcode (*curl_proto_fdset)(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp);
/* Called from the multi interface during the DOING phase, and it should
then return a proper fd set */
CURLcode (*curl_doing_fdset)(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
int *max_fdp);
/* This function *MAY* be set to a protocol-dependent function that is run /* This function *MAY* be set to a protocol-dependent function that is run
* by the curl_disconnect(), as a step in the disconnection. * by the curl_disconnect(), as a step in the disconnection.
@@ -623,6 +693,8 @@ struct connectdata {
#endif #endif
struct connectdata *sec_conn; /* secondary connection for 3rd party struct connectdata *sec_conn; /* secondary connection for 3rd party
transfer */ transfer */
enum { NORMAL, SOURCE3RD, TARGET3RD } xfertype;
}; };
/* The end of connectdata. */ /* The end of connectdata. */
@@ -875,9 +947,11 @@ struct UserDefined {
char *cookiejar; /* dump all cookies to this file */ char *cookiejar; /* dump all cookies to this file */
bool cookiesession; /* new cookie session? */ bool cookiesession; /* new cookie session? */
bool crlf; /* convert crlf on ftp upload(?) */ bool crlf; /* convert crlf on ftp upload(?) */
char *ftp_account; /* ftp account data */
struct curl_slist *quote; /* after connection is established */ struct curl_slist *quote; /* after connection is established */
struct curl_slist *postquote; /* after the transfer */ struct curl_slist *postquote; /* after the transfer */
struct curl_slist *prequote; /* before the transfer, after type */ struct curl_slist *prequote; /* before the transfer, after type */
struct curl_slist *source_quote; /* 3rd party quote */
struct curl_slist *source_prequote; /* in 3rd party transfer mode - before struct curl_slist *source_prequote; /* in 3rd party transfer mode - before
the transfer on source host */ the transfer on source host */
struct curl_slist *source_postquote; /* in 3rd party transfer mode - after struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
@@ -910,11 +984,8 @@ struct UserDefined {
curl_off_t max_filesize; /* Maximum file size to download */ curl_off_t max_filesize; /* Maximum file size to download */
char *source_host; /* for 3rd party transfer */ char *source_url; /* for 3rd party transfer */
char *source_port; /* for 3rd party transfer */
char *source_userpwd; /* for 3rd party transfer */ char *source_userpwd; /* for 3rd party transfer */
char *source_path; /* for 3rd party transfer */
curl_pasv_side pasvHost; /* for 3rd party transfer indicates passive host */
/* Here follows boolean settings that define how to behave during /* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially this session. They are STATIC, set by libcurl users or at least initially
@@ -970,7 +1041,9 @@ struct UserDefined {
* 'struct urlstate' instead. */ * 'struct urlstate' instead. */
struct SessionHandle { struct SessionHandle {
curl_hash *hostcache; struct curl_hash *hostcache;
void *multi; /* if non-NULL, points to the multi handle
struct of which this "belongs" */
struct Curl_share *share; /* Share, handles global variable mutexing */ struct Curl_share *share; /* Share, handles global variable mutexing */
struct UserDefined set; /* values set by the libcurl user */ struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */ struct DynamicStatic change; /* possibly modified userdefined data */

View File

@@ -146,7 +146,7 @@ char *curl_version(void)
/* data for curl_version_info */ /* data for curl_version_info */
static const char *protocols[] = { static const char * const protocols[] = {
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
"ftp", "ftp",
#endif #endif

View File

@@ -1,2 +1,4 @@
curlmsg.h
curlmsg.sdl
Makefile Makefile
Makefile.in Makefile.in

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