Compare commits

...

274 Commits

Author SHA1 Message Date
Daniel Stenberg
719bec2606 7.16.0 material 2006-10-29 23:03:14 +00:00
Daniel Stenberg
b1db9dbb16 corrected how tests/memanalyze.pl is used 2006-10-29 23:00:52 +00:00
Yang Tse
609044aea2 Compiler warning fix 2006-10-29 21:19:23 +00:00
Yang Tse
ba481718a4 Make more human readable and maintainable previous
compiler warning fix since it was Ok and actually
avoids the targeted compiler warning.
2006-10-29 14:58:59 +00:00
Daniel Stenberg
1be60dde7f updated to current status 2006-10-29 09:18:32 +00:00
Daniel Stenberg
e92e811a61 updated to reflect reality 2006-10-29 09:11:44 +00:00
Daniel Stenberg
5aa0db8681 a small unification of the error text on failed server startups 2006-10-27 21:07:08 +00:00
Yang Tse
d5691211dd Sync with lib/setup_once.h 2006-10-27 15:37:26 +00:00
Yang Tse
a93695a70e Compiler warning fix.
Assigning the const value zero to a pointer to function
results in a null pointer value assignment to the function
pointer.

Assignment of any nonzero value is what should result in a
implementation compiler dependent result.

Since what we want to do here is the first case, this should
not trigger compiler warnings related with conversions from
'pointer to data' to 'pointer to function'.

Our autobuild test suite will judge.
2006-10-27 15:32:18 +00:00
Gisle Vanem
ce935a2697 Fixed 'x_TYPE_ARG2' to match prototypes of recv() and send(). 2006-10-27 14:13:32 +00:00
Gisle Vanem
812ce0d93f Get rid of the special sread()+swrite() for MSDOS. Use recv()
and send(). Added needed HAVE_x defines.
2006-10-27 14:07:32 +00:00
Gisle Vanem
bbae5b49f9 Added 'RECV_TYPE_ARGx' needed in getinfo.c. 2006-10-27 13:57:16 +00:00
Yang Tse
772a985dc3 Update copyright year, since the file has been modified 2006-10-27 03:47:57 +00:00
Yang Tse
8a7514de8a Compiler warning fix 2006-10-27 02:18:29 +00:00
Yang Tse
32ad212ac9 30 seconds isn't long enough for this test on a loaded server. 2006-10-27 01:58:59 +00:00
Yang Tse
8a8d5c784c Do an explicit typecast of data pointers to function pointers
to avoid picky compiler warnings, since this is what we want!
2006-10-27 01:04:41 +00:00
Gisle Vanem
125830ab4b Use proper 'stat' structure for fstat(). I.e. 'struct _stati64' and '_fstati64()'
on Win32.
2006-10-26 14:30:11 +00:00
Yang Tse
5b75b423e6 Improved rlimit logic:
- Take in account RLIM_INFINITY.
- Verify that soft limit is actually changed when doing so.
- Show errno in case getrlimit or setrlimit fails.
- Keep file descriptors open only while runing this test.
2006-10-26 13:55:24 +00:00
Yang Tse
012d7e2878 Fix Curl_open() not reporting failure when allocation of the
buffer used to store headers in the SessionHandle failed.
2006-10-26 11:15:25 +00:00
Yang Tse
cd3029f36f 30 seconds isn't long enough for this test on a loaded server. 2006-10-26 09:50:21 +00:00
Daniel Stenberg
6adaac7e18 a Smalltalk binding 2006-10-25 21:07:26 +00:00
Daniel Stenberg
cde5e35d9b Fixed CURLOPT_FAILONERROR to return CURLE_HTTP_RETURNED_ERROR even for the
case when 401 or 407 are returned, *IF* no auth credentials have been given.
The CURLOPT_FAILONERROR option is not possible to make fool-proof for 401
and 407 cases when auth credentials is given, but we've now covered this
somewhat more.

You might get some amounts of headers transferred before this situation is
detected, like for when a "100-continue" is received as a response to a
POST/PUT and a 401 or 407 is received immediately afterwards.

Added test 281 to verify this change.
2006-10-25 20:40:14 +00:00
Gisle Vanem
ee17fba72e Fixed "'x' might be used uninitialized in this function" warning.
Removed trailing whitespace.
2006-10-25 14:16:01 +00:00
Gisle Vanem
6296b89319 Added '-d' option for Watt32 targets. Added cvs id. 2006-10-25 14:13:35 +00:00
Yang Tse
5450db9151 Compiler warning fix 2006-10-25 10:25:43 +00:00
Yang Tse
b4700f026b Add project notice and file Id 2006-10-25 09:20:44 +00:00
Yang Tse
d771fa7c48 Compiler warning fix 2006-10-25 08:52:00 +00:00
Daniel Stenberg
b2c378267b updated copyright year 2006-10-25 07:19:45 +00:00
Yang Tse
384c8f3560 Use curl_global_init() and curl_global_cleanup().
Improve cleanup in case of initialization failure.
2006-10-25 05:59:46 +00:00
Daniel Stenberg
f44ef427a2 other pipelining fixes by Ravi Pratap, that now makes pipelines get used better 2006-10-24 21:14:40 +00:00
Yang Tse
c54a4301ee Abort test if it seems that it would have run forever. This is just to prevent
test hanging and actually is an indication that there's a condition that is
not being properly handled at some point in the library.

Remove a pair of braces and adjust indentation appropriately.
2006-10-24 15:51:42 +00:00
Daniel Stenberg
36a3514225 the check in ConnectionExists() for not re-using a non-resolved connection now
applies for asynch name resolves in general and not only ares
2006-10-23 20:41:50 +00:00
Daniel Stenberg
e1edd41e1b Ravi Pratap provided a major update with pipelining fixes. We also no longer
re-use connections (for pipelining) before the name resolving is done.
2006-10-23 20:34:56 +00:00
Yang Tse
13e60c55a1 Avoid trying to compare more than strlen bytes. 2006-10-23 19:16:19 +00:00
Dan Fandrich
9b8b1a68f0 30 seconds isn't long enough for this test on a loaded server. 2006-10-23 19:15:14 +00:00
Yang Tse
4ec9316155 Replace is*() macros with our own IS*() ones. 2006-10-23 19:14:54 +00:00
Daniel Stenberg
ef769500d4 Nir Soffer fixed a cp line and got rid of an rm 2006-10-22 22:18:24 +00:00
Daniel Stenberg
23692574a2 until we learn how to use Makefile.inc from here, I've added socks.o in here
as well
2006-10-22 07:43:34 +00:00
Yang Tse
5f6fd682a5 Provide 'datarootdir' parameter to shutup configuration warning,
'packages/EPM/curl.list.in seems to ignore the --datarootdir setting'
2006-10-21 17:08:48 +00:00
Yang Tse
db24518a30 Fix misplaced runtime library specification for 'release-dll' target 2006-10-21 16:25:31 +00:00
Daniel Stenberg
90933ac660 rely on the global LDADD instead of having specific ones for every program 2006-10-21 13:00:51 +00:00
Daniel Stenberg
087579a6f4 Nir Soffer for his Makefile.am fix 2006-10-21 12:49:45 +00:00
Yang Tse
de59cde155 Fix copy-paste error 2006-10-21 12:36:10 +00:00
Yang Tse
3cd95eacdf Compiler warning fix 2006-10-21 12:35:16 +00:00
Daniel Stenberg
deb81b2ad4 Nir Soffer made the tests/libtest/Makefile.am use a proper variable for all
the single test applications' link and dependences, so that you easier can
override those from the command line when using make.
2006-10-21 11:40:04 +00:00
Daniel Stenberg
4e717cdb30 Armel Asselin separated CA cert verification problems from problems with
reading the (local) CA cert file to let users easier pinpoint the actual
problem. CURLE_SSL_CACERT_BADFILE (77) is the new libcurl error code.
2006-10-21 11:32:05 +00:00
Yang Tse
33acd6f041 Compiler warning fix 2006-10-21 10:54:41 +00:00
Daniel Stenberg
7575e6afc4 made the arrow for 'Send SSL data' point in the right direction! 2006-10-20 21:26:10 +00:00
Yang Tse
316a9f6480 Compiler warning fix 2006-10-20 17:54:05 +00:00
Yang Tse
c6de584cad Since now src/setup.h includes setup_once.h, src/config-win32.h needs
the definitions for the return type and arguments types of functions
recv() and send().
2006-10-20 17:16:06 +00:00
Yang Tse
d997ff6aa8 Oops! Actually set the limit to 30 seconds. 2006-10-20 15:45:12 +00:00
Yang Tse
b9ccecf86e Decrease the posibility of aborting a test which actually is not
stale by replacing loop counters with timeouts. In this way the
main loop of the test will be allowed to run up to 30 seconds on
any platform before aborting it.
2006-10-20 15:39:54 +00:00
Daniel Stenberg
bd5d21aaf2 When a resolve is made on a pipelined connection we need to detect it properly
(when the resoling isn't completede yet) and not confuse it with a simple
connection re-use (non-pipelined).
2006-10-20 12:25:39 +00:00
Yang Tse
19e07771d1 Set loop2 counter limit to 60 on this test to avoid a false positive. 2006-10-19 23:35:52 +00:00
Yang Tse
ef267ab449 Replace tabs with spaces and Compiler warning fix. 2006-10-19 22:49:33 +00:00
Yang Tse
4f6ed683e8 Compiler warning fix 2006-10-19 22:48:33 +00:00
Yang Tse
c818e7064f When aborting, show loop counter values when more than one counter exists. 2006-10-19 21:12:27 +00:00
Yang Tse
ead6ab2ef7 Abort test if it seems that it would have run forever. This is just to prevent
test hanging and actually is an indication that there's a condition that is
not being properly handled at some point in the library.

Loop counter limits might need to be further increased on false positives.
2006-10-19 17:29:25 +00:00
Daniel Stenberg
5c3dc49f44 Here's an effort to avoid saying 'data not shown' in the debug parts when the
data is actually shown on screen. Like when you do 'curl -v host' with data
and debug info sent to the same terminal.
2006-10-19 14:28:50 +00:00
Yang Tse
83884180ac Builds using synchronous name resolver dislike marking the connection as async. 2006-10-19 02:30:02 +00:00
Yang Tse
4cac96c33a Sync with lib/setup_once.h 2006-10-18 21:25:12 +00:00
Yang Tse
5df4be1165 Check for USE_WINSOCK instead of WIN32 where the check was done
to verify winsock API availability.
2006-10-18 21:05:40 +00:00
Yang Tse
96445f1b7d Introduce symbol USE_WINSOCK which will be defined when
using winsock or winsock2 API.
2006-10-18 15:57:49 +00:00
Daniel Stenberg
4bdd7596d3 the expire timer is a bit too annoying to see all the time ;-) 2006-10-18 15:11:24 +00:00
Daniel Stenberg
18aae32015 When a connection is re-used, it can be flagged for re-use before the name
resolving is completed so we must make sure to survive it and mark the
connection as async (ie not yet connected completely).
2006-10-18 15:10:49 +00:00
Daniel Stenberg
a8996b9e52 use the return code from lseek() to detect problems and bail out if so 2006-10-18 14:47:58 +00:00
Gisle Vanem
94095c61d8 Added ISPRINT() required for src/main.c. 2006-10-18 13:50:23 +00:00
Daniel Stenberg
1cddd744ad Tor's spell fixes 2006-10-18 12:59:02 +00:00
Daniel Stenberg
786738dd00 changes done the last few days 2006-10-18 11:13:56 +00:00
Daniel Stenberg
5b8d5fdf2f cut out matching host names starting with telnet or ftps, since they hardly
ever actually are used
2006-10-18 11:13:39 +00:00
Daniel Stenberg
694f31ca37 the "work in progress" for #25 was ditched a long time ago 2006-10-18 07:53:24 +00:00
Yang Tse
9c1ad0f9f7 Replace is*() macros with our own IS*() ones.
Get rid of non ANSI/ISO isascii().
2006-10-18 03:42:06 +00:00
Yang Tse
71c6335293 Move definition of IS*() macros to setup_once.h 2006-10-18 03:41:19 +00:00
Dan Fandrich
8c38ea4ebc Fixed compile error in HAVE_SIGACTION case. 2006-10-17 21:45:37 +00:00
Daniel Stenberg
44d84ac164 Avoid typecasting a signed char to an int when using is*() functions, as that
could very well cause a negate number get passed in and thus cause reading
outside of the array usually used for this purpose.

We avoid this by using the uppercase macro versions introduced just now that
does some extra crazy typecasts to avoid byte codes > 127 to cause negative
int values.
2006-10-17 21:32:56 +00:00
Daniel Stenberg
930f9bd534 clear the struct size not the pointer size, pointed out in bug report
#1579171
2006-10-17 20:34:11 +00:00
Daniel Stenberg
b61fbbde46 buildconf already runs ares/buildconf by itself if there is an ares subdir
present, so there's no use to doing it again in this script!
2006-10-17 11:46:42 +00:00
Yang Tse
ec956b0334 Explicit typecast for Curl_debug() size argument 2006-10-17 10:04:13 +00:00
Yang Tse
44ffe0dc79 Typo 2006-10-17 09:07:38 +00:00
Daniel Stenberg
e3a61fba52 make the low_speed check set the expire timer so that it has a chance to work
even when using curl_multi_socket() or even using the multi_perform() when
relying on multi_timeout() to be good.
2006-10-17 09:05:44 +00:00
Daniel Stenberg
65794f60ec Please welcome our new haxx.se curl mirror, for really fast Swedish access. 2006-10-17 08:07:48 +00:00
Daniel Stenberg
7a710b4970 Jeff helped me pinpoint that we didn't properly set the expire timer during
c-ares name resolves, but now we do!
2006-10-17 08:06:27 +00:00
Daniel Stenberg
0bb20cc611 fix the name resolve abort timeout calculation (when signals are used) 2006-10-17 08:05:41 +00:00
Yang Tse
433c0c895e Compiler warning fix 2006-10-17 02:31:06 +00:00
Daniel Stenberg
67e8d22958 Added a check in configure that simply tries to run a program (not when
cross-compiling) in order to detect problems with run-time libraries that
otherwise would occur when the sizeof tests for curl_off_t would run and
thus be much more confusing to users. The check of course should run after
all lib-checks are done and before any other test is used that would run an
executable built for testing-purposes.
2006-10-16 08:30:54 +00:00
Yang Tse
10d1fc0e73 Compiler warning fix 2006-10-15 23:13:12 +00:00
Gisle Vanem
2260c8aa11 Replace ";;" with ";". 2006-10-15 20:28:03 +00:00
Gisle Vanem
97eb62aff8 Rearranged target HAVE_x section. 2006-10-15 19:41:15 +00:00
Yang Tse
1855fc35f2 Declare our own timeval struct if HAVE_STRUCT_TIMEVAL is not defined 2006-10-14 12:02:19 +00:00
Yang Tse
dc3ed35313 Define HAVE_STRUCT_TIMEVAL as appropriate for platforms that lack autotools support 2006-10-14 12:01:44 +00:00
Daniel Stenberg
6b868df554 Prevent ares_getsock() to overflow if more than 16 sockets are used. 2006-10-13 21:25:11 +00:00
Dan Fandrich
5ccbbe40c2 The tagging of application/x-www-form-urlencoded POST body data sent
to the CURLOPT_DEBUGFUNCTION callback has been fixed (it was erroneously
included as part of the header).  A message was also added to the
command line tool to show when data is being sent, enabled when
--verbose is used.
2006-10-13 21:02:27 +00:00
Daniel Stenberg
86f93a53d6 print the actual (externally known) easy handle and not the internal container
for it
2006-10-13 14:54:36 +00:00
Daniel Stenberg
f53347631e Added comments about checking return code and the maxfd counter 2006-10-13 14:01:19 +00:00
Daniel Stenberg
efe3cb6e1a Added curl_multi_dump() when built with CURLDEBUG - this is not a stable public
function, this is only meant to allow easier tracking of the internal handle's
state and what sockets they use. Only for research and development.
2006-10-13 07:11:26 +00:00
Yang Tse
32ac4edeed Check for struct timeval at configuration time 2006-10-13 01:35:14 +00:00
Daniel Stenberg
4c04c09138 ghiper now uses the timer callback in the multi interface 2006-10-12 21:26:50 +00:00
Daniel Stenberg
47ea80baee avoid an overflow if an excessive amount of servers are used 2006-10-12 16:47:50 +00:00
Daniel Stenberg
95c3fa836b clarify more 2006-10-12 14:35:20 +00:00
Daniel Stenberg
ab60a12465 Starting now, adding an easy handle to a multi stack that was already added
to a multi stack will cause CURLM_BAD_EASY_HANDLE to get returned.
2006-10-12 14:30:47 +00:00
Daniel Stenberg
2d38e51867 deleted #19 since it concerted FTP third party transfers and they are no longer
supported
2006-10-12 09:02:46 +00:00
Daniel Stenberg
a5dda669e3 we've cut out third party transfers 2006-10-12 08:55:01 +00:00
Daniel Stenberg
3c4f3a680a point out the sslcert web page for -k/--insecure 2006-10-12 08:52:20 +00:00
Daniel Stenberg
b61c06384a Jeff Pohlmeyer has been working with the hiperfifo.c example source code,
and while doing so it became apparent that the current timeout system for
the socket API really was a bit awkward since it become quite some work to
be sure we have the correct timeout set.

Jeff then provided the new CURLMOPT_TIMERFUNCTION that is yet another
callback the app can set to get to know when the general timeout time
changes and thus for an application like hiperfifo.c it makes everything a
lot easier and nicer. There's a CURLMOPT_TIMERDATA option too of course in
good old libcurl tradition.
2006-10-12 08:36:47 +00:00
Daniel Stenberg
e7742bfb7c the textual arraw for "Send SSL data" was the wrong way 2006-10-12 08:14:13 +00:00
Yang Tse
22307ae0ee Inclusion of time header files based on header existance 2006-10-12 03:57:33 +00:00
Yang Tse
e150150d9f Remove redundant __CYGWIN__ symbol check 2006-10-11 16:01:16 +00:00
Yang Tse
943f0733bb Compiler warning fix 2006-10-10 23:58:02 +00:00
Yang Tse
8274447dd9 Call curl_global_cleanup() in all code paths before exiting test 2006-10-10 23:50:37 +00:00
Daniel Stenberg
083a84e5d0 repair id string 2006-10-10 19:48:24 +00:00
Daniel Stenberg
d5eb386d00 Added ghiper.c, Jeff Pohlmeyer's example code using the curl_multi_socket()
API with glib2
2006-10-10 19:46:57 +00:00
Daniel Stenberg
1ce7b48057 mark the handle as no longer having a broken pipe when a transfer has failed 2006-10-10 14:23:34 +00:00
Daniel Stenberg
cbcdd337aa Added test case 536 in an attempt to add Bogdan Nicula's problematic case
with multi interface and pipelining. This test just works and did not repeat
the problem his test code showed, but could still serve as a useful test.
2006-10-09 21:29:53 +00:00
Daniel Stenberg
c144adf77c used for test 535 too 2006-10-09 21:26:09 +00:00
Daniel Stenberg
d390039873 minor indent fix 2006-10-09 21:24:50 +00:00
Daniel Stenberg
7d0c58a285 when going to completed due to error, mark the handle as not in a pipeline
anymore
2006-10-09 21:24:34 +00:00
Daniel Stenberg
9263001b21 new mirrors 2006-10-09 21:04:48 +00:00
Daniel Stenberg
66ee6d07f8 kill trailing whitespace 2006-10-09 14:59:53 +00:00
Daniel Stenberg
a40dcca794 changed the wording about removal of internal headers with -H 2006-10-09 14:54:11 +00:00
Yang Tse
15e3dfe1d3 Compiler warning fix 2006-10-09 11:21:40 +00:00
Daniel Stenberg
a1de9367ec Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test
case 535 and it now runs fine. Again a problem with the pipelining code not
taking all possible (error) conditions into account.
2006-10-09 06:58:05 +00:00
Yang Tse
eceb37bde2 Cygwin 1.5.21 needs this hack to pass test 160.
In this way 304 tests out of 304 reported OK.
2006-10-09 00:35:36 +00:00
Daniel Stenberg
56fcf85ab6 slightly improved 2006-10-08 22:19:25 +00:00
Daniel Stenberg
77db81d661 clarified more 2006-10-08 21:41:22 +00:00
Daniel Stenberg
2ad7fcbc2f test 534 added in an attempt to repeat Bogdan Nicula's bug... 2006-10-08 10:51:53 +00:00
Daniel Stenberg
2c62dfd124 modified lib533 to accept both URLs on the command line 2006-10-08 08:50:12 +00:00
Daniel Stenberg
ef66497a0d Fix a "sockfilt" leak. When a new 'data' connection sockfilt server is started,
make sure that a previously used one is killed first (since they re-use the
same .pid file etc)
2006-10-08 08:43:32 +00:00
Daniel Stenberg
1128029599 don't display or act on state changes that doesn't actually change state 2006-10-07 21:04:57 +00:00
Daniel Stenberg
befc30bc55 Bogdan Nicula's hanging test case was converted to test case 533 and the test
now runs fine.
2006-10-06 21:19:57 +00:00
Daniel Stenberg
ca5846cde9 catch silly mistakes better 2006-10-06 21:19:40 +00:00
Gunter Knauf
8547ab1663 updated for latest OpenSSL release. 2006-10-06 00:24:25 +00:00
Daniel Stenberg
9c0e6ac365 planned stuff to do before release 2006-10-05 14:33:23 +00:00
Daniel Stenberg
552b963e6d Dmitriy Sergeyev provided an example source code that crashed CVS libcurl
but that worked nicely in 7.15.5. I converted it into test case 532 and
fixed the problem.
2006-10-04 21:11:08 +00:00
Daniel Stenberg
e2b48366d3 removed more dead code that is unused since the removal of the third party
transfer support
2006-10-02 13:00:54 +00:00
Daniel Stenberg
5e0d9aea32 Support for FTP third party transfers is now dropped 2006-09-30 20:31:11 +00:00
Daniel Stenberg
ae13c93b7d Reported in #1561470 (http://curl.haxx.se/bug/view.cgi?id=1561470), libcurl
would crash if a bad function sequence was used when shutting down after
using the multi interface (i.e using easy_cleanup after multi_cleanup) so
precautions have been added to make sure it doesn't any more - test case 529
was added to verify.
2006-09-28 21:26:06 +00:00
Daniel Stenberg
b9f8a4a477 added more explanations 2006-09-27 21:15:36 +00:00
Daniel Stenberg
68e9f75708 As reported in bug: #1566077 the former URL mentioned in the generated cookie
jar has died and we now instead point out our own version of that
2006-09-27 21:00:45 +00:00
Daniel Stenberg
d569693f24 Armel Asselin's fix for the RESUME_FROM docu 2006-09-26 10:38:24 +00:00
Yang Tse
15d8bb2105 Compiler warning fix 2006-09-25 00:54:32 +00:00
Yang Tse
b2ca777a08 Compiler warning fix 2006-09-25 00:16:23 +00:00
Yang Tse
ba01198e6c Compiler warning fix 2006-09-25 00:05:39 +00:00
Yang Tse
6ebd5e1761 Compiler warning fix 2006-09-24 23:55:53 +00:00
Daniel Stenberg
2723eda1e4 Bernard Leak fixed configure --with-gssapi-libs 2006-09-24 22:03:01 +00:00
Daniel Stenberg
1fa3a5cce9 Cory Nelson made libcurl use the WSAPoll() function if built for Windows
Vista (_WIN32_WINNT >= 0x0600)
2006-09-24 10:41:00 +00:00
Daniel Stenberg
fe8aee6b08 eeep, tab completion error 2006-09-24 10:33:25 +00:00
Daniel Stenberg
0639e2a6e2 --ftp-ssl-control requires SSL/TLS, it does not "try" it 2006-09-24 10:30:40 +00:00
Daniel Stenberg
f1d707705e allow user in passwd state for test 280 to work (--ftp-alternative-to-user) 2006-09-24 10:30:02 +00:00
Daniel Stenberg
296a7db960 updated numbers 2006-09-23 20:50:44 +00:00
Daniel Stenberg
4c0936e72f minor edits 2006-09-23 20:46:07 +00:00
Daniel Stenberg
0992e391ba filled in some docs for the FTP server control commands 2006-09-23 20:39:34 +00:00
Daniel Stenberg
b22aaeef6a added simple test of --ftp-alternative-to-user 2006-09-23 20:39:15 +00:00
Daniel Stenberg
8090ee0e5d --ftp-alternative-to-user was missing in the help text 2006-09-23 20:25:45 +00:00
Daniel Stenberg
f7d31bb3e3 Mike Protts added --ftp-ssl-control to make curl use FTP-SSL, but only
encrypt the control connection and use the data connection "plain".
2006-09-23 19:37:23 +00:00
Daniel Stenberg
9cd928674f standard curl source code headers 2006-09-23 19:09:39 +00:00
Daniel Stenberg
3ea8a4d220 Dmitriy Sergeyev provided a patch that made the SOCKS[45] code work better as
it now will read the full data sent from servers. The SOCKS-related code was
also moved to the new lib/socks.c source file.
2006-09-23 19:07:20 +00:00
Dan Fandrich
b0d3ba76a0 -z works on FTP, too 2006-09-21 22:15:05 +00:00
Daniel Stenberg
ab798fe5ba (FTP) a failed upload does not invalidate the control connection 2006-09-21 20:52:58 +00:00
Daniel Stenberg
e7d90e08b9 Added test case 531 in an attempt to repeat bug report #1561470
(http://curl.haxx.se/bug/view.cgi?id=1561470) that is said to crash when an
FTP upload fails with the multi interface. It did not, but I made a failed
upload still assume the control connection to be fine.
2006-09-21 20:52:20 +00:00
Daniel Stenberg
c2404f77e9 Extended the explanation for CURLM_CALL_MULTI_PERFORM somewhat. 2006-09-21 11:09:54 +00:00
Daniel Stenberg
ec4a16f2e0 Armel Asselin fixed problems when you gave a proxy URL with user name and
empty password or no password at all. Test case 278 and 279 were added to
verify.
2006-09-20 21:49:41 +00:00
Daniel Stenberg
ca5de26f50 lots of "HTTPS" features are really "SSL" ones as they are also valid for
FTPS
2006-09-20 13:09:27 +00:00
Daniel Stenberg
71920d61e6 Michael Wallner's test program again help me track down a problem. This time
it basically was that we didn't remove the current connection from the pipe
list when following a redirect. Also in this commit: several cases of
additional debug code for debug builds helping to check and track down some
signs of run-time trouble.
2006-09-20 12:03:50 +00:00
Daniel Stenberg
5de75eee56 PEM is default type for key and cert 2006-09-20 11:35:13 +00:00
Daniel Stenberg
2d5fc39d35 Resize the connection cache upwards when adding more handles than what
currently fits in the cache, to make the cache work better especially for
pipelining cases but also for "mere" (persistent) connection re-use.
2006-09-16 21:50:29 +00:00
Daniel Stenberg
c001ed53fa Armel Asselin - When the easy handle is removed from the multi while libcurl
is still trying to resolve the host name, it seems that the ftp struct is not
yet initialized, but the removal action calls Curl_done() which calls
Curl_ftp_done. So we simply return success from there if no ftp pointer is
set.
2006-09-16 20:57:59 +00:00
Daniel Stenberg
39e01e9349 file-local function should be static and not use Curl_ prefix!
Curl_signalPipeClose is now signalPipeClose().
2006-09-15 08:47:55 +00:00
Gisle Vanem
9e54d4c7d2 Use CSOURCES as other makefiles. Add line for dependency generation. 2006-09-13 13:51:03 +00:00
Gisle Vanem
56bf97ffc9 'in6addr_any' must be placed in .c-file. Added 'REAL_WIN32' for
all Win32 targets except CygWin. Cleanup.
2006-09-13 13:41:53 +00:00
Yang Tse
7d3e719a2c Compiler warning fix 2006-09-13 12:42:12 +00:00
Daniel Stenberg
e55d4fd5c1 nicer reporting of disabled tests 2006-09-13 10:48:03 +00:00
Daniel Stenberg
5ee231415f added CVS id and clarified the comment lines 2006-09-13 10:18:01 +00:00
Daniel Stenberg
c866771cd2 Added a generic way to disable test cases when "all" is run, and added the
FTP 3rd party transfers to that file for now until I have them sorted out.
2006-09-13 10:16:36 +00:00
Yang Tse
4a24219a1a Fix error introduced in file version 1.369 2006-09-13 01:35:28 +00:00
Yang Tse
733a184ce0 Compiler warning fix 2006-09-12 23:51:01 +00:00
Daniel Stenberg
eee09e79e8 stuff we do 2006-09-12 11:31:34 +00:00
Daniel Stenberg
6df85adf3e hiperfifo.c by Jeff Pohlmeyer 2006-09-12 11:25:00 +00:00
Daniel Stenberg
3ee6036551 pipelining support is added now 2006-09-12 09:39:16 +00:00
Daniel Stenberg
fb65080548 example code by Michael Wallner 2006-09-12 07:54:55 +00:00
Daniel Stenberg
3a5f21b0d1 corrected URL 2006-09-12 06:28:34 +00:00
Daniel Stenberg
13a5598dc3 so it seems SOCKS5 too (still) has problems with connect timeouts 2006-09-12 06:14:10 +00:00
Yang Tse
5a6c89661a Cygwin preprocessor adjustments 2006-09-12 01:17:16 +00:00
Daniel Stenberg
7c5745720a If the current connection doesn't fit to get added to the connection cache,
we certainly MUST NOT kill an active connection... Problem tracked down thanks
to Michael Wallner's excellent test program.
2006-09-11 20:50:58 +00:00
Daniel Stenberg
00ae13f966 - Guilherme Balena Versiani: I noted a strange BUG in Win32 port
(ares_init.c/get_iphlpapi_dns_info() function): when I disable the network
  by hand or disconnect the network cable in Windows 2000 or Windows XP, my
  application gets 127.0.0.1 as the only name server. The problem comes from
  'GetNetworkParams' function, that returns the empty string "" as the only
  name server in that case. Moreover, the Windows implementation of
  inet_addr() returns INADDR_LOOPBACK instead of INADDR_NONE.
2006-09-11 20:25:13 +00:00
Daniel Stenberg
29dc39fce1 - Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a
handle that is part of a multi handle first removes the handle from the
  stack.

- Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL
  session-ID re-use on demand since there obviously are broken servers out
  there that misbehave with session-IDs used.
2006-09-11 17:18:18 +00:00
Daniel Stenberg
5c184cfc0d stupid mistake rectified by Jeff Pohlmeyer 2006-09-11 11:25:47 +00:00
Yang Tse
055022a55f Compiler warning fix 2006-09-10 23:45:54 +00:00
Yang Tse
c30e908034 Compiler warning fix 2006-09-10 23:37:42 +00:00
Daniel Stenberg
8d24c0212e curl_multi_socket() fix thanks to Jeff's test code 2006-09-10 22:15:57 +00:00
Daniel Stenberg
8240cea628 Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a
problem with it (SIGSEGV-style). It clearly showed that the existing
  socket-state and state-difference function wasn't good enough so I rewrote
  it and could then re-run Jeff's program without any crash. The previous
  version clearly could miss to tell the application when a handle changed
  from using one socket to using another.

  While I was at it (as I could use this as a means to track this problem
  down), I've now added a 'magic' number to the easy handle struct that is
  inited at curl_easy_init() time and cleared at curl_easy_cleanup() time that
  we can use internally to detect that an easy handle seems to be fine, or at
  least not closed or freed (freeing in debug builds fill the area with 0x13
  bytes but in normal builds we can of course not assume any particular data
  in the freed areas).
2006-09-10 22:15:32 +00:00
Daniel Stenberg
f2a33eb372 Added a useful debug function within #if 0. The function makes it easy to
"dump" a hash table which is useful when tracking problems with data stored
in one of our hashes.
2006-09-10 22:12:24 +00:00
Gisle Vanem
e134a40208 Added select_test() function to allow selecting on no sockets on
Winsock.
2006-09-10 19:01:04 +00:00
Gisle Vanem
690888cfc1 SIGALARM -> SIGALRM. 2006-09-09 19:13:13 +00:00
Gisle Vanem
fb8d9b6645 #ifdef around alarmfunc() to supress warning. 2006-09-09 19:11:54 +00:00
Gisle Vanem
f7ddb39ee1 iconv-data needs to be fully reallocated (to prevent a double-free). 2006-09-09 18:23:29 +00:00
Gisle Vanem
145084b699 Print usage in case 'arg2 == NULL'. 2006-09-09 16:55:21 +00:00
Gisle Vanem
f1ba12607a Duplicate iconv-data too in curl_easy_duphandle(). 2006-09-09 16:36:05 +00:00
Yang Tse
bb87b65f08 Compiler warning fix 2006-09-09 13:24:42 +00:00
Daniel Stenberg
b0f6e7cee4 Michele Bini fixed how the hostname is put in NTLM packages. As servers
don't expect fully qualified names we need to cut them off at the first dot.
2006-09-09 11:45:27 +00:00
Daniel Stenberg
ed72d4e104 tab => space 2006-09-09 11:45:05 +00:00
Daniel Stenberg
8ec1bfe897 Peter Sylvester cleaned up and fixed the getsockname() uses in ftp.c. Some
of them can be completetly removed though...
2006-09-08 22:17:39 +00:00
Gisle Vanem
1dec17562f signal() returns 'void (*)(int)'. 2006-09-08 13:06:41 +00:00
Daniel Stenberg
9cc3795f1a Mention that CURLOPT_MAX_RECV/SEND* were added in 7.15.5 2006-09-08 12:46:41 +00:00
Gisle Vanem
be1306a6c2 Update comment reflecting structure change. 2006-09-08 12:17:58 +00:00
Daniel Stenberg
e9160a31e0 removed the comment that isn't valid for this file, just a copy'n paste error 2006-09-08 12:03:55 +00:00
Gisle Vanem
0a670c578f Compilation fix; 'reqdata' is not a pointer. 'path' is part of SessionHandle. 2006-09-08 12:03:39 +00:00
Daniel Stenberg
e3c15fc4b9 test 530 is the first ever HTTP pipelining test for libcurl 2006-09-08 11:56:56 +00:00
Yang Tse
dc7c915553 Compilation fix 2006-09-08 05:18:07 +00:00
Daniel Stenberg
b7eeb6e67f Major overhaul introducing http pipelining support and shared connection
cache within the multi handle.
2006-09-07 21:49:20 +00:00
Yang Tse
7e4193b538 Fix compiler warning 2006-09-07 01:18:46 +00:00
Daniel Stenberg
a932803eac Invoke memanalyze from the source path and hush up about killing the FTP
server as part of test cases
2006-09-06 10:03:34 +00:00
Daniel Stenberg
52560142bf added some fresh new blurb 2006-09-05 21:17:04 +00:00
Daniel Stenberg
874a4ef8c7 spell fix and added Jari 2006-09-04 22:21:32 +00:00
Daniel Stenberg
0bb3ac7c31 Jari Sundell's minor cleanup, added comments and some extra error-checkings
for easier future error-tracking.
2006-09-04 22:19:13 +00:00
Daniel Stenberg
1e9f5845ab I fell over a new libtool that starts with a newline so we need to fetch
the two first lines to get the version string. The good news is that older
libtools have an empty line after the first so I think this works fine all
over...
2006-09-04 08:53:28 +00:00
Daniel Stenberg
c41dfc2501 oops, we're on the .6 track now 2006-09-04 08:43:44 +00:00
Daniel Stenberg
30ac7eced1 proper credit 2006-09-04 06:17:55 +00:00
Daniel Stenberg
466d093a92 - "Dortik" (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a patch that
while not fixing things very nicely, it does make the SOCKS5 proxy
  connection slightly better as it now acknowledges the timeout for connection
  and it no longer segfaults in the case when SOCKS requires authentication
  and you did not specify username:password.
2006-09-03 22:52:42 +00:00
Daniel Stenberg
1e9be353c2 Mohun Biswas' improvements and clarifications about the options and how to use
them.
2006-09-03 22:12:57 +00:00
Gisle Vanem
4f4277d9c7 Simplified #ifdef on WIN32; the statement
" !defined(__GNUC__) || defined(__MINGW32__)" implies
CygWin.
2006-09-03 13:52:07 +00:00
Gisle Vanem
6728bda5c5 Watcom lacks <sys/time.h>. 2006-09-03 13:45:42 +00:00
Daniel Stenberg
dc9f154823 added missing test 2006-08-31 22:18:08 +00:00
Daniel Stenberg
d7168a82e2 Dmitriy Sergeyev found and fixed a multi interface flaw when using asynch
name resolves. It could get stuck in the wrong state.
2006-08-31 12:53:39 +00:00
Gisle Vanem
c9c8ee3796 Added HAVE_SYS_TIME_H for djgpp and HighC. 2006-08-30 16:18:03 +00:00
Gisle Vanem
c7aae10300 Removed "#ifndef__WATCOMC__". Use "#ifdef HAVE_SYS_TIME_H" instead. 2006-08-30 16:17:06 +00:00
Gisle Vanem
909941405f Added support for more MS-DOS compilers. 2006-08-30 12:10:30 +00:00
Gisle Vanem
4031eb1d91 Avoid Metaware's High-C warning "'=' encountered where '==' may have been intended." 2006-08-29 21:11:55 +00:00
Gisle Vanem
59cf6fd4f0 Watcom lacks <sys/time.h>. 2006-08-29 18:45:55 +00:00
Gisle Vanem
6de9732a88 Added support for Watcom/DOS. 2006-08-29 18:40:36 +00:00
Gisle Vanem
1f7f500922 Updated dependency section. 2006-08-29 18:17:43 +00:00
Gisle Vanem
4b1462ec65 Don't include zlib headers in dependency output. 2006-08-29 18:13:54 +00:00
Gisle Vanem
6ed47f0aad Renamed config.dj -> config.dos. 2006-08-29 16:40:47 +00:00
Gisle Vanem
2d8c7ba9fc Use config.dos instead. Updated generated dependencies. 2006-08-29 16:35:11 +00:00
Gisle Vanem
3b342d18bc Removed. New file is config.dos. 2006-08-29 16:34:40 +00:00
Gisle Vanem
f24ad3800c Renamed config.dj -> config.dos. Added #ifdef-section for djgpp. 2006-08-29 16:33:41 +00:00
Gisle Vanem
e2ff369eba BUFSIZE defined in Metaware's <stdio.h>. Undefine to avoid warning. 2006-08-29 16:27:13 +00:00
Gisle Vanem
9691a78f6b Support other MS-DOS compilers (MSDOS is a djgpp built-in define). 2006-08-29 16:26:41 +00:00
Gisle Vanem
7ff6b6fafd Metaware's High-C has an ISO cpp. 2006-08-29 16:16:13 +00:00
Daniel Stenberg
7c621cfbdf Brad Spencer did
o made ares_version.h use extern "C" for c++ compilers
 o fixed compiler warnings in ares_getnameinfo.c
 o fixed a buffer position init for TCP reads
2006-08-29 15:17:47 +00:00
Daniel Stenberg
5acadc9cd7 David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to
allow applications to set their own socket options.
2006-08-29 14:39:33 +00:00
Daniel Stenberg
2ff609dd43 Armel Asselin reported that the 'running_handles' counter wasn't updated
properly if you removed a "live" handle from a multi handle with
curl_multi_remove_handle().
2006-08-25 13:53:20 +00:00
Daniel Stenberg
da48a6ba87 clarify the string syntax support in the CURLOPT_PROXY section 2006-08-23 21:49:44 +00:00
Dan Fandrich
cd6c58216a Use /usr/bin/env to invoke perl like the other test scripts. 2006-08-23 21:20:00 +00:00
Daniel Stenberg
bdbd0cf27a David McCreedy fixed a remaining mistake from the August 19 TYPE change. 2006-08-22 21:23:25 +00:00
Daniel Stenberg
d792937686 Peter Sylvester pointed out a flaw in the AllowServerConnect() in the FTP
code when doing pure ipv6 EPRT connections.
2006-08-22 21:21:01 +00:00
Daniel Stenberg
bac66ec26b as Jeff Pohlmeyer pointed out, first get the multi handle _then_ use it 2006-08-22 06:29:21 +00:00
Dan Fandrich
77516822f6 Workaround for Cray UNICOS 9.0 to fix ftp. 2006-08-21 22:28:19 +00:00
Daniel Stenberg
37d8c67530 clarify for what protocols the changes are 2006-08-21 06:39:52 +00:00
Daniel Stenberg
cfdcae4bc7 Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE
command on subsequent requests on a re-used connection unless it has to.
2006-08-19 21:18:36 +00:00
Daniel Stenberg
74a6921bc4 Armel Asselin fixed a crash in the FTP code when using SINGLECWD mode and
files in the root directory.
2006-08-18 23:17:33 +00:00
Daniel Stenberg
490cccba3c Andrew Biggs pointed out a "Expect: 100-continue" flaw where libcurl didn't
send the whole request at once, even though the Expect: header was disabled
by the application. An effect of this change is also that small (< 1024
bytes) POSTs are now always sent without Expect: header since we deem it
more costly to bother about that than the risk that we send the data in
vain.
2006-08-18 22:54:57 +00:00
Dan Fandrich
839441e236 Minor portability fixes to get things running on UNICOS 9.0 on a Cray Y-MP 2006-08-16 18:48:27 +00:00
Daniel Stenberg
ba9ea943e2 related info 2006-08-16 17:56:49 +00:00
Gisle Vanem
455087faae Use gnutls_strerror() for clearer error message. 2006-08-16 17:05:54 +00:00
Gisle Vanem
31def9e217 Use '_LIBICONV_VERSION' instead of variable '_libiconv_version'
to support older iconv versions.
2006-08-15 17:02:24 +00:00
Yang Tse
ee3514ccdc Replace exit() with return() in main() 2006-08-14 17:00:08 +00:00
Daniel Stenberg
cf606d7da0 add missing man page 2006-08-14 07:21:33 +00:00
Dan Fandrich
eb26a581f9 Use __minix to detect Minix, which works on both ACK and GCC. 2006-08-11 18:11:42 +00:00
Daniel Stenberg
b04cbebf86 option name spell fix 2006-08-09 20:54:17 +00:00
Dan Fandrich
4272af801f Only define the string prototypes in ANSI mode to reduce interference on
systems that prototype them slightly differently.
2006-08-09 16:36:17 +00:00
Dan Fandrich
0b633027cb Added eCos and Minix sections. 2006-08-09 16:10:20 +00:00
Gunter Knauf
93943ef949 added build info output. 2006-08-09 14:04:51 +00:00
Gunter Knauf
b184b87714 fixed some web links. 2006-08-09 13:59:39 +00:00
Gunter Knauf
a11473f85d fixed some web links. 2006-08-08 23:37:11 +00:00
Daniel Stenberg
1eedad27a2 Armel Asselin made the CURLOPT_PREQUOTE option work fine even when
CURLOPT_NOBODY is set true. PREQUOTE is then run roughly at the same place
in the command sequence as it would have run if there would've been a
transfer.
2006-08-08 22:56:46 +00:00
Gunter Knauf
ac02d379ba moved ugly NetWare hack to hostip.h so that hostip.c uses it too. 2006-08-08 22:37:53 +00:00
Daniel Stenberg
a4ebf5b507 Fixed a flaw in the "Expect: 100-continue" treatment. If you did two POSTs
on a persistent connection and allowed the first to use that header, you
could not disable it for the second request.
2006-08-08 21:12:49 +00:00
Daniel Stenberg
c410769588 make REALLY sure src/config.h.in is a copy of lib/config.h.in 2006-08-08 21:11:31 +00:00
Dan Fandrich
997a987943 Minix 3 doesn't have MSG_PEEK 2006-08-08 18:47:14 +00:00
Daniel Stenberg
6201dc083a better updating of the single timeout 2006-08-08 13:39:40 +00:00
Yang Tse
b33f47804d Allow again proper compilation outside of the source tree 2006-08-07 18:06:37 +00:00
Daniel Stenberg
7ba5e098a3 Jeff Pohlmeyer pointed out this stupid variable type error 2006-08-07 16:54:50 +00:00
Daniel Stenberg
824b78021c start working towards 7.15.6 2006-08-07 06:48:01 +00:00
Daniel Stenberg
31657c85e5 added contributors to 7.15.5 2006-08-07 06:46:05 +00:00
240 changed files with 10069 additions and 4265 deletions

284
CHANGES
View File

@@ -6,6 +6,276 @@
Changelog Changelog
Version 7.16.0 (30 October 2006)
Daniel (25 October 2006)
- Fixed CURLOPT_FAILONERROR to return CURLE_HTTP_RETURNED_ERROR even for the
case when 401 or 407 are returned, *IF* no auth credentials have been given.
The CURLOPT_FAILONERROR option is not possible to make fool-proof for 401
and 407 cases when auth credentials is given, but we've now covered this
somewhat more.
You might get some amounts of headers transferred before this situation is
detected, like for when a "100-continue" is received as a response to a
POST/PUT and a 401 or 407 is received immediately afterwards.
Added test 281 to verify this change.
Daniel (23 October 2006)
- Ravi Pratap provided a major update with pipelining fixes. We also no longer
re-use connections (for pipelining) before the name resolving is done.
Daniel (21 October 2006)
- Nir Soffer made the tests/libtest/Makefile.am use a proper variable for all
the single test applications' link and dependences, so that you easier can
override those from the command line when using make.
- Armel Asselin separated CA cert verification problems from problems with
reading the (local) CA cert file to let users easier pinpoint the actual
problem. CURLE_SSL_CACERT_BADFILE (77) is the new libcurl error code.
Daniel (18 October 2006)
- Removed the "protocol-guessing" for URLs with host names starting with FTPS
or TELNET since they are practically non-existant. This leaves us with only
three different prefixes that would assume the protocol is anything but
HTTP, and they are host names starting with "ftp.", "dict." or "ldap.".
Daniel (17 October 2006)
- Bug report #1579171 pointed out code flaws detected with "prefast", and they
were 1 - a too small memory clear with memset() in the threaded resolver and
2 - a range of potentially bad uses of the ctype family of is*() functions
such as isdigit(), isalnum(), isprint() and more. The latter made me switch
to using our own set of these functions/macros using uppercase letters, and
with some extra set of crazy typecasts to avoid mistakingly passing in
negative numbers to the underlying is*() functions.
- With Jeff Pohlmeyer's help, I fixed the expire timer when using
curl_multi_socket() during name resolves with c-ares and the LOW_SPEED
options now work fine with curl_multi_socket() as well.
Daniel (16 October 2006)
- Added a check in configure that simply tries to run a program (not when
cross-compiling) in order to detect problems with run-time libraries that
otherwise would occur when the sizeof tests for curl_off_t would run and
thus be much more confusing to users. The check of course should run after
all lib-checks are done and before any other test is used that would run an
executable built for testing-purposes.
Dan F (13 October 2006)
- The tagging of application/x-www-form-urlencoded POST body data sent
to the CURLOPT_DEBUGFUNCTION callback has been fixed (it was erroneously
included as part of the header). A message was also added to the
command line tool to show when data is being sent, enabled when
--verbose is used.
Daniel (12 October 2006)
- Starting now, adding an easy handle to a multi stack that was already added
to a multi stack will cause CURLM_BAD_EASY_HANDLE to get returned.
- Jeff Pohlmeyer has been working with the hiperfifo.c example source code,
and while doing so it became apparent that the current timeout system for
the socket API really was a bit awkward since it become quite some work to
be sure we have the correct timeout set.
Jeff then provided the new CURLMOPT_TIMERFUNCTION that is yet another
callback the app can set to get to know when the general timeout time
changes and thus for an application like hiperfifo.c it makes everything a
lot easier and nicer. There's a CURLMOPT_TIMERDATA option too of course in
good old libcurl tradition.
Jeff has also updated the hiperfifo.c example code to use this news.
Daniel (9 October 2006)
- Bogdan Nicula's second test case (posted Sun, 08 Oct 2006) converted to test
case 535 and it now runs fine. Again a problem with the pipelining code not
taking all possible (error) conditions into account.
Daniel (6 October 2006)
- Bogdan Nicula's hanging test case (posted Wed, 04 Oct 2006) was converted to
test case 533 and the test now runs fine.
Daniel (4 October 2006)
- Dmitriy Sergeyev provided an example source code that crashed CVS libcurl
but that worked nicely in 7.15.5. I converted it into test case 532 and
fixed the problem.
Daniel (29 September 2006)
- Removed a few other no-longer present options from the header file.
- Support for FTP third party transfers was removed. Here's why:
o The recent multi interface changes broke it and the design of the 3rd party
transfers made it very hard to fix the problems
o It was still blocking and thus nasty for the multi interface
o It was a lot of extra code for a very rarely used feature
o It didn't use the same code as for "plain" FTP transfers, so it didn't work
fine for IPv6 and it didn't properly re-use connections and more
o There's nobody around who's willing to work on and improve the existing
code
This does not mean that third party transfers are banned forever, only that
they need to be done better if they are to be re-added in the future.
The CURLOPT_SOURCE_* options are removed from the lib and so are the --3p*
options from the command line tool. For this reason, I also bumped the
version info for the lib.
Daniel (28 September 2006)
- Reported in #1561470 (http://curl.haxx.se/bug/view.cgi?id=1561470), libcurl
would crash if a bad function sequence was used when shutting down after
using the multi interface (i.e using easy_cleanup after multi_cleanup) so
precautions have been added to make sure it doesn't any more - test case 529
was added to verify.
Daniel (27 September 2006)
- The URL in the cookie jar file is now changed since it was giving a 404.
Reported by Timothy Stone. The new URL will take the visitor to a curl web
site mirror with the document.
Daniel (24 September 2006)
- Bernard Leak fixed configure --with-gssapi-libs.
- Cory Nelson made libcurl use the WSAPoll() function if built for Windows
Vista (_WIN32_WINNT >= 0x0600)
Daniel (23 September 2006)
- Mike Protts added --ftp-ssl-control to make curl use FTP-SSL, but only
encrypt the control connection and use the data connection "plain".
- Dmitriy Sergeyev provided a patch that made the SOCKS[45] code work better
as it now will read the full data sent from servers. The SOCKS-related code
was also moved to the new lib/socks.c source file.
Daniel (21 September 2006)
- Added test case 531 in an attempt to repeat bug report #1561470
(http://curl.haxx.se/bug/view.cgi?id=1561470) that is said to crash when an
FTP upload fails with the multi interface. It did not, but I made a failed
upload still assume the control connection to be fine.
Daniel (20 September 2006)
- Armel Asselin fixed problems when you gave a proxy URL with user name and
empty password or no password at all. Test case 278 and 279 were added to
verify.
Daniel (12 September 2006)
- Added docs/examples/10-at-a-time.c by Michael Wallner
- Added docs/examples/hiperfifo.c by Jeff Pohlmeyer
Daniel (11 September 2006)
- Fixed my breakage from earlier today so that doing curl_easy_cleanup() on a
handle that is part of a multi handle first removes the handle from the
stack.
- Added CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid to disable SSL
session-ID re-use on demand since there obviously are broken servers out
there that misbehave with session-IDs used.
- Jeff Pohlmeyer presented a *multi_socket()-using program that exposed a
problem with it (SIGSEGV-style). It clearly showed that the existing
socket-state and state-difference function wasn't good enough so I rewrote
it and could then re-run Jeff's program without any crash. The previous
version clearly could miss to tell the application when a handle changed
from using one socket to using another.
While I was at it (as I could use this as a means to track this problem
down), I've now added a 'magic' number to the easy handle struct that is
inited at curl_easy_init() time and cleared at curl_easy_cleanup() time that
we can use internally to detect that an easy handle seems to be fine, or at
least not closed or freed (freeing in debug builds fill the area with 0x13
bytes but in normal builds we can of course not assume any particular data
in the freed areas).
Daniel (9 September 2006)
- Michele Bini fixed how the hostname is put in NTLM packages. As servers
don't expect fully qualified names we need to cut them off at the first dot.
- Peter Sylvester cleaned up and fixed the getsockname() uses in ftp.c. Some
of them can be completetly removed though...
Daniel (6 September 2006)
- Ravi Pratap and I have implemented HTTP Pipelining support. Enable it for a
multi handle using CURLMOPT_PIPELINING and all HTTP connections done on that
handle will be attempted to get pipelined instead of done in parallell as
they are performed otherwise.
As a side-effect from this work, connections are now shared between all easy
handles within a multi handle, so if you use N easy handles for transfers,
each of them can pick up and re-use a connection that was previously used by
any of the handles, be it the same or one of the others.
This separation of the tight relationship between connections and easy
handles is most noticable when you close easy handles that have been used in
a multi handle and check amount of used memory or watch the debug output, as
there are times when libcurl will keep the easy handle around for a while
longer to be able to close it properly. Like for sending QUIT to close down
an FTP connection.
This is a major change.
Daniel (4 September 2006)
- Dmitry Rechkin (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a
patch that while not fixing things very nicely, it does make the SOCKS5
proxy connection slightly better as it now acknowledges the timeout for
connection and it no longer segfaults in the case when SOCKS requires
authentication and you did not specify username:password.
Daniel (31 August 2006)
- Dmitriy Sergeyev found and fixed a multi interface flaw when using asynch
name resolves. It could get stuck in the wrong state.
Gisle (29 August 2006)
- Added support for other MS-DOS compilers (desides djgpp). All MS-DOS
compiler now uses the same config.dos file (renamed to config.h by
make). libcurl now builds fine using Watcom and Metaware's High-C
using the Watt-32 tcp/ip-stack.
Daniel (29 August 2006)
- David McCreedy added CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA to
allow applications to set their own socket options.
Daniel (25 August 2006)
- Armel Asselin reported that the 'running_handles' counter wasn't updated
properly if you removed a "live" handle from a multi handle with
curl_multi_remove_handle().
Daniel (22 August 2006)
- David McCreedy fixed a remaining mistake from the August 19 TYPE change.
- Peter Sylvester pointed out a flaw in the AllowServerConnect() in the FTP
code when doing pure ipv6 EPRT connections.
Daniel (19 August 2006)
- Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE
command on subsequent requests on a re-used connection unless it has to.
- Armel Asselin fixed a crash in the FTP code when using SINGLECWD mode and
files in the root directory.
- Andrew Biggs pointed out a "Expect: 100-continue" flaw where libcurl didn't
send the whole request at once, even though the Expect: header was disabled
by the application. An effect of this change is also that small (< 1024
bytes) POSTs are now always sent without Expect: header since we deem it
more costly to bother about that than the risk that we send the data in
vain.
Daniel (9 August 2006)
- Armel Asselin made the CURLOPT_PREQUOTE option work fine even when
CURLOPT_NOBODY is set true. PREQUOTE is then run roughly at the same place
in the command sequence as it would have run if there would've been a
transfer.
Daniel (8 August 2006)
- Fixed a flaw in the "Expect: 100-continue" treatment. If you did two POSTs
on a persistent connection and allowed the first to use that header, you
could not disable it for the second request.
Daniel (7 August 2006)
- Domenico Andreolfound a quick build error which happened because
src/config.h.in was not a proper duplcate of lib/config.h.in which it
should've been and this was due to the maketgz script not doing the cp
properly.
Version 7.15.5 (7 August 2006) Version 7.15.5 (7 August 2006)
Daniel (2 August 2006) Daniel (2 August 2006)
@@ -99,7 +369,7 @@ Daniel (8 July 2006)
Daniel (4 July 2006) Daniel (4 July 2006)
- Toshiyuki Maezawa fixed a problem where you couldn't override the - Toshiyuki Maezawa fixed a problem where you couldn't override the
Proxy-Connection: header when using a proxy and not doing CONNECT. Proxy-Connection: header when using a proxy and not doing CONNECT.
Daniel (24 June 2006) Daniel (24 June 2006)
- Michael Wallner added curl_formget(), which allows an application to extract - Michael Wallner added curl_formget(), which allows an application to extract
(serialise) a previously built formpost (as with curl_formadd()). (serialise) a previously built formpost (as with curl_formadd()).
@@ -270,11 +540,11 @@ Daniel (4 May 2006)
already did this. already did this.
Daniel (2 May 2006) Daniel (2 May 2006)
- Added a --checkfor option to curl-config to allow users to easier - Added a --checkfor option to curl-config to allow users to easier
write for example shell scripts that test for the presence of a write for example shell scripts that test for the presence of a
new-enough libcurl version. If --checkfor is given a version string new-enough libcurl version. If --checkfor is given a version string
newer than what is currently installed, curl-config will return a newer than what is currently installed, curl-config will return a
non-zero exit code and output a string about the unfulfilled non-zero exit code and output a string about the unfulfilled
requirement. requirement.
Daniel (26 April 2006) Daniel (26 April 2006)
@@ -330,7 +600,7 @@ Daniel (7 April 2006)
CONV_FROM_NETWORK_FUNCTION CONV_FROM_NETWORK_FUNCTION
CONV_TO_NETWORK_FUNCTION CONV_TO_NETWORK_FUNCTION
CONV_FROM_UTF8_FUNCTION CONV_FROM_UTF8_FUNCTION
Daniel (5 April 2006) Daniel (5 April 2006)
- Michele Bini modified the NTLM code to work for his "weird IIS case" - Michele Bini modified the NTLM code to work for his "weird IIS case"

View File

@@ -1,57 +1,80 @@
Curl and libcurl 7.15.5 Curl and libcurl 7.16.0
Public curl release number: 95 Public curl release number: 96
Releases counted from the very beginning: 122 Releases counted from the very beginning: 123
Available command line options: 114 Available command line options: 112
Available curl_easy_setopt() options: 133 Available curl_easy_setopt() options: 133
Number of public functions in libcurl: 54 Number of public functions in libcurl: 54
Amount of public web site mirrors: 33 Amount of public web site mirrors: 37
Number of known libcurl bindings: 32 Number of known libcurl bindings: 35
Number of contributors: 506 Number of contributors: 515
This release includes the following changes: This release includes the following changes:
o added --ftp-ssl-reqd o Added CURLE_SSL_CACERT_BADFILE
o modified the prototype for the socket callback set with o Added CURLMOPT_TIMERFUNCTION and CURLMOPT_TIMERDATA
CURLMOPT_SOCKETFUNCTION o (FTP) the CURLOPT_SOURCE_* options are removed and so are the --3p* command
o added curl_multi_assign() line options
o added CURLOPT_FTP_ALTERNATIVE_TO_USER and --ftp-alternative-to-user o curl_multi_socket() and family are suitable to start using
o added a vcproj file for building libcurl o uses WSAPoll() on Windows Vista
o added curl_formget() o (FTP) --ftp-ssl-control was added
o added CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE o CURLOPT_SSL_SESSIONID_CACHE and --no-sessionid added
o added configure --enable-hidden-symbols o CURLMOPT_PIPELINING added for enabling HTTP pipelined transfers
o Made -K on a file that couldn't be read cause a warning to be displayed o multi handles now have a shared connection cache
o Added support for other MS-DOS compilers (besides djgpp)
o CURLOPT_SOCKOPTFUNCTION and CURLOPT_SOCKOPTDATA were added
o (FTP) libcurl avoids sending TYPE if the desired type was already set
o (FTP) CURLOPT_PREQUOTE works even when CURLOPT_NOBODY is set true
This release includes the following bugfixes: This release includes the following bugfixes:
o chunked encoding when custom header "Transfer-Encoding: chunked" is set o (HTTP) CURLOPT_FAILONERROR (curl -f) covers a few more reponse cases
o Curl_strerror() crash on unknown errors o curl_multi_socket() and the LOW_SPEED options
o changing Content-Type when doing formposts o curl_multi_socket() expire timer during c-ares name resolves
o added CURL_EXTERN to a few recent multi functions that lacked them o curl_multi_add_handle on an already added handle now fails gracefully
o splay-tree related problems for internal expire time handling o multi interface crash if bad function call order was used for cleanup
o FTP ASCII CRLF counter reset o put a new URL in saved cookie jar files
o cookie parser now compares paths case sensitive o configure --with-gssapi-libs
o an easy handle with shared DNS cache added to a multi handle caused a crash o SOCKS proxy connection fixes
o couldn't override the Proxy-Connection: header for non-CONNECT requests o (FTP) a failed upload does not invalidate the control connection
o curl_multi_fdset() could wrongly return -1 as max_fd value o proxy URL with user name and empty password or no password at all now work
o fixed a socket state problem with *multi_socket()
o (HTTP) NTLM hostname fix
o getsockname usage fixes
o SOCKS5 proxy connects can now time-out
o SOCKS5 connects that require auth no longer segfaults when auth not given
o multi interface using asynch resolves could get stuck in wrong state
o the 'running_handles' counter wasn't always updated properly when
curl_multi_remove_handle() was used
o (FTP) EPRT transfers with IPv6 didn't work properly
o (FTP) SINGLECWD mode and using files in the root dir
o (HTTP) Expect: header disabling work better
o (HTTP) "Expect: 100-continue" disable on second POST on re-used connection
o src/config.h.in is fixed
o (HTTP) POST data logged to the debug callback function is now correctly
tagged as data, not header
Other curl-related news: Other curl-related news:
o yassl 1.3.7 can now be used with libcurl as an optional TLS library for o a Smalltalk binding: http://curl.haxx.se/libcurl/smalltalk/
HTTPS/FTPS support: http://www.yassl.com/ o pycurl-7.15.5 was released: http://pycurl.sf.net
o cURLpp 0.6.0 was released: http://rrette.com/curlpp.html
o pycurl-7.15.4 was released: http://pycurl.sf.net
New curl mirrors: New curl mirrors:
o o http://curl.geosdreams.info/ is a new Polish mirror
o http://curl.gfiles.org/ is a new Russian mirror
o http://curl.online-mirror.de/ is a new German mirror
o http://curl.blogvoid.com/ is a new Canadian mirror
o http://curl.internet.bs/ is a new United Kingdom mirror
o http://curl2.haxx.se/ is a new Swedish mirror
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Dan Fandrich, Peter Silva, Arve Knudsen, Michael Wallner, Toshiyuki Maezawa, Domenico Andreoli, Armel Asselin, Gisle Vanem, Yang Tse, Andrew Biggs,
Ingmar Runge, Ates Goral, David McCreedy, Jari Sundell, Georg Horn, Peter Sylvester, David McCreedy, Dmitriy Sergeyev, Dmitry Rechkin,
Gisle Vanem, Yang Tse, Michael Jerris, Dan Nelson, Yves Lejeune, Jari Sundell, Ravi Pratap, Michele Bini, Jeff Pohlmeyer, Michael Wallner,
Maciej Karpiuk, Mark Lentczner Mike Protts, Cory Nelson, Bernard Leak, Bogdan Nicula, Dan Fandrich,
Nir Soffer
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,5 +1,6 @@
To get fixed in 7.15.5 (planned release: August 2006) To get fixed in 7.16.0 (planned release: October 2006)
====================== ======================
66 - 67 - Jeff Pohlmeyer's crashing pipelining test case
69 -

View File

@@ -976,6 +976,65 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [
]) # AC_DEFUN ]) # AC_DEFUN
dnl CURL_CHECK_STRUCT_TIMEVAL
dnl -------------------------------------------------
dnl Check for timeval struct
AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
AC_REQUIRE([AC_HEADER_TIME])dnl
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#undef inline
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#endif
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#endif
#else
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#endif
],[
struct timeval ts;
ts.tv_sec = 0;
ts.tv_usec = 0;
])
],[
ac_cv_struct_timeval="yes"
],[
ac_cv_struct_timeval="no"
])
])
case "$ac_cv_struct_timeval" in
yes)
AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1,
[Define to 1 if you have the timeval struct.])
;;
esac
]) # AC_DEFUN
dnl CURL_CHECK_NONBLOCKING_SOCKET dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist dnl Check for how to set a socket to non-blocking state. There seems to exist
@@ -1814,3 +1873,37 @@ else
AC_MSG_WARN([`missing' script is too old or missing]) AC_MSG_WARN([`missing' script is too old or missing])
fi fi
]) ])
dnl CURL_VERIFY_RUNTIMELIBS
dnl -------------------------------------------------
dnl Verify that the shared libs found so far can be used when running
dnl programs, since otherwise the situation will create odd configure errors
dnl that are misleading people.
dnl
dnl Make sure this test is run BEFORE the first test in the script that
dnl runs anything, which at the time of this writing is the AC_CHECK_SIZEOF
dnl macro. It must also run AFTER all lib-checking macros are complete.
AC_DEFUN([CURL_VERIFY_RUNTIMELIBS], [
dnl this test is of course not sensible if we are cross-compiling!
if test "x$cross_compiling" != xyes; then
dnl just run a program to verify that the libs checked for previous to this
dnl point also is available run-time!
AC_MSG_CHECKING([run-time libs availability])
AC_TRY_RUN([
main()
{
return 0;
}
],
AC_MSG_RESULT([fine]),
AC_MSG_RESULT([failed])
AC_MSG_ERROR([one or more libs available at link-time are not available run-time. Libs used at link-time: $LIBS])
)
dnl if this test fails, configure has already stopped
fi
])

View File

@@ -1,5 +1,27 @@
Changelog for the c-ares project Changelog for the c-ares project
* October 12 2006
- Prevent ares_getsock() to overflow if more than 16 sockets are used.
* September 11 2006
- Guilherme Balena Versiani: I noted a strange BUG in Win32 port
(ares_init.c/get_iphlpapi_dns_info() function): when I disable the network
by hand or disconnect the network cable in Windows 2000 or Windows XP, my
application gets 127.0.0.1 as the only name server. The problem comes from
'GetNetworkParams' function, that returns the empty string "" as the only
name server in that case. Moreover, the Windows implementation of
inet_addr() returns INADDR_LOOPBACK instead of INADDR_NONE.
* August 29 2006
- Brad Spencer did
o made ares_version.h use extern "C" for c++ compilers
o fixed compiler warnings in ares_getnameinfo.c
o fixed a buffer position init for TCP reads
* August 3 2006 * August 3 2006
- Ravi Pratap fixed ares_getsock() to actually return the proper bitmap and - Ravi Pratap fixed ares_getsock() to actually return the proper bitmap and

View File

@@ -13,6 +13,8 @@ CFLAGS = -O2 -Wall -DWATT32 -Dselect=select_s -DHAVE_AF_INET6 \
-DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET -DHAVE_STRUCT_IN6_ADDR \ -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET -DHAVE_STRUCT_IN6_ADDR \
-DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \ -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 \ -DHAVE_ARPA_NAMESER_H -DNS_INADDRSZ=4 \
-DHAVE_SYS_TIME_H -DHAVE_TIME_H \
-DTIME_WITH_SYS_TIME -DHAVE_STRUCT_TIMEVAL \
-DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -I$(WATT32_ROOT)/inc -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -I$(WATT32_ROOT)/inc
LDFLAGS = -s LDFLAGS = -s

View File

@@ -16,4 +16,6 @@ MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \ ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \ ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \
ares_getsock.3

View File

@@ -316,9 +316,10 @@ config.h: Makefile.netware
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ @echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@ @echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@ @echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ @echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ @echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
ifdef NW_WINSOCK ifdef NW_WINSOCK

View File

@@ -954,6 +954,65 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [
]) # AC_DEFUN ]) # AC_DEFUN
dnl CURL_CHECK_STRUCT_TIMEVAL
dnl -------------------------------------------------
dnl Check for timeval struct
AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [
AC_REQUIRE([AC_HEADER_TIME])dnl
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK])dnl
AC_REQUIRE([CURL_CHECK_HEADER_WINSOCK2])dnl
AC_CHECK_HEADERS(sys/types.h sys/time.h time.h)
AC_CACHE_CHECK([for struct timeval], [ac_cv_struct_timeval], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#undef inline
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#endif
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#endif
#else
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#endif
],[
struct timeval ts;
ts.tv_sec = 0;
ts.tv_usec = 0;
])
],[
ac_cv_struct_timeval="yes"
],[
ac_cv_struct_timeval="no"
])
])
case "$ac_cv_struct_timeval" in
yes)
AC_DEFINE_UNQUOTED(HAVE_STRUCT_TIMEVAL, 1,
[Define to 1 if you have the timeval struct.])
;;
esac
]) # AC_DEFUN
dnl CURL_CHECK_NONBLOCKING_SOCKET dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist dnl Check for how to set a socket to non-blocking state. There seems to exist

View File

@@ -1,4 +1,6 @@
/* Copyright 1998 by the Massachusetts Institute of Technology. /* Copyright 1998 by the Massachusetts Institute of Technology.
*
* $Id$
* *
* Permission to use, copy, modify, and distribute this * Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without * software and its documentation for any purpose and without
@@ -153,8 +155,8 @@ int main(int argc, char **argv)
fd_set read_fds, write_fds; fd_set read_fds, write_fds;
struct timeval *tvp, tv; struct timeval *tvp, tv;
#ifdef WIN32 #ifdef USE_WINSOCK
WORD wVersionRequested = MAKEWORD(1,1); WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
WSADATA wsaData; WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData); WSAStartup(wVersionRequested, &wsaData);
#endif #endif
@@ -162,10 +164,16 @@ int main(int argc, char **argv)
options.flags = ARES_FLAG_NOCHECKRESP; options.flags = ARES_FLAG_NOCHECKRESP;
options.servers = NULL; options.servers = NULL;
options.nservers = 0; options.nservers = 0;
while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1) while ((c = getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
{ {
switch (c) switch (c)
{ {
case 'd':
#ifdef WATT32
dbug_init();
#endif
break;
case 'f': case 'f':
/* Add a flag. */ /* Add a flag. */
for (i = 0; i < nflags; i++) for (i = 0; i < nflags; i++)
@@ -225,7 +233,7 @@ int main(int argc, char **argv)
case 'T': case 'T':
/* Set the TCP port number. */ /* Set the TCP port number. */
if (!isdigit((unsigned char)*optarg)) if (!ISDIGIT(*optarg))
usage(); usage();
options.tcp_port = (unsigned short)strtol(optarg, NULL, 0); options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
optmask |= ARES_OPT_TCP_PORT; optmask |= ARES_OPT_TCP_PORT;
@@ -233,7 +241,7 @@ int main(int argc, char **argv)
case 'U': case 'U':
/* Set the UDP port number. */ /* Set the UDP port number. */
if (!isdigit((unsigned char)*optarg)) if (!ISDIGIT(*optarg))
usage(); usage();
options.udp_port = (unsigned short)strtol(optarg, NULL, 0); options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
optmask |= ARES_OPT_UDP_PORT; optmask |= ARES_OPT_UDP_PORT;

View File

@@ -64,8 +64,8 @@ int main(int argc, char **argv)
struct in_addr addr4; struct in_addr addr4;
struct in6_addr addr6; struct in6_addr addr6;
#ifdef WIN32 #ifdef USE_WINSOCK
WORD wVersionRequested = MAKEWORD(1,1); WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
WSADATA wsaData; WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData); WSAStartup(wVersionRequested, &wsaData);
#endif #endif

View File

@@ -31,7 +31,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <tcp.h> #include <tcp.h>
#elif defined(WIN32) && !defined(__CYGWIN__) #elif defined(WIN32)
#include <winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#else #else

View File

@@ -54,7 +54,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
/* Get the address part. */ /* Get the address part. */
p = line; p = line;
while (*p && !isspace((unsigned char)*p)) while (*p && !ISSPACE(*p))
p++; p++;
if (!*p) if (!*p)
continue; continue;
@@ -76,12 +76,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
/* Get the canonical hostname. */ /* Get the canonical hostname. */
p++; p++;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
if (!*p) if (!*p)
continue; continue;
q = p; q = p;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
end_at_hostname = (*q == 0); end_at_hostname = (*q == 0);
*q = 0; *q = 0;
@@ -92,13 +92,13 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
{ {
/* Count the aliases. */ /* Count the aliases. */
p = q + 1; p = q + 1;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
while (*p) while (*p)
{ {
while (*p && !isspace((unsigned char)*p)) while (*p && !ISSPACE(*p))
p++; p++;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
naliases++; naliases++;
} }
@@ -128,12 +128,12 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
if (!end_at_hostname) if (!end_at_hostname)
{ {
p = canonical + strlen(canonical) + 1; p = canonical + strlen(canonical) + 1;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
while (*p) while (*p)
{ {
q = p; q = p;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
hostent->h_aliases[naliases] = malloc(q - p + 1); hostent->h_aliases[naliases] = malloc(q - p + 1);
if (hostent->h_aliases[naliases] == NULL) if (hostent->h_aliases[naliases] == NULL)
@@ -141,7 +141,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host)
memcpy(hostent->h_aliases[naliases], p, q - p); memcpy(hostent->h_aliases[naliases], p, q - p);
hostent->h_aliases[naliases][q - p] = 0; hostent->h_aliases[naliases][q - p] = 0;
p = q; p = q;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
naliases++; naliases++;
} }

View File

@@ -264,11 +264,11 @@ static char *lookup_service(unsigned short port, int flags,
char tmpbuf[4096]; char tmpbuf[4096];
if (port) if (port)
{ {
if (flags & ARES_NI_NUMERICSERV) if (flags & ARES_NI_NUMERICSERV)
sep = NULL; sep = NULL;
else else
{ {
if (flags & ARES_NI_UDP) if (flags & ARES_NI_UDP)
proto = "udp"; proto = "udp";
else if (flags & ARES_NI_SCTP) else if (flags & ARES_NI_SCTP)
@@ -288,15 +288,15 @@ static char *lookup_service(unsigned short port, int flags,
#elif GETSERVBYPORT_R_ARGS == 4 #elif GETSERVBYPORT_R_ARGS == 4
if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0) if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0)
sep = NULL; sep = NULL;
#else #else
/* Lets just hope the OS uses TLS! */ /* Lets just hope the OS uses TLS! */
sep = getservbyport(port, proto); sep = getservbyport(port, proto);
#endif #endif
#else #else
/* Lets just hope the OS uses TLS! */ /* Lets just hope the OS uses TLS! */
sep = getservbyport(port, proto); sep = getservbyport(port, proto);
#endif #endif
} }
if (sep && sep->s_name) if (sep && sep->s_name)
/* get service name */ /* get service name */
strcpy(tmpbuf, sep->s_name); strcpy(tmpbuf, sep->s_name);

View File

@@ -1,6 +1,6 @@
/* $Id$ */ /* $Id$ */
/* Copyright 2005 by Daniel Stenberg. /* Copyright (C) 2005 - 2006, Daniel Stenberg
* *
* Permission to use, copy, modify, and distribute this software and its * Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided * documentation for any purpose and without fee is hereby granted, provided
@@ -39,7 +39,9 @@ int ares_getsock(ares_channel channel,
if (!channel->queries) if (!channel->queries)
return 0; return 0;
for (i = 0; i < channel->nservers; i++) for (i = 0;
(i < channel->nservers) && (sockindex < ARES_GETSOCK_MAXNUM);
i++)
{ {
server = &channel->servers[i]; server = &channel->servers[i];
if (server->udp_socket != ARES_SOCKET_BAD) if (server->udp_socket != ARES_SOCKET_BAD)
@@ -56,13 +58,12 @@ int ares_getsock(ares_channel channel,
break; break;
socks[sockindex] = server->tcp_socket; socks[sockindex] = server->tcp_socket;
bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
sockindex++;
if (server->qhead) { if (server->qhead)
/* then the tcp socket is also writable! */ /* then the tcp socket is also writable! */
bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex-1); bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
}
sockindex++;
} }
} }
return bitmap; return bitmap;

View File

@@ -373,7 +373,8 @@ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
printf ("DNS Servers:\n" printf ("DNS Servers:\n"
" %s (primary)\n", fi->DnsServerList.IpAddress.String); " %s (primary)\n", fi->DnsServerList.IpAddress.String);
} }
if (inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE && if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
left > ip_size) left > ip_size)
{ {
ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String); ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
@@ -749,7 +750,7 @@ static int config_domain(ares_channel channel, char *str)
/* Set a single search domain. */ /* Set a single search domain. */
q = str; q = str;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
*q = 0; *q = 0;
return set_search(channel, str); return set_search(channel, str);
@@ -773,9 +774,9 @@ static int config_lookup(ares_channel channel, const char *str,
if (*p == *bindch) *l++ = 'b'; if (*p == *bindch) *l++ = 'b';
else *l++ = 'f'; else *l++ = 'f';
} }
while (*p && !isspace((unsigned char)*p) && (*p != ',')) while (*p && !ISSPACE(*p) && (*p != ','))
p++; p++;
while (*p && (isspace((unsigned char)*p) || (*p == ','))) while (*p && (ISSPACE(*p) || (*p == ',')))
p++; p++;
} }
*l = 0; *l = 0;
@@ -800,7 +801,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
while (more) while (more)
{ {
more = 0; more = 0;
while (*p && !isspace(*p) && *p != ',') while (*p && !ISSPACE(*p) && *p != ',')
p++; p++;
if (*p) if (*p)
@@ -860,7 +861,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
char ipbuf[16], ipbufpfx[32]; char ipbuf[16], ipbufpfx[32];
/* Find just the IP */ /* Find just the IP */
q = str; q = str;
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q)) while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
q++; q++;
memcpy(ipbuf, str, (int)(q-str)); memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = 0; ipbuf[(int)(q-str)] = 0;
@@ -868,7 +869,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
if (*q == '/') if (*q == '/')
{ {
const char *str2 = q+1; const char *str2 = q+1;
while (*q && *q != ';' && !isspace((unsigned char)*q)) while (*q && *q != ';' && !ISSPACE(*q))
q++; q++;
memcpy(ipbufpfx, str, (int)(q-str)); memcpy(ipbufpfx, str, (int)(q-str));
ipbufpfx[(int)(q-str)] = 0; ipbufpfx[(int)(q-str)] = 0;
@@ -917,11 +918,11 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
} }
else else
{ {
while (*q && *q != ';' && !isspace((unsigned char)*q)) while (*q && *q != ';' && !ISSPACE(*q))
q++; q++;
} }
str = q; str = q;
while (isspace((unsigned char)*str)) while (ISSPACE(*str))
str++; str++;
} }
@@ -947,9 +948,9 @@ static int set_search(ares_channel channel, const char *str)
p = str; p = str;
while (*p) while (*p)
{ {
while (*p && !isspace((unsigned char)*p)) while (*p && !ISSPACE(*p))
p++; p++;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
n++; n++;
} }
@@ -965,7 +966,7 @@ static int set_search(ares_channel channel, const char *str)
{ {
channel->ndomains = n; channel->ndomains = n;
q = p; q = p;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
channel->domains[n] = malloc(q - p + 1); channel->domains[n] = malloc(q - p + 1);
if (!channel->domains[n]) if (!channel->domains[n])
@@ -973,7 +974,7 @@ static int set_search(ares_channel channel, const char *str)
memcpy(channel->domains[n], p, q - p); memcpy(channel->domains[n], p, q - p);
channel->domains[n][q - p] = 0; channel->domains[n][q - p] = 0;
p = q; p = q;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
n++; n++;
} }
@@ -990,7 +991,7 @@ static int set_options(ares_channel channel, const char *str)
while (*p) while (*p)
{ {
q = p; q = p;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
val = try_option(p, q, "ndots:"); val = try_option(p, q, "ndots:");
if (val && channel->ndots == -1) if (val && channel->ndots == -1)
@@ -1002,7 +1003,7 @@ static int set_options(ares_channel channel, const char *str)
if (val && channel->tries == -1) if (val && channel->tries == -1)
channel->tries = atoi(val); channel->tries = atoi(val);
p = q; p = q;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
} }
@@ -1015,10 +1016,10 @@ static char *try_config(char *s, const char *opt)
size_t len; size_t len;
len = strlen(opt); len = strlen(opt);
if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len])) if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len]))
return NULL; return NULL;
s += len; s += len;
while (isspace((unsigned char)*s)) while (ISSPACE(*s))
s++; s++;
return s; return s;
} }

View File

@@ -59,7 +59,7 @@
#define TRUE 1 #define TRUE 1
#endif #endif
#if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS) #ifdef USE_WINSOCK
#define GET_ERRNO() WSAGetLastError() #define GET_ERRNO() WSAGetLastError()
#else #else
#define GET_ERRNO() errno #define GET_ERRNO() errno
@@ -160,7 +160,7 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now)
vec[n].iov_len = sendreq->len; vec[n].iov_len = sendreq->len;
n++; n++;
} }
wcount = (ssize_t)writev(server->tcp_socket, vec, n); wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
free(vec); free(vec);
if (wcount < 0) if (wcount < 0)
{ {
@@ -297,6 +297,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now)
free(server->tcp_buffer); free(server->tcp_buffer);
server->tcp_buffer = NULL; server->tcp_buffer = NULL;
server->tcp_lenbuf_pos = 0; server->tcp_lenbuf_pos = 0;
server->tcp_buffer_pos = 0;
} }
} }
} }

View File

@@ -239,15 +239,15 @@ static int single_domain(ares_channel channel, const char *name, char **s)
== ARES_SUCCESS) == ARES_SUCCESS)
{ {
if (strncasecmp(line, name, len) != 0 || if (strncasecmp(line, name, len) != 0 ||
!isspace((unsigned char)line[len])) !ISSPACE(line[len]))
continue; continue;
p = line + len; p = line + len;
while (isspace((unsigned char)*p)) while (ISSPACE(*p))
p++; p++;
if (*p) if (*p)
{ {
q = p + 1; q = p + 1;
while (*q && !isspace((unsigned char)*q)) while (*q && !ISSPACE(*q))
q++; q++;
*s = malloc(q - p + 1); *s = malloc(q - p + 1);
if (*s) if (*s)

View File

@@ -11,7 +11,15 @@
(ARES_VERSION_PATCH)) (ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.3.1" #define ARES_VERSION_STR "1.3.1"
#ifdef __cplusplus
extern "C" {
#endif
const char *ares_version(int *version); const char *ares_version(int *version);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@@ -29,6 +29,12 @@
#define HAVE_GETOPT_H 1 #define HAVE_GETOPT_H 1
#endif #endif
/* Define if you have the <sys/time.h> header file */
/* #define HAVE_SYS_TIME_H 1 */
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */ /* Define if you have the <unistd.h> header file. */
#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ #if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
defined(__POCC__) defined(__POCC__)
@@ -47,6 +53,16 @@
/* Define if you have the <ws2tcpip.h> header file. */ /* Define if you have the <ws2tcpip.h> header file. */
#define HAVE_WS2TCPIP_H 1 #define HAVE_WS2TCPIP_H 1
/* ---------------------------------------------------------------- */
/* OTHER HEADER INFO */
/* ---------------------------------------------------------------- */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if you can safely include both <sys/time.h> and <time.h>. */
/* #define TIME_WITH_SYS_TIME 1 */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* FUNCTIONS */ /* FUNCTIONS */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
@@ -121,6 +137,9 @@
/* Define this if you have struct sockaddr_storage */ /* Define this if you have struct sockaddr_storage */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1 #define HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define this if you have struct timeval */
#define HAVE_STRUCT_TIMEVAL 1
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* IPV6 COMPATIBILITY */ /* IPV6 COMPATIBILITY */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */

View File

@@ -265,6 +265,7 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_HEADER_TIME AC_HEADER_TIME
CURL_CHECK_STRUCT_TIMEVAL
AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(size_t)
AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long)

View File

@@ -79,14 +79,13 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
ch = *src++; ch = *src++;
if (ch == '0' && (src[0] == 'x' || src[0] == 'X') if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
&& isascii((unsigned char)(src[1])) && ISXDIGIT(src[1])) {
&& isxdigit((unsigned char)(src[1]))) {
/* Hexadecimal: Eat nybble string. */ /* Hexadecimal: Eat nybble string. */
if (size <= 0U) if (size <= 0U)
goto emsgsize; goto emsgsize;
dirty = 0; dirty = 0;
src++; /* skip x or X. */ src++; /* skip x or X. */
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
if (isupper(ch)) if (isupper(ch))
ch = tolower(ch); ch = tolower(ch);
n = (int)(strchr(xdigits, ch) - xdigits); n = (int)(strchr(xdigits, ch) - xdigits);
@@ -106,7 +105,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) (tmp << 4); *dst++ = (unsigned char) (tmp << 4);
} }
} else if (isascii(ch) && isdigit(ch)) { } else if (ISDIGIT(ch)) {
/* Decimal: eat dotted digit string. */ /* Decimal: eat dotted digit string. */
for (;;) { for (;;) {
tmp = 0; tmp = 0;
@@ -117,7 +116,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
if (tmp > 255) if (tmp > 255)
goto enoent; goto enoent;
} while ((ch = *src++) != '\0' && } while ((ch = *src++) != '\0' &&
isascii(ch) && isdigit(ch)); ISDIGIT(ch));
if (size-- <= 0U) if (size-- <= 0U)
goto emsgsize; goto emsgsize;
*dst++ = (unsigned char) tmp; *dst++ = (unsigned char) tmp;
@@ -126,15 +125,15 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
if (ch != '.') if (ch != '.')
goto enoent; goto enoent;
ch = *src++; ch = *src++;
if (!isascii(ch) || !isdigit(ch)) if (!ISDIGIT(ch))
goto enoent; goto enoent;
} }
} else } else
goto enoent; goto enoent;
bits = -1; bits = -1;
if (ch == '/' && isascii((unsigned char)(src[0])) && if (ch == '/' &&
isdigit((unsigned char)(src[0])) && dst > odst) { ISDIGIT(src[0]) && dst > odst) {
/* CIDR width specifier. Nothing can follow it. */ /* CIDR width specifier. Nothing can follow it. */
ch = *src++; /* Skip over the /. */ ch = *src++; /* Skip over the /. */
bits = 0; bits = 0;
@@ -142,7 +141,7 @@ inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
n = (int)(strchr(digits, ch) - digits); n = (int)(strchr(digits, ch) - digits);
bits *= 10; bits *= 10;
bits += n; bits += n;
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); } while ((ch = *src++) != '\0' && ISDIGIT(ch));
if (ch != '\0') if (ch != '\0')
goto enoent; goto enoent;
if (bits > 32) if (bits > 32)

View File

@@ -69,6 +69,22 @@
# endif # endif
#endif #endif
/*
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
* define USE_WINSOCK to 1 if we have and use WINSOCK API, else
* undefine USE_WINSOCK.
*/
#undef USE_WINSOCK
#ifdef HAVE_WINSOCK2_H
# define USE_WINSOCK 2
#else
# ifdef HAVE_WINSOCK_H
# define USE_WINSOCK 1
# endif
#endif
/* /*
* Work-arounds for systems without configure support * Work-arounds for systems without configure support
*/ */
@@ -105,7 +121,7 @@
* Typedef our socket type * Typedef our socket type
*/ */
#if defined(WIN32) && !defined(WATT32) #ifdef USE_WINSOCK
typedef SOCKET ares_socket_t; typedef SOCKET ares_socket_t;
#define ARES_SOCKET_BAD INVALID_SOCKET #define ARES_SOCKET_BAD INVALID_SOCKET
#else #else

View File

@@ -17,6 +17,16 @@
*/ */
/********************************************************************
* NOTICE *
* ======== *
* *
* Content of header files lib/setup_once.h and ares/setup_once.h *
* must be kept in sync. Modify the other one if you change this. *
* *
********************************************************************/
/* /*
* If we have the MSG_NOSIGNAL define, make sure we use * If we have the MSG_NOSIGNAL define, make sure we use
* it as the fourth argument of send() and recv() * it as the fourth argument of send() and recv()
@@ -67,9 +77,6 @@
(RECV_TYPE_ARG4)(SEND_4TH_ARG)) (RECV_TYPE_ARG4)(SEND_4TH_ARG))
#endif #endif
#else /* HAVE_RECV */ #else /* HAVE_RECV */
#ifdef DJGPP
#define sread(x,y,z) (ssize_t)read_s((int)(x), (char *)(y), (int)(z))
#endif
#ifndef sread #ifndef sread
/* */ /* */
Error Missing_definition_of_macro_sread Error Missing_definition_of_macro_sread
@@ -94,9 +101,6 @@
(SEND_TYPE_ARG4)(SEND_4TH_ARG)) (SEND_TYPE_ARG4)(SEND_4TH_ARG))
#endif #endif
#else /* HAVE_SEND */ #else /* HAVE_SEND */
#ifdef DJGPP
#define swrite(x,y,z) (ssize_t)write_s((int)(x), (char *)(y), (int)(z))
#endif
#ifndef swrite #ifndef swrite
/* */ /* */
Error Missing_definition_of_macro_swrite Error Missing_definition_of_macro_swrite
@@ -105,5 +109,19 @@
#endif /* HAVE_SEND */ #endif /* HAVE_SEND */
/*
* Uppercase macro versions of ANSI/ISO is*() functions/macros which
* avoid negative number inputs with argument byte codes > 127.
*/
#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
#endif /* __SETUP_ONCE_H */ #endif /* __SETUP_ONCE_H */

View File

@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___ # | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____| # \___|\___/|_| \_\_____|
# #
# Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. # Copyright (C) 1998 - 2006, 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
@@ -140,7 +140,7 @@ else
libtoolize=`findtool $LIBTOOLIZE` libtoolize=`findtool $LIBTOOLIZE`
fi fi
lt_pversion=`$libtool --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'` lt_pversion=`$libtool --version 2>/dev/null|head -n 2|sed -e 's/^[^0-9]*//g' -e 's/[- ].*//'`
if test -z "$lt_pversion"; then if test -z "$lt_pversion"; then
echo "buildconf: libtool not found." echo "buildconf: libtool not found."
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed" echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"

View File

@@ -28,7 +28,7 @@ dnl We don't know the version number "staticly" so we use a dash here
AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/]) AC_INIT(curl, [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
dnl configure script copyright dnl configure script copyright
AC_COPYRIGHT([Copyright (c) 1998 - 2005 Daniel Stenberg, <daniel@haxx.se> AC_COPYRIGHT([Copyright (c) 1998 - 2006 Daniel Stenberg, <daniel@haxx.se>
This configure script may be copied, distributed and modified under the This configure script may be copied, distributed and modified under the
terms of the curl license; see COPYING for more details]) terms of the curl license; see COPYING for more details])
@@ -747,7 +747,7 @@ AC_ARG_WITH(gssapi-includes,
AC_ARG_WITH(gssapi-libs, AC_ARG_WITH(gssapi-libs,
AC_HELP_STRING([--with-gssapi-libs=DIR], AC_HELP_STRING([--with-gssapi-libs=DIR],
[Specify location of GSSAPI libs]), [Specify location of GSSAPI libs]),
[ GSSAPI_LIBS="-L$withval" [ GSSAPI_LIB_DIR="-L$withval"
want_gss="yes" ] want_gss="yes" ]
) )
@@ -1527,6 +1527,8 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_HEADER_TIME AC_HEADER_TIME
CURL_CHECK_STRUCT_TIMEVAL
CURL_VERIFY_RUNTIMELIBS
AC_CHECK_SIZEOF(curl_off_t, ,[ AC_CHECK_SIZEOF(curl_off_t, ,[
#include <stdio.h> #include <stdio.h>

View File

@@ -155,6 +155,11 @@ S-Lang
S-Lang binding written by John E Davis S-Lang binding written by John E Davis
http://www.jedsoft.org/slang/modules/curl.html http://www.jedsoft.org/slang/modules/curl.html
Smalltalk
Smalltalk binding written by Danil Osipchuk
http://www.squeaksource.com/CurlPlugin/
SPL SPL
SPL binding written by Clifford Wolf SPL binding written by Clifford Wolf

View File

@@ -87,7 +87,6 @@ FTP
- via http-proxy - via http-proxy
- all operations can be tunneled through a http-proxy - all operations can be tunneled through a http-proxy
- customizable to retrieve file modification date - customizable to retrieve file modification date
- third party transfers
- no dir depth limit - no dir depth limit
FTPS (*1) FTPS (*1)

View File

@@ -16,7 +16,6 @@ Installing Binary Packages
UNIX UNIX
==== ====
A normal unix installation is made in three or four steps (after you've A normal unix installation is made in three or four steps (after you've
unpacked the source archive): unpacked the source archive):
@@ -141,6 +140,7 @@ UNIX
yassl with its OpenSSL emulation enabled and point to that directory root yassl with its OpenSSL emulation enabled and point to that directory root
with configure --with-ssl. with configure --with-ssl.
Win32 Win32
===== =====
@@ -292,7 +292,6 @@ Win32
IBM OS/2 IBM OS/2
======== ========
Building under OS/2 is not much different from building under unix. Building under OS/2 is not much different from building under unix.
You need: You need:
@@ -320,6 +319,7 @@ IBM OS/2
If you're getting huge binaries, probably your makefiles have the -g in If you're getting huge binaries, probably your makefiles have the -g in
CFLAGS. CFLAGS.
VMS VMS
=== ===
(The VMS section is in whole contributed by the friendly Nico Baggus) (The VMS section is in whole contributed by the friendly Nico Baggus)
@@ -390,6 +390,7 @@ VMS
13-jul-2001 13-jul-2001
N. Baggus N. Baggus
QNX QNX
=== ===
(This section was graciously brought to us by David Bentham) (This section was graciously brought to us by David Bentham)
@@ -441,17 +442,16 @@ AmigaOS
NetWare NetWare
======= =======
To compile curl.nlm / libcurl.nlm you need: To compile curl.nlm / libcurl.nlm you need:
- 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.net/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.net/mirror/zlib/
- optional OpenSSL sources (version 0.9.8 or later which builds with BSD); - optional OpenSSL sources (version 0.9.8 or later which builds with BSD);
Set a search path to your compiler, linker and tools; on Linux make Set a search path to your compiler, linker and tools; on Linux make
@@ -465,14 +465,101 @@ NetWare
with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked... with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...
Any help in testing appreciated! Any help in testing appreciated!
Builds automatically created 8 times a day from current CVS are here: Builds automatically created 8 times a day from current CVS are here:
http://www.gknw.com/mirror/curl/autobuilds/ http://www.gknw.net/mirror/curl/autobuilds/
the status of these builds can be viewed at the autobuild table: the status of these builds can be viewed at the autobuild table:
http://curl.haxx.se/auto/ http://curl.haxx.se/auto/
eCos
====
curl does not use the eCos build system, so you must first build eCos
separately, then link curl to the resulting eCos library. Here's a sample
configure line to do so on an x86 Linux box targeting x86:
GCCLIB=`gcc -print-libgcc-file-name` && \
CFLAGS="-D__ECOS=1 -nostdinc -I$ECOS_INSTALL/include \
-I`dirname $GCCLIB`/include" \
LDFLAGS="-nostdlib -Wl,--gc-sections -Wl,-static \
-L$ECOS_INSTALL/lib -Ttarget.ld -ltarget" \
./configure --host=i386 --disable-shared \
--without-ssl --without-zlib --disable-manual --disable-ldap
In most cases, eCos users will be using libcurl from within a custom
embedded application. Using the standard 'curl' executable from
within eCos means facing the limitation of the standard eCos C
startup code which does not allow passing arguments in main(). To
run 'curl' from eCos and have it do something useful, you will need
to either modify the eCos startup code to pass in some arguments, or
modify the curl application itself to retrieve its arguments from
some location set by the bootloader or hard-code them.
Something like the following patch could be used to hard-code some
arguments. The MTAB_ENTRY line mounts a RAM disk as the root filesystem
(without mounting some kind of filesystem, eCos errors out all file
operations which curl does not take to well). The next section synthesizes
some command-line arguments for curl to use, in this case to direct curl
to read further arguments from a file. It then creates that file on the
RAM disk and places within it a URL to download: a file: URL that
just happens to point to the configuration file itself. The results
of running curl in this way is the contents of the configuration file
printed to the console.
--- src/main.c 19 Jul 2006 19:09:56 -0000 1.363
+++ src/main.c 24 Jul 2006 21:37:23 -0000
@@ -4286,11 +4286,31 @@
}
+#ifdef __ECOS
+#include <cyg/fileio/fileio.h>
+MTAB_ENTRY( testfs_mte1,
+ "/",
+ "ramfs",
+ "",
+ 0);
+#endif
int main(int argc, char *argv[])
{
int res;
struct Configurable config;
+#ifdef __ECOS
+ char *args[] = {"ecos-curl", "-K", "curlconf.txt"};
+ FILE *f;
+ argc = sizeof(args)/sizeof(args[0]);
+ argv = args;
+
+ f = fopen("curlconf.txt", "w");
+ if (f) {
+ fprintf(f, "--url file:curlconf.txt");
+ fclose(f);
+ }
+#endif
memset(&config, 0, sizeof(struct Configurable));
config.errors = stderr; /* default errors to stderr */
Minix
=====
curl can be compiled on Minix 3 using gcc (ACK has a few problems due
to mismatched headers and libraries as of ver. 3.1.2). The gcc and bash
packages must be installed first. The default heap size allocated to
bash is inadequate for running configure and will result in out of memory
errors. Increase it with the command:
chmem =2048000 /usr/local/bin/bash
Make sure gcc and bash are in the PATH then configure curl with a
command like this:
./configure GREP=/usr/bin/grep AR=/usr/gnu/bin/gar --disable-ldap
Then simply run 'make'.
CROSS COMPILE CROSS COMPILE
============= =============
(This section was graciously brought to us by Jim Duey, with additions by (This section was graciously brought to us by Jim Duey, with additions by
Dan Fandrich) Dan Fandrich)
@@ -518,9 +605,9 @@ CROSS COMPILE
./configure --host=ARCH-OS ./configure --host=ARCH-OS
REDUCING SIZE REDUCING SIZE
============= =============
There are a number of configure options that can be used to reduce the There are a number of configure options that can be used to reduce the
size of libcurl for embedded applications where binary size is an size of libcurl for embedded applications where binary size is an
important factor. First, be sure to set the CFLAGS variable when important factor. First, be sure to set the CFLAGS variable when
@@ -542,7 +629,7 @@ REDUCING SIZE
--disable-crypto-auth (disables HTTP cryptographic authentication) --disable-crypto-auth (disables HTTP cryptographic authentication)
--disable-ipv6 (disables support for IPv6) --disable-ipv6 (disables support for IPv6)
--disable-verbose (eliminates debugging strings and error code strings) --disable-verbose (eliminates debugging strings and error code strings)
--enable-hidden-symbols (eliminates unneeded symbols in library) --enable-hidden-symbols (eliminates unneeded symbols in the shared library)
--without-libidn (disables support for the libidn DNS library) --without-libidn (disables support for the libidn DNS library)
--without-ssl (disables support for SSL/TLS) --without-ssl (disables support for SSL/TLS)
--without-zlib (disables support for on-the-fly decompression) --without-zlib (disables support for on-the-fly decompression)
@@ -553,7 +640,7 @@ REDUCING SIZE
Be sure also to strip debugging symbols from your binaries after Be sure also to strip debugging symbols from your binaries after
compiling using 'strip' (or the appropriate variant if cross-compiling). compiling using 'strip' (or the appropriate variant if cross-compiling).
If space is really tight, you may be able to remove some unneeded If space is really tight, you may be able to remove some unneeded
sections of the library using the -R option to objcopy (e.g. the sections of the shared library using the -R option to objcopy (e.g. the
.comment section). .comment section).
Using these techniques it is possible to create an HTTP-only shared Using these techniques it is possible to create an HTTP-only shared
@@ -597,12 +684,15 @@ PORTS
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6 - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
- StrongARM NetBSD 1.4.1 - StrongARM NetBSD 1.4.1
- Ultrix 4.3a - Ultrix 4.3a
- UNICOS 9.0
- i386 BeOS - i386 BeOS
- i386 DOS - i386 DOS
- i386 eCos 1.3.1
- i386 Esix 4.1 - i386 Esix 4.1
- i386 FreeBSD - i386 FreeBSD
- i386 HURD - i386 HURD
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
- i386 MINIX 3.1.2
- i386 NetBSD - i386 NetBSD
- i386 Novell NetWare - i386 Novell NetWare
- i386 OS/2 - i386 OS/2

View File

@@ -3,7 +3,12 @@ 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!
34. The SOCKS connection codes don't properly acknowledge (connect) timeouts. 35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
bad when used with the multi interface.
34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
Also see #12. According to bug #1556528, even the SOCKS5 connect code does
not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
33. Doing multi-pass HTTP authentication on a non-default port does not work. 33. Doing multi-pass HTTP authentication on a non-default port does not work.
This happens because the multi-pass code abuses the redirect following code This happens because the multi-pass code abuses the redirect following code
@@ -42,8 +47,7 @@ may have been fixed since this was written!
25. When doing a CONNECT request with curl it doesn't properly handle if the 25. When doing a CONNECT request with curl it doesn't properly handle if the
proxy closes the connection within the authentication "negotiation phase". proxy closes the connection within the authentication "negotiation phase".
Like if you do HTTPS or similar over a proxy and you use perhaps Like if you do HTTPS or similar over a proxy and you use perhaps
--proxy-anyauth. There's work in progress on this problem, and a recent --proxy-anyauth.
patch was posted here: http://curl.haxx.se/mail/lib-2005-08/0074.html
23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy. 23. We don't support SOCKS for IPv6. We don't support FTPS over a SOCKS proxy.
We don't have any test cases for SOCKS proxy. We probably have even more We don't have any test cases for SOCKS proxy. We probably have even more
@@ -68,9 +72,6 @@ may have been fixed since this was written!
Since 7.15.4 at least line endings are converted. Since 7.15.4 at least line endings are converted.
19. FTP 3rd party transfers with the multi interface doesn't work. Test:
define CURL_MULTIEASY, rebuild curl, run test case 230 - 232.
16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>, 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 <password>, and <fpath> components, encoded as "%00". The problem is that
curl_unescape does not detect this, but instead returns a shortened C curl_unescape does not detect this, but instead returns a shortened C
@@ -92,7 +93,7 @@ may have been fixed since this was written!
12. 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).
11. 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).

View File

@@ -31,6 +31,15 @@ SIMPLE USAGE
curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/ curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/
Get a file off an FTPS server:
curl ftps://files.are.secure.com/secrets.txt
or use the more appropriate FTPS way to get the same file:
curl --ftp-ssl ftp://files.are.secure.com/secrets.txt
DOWNLOAD TO A FILE DOWNLOAD TO A FILE
Get a web page and store in a local file: Get a web page and store in a local file:
@@ -64,6 +73,10 @@ USING PASSWORDS
It is just like for FTP, but you may also want to specify and use It is just like for FTP, but you may also want to specify and use
SSL-specific options for certificates etc. SSL-specific options for certificates etc.
Note that using FTPS:// as prefix is the "implicit" way as described in the
standards while the recommended "explicit" way is done by using FTP:// and
the --ftp-ssl option.
HTTP HTTP
The HTTP URL doesn't support user and password in the URL string. Curl The HTTP URL doesn't support user and password in the URL string. Curl
@@ -105,6 +118,8 @@ PROXY
curl -U user:passwd -x my-proxy:888 http://www.get.this/ curl -U user:passwd -x my-proxy:888 http://www.get.this/
curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5.
See also the environment variables Curl support that offer further proxy See also the environment variables Curl support that offer further proxy
control. control.
@@ -846,6 +861,22 @@ PERSISTENT CONNECTIONS
transfers faster. If you use a http proxy for file transfers, practically transfers faster. If you use a http proxy for file transfers, practically
all transfers will be persistent. all transfers will be persistent.
MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE
As is mentioned above, you can download multiple files with one command line
by simply adding more URLs. If you want those to get saved to a local file
instead of just printed to stdout, you need to add one save option for each
URL you specify. Note that this also goes for the -O option.
For example: get two files and use -O for the first and a custom file
name for the second:
curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg
You can also upload multiple files in a similar fashion:
curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt
MAILING LISTS MAILING LISTS
For your convenience, we have several open mailing lists to discuss curl, For your convenience, we have several open mailing lists to discuss curl,

View File

@@ -36,6 +36,7 @@ Angus Mackay
Antoine Calando Antoine Calando
Anton Kalmykov Anton Kalmykov
Arkadiusz Miskiewicz Arkadiusz Miskiewicz
Arve Knudsen
Ates Goral Ates Goral
Augustus Saunders Augustus Saunders
Avery Fay Avery Fay
@@ -81,6 +82,7 @@ Damien Adant
Dan Becker Dan Becker
Dan C Dan C
Dan Fandrich Dan Fandrich
Dan Nelson
Dan Torop Dan Torop
Dan Zitter Dan Zitter
Daniel Stenberg Daniel Stenberg
@@ -194,6 +196,7 @@ Ignacio Vazquez-Abrams
Igor Polyakov Igor Polyakov
Ilguiz Latypov Ilguiz Latypov
Ilja van Sprundel Ilja van Sprundel
Ingmar Runge
Ingo Ralf Blum Ingo Ralf Blum
Ingo Wilken Ingo Wilken
Jacky Lam Jacky Lam
@@ -208,6 +211,7 @@ Jamie Lokier
Jamie Newton Jamie Newton
Jamie Wilkinson Jamie Wilkinson
Jan Kunder Jan Kunder
Jari Sundell
Jason S. Priebe Jason S. Priebe
Jaz Fresh Jaz Fresh
Jean Jacques Drouin Jean Jacques Drouin
@@ -292,6 +296,7 @@ Lucas Adamski
Lukasz Czekierda Lukasz Czekierda
Luke Call Luke Call
Luong Dinh Dung Luong Dinh Dung
Maciej Karpiuk
Maciej W. Rozycki Maciej W. Rozycki
Marc Boucher Marc Boucher
Marcelo Juchem Marcelo Juchem
@@ -301,6 +306,7 @@ Marcus Webster
Mario Schroeder Mario Schroeder
Mark Butler Mark Butler
Mark Eichin Mark Eichin
Mark Lentczner
Markus Koetter Markus Koetter
Markus Moeller Markus Moeller
Markus Oberhumer Markus Oberhumer
@@ -321,6 +327,7 @@ Mettgut Jamalla
Michael Benedict Michael Benedict
Michael Curtis Michael Curtis
Michael Jahn Michael Jahn
Michael Jerris
Michael Mealling Michael Mealling
Michael Wallner Michael Wallner
Michal Bonino Michal Bonino
@@ -371,6 +378,7 @@ Peter Bray
Peter Forret Peter Forret
Peter Heuchert Peter Heuchert
Peter Pentchev Peter Pentchev
Peter Silva
Peter Su Peter Su
Peter Sylvester Peter Sylvester
Peter Todd Peter Todd
@@ -506,6 +514,7 @@ Wojciech Zwiefka
Xavier Bouchoux Xavier Bouchoux
Yang Tse Yang Tse
Yarram Sunil Yarram Sunil
Yves Lejeune
Zvi Har'El Zvi Har'El
nk nk
swalkaus at yahoo.com swalkaus at yahoo.com

View File

@@ -115,10 +115,6 @@ TODO
HTTP HTTP
* Pipelining. Sending multiple requests before the previous one(s) are done.
This could possibly be implemented using the multi interface to queue
requests and the response data.
* When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has * 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 never been reported as causing trouble to anyone, but should be considered
to use the HTTP version the user has chosen. to use the HTTP version the user has chosen.

View File

@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl 1 "21 Mar 2006" "Curl 7.15.4" "Curl Manual" .TH curl 1 "23 Sep 2006" "Curl 7.16.0" "Curl Manual"
.SH NAME .SH NAME
curl \- transfer a URL curl \- transfer a URL
.SH SYNOPSIS .SH SYNOPSIS
@@ -34,9 +34,9 @@ protocols (HTTP, HTTPS, FTP, FTPS, TFTP, DICT, TELNET, LDAP or FILE).
The command is designed to work without user interaction. The command is designed to work without user interaction.
curl offers a busload of useful tricks like proxy support, user curl offers a busload of useful tricks like proxy support, user
authentication, ftp upload, HTTP post, SSL (https:) connections, cookies, file authentication, ftp upload, HTTP post, SSL connections, cookies, file transfer
transfer resume and more. As you will see below, the amount of features will resume and more. As you will see below, the amount of features will make your
make your head spin! head spin!
curl is powered by libcurl for all transfer-related features. See curl is powered by libcurl for all transfer-related features. See
.BR libcurl (3) .BR libcurl (3)
@@ -312,25 +312,25 @@ run curl.
If this option is used several times, each occurrence will toggle this on/off. If this option is used several times, each occurrence will toggle this on/off.
.IP "--egd-file <file>" .IP "--egd-file <file>"
(HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The (SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket
socket is used to seed the random engine for SSL connections. See also the is used to seed the random engine for SSL connections. See also the
\fI--random-file\fP option. \fI--random-file\fP option.
.IP "-E/--cert <certificate[:password]>" .IP "-E/--cert <certificate[:password]>"
(HTTPS) (SSL) Tells curl to use the specified certificate file when getting a file
Tells curl to use the specified certificate file when getting a file with HTTPS or FTPS. The certificate must be in PEM format. If the optional
with HTTPS. The certificate must be in PEM format. password isn't specified, it will be queried for on the terminal. Note that
If the optional password isn't specified, it will be queried for on this option assumes a \&"certificate" file that is the private key and the
the terminal. Note that this certificate is the private key and the private private certificate concatenated! See \fI--cert\P and \fI--key\fP to specify
certificate concatenated! them independently.
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 "--cert-type <type>" .IP "--cert-type <type>"
(SSL) Tells curl what certificate type the provided certificate is in. PEM, (SSL) Tells curl what certificate type the provided certificate is in. PEM,
DER and ENG are recognized types. DER and ENG are recognized types. If not specified, PEM is assumed.
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 "--cacert <CA certificate>" .IP "--cacert <CA certificate>"
(HTTPS) Tells curl to use the specified certificate file to verify the (SSL) Tells curl to use the specified certificate file to verify the
peer. The file may contain multiple CA certificates. The certificate(s) must peer. The file may contain multiple CA certificates. The certificate(s) must
be in PEM format. be in PEM format.
@@ -344,10 +344,10 @@ Current Working Directory, or in any folder along your PATH.
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 "--capath <CA certificate directory>" .IP "--capath <CA certificate directory>"
(HTTPS) Tells curl to use the specified certificate directory to verify the (SSL) Tells curl to use the specified certificate directory to verify the
peer. The certificates must be in PEM format, and the directory must have been peer. The certificates must be in PEM format, and the directory must have been
processed using the c_rehash utility supplied with openssl. Using processed using the c_rehash utility supplied with openssl. Using
\fI--capath\fP can allow curl to make https connections much more efficiently \fI--capath\fP can allow curl to make SSL-connections much more efficiently
than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA
certificates. certificates.
@@ -359,6 +359,10 @@ normal cases when a HTTP server fails to deliver a document, it returns an
HTML document stating so (which often also describes why and more). This flag HTML document stating so (which often also describes why and more). This flag
will prevent curl from outputting that and return error 22. will prevent curl from outputting that and return error 22.
This method is not fail-safe and there are occasions where non-succesful
response codes will slip through, especially when authentication is involved
(response codes 401 and 407).
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]" .IP "--ftp-account [data]"
(FTP) When an FTP server asks for "account data" after user name and password (FTP) When an FTP server asks for "account data" after user name and password
@@ -395,7 +399,6 @@ in 7.11.0)
If this option is used several times, the following occurrences make no If this option is used several times, the following occurrences make no
difference. difference.
.IP "--ftp-alternative-to-user <command>" .IP "--ftp-alternative-to-user <command>"
(FTP) If authenticating with the USER and PASS commands fails, send this (FTP) If authenticating with the USER and PASS commands fails, send this
command. When connecting to Tumbleweed's Secure Transport server over FTPS command. When connecting to Tumbleweed's Secure Transport server over FTPS
@@ -412,9 +415,16 @@ This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
If this option is used twice, the second will again use the server's suggested If this option is used twice, the second will again use the server's suggested
address. address.
.IP "--ftp-ssl" .IP "--ftp-ssl"
(FTP) Try to use SSL/TLS for the FTP connection. (FTP) Try to use SSL/TLS for the FTP connection. Reverts to a non-secure
Reverts to a non-secure connection if the server doesn't support SSL/TLS. connection if the server doesn't support SSL/TLS. See also
(Added in 7.11.0) \fI--ftp-ssl-control\fP and \fI--ftp-ssl-reqd\fP for different levels of
encryption required. (Added in 7.11.0)
If this option is used twice, the second will again disable this.
.IP "--ftp-ssl-control"
(FTP) Require SSL/TLS for the ftp login, clear for transfer. Allows secure
authentication, but non-encrypted data transfers for efficiency. Fails the
transfer if the server doesn't support SSL/TLS. (Added in 7.16.0)
If this option is used twice, the second will again disable this. If this option is used twice, the second will again disable this.
.IP "--ftp-ssl-reqd" .IP "--ftp-ssl-reqd"
@@ -489,9 +499,9 @@ of extra headers. Note that if you should add a custom header that has the
same name as one of the internal ones curl would use, your externally set same name as one of the internal ones curl would use, your externally set
header will be used instead of the internal one. This allows you to make even header will be used instead of the internal one. This allows you to make even
trickier stuff than curl would normally do. You should not replace internally trickier stuff than curl would normally do. You should not replace internally
set headers without knowing perfectly well what you're doing. Replacing an set headers without knowing perfectly well what you're doing. Remove an
internal header with one without content on the right side of the colon will internal header by giving a replacement without content on the right side of
prevent that header from appearing. the colon, as in: -H \&"Host:".
curl will make sure that each header you add/replace get sent with the proper curl will make sure that each header you add/replace get sent with the proper
end of line marker, you should thus \fBnot\fP add that as a part of the header end of line marker, you should thus \fBnot\fP add that as a part of the header
@@ -540,6 +550,9 @@ and transfers. All SSL connections are attempted to be made secure by using
the CA certificate bundle installed by default. This makes all connections the CA certificate bundle installed by default. This makes all connections
considered "insecure" to fail unless \fI-k/--insecure\fP is used. considered "insecure" to fail unless \fI-k/--insecure\fP is used.
See this online resource for further details:
\fBhttp://curl.haxx.se/docs/sslcerts.html\fP
If this option is used twice, the second time will again disable it. If this option is used twice, the second time will again disable it.
.IP "--key <key>" .IP "--key <key>"
(SSL) Private key file name. Allows you to provide your private key in this (SSL) Private key file name. Allows you to provide your private key in this
@@ -548,7 +561,8 @@ separate file.
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 "--key-type <type>" .IP "--key-type <type>"
(SSL) Private key file type. Specify which type your \fI--key\fP provided (SSL) Private key file type. Specify which type your \fI--key\fP provided
private key is. DER, PEM and ENG are supported. private key is. DER, PEM and ENG are supported. If not specified, PEM is
assumed.
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 "--krb4 <level>" .IP "--krb4 <level>"
@@ -705,6 +719,15 @@ will output the data in chunks, not necessarily exactly when the data arrives.
Using this option will disable that buffering. Using this option will disable that buffering.
If this option is used twice, the second will again switch on buffering. If this option is used twice, the second will again switch on buffering.
.IP "--no-sessionid"
(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
are done using the cache. Note that while nothing ever should get hurt by
attempting to reuse SSL session-IDs, there seem to be broken SSL
implementations in the wild that may require you to disable this in order for
you to succeed. (Added in 7.16.0)
If this option is used twice, the second will again switch on use of the
session cache.
.IP "--ntlm" .IP "--ntlm"
(HTTP) Enables NTLM authentication. The NTLM authentication method was (HTTP) Enables NTLM authentication. The NTLM authentication method was
designed by Microsoft and is used by IIS web servers. It is a proprietary designed by Microsoft and is used by IIS web servers. It is a proprietary
@@ -818,7 +841,7 @@ must send syntactically correct FTP commands as RFC959 defines.
This option can be used multiple times. This option can be used multiple times.
.IP "--random-file <file>" .IP "--random-file <file>"
(HTTPS) Specify the path name to file containing what will be considered as (SSL) Specify the path name to file containing what will be considered as
random data. The data is used to seed the random engine for SSL connections. random data. The data is used to seed the random engine for SSL connections.
See also the \fI--egd-file\fP option. See also the \fI--egd-file\fP option.
.IP "-r/--range <range>" .IP "-r/--range <range>"
@@ -1196,7 +1219,7 @@ not set.
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 "-z/--time-cond <date expression>" .IP "-z/--time-cond <date expression>"
(HTTP) Request a file that has been modified later than the given time and (HTTP/FTP) Request a file that has been modified later than the given time and
date, or one that has been modified before that time. The date expression can date, or one that has been modified before that time. The date expression can
be all sorts of date strings or if it doesn't match any internal ones, it be all sorts of date strings or if it doesn't match any internal ones, it
tries to get the time from a given file name instead! See the tries to get the time from a given file name instead! See the
@@ -1218,25 +1241,14 @@ If this option is used several times, the last one will be used.
(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its (HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
internally preferred: HTTP 1.1. internally preferred: HTTP 1.1.
.IP "-1/--tlsv1" .IP "-1/--tlsv1"
(HTTPS) (SSL)
Forces curl to use TSL version 1 when negotiating with a remote TLS server. Forces curl to use TSL version 1 when negotiating with a remote TLS server.
.IP "-2/--sslv2" .IP "-2/--sslv2"
(HTTPS) (SSL)
Forces curl to use SSL version 2 when negotiating with a remote SSL server. Forces curl to use SSL version 2 when negotiating with a remote SSL server.
.IP "-3/--sslv3" .IP "-3/--sslv3"
(HTTPS) (SSL)
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

@@ -0,0 +1,166 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Example application source code using the multi interface to download many
* files, but with a capped maximum amount of simultaneous transfers.
*
* Written by Michael Wallner
*/
#include <stdlib.h>
#include <curl/multi.h>
static const char *urls[] = {
"http://www.microsoft.com",
"http://www.opensource.org",
"http://www.google.com",
"http://www.yahoo.com",
"http://www.ibm.com",
"http://www.mysql.com",
"http://www.oracle.com",
"http://www.ripe.net",
"http://www.iana.org",
"http://www.amazon.com",
"http://www.netcraft.com",
"http://www.heise.de",
"http://www.chip.de",
"http://www.ca.com",
"http://www.cnet.com",
"http://www.news.com",
"http://www.cnn.com",
"http://www.wikipedia.org",
"http://www.dell.com",
"http://www.hp.com",
"http://www.cert.org",
"http://www.mit.edu",
"http://www.nist.gov",
"http://www.ebay.com",
"http://www.playstation.com",
"http://www.uefa.com",
"http://www.ieee.org",
"http://www.apple.com",
"http://www.sony.com",
"http://www.symantec.com",
"http://www.zdnet.com",
"http://www.fujitsu.com",
"http://www.supermicro.com",
"http://www.hotmail.com",
"http://www.ecma.com",
"http://www.bbc.co.uk",
"http://news.google.com",
"http://www.foxnews.com",
"http://www.msn.com",
"http://www.wired.com",
"http://www.sky.com",
"http://www.usatoday.com",
"http://www.cbs.com",
"http://www.nbc.com",
"http://slashdot.org",
"http://www.bloglines.com",
"http://www.techweb.com",
"http://www.newslink.org",
"http://www.un.org",
};
#define MAX 10 /* number of simultaneous transfers */
#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
static int cb(char *d, size_t n, size_t l, void *p)
{
/* take care of the data here, ignored in this example */
(void)d;
(void)p;
return n*l;
}
static void init(CURLM *cm, int i)
{
CURL *eh = curl_easy_init();
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(eh, CURLOPT_HEADER, 0);
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0);
curl_multi_add_handle(cm, eh);
}
int main(void)
{
CURLM *cm;
CURLMsg *msg;
long L;
unsigned int C=0;
int M, Q, U = -1;
fd_set R, W, E;
struct timeval T;
curl_global_init(CURL_GLOBAL_ALL);
cm = curl_multi_init();
for (C = 0; C < MAX; ++C) {
init(cm, C);
}
while (U) {
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(cm, &U));
if (U) {
FD_ZERO(&R);
FD_ZERO(&W);
FD_ZERO(&E);
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
fprintf(stderr, "E: curl_multi_fdset\n");
return EXIT_FAILURE;
}
/* In a real-world program you OF COURSE check the return that maxfd is
bigger than -1 so that the call to select() below makes sense! */
if (curl_multi_timeout(cm, &L)) {
fprintf(stderr, "E: curl_multi_timeout\n");
return EXIT_FAILURE;
}
T.tv_sec = L/1000;
T.tv_usec = (L%1000)*1000;
if (0 > select(M+1, &R, &W, &E, &T)) {
fprintf(stderr, "E: select\n");
return EXIT_FAILURE;
}
}
while ((msg = curl_multi_info_read(cm, &Q))) {
if (msg->msg == CURLMSG_DONE) {
char *url;
CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
fprintf(stderr, "R: %d - %s <%s>\n",
msg->data.result, curl_easy_strerror(msg->data.result), url);
curl_multi_remove_handle(cm, e);
curl_easy_cleanup(e);
}
else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
}
if (C < CNT) {
init(cm, C++);
}
}
}
curl_multi_cleanup(cm);
curl_global_cleanup();
return EXIT_SUCCESS;
}

View File

@@ -11,7 +11,8 @@ EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit2.c \
multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \ multi-post.c fopen.c simplepost.c makefile.dj curlx.c https.c \
multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \ multi-debugcallback.c fileupload.c getinfo.c ftp3rdparty.c debug.c \
anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \ anyauthput.c htmltitle.cc htmltidy.c opensslthreadlock.c \
cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c cookie_interface.c cacertinmem.c synctime.c sampleconv.c ftpuploadresume.c \
10-at-a-time.c hiperfifo.c ghiper.c
all: all:
@echo "done" @echo "done"

View File

@@ -26,9 +26,9 @@ want you do reorganize them like:
$ `curl-config --cc` -o example example.c `curl-config --cflags --libs` $ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl *PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
applications/experiments. Even if the examples in this directory use that site applications/experiments. Even if some of the examples use that site as a URL
as an example URL at some places, it doesn't mean that the URLs work or that at some places, it doesn't mean that the URLs work or that we expect you to
we expect you to actually torture our web site with your tests! Thanks. actually torture our web site with your tests! Thanks.
EXAMPLES EXAMPLES
@@ -43,9 +43,13 @@ fopen.c - fopen() layer that supports opening URLs and files
ftp3rdparty.c - FTP 3rd party transfer ftp3rdparty.c - FTP 3rd party transfer
ftpget.c - simple getting a file from FTP ftpget.c - simple getting a file from FTP
ftpgetresp.c - get the response strings from the FTP server 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 an FTP server
ftpuploadresume.c - resume an upload to an 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
ghiper.c - curl_multi_socket() using code with glib-2
hiperfifo.c - downloads all URLs written to the fifo, using
curl_multi_socket() and libevent
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
page using libxml page using libxml
http-post.c - HTTP POST http-post.c - HTTP POST
@@ -61,8 +65,12 @@ opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
persistant.c - request two URLs with a persistant connection persistant.c - request two URLs with a persistant connection
post-callback.c - send a HTTP POST using a callback post-callback.c - send a HTTP POST using a callback
postit2.c - send a HTTP multipart formpost postit2.c - send a HTTP multipart formpost
sampleconv.c - showing how a program on a non-ASCII platform would invoke
callbacks to do its own codeset conversions instead of using
the built-in iconv functions in libcurl
sepheaders.c - download headers to a separate file sepheaders.c - download headers to a separate file
simple.c - the most simple download a URL source simple.c - the most simple download a URL source
simplepost.c - HTTP POST simplepost.c - HTTP POST
simplessl.c - HTTPS example with certificates many options set simplessl.c - HTTPS example with certificates many options set
synctime.c - Sync local time by extracing date from remote HTTP servers synctime.c - Sync local time by extracing date from remote HTTP servers
10-at-a-time.c - Download many files simultaneously, 10 at a time.

View File

@@ -114,6 +114,13 @@ static char *curlx_usage[]={
*/ */
/*
* We use this ZERO_NULL to avoid picky compiler warnings,
* when assigning a NULL pointer to a function pointer var.
*/
#define ZERO_NULL 0
/* This is a context that we pass to all callbacks */ /* This is a context that we pass to all callbacks */
typedef struct sslctxparm_st { typedef struct sslctxparm_st {
@@ -236,7 +243,7 @@ static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
SSL_CTX_set_verify_depth(ctx,2); SSL_CTX_set_verify_depth(ctx,2);
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm); SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);

View File

@@ -84,6 +84,9 @@ int my_trace(CURL *handle, curl_infotype type,
case CURLINFO_DATA_OUT: case CURLINFO_DATA_OUT:
text = "=> Send data"; text = "=> Send data";
break; break;
case CURLINFO_SSL_DATA_OUT:
text = "=> Send SSL data";
break;
case CURLINFO_HEADER_IN: case CURLINFO_HEADER_IN:
text = "<= Recv header"; text = "<= Recv header";
break; break;
@@ -93,9 +96,6 @@ int my_trace(CURL *handle, curl_infotype type,
case CURLINFO_SSL_DATA_IN: case CURLINFO_SSL_DATA_IN:
text = "<= Recv SSL data"; text = "<= Recv SSL data";
break; break;
case CURLINFO_SSL_DATA_OUT:
text = "<= Send SSL data";
break;
} }
dump(text, stderr, data, size, config->trace_ascii); dump(text, stderr, data, size, config->trace_ascii);

View File

@@ -153,6 +153,10 @@ fill_buffer(URL_FILE *file,int want,int waittime)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1
so that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

461
docs/examples/ghiper.c Normal file
View File

@@ -0,0 +1,461 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Example application source code using the multi socket interface to
* download many files at once.
*
* Written by Jeff Pohlmeyer
Requires glib-2.x and a (POSIX?) system that has mkfifo().
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
sample programs, adapted to use glib's g_io_channel in place of libevent.
When running, the program creates the named pipe "hiper.fifo"
Whenever there is input into the fifo, the program reads the input as a list
of URL's and creates some new easy handles to fetch each URL via the
curl_multi "hiper" API.
Thus, you can try a single URL:
% echo http://www.yahoo.com > hiper.fifo
Or a whole bunch of them:
% cat my-url-list > hiper.fifo
The fifo buffer is handled almost instantly, so you can even add more URL's
while the previous requests are still being downloaded.
This is purely a demo app, all retrieved data is simply discarded by the write
callback.
*/
#include <glib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <curl/curl.h>
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
/* Global information, common to all connections */
typedef struct _GlobalInfo {
CURLM *multi;
guint timer_event;
int prev_running;
int still_running;
int requested; /* count: curl_easy_init() */
int completed; /* count: curl_easy_cleanup() */
} GlobalInfo;
/* Information associated with a specific easy handle */
typedef struct _ConnInfo {
CURL *easy;
char *url;
GlobalInfo *global;
char error[CURL_ERROR_SIZE];
} ConnInfo;
/* Information associated with a specific socket */
typedef struct _SockInfo {
curl_socket_t sockfd;
CURL *easy;
int action;
long timeout;
GIOChannel *ch;
guint ev;
GlobalInfo *global;
} SockInfo;
/* Die if we get a bad CURLMcode somewhere */
static void mcode_or_die(char *where, CURLMcode code) {
if ( CURLM_OK != code ) {
char *s;
switch (code) {
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
case CURLM_OK: s="CURLM_OK"; break;
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
case CURLM_LAST: s="CURLM_LAST"; break;
default: s="CURLM_unknown";
}
MSG_OUT("ERROR: %s returns %s\n", where, s);
exit(code);
}
}
/* Check for completed transfers, and remove their easy handles */
static void check_run_count(GlobalInfo *g)
{
if (g->prev_running > g->still_running) {
char *eff_url=NULL;
CURLMsg *msg;
int msgs_left;
ConnInfo *conn=NULL;
CURL*easy;
CURLcode res;
MSG_OUT("REMAINING: %d\n", g->still_running);
/*
I am still uncertain whether it is safe to remove an easy handle
from inside the curl_multi_info_read loop, so here I will search
for completed transfers in the inner "while" loop, and then remove
them in the outer "do-while" loop...
*/
do {
easy=NULL;
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) {
easy=msg->easy_handle;
res=msg->data.result;
break;
}
}
if (easy) {
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
curl_multi_remove_handle(g->multi, easy);
g_free(conn->url);
curl_easy_cleanup(easy);
g_free(conn);
g->completed++;
}
} while ( easy );
MSG_OUT("Requested: %d Completed:%d\n", g->requested, g->completed);
}
g->prev_running = g->still_running;
}
/* Called by glib when our timeout expires */
static gboolean timer_cb(gpointer data)
{
GlobalInfo *g = (GlobalInfo *)data;
CURLMcode rc;
do {
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("timer_cb: curl_multi_socket", rc);
check_run_count(g);
return FALSE;
}
/* Update the event timer after curl_multi library calls */
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
{
struct timeval timeout;
GlobalInfo *g=(GlobalInfo *)userp;
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
timeout_ms, timeout.tv_sec, timeout.tv_usec);
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
return 0;
}
/* Called by glib when we get action on a multi socket */
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
{
GlobalInfo *g = (GlobalInfo*) data;
CURLMcode rc;
int fd=g_io_channel_unix_get_fd(ch);
do {
rc = curl_multi_socket(g->multi, fd, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("event_cb: curl_multi_socket", rc);
check_run_count(g);
if(g->still_running) {
return TRUE;
} else {
MSG_OUT("last transfer done, kill timeout\n");
if (g->timer_event) { g_source_remove(g->timer_event); }
return FALSE;
}
}
/* Clean up the SockInfo structure */
static void remsock(SockInfo *f)
{
if (!f) { return; }
if (f->ev) { g_source_remove(f->ev); }
g_free(f);
}
/* Assign information to a SockInfo structure */
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
{
GIOCondition kind =
(act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
f->sockfd = s;
f->action = act;
f->easy = e;
if (f->ev) { g_source_remove(f->ev); }
f->ev=g_io_add_watch(f->ch, kind, event_cb,g);
}
/* Initialize a new SockInfo structure */
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
{
SockInfo *fdp = g_malloc0(sizeof(SockInfo));
fdp->global = g;
fdp->ch=g_io_channel_unix_new(s);
setsock(fdp, s, easy, action, g);
curl_multi_assign(g->multi, s, fdp);
}
/* CURLMOPT_SOCKETFUNCTION */
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
{
GlobalInfo *g = (GlobalInfo*) cbp;
SockInfo *fdp = (SockInfo*) sockp;
char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if (what == CURL_POLL_REMOVE) {
MSG_OUT("\n");
remsock(fdp);
} else {
if (!fdp) {
MSG_OUT("Adding data: %s%s\n",
what&CURL_POLL_IN?"READ":"",
what&CURL_POLL_OUT?"WRITE":"" );
addsock(s, e, what, g);
}
else {
MSG_OUT(
"Changing action from %d to %d\n", fdp->action, what);
setsock(fdp, s, e, what, g);
}
}
return 0;
}
/* CURLOPT_WRITEFUNCTION */
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
ConnInfo *conn = (ConnInfo*) data;
(void)ptr;
(void)conn;
return realsize;
}
/* CURLOPT_PROGRESSFUNCTION */
static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
{
ConnInfo *conn = (ConnInfo *)p;
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
return 0;
}
/* Create a new easy handle, and add it to the global curl_multi */
static void new_conn(char *url, GlobalInfo *g )
{
ConnInfo *conn;
CURLMcode rc;
conn = g_malloc0(sizeof(ConnInfo));
conn->error[0]='\0';
conn->easy = curl_easy_init();
if (!conn->easy) {
MSG_OUT("curl_easy_init() failed, exiting!\n");
exit(2);
}
conn->global = g;
conn->url = g_strdup(url);
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, SHOW_VERBOSE);
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0:1);
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30);
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30);
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
rc =curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc);
g->requested++;
do {
rc = curl_multi_socket_all(g->multi, &g->still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
mcode_or_die("new_conn: curl_multi_socket_all", rc);
check_run_count(g);
}
/* This gets called by glib whenever data is received from the fifo */
static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data)
{
#define BUF_SIZE 1024
gsize len, tp;
gchar *buf, *tmp, *all=NULL;
GIOStatus rv;
do {
GError *err=NULL;
rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err);
if ( buf ) {
if (tp) { buf[tp]='\0'; }
new_conn(buf,(GlobalInfo*)data);
g_free(buf);
} else {
buf = g_malloc(BUF_SIZE+1);
while (TRUE) {
buf[BUF_SIZE]='\0';
g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err);
if (len) {
buf[len]='\0';
if (all) {
tmp=all;
all=g_strdup_printf("%s%s", tmp, buf);
g_free(tmp);
} else {
all = g_strdup(buf);
}
} else {
break;
}
}
if (all) {
new_conn(all,(GlobalInfo*)data);
g_free(all);
}
g_free(buf);
}
if ( err ) {
g_error("fifo_cb: %s", err->message);
g_free(err);
break;
}
} while ( (len) && (rv == G_IO_STATUS_NORMAL) );
return TRUE;
}
int init_fifo(void)
{
struct stat st;
char *fifo = "hiper.fifo";
int socket;
if (lstat (fifo, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
exit (1);
}
}
unlink (fifo);
if (mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
exit (1);
}
socket = open (fifo, O_RDWR | O_NONBLOCK, 0);
if (socket == -1) {
perror("open");
exit (1);
}
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
return socket;
}
int main(int argc, char **argv)
{
GlobalInfo *g;
CURLMcode rc;
GMainLoop*gmain;
int fd;
GIOChannel* ch;
g=g_malloc0(sizeof(GlobalInfo));
fd=init_fifo();
ch=g_io_channel_unix_new(fd);
g_io_add_watch(ch,G_IO_IN,fifo_cb,g);
gmain=g_main_loop_new(NULL,FALSE);
g->multi = curl_multi_init();
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
do {
rc = curl_multi_socket_all(g->multi, &g->still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
g_main_loop_run(gmain);
curl_multi_cleanup(g->multi);
return 0;
}

416
docs/examples/hiperfifo.c Normal file
View File

@@ -0,0 +1,416 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Example application source code using the multi socket interface to
* download many files at once.
*
* Written by Jeff Pohlmeyer
Requires libevent and a (POSIX?) system that has mkfifo().
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
sample programs.
When running, the program creates the named pipe "hiper.fifo"
Whenever there is input into the fifo, the program reads the input as a list
of URL's and creates some new easy handles to fetch each URL via the
curl_multi "hiper" API.
Thus, you can try a single URL:
% echo http://www.yahoo.com > hiper.fifo
Or a whole bunch of them:
% cat my-url-list > hiper.fifo
The fifo buffer is handled almost instantly, so you can even add more URL's
while the previous requests are still being downloaded.
Note:
For the sake of simplicity, URL length is limited to 1023 char's !
This is purely a demo app, all retrieved data is simply discarded by the write
callback.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <sys/poll.h>
#include <curl/curl.h>
#include <event.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
/* Global information, common to all connections */
typedef struct _GlobalInfo {
struct event fifo_event;
struct event timer_event;
CURLM *multi;
int prev_running;
int still_running;
FILE* input;
} GlobalInfo;
/* Information associated with a specific easy handle */
typedef struct _ConnInfo {
CURL *easy;
char *url;
GlobalInfo *global;
char error[CURL_ERROR_SIZE];
} ConnInfo;
/* Information associated with a specific socket */
typedef struct _SockInfo {
curl_socket_t sockfd;
CURL *easy;
int action;
long timeout;
struct event ev;
int evset;
GlobalInfo *global;
} SockInfo;
/* Update the event timer after curl_multi library calls */
static void update_timeout(GlobalInfo *g)
{
long timeout_ms;
struct timeval timeout;
curl_multi_timeout(g->multi, &timeout_ms);
if(timeout_ms < 0)
return;
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
evtimer_add(&g->timer_event, &timeout);
}
/* Die if we get a bad CURLMcode somewhere */
void mcode_or_die(char *where, CURLMcode code) {
if ( CURLM_OK != code ) {
char *s;
switch (code) {
case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
case CURLM_OK: s="CURLM_OK"; break;
case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
case CURLM_LAST: s="CURLM_LAST"; break;
default: s="CURLM_unknown";
}
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
exit(code);
}
}
/* Check for completed transfers, and remove their easy handles */
static void check_run_count(GlobalInfo *g)
{
if (g->prev_running > g->still_running) {
char *eff_url=NULL;
CURLMsg *msg;
int msgs_left;
ConnInfo *conn=NULL;
CURL*easy;
CURLcode res;
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
/*
I am still uncertain whether it is safe to remove an easy handle
from inside the curl_multi_info_read loop, so here I will search
for completed transfers in the inner "while" loop, and then remove
them in the outer "do-while" loop...
*/
do {
easy=NULL;
while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) {
easy=msg->easy_handle;
res=msg->data.result;
break;
}
}
if (easy) {
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
curl_multi_remove_handle(g->multi, easy);
free(conn->url);
curl_easy_cleanup(easy);
free(conn);
}
} while ( easy );
}
g->prev_running = g->still_running;
}
/* Called by libevent when we get action on a multi socket */
static void event_cb(int fd, short kind, void *userp)
{
GlobalInfo *g = (GlobalInfo*) userp;
CURLMcode rc;
do {
rc = curl_multi_socket(g->multi, fd, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("event_cb: curl_multi_socket", rc);
check_run_count(g);
if(g->still_running) {
update_timeout(g);
} else {
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
if (evtimer_pending(&g->timer_event, NULL)) {
evtimer_del(&g->timer_event);
}
}
}
/* Called by libevent when our timeout expires */
static void timer_cb(int fd, short kind, void *userp)
{
(void)fd;
(void)kind;
GlobalInfo *g = (GlobalInfo *)userp;
CURLMcode rc;
do {
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("timer_cb: curl_multi_socket", rc);
check_run_count(g);
if ( g->still_running ) { update_timeout(g); }
}
/* Clean up the SockInfo structure */
static void remsock(SockInfo *f)
{
if (!f) { return; }
if (f->evset) { event_del(&f->ev); }
free(f);
}
/* Assign information to a SockInfo structure */
static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
{
int kind =
(act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
f->sockfd = s;
f->action = act;
f->easy = e;
if (f->evset) { event_del(&f->ev); }
event_set( &f->ev, f->sockfd, kind, event_cb, g);
f->evset=1;
event_add(&f->ev, NULL);
}
/* Initialize a new SockInfo structure */
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) {
SockInfo *fdp = calloc(sizeof(SockInfo), 1);
fdp->global = g;
setsock(fdp, s, easy, action, g);
curl_multi_assign(g->multi, s, fdp);
}
/* CURLMOPT_SOCKETFUNCTION */
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
{
GlobalInfo *g = (GlobalInfo*) cbp;
SockInfo *fdp = (SockInfo*) sockp;
char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
fprintf(MSG_OUT,
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
if (what == CURL_POLL_REMOVE) {
fprintf(MSG_OUT, "\n");
remsock(fdp);
} else {
if (!fdp) {
fprintf(MSG_OUT, "Adding data: %s%s\n",
what&CURL_POLL_IN?"READ":"",
what&CURL_POLL_OUT?"WRITE":"" );
addsock(s, e, what, g);
}
else {
fprintf(MSG_OUT,
"Changing action from %d to %d\n", fdp->action, what);
setsock(fdp, s, e, what, g);
}
}
return 0;
}
/* CURLOPT_WRITEFUNCTION */
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
ConnInfo *conn = (ConnInfo*) data;
(void)ptr;
(void)conn;
return realsize;
}
/* CURLOPT_PROGRESSFUNCTION */
int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
{
ConnInfo *conn = (ConnInfo *)p;
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
return 0;
}
/* Create a new easy handle, and add it to the global curl_multi */
void new_conn(char *url, GlobalInfo *g ) {
ConnInfo *conn;
CURLMcode rc;
conn = calloc(1, sizeof(ConnInfo));
memset(conn, 0, sizeof(ConnInfo));
conn->error[0]='\0';
conn->easy = curl_easy_init();
if (!conn->easy) {
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
exit(2);
}
conn->global = g;
conn->url = strdup(url);
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 0);
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
fprintf(MSG_OUT,
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
rc =curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc);
do {
rc = curl_multi_socket_all(g->multi, &g->still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
mcode_or_die("new_conn: curl_multi_socket_all", rc);
check_run_count(g);
}
/* This gets called whenever data is received from the fifo */
void fifo_cb(int fd, short event, void *arg) {
char s[1024];
long int rv=0;
int n=0;
GlobalInfo *g = (GlobalInfo *)arg;
do {
s[0]='\0';
rv=fscanf(g->input, "%1023s%n", s, &n);
s[n]='\0';
if ( n && s[0] ) {
new_conn(s,arg); /* if we read a URL, go get it! */
} else break;
} while ( rv != EOF);
}
/* Create a named pipe and tell libevent to monitor it */
int init_fifo (GlobalInfo *g) {
struct stat st;
char *fifo = "hiper.fifo";
int socket;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if (lstat (fifo, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
exit (1);
}
}
unlink(fifo);
if (mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
exit (1);
}
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
if (socket == -1) {
perror("open");
exit (1);
}
g->input = fdopen(socket, "r");
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
event_set(&g->fifo_event, socket, EV_READ | EV_PERSIST, fifo_cb, g);
event_add(&g->fifo_event, NULL);
return (0);
}
int main(int argc, char **argv)
{
GlobalInfo g;
CURLMcode rc;
memset(&g, 0, sizeof(GlobalInfo));
event_init();
init_fifo(&g);
g.multi = curl_multi_init();
evtimer_set(&g.timer_event, timer_cb, &g);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
do {
rc = curl_multi_socket_all(g.multi, &g.still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
update_timeout(&g);
event_dispatch();
curl_multi_cleanup(g.multi);
return 0;
}

View File

@@ -15,13 +15,13 @@ endif
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
PROGRAMS = fopen.exe ftpget.exe ftpgetresp.exe ftpupload.exe \ CSOURCES = fopen.c ftpget.c ftpgetresp.c ftpupload.c getinmemory.c \
getinmemory.exe http-post.exe httpput.exe multi-app.exe \ http-post.c httpput.c multi-app.c multi-double.c multi-post.c \
multi-double.exe multi-post.exe multi-single.exe \ multi-single.c persistant.c post-callback.c postit2.c \
persistant.exe post-callback.exe postit2.exe \ sepheaders.c simple.c simplessl.c https.c ftp3rdparty.c \
sepheaders.exe simple.exe simplessl.exe https.exe \ getinfo.c anyauthput.c cookie_interface.c 10-at-a-time.c
ftp3rdparty.exe getinfo.exe anyauthput.exe \
cookie_interface.exe PROGRAMS = $(CSOURCES:.c=.exe)
all: $(PROGRAMS) all: $(PROGRAMS)
@@ -32,3 +32,5 @@ all: $(PROGRAMS)
clean: clean:
rm -f $(PROGRAMS) rm -f $(PROGRAMS)
# DO NOT DELETE THIS LINE

View File

@@ -80,6 +80,10 @@ int main(int argc, char **argv)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1 so
that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

View File

@@ -153,6 +153,10 @@ int main(int argc, char **argv)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1
so that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

View File

@@ -71,6 +71,10 @@ int main(int argc, char **argv)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1 so
that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

View File

@@ -93,6 +93,10 @@ int main(int argc, char *argv[])
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1
so that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

View File

@@ -65,6 +65,10 @@ int main(int argc, char **argv)
/* get file descriptors from the transfers */ /* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1 so
that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) { switch(rc) {

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_easy_cleanup 3 "13 Nov 2002" "libcurl 7.7" "libcurl Manual" .TH curl_easy_cleanup 3 "12 Oct 2006" "libcurl 7.7" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_cleanup - End a libcurl easy session curl_easy_cleanup - End a libcurl easy session
.SH SYNOPSIS .SH SYNOPSIS
@@ -21,6 +21,9 @@ more files.
When you've called this, you can safely remove all the strings you've When you've called this, you can safely remove all the strings you've
previously told libcurl to use, as it won't use them anymore now. previously told libcurl to use, as it won't use them anymore now.
Any uses of the \fBhandle\fP after this function has been called are
illegal. This kills the handle and all memory associated with it!
.SH RETURN VALUE .SH RETURN VALUE
None None
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@@ -160,12 +160,28 @@ found in \fI<curl/curl.h>\fP. This function gets called by libcurl when
something special I/O-related needs to be done that the library can't do by something special I/O-related needs to be done that the library can't do by
itself. For now, rewinding the read data stream is the only action it can itself. For now, rewinding the read data stream is the only action it can
request. The rewinding of the read data stream may be necessary when doing a request. The rewinding of the read data stream may be necessary when doing a
HTTP PUT or POST with a multi-pass authentication method. (Opion added in HTTP PUT or POST with a multi-pass authentication method. (Option added in
7.12.3) 7.12.3)
.IP CURLOPT_IOCTLDATA .IP CURLOPT_IOCTLDATA
Pass a pointer that will be untouched by libcurl and passed as the 3rd Pass a pointer that will be untouched by libcurl and passed as the 3rd
argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option
added in 7.12.3) added in 7.12.3)
.IP CURLOPT_SOCKOPTFUNCTION
Function pointer that should match the \fIcurl_sockopt_callback\fP prototype
found in \fI<curl/curl.h>\fP. This function gets called by libcurl after the
socket() call but before the connect() call. The callback's \fIpurpose\fP
argument identifies the exact purpose for this particular socket, and
currently only one value is supported: \fICURLSOCKTYPE_IPCXN\fP for the
primary connection (meaning the control connection in the FTP case). Future
versions of libcurl may support more purposes. It passes the newly created
socket descriptor so additional setsockopt() calls can be done at the user's
discretion. A non-zero return code from the callback function will signal an
unrecoverable error to the library and it will close the socket and return
\fICURLE_COULDNT_CONNECT\fP. (Option added in 7.15.6.)
.IP CURLOPT_SOCKOPTDATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
(Option added in 7.15.6.)
.IP CURLOPT_PROGRESSFUNCTION .IP CURLOPT_PROGRESSFUNCTION
Function pointer that should match the \fIcurl_progress_callback\fP prototype Function pointer that should match the \fIcurl_progress_callback\fP prototype
found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of found in \fI<curl/curl.h>\fP. This function gets called by libcurl instead of
@@ -328,6 +344,14 @@ when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
A non-zero parameter tells the library to fail silently if the HTTP code A non-zero parameter tells the library to fail silently if the HTTP code
returned is equal to or larger than 400. The default action would be to return returned is equal to or larger than 400. The default action would be to return
the page normally, ignoring that code. the page normally, ignoring that code.
This method is not fail-safe and there are occasions where non-succesful
response codes will slip through, especially when authentication is involved
(response codes 401 and 407).
You might get some amounts of headers transferred before this situation is
detected, like for when a "100-continue" is received as a response to a
POST/PUT and a 401 or 407 is received immediately afterwards.
.SH NETWORK OPTIONS .SH NETWORK OPTIONS
.IP CURLOPT_URL .IP CURLOPT_URL
The actual URL to deal with. The parameter should be a char * to a zero The actual URL to deal with. The parameter should be a char * to a zero
@@ -365,9 +389,10 @@ libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP,
\fBall_proxy\fP etc, if any of those is set. The \fICURLOPT_PROXY\fP option \fBall_proxy\fP etc, if any of those is set. The \fICURLOPT_PROXY\fP option
does however override any possibly set environment variables. does however override any possibly set environment variables.
Starting with 7.14.1, the proxy host string can be specified the exact same Starting with 7.14.1, the proxy host string given in environment variables can
way as the proxy environment variables, include protocol prefix (http://) and be specified the exact same way as the proxy can be set with
embedded user + password. \fICURLOPT_PROXY\fP, include protocol prefix (http://) and embedded user +
password.
.IP CURLOPT_PROXYPORT .IP CURLOPT_PROXYPORT
Pass a long with this option to set the proxy port to connect to unless it is Pass a long with this option to set the proxy port to connect to unless it is
specified in the proxy string \fICURLOPT_PROXY\fP. specified in the proxy string \fICURLOPT_PROXY\fP.
@@ -821,7 +846,8 @@ Pass a pointer to a linked list of FTP commands to pass to the server after
the transfer type is set. The linked list should be a fully valid list of the transfer type is set. The linked list should be a fully valid list of
struct curl_slist structs properly filled in as described for struct curl_slist structs properly filled in as described for
\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this \fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this
option. option. Before version 7.15.6, if you also set \fICURLOPT_NOBODY\fP non-zero,
this option didn't work.
.IP CURLOPT_FTPLISTONLY .IP CURLOPT_FTPLISTONLY
A non-zero parameter tells the library to just list the names of an ftp A non-zero parameter tells the library to just list the names of an ftp
directory, instead of doing a full directory listing that would include file directory, instead of doing a full directory listing that would include file
@@ -899,18 +925,6 @@ 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 .IP CURLOPT_FTP_ACCOUNT
Pass a pointer to a zero-terminated string (or NULL to disable). When an FTP 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, server asks for "account data" after user name and password has been provided,
@@ -955,7 +969,9 @@ techniques). Pass a NULL to this option to disable the use of ranges.
.IP CURLOPT_RESUME_FROM .IP CURLOPT_RESUME_FROM
Pass a long as parameter. It contains the offset in number of bytes that you Pass a long as parameter. It contains the offset in number of bytes that you
want the transfer to start from. Set this option to 0 to make the transfer want the transfer to start from. Set this option to 0 to make the transfer
start from the beginning (effectively disabling resume). start from the beginning (effectively disabling resume). For FTP, set this
option to -1 to make the transfer start from the end of the target file
(useful to continue an interrupted upload).
.IP CURLOPT_RESUME_FROM_LARGE .IP CURLOPT_RESUME_FROM_LARGE
Pass a curl_off_t as parameter. It contains the offset in number of bytes that Pass a curl_off_t as parameter. It contains the offset in number of bytes that
you want the transfer to start from. (Added in 7.11.0) you want the transfer to start from. (Added in 7.11.0)
@@ -998,9 +1014,9 @@ libcurl what the expected size of the infile is. This value should be passed
as a curl_off_t. (Added in 7.11.0) as a curl_off_t. (Added in 7.11.0)
.IP CURLOPT_UPLOAD .IP CURLOPT_UPLOAD
A non-zero parameter tells the library to prepare for an upload. The A non-zero parameter tells the library to prepare for an upload. The
\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZEE\fP or \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or
\fICURLOPT_INFILESIZE_LARGE\fP are also interesting for uploads. If the \fICURLOPT_INFILESIZE_LARGE\fP options are also interesting for uploads. If
protocol is HTTP, uploading means using the PUT request unless you tell the protocol is HTTP, uploading means using the PUT request unless you tell
libcurl otherwise. libcurl otherwise.
Using PUT with HTTP 1.1 implies the use of a "Expect: 100-continue" header. Using PUT with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
@@ -1059,13 +1075,15 @@ Pass a long as parameter. It contains the time in seconds that the transfer
should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider
it too slow and abort. it too slow and abort.
.IP CURLOPT_MAX_SEND_SPEED_LARGE .IP CURLOPT_MAX_SEND_SPEED_LARGE
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
average during the transfer, the transfer will pause to keep the average rate average during the transfer, the transfer will pause to keep the average rate
less than or equal to the parameter value. (default: 0, unlimited) less than or equal to the parameter value. Defaults to unlimited
speed. (Added in 7.15.5)
.IP CURLOPT_MAX_RECV_SPEED_LARGE .IP CURLOPT_MAX_RECV_SPEED_LARGE
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
average during the transfer, the transfer will pause to keep the average rate average during the transfer, the transfer will pause to keep the average rate
less than or equal to the parameter value. (default: 0, unlimited) less than or equal to the parameter value. Defaults to unlimited speed. (Added
in 7.15.5)
.IP CURLOPT_MAXCONNECTS .IP CURLOPT_MAXCONNECTS
Pass a long. The set number will be the persistent connection cache size. The Pass a long. The set number will be the persistent connection cache size. The
set amount will be the maximum amount of simultaneously open connections that set amount will be the maximum amount of simultaneously open connections that
@@ -1282,6 +1300,12 @@ compile OpenSSL.
You'll find more details about cipher lists on this URL: You'll find more details about cipher lists on this URL:
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP \fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
.IP CURLOPT_SSL_SESSIONID_CACHE
Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set
this to 1 to enable it. By default all transfers are done using the
cache. Note that while nothing ever should get hurt by attempting to reuse SSL
session-IDs, there seem to be broken SSL implementations in the wild that may
require you to disable this in order for you to succeed. (Added in 7.16.0)
.IP CURLOPT_KRB4LEVEL .IP CURLOPT_KRB4LEVEL
Pass a char * as parameter. Set the krb4 security level, this also enables Pass a char * as parameter. Set the krb4 security level, this also enables
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or

View File

@@ -23,88 +23,96 @@ After the \fIlastitem\fP pointer follow the real arguments.
The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to The pointers \fI*firstitem\fP and \fI*lastitem\fP should both be pointing to
NULL in the first call to this function. All list-data will be allocated by NULL in the first call to this function. All list-data will be allocated by
the function itself. You must call \fIcurl_formfree\fP after the form post has the function itself. You must call \fIcurl_formfree(3)\fP after the form post
been done to free the resources again. has been done to free the resources.
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.
First, there are some basics you need to understand about multipart/formdata First, there are some basics you need to understand about multipart/formdata
posts. Each part consists of at least a NAME and a CONTENTS part. If the part posts. Each part consists of at least a NAME and a CONTENTS part. If the part
is made for file upload, there are also a stored CONTENT-TYPE and a is made for file upload, there are also a stored CONTENT-TYPE and a FILENAME.
FILENAME. Below here, we'll discuss on what options you use to set these Below, we'll discuss what options you use to set these properties in the
properties in the parts you want to add to your post. parts you want to add to your post.
The options listed first are for making normal parts. The options from
\fICURLFORM_FILE\fP through \fICURLFORM_BUFFERLENGTH\fP are for file upload
parts.
.SH OPTIONS .SH OPTIONS
.IP CURLFORM_COPYNAME .IP CURLFORM_COPYNAME
followed by string is used to set the name of this part. libcurl copies the followed by a string which provides the \fIname\fP of this part. libcurl
given data, so your application doesn't need to keep it around after this copies the string so your application doesn't need to keep it around after
function call. If the name isn't zero terminated properly, or if you'd like it this function call. If the name isn't null terminated, or if you'd
to contain zero bytes, you need to set the length of the name with like it to contain zero bytes, you must set its length with
\fBCURLFORM_NAMELENGTH\fP. \fBCURLFORM_NAMELENGTH\fP. The copied data will be freed by
\fIcurl_formfree(3)\fP.
.IP CURLFORM_PTRNAME .IP CURLFORM_PTRNAME
followed by a string is used for the name of this part. libcurl will use the followed by a string which provides the \fIname\fP of this part. libcurl
pointer and refer to the data in your application, you must make sure it will use the pointer and refer to the data in your application, so you
remains until curl no longer needs it. If the name isn't zero terminated must make sure it remains until curl no longer needs it. If the name
properly, or if you'd like it to contain zero bytes, you need to set the isn't null terminated, or if you'd like it to contain zero
length of the name with \fBCURLFORM_NAMELENGTH\fP. bytes, you must set its length with \fBCURLFORM_NAMELENGTH\fP.
.IP CURLFORM_COPYCONTENTS .IP CURLFORM_COPYCONTENTS
followed by a string is used for the contents of this part, the actual data to followed by a pointer to the contents of this part, the actual data
send away. libcurl copies the given data, so your application doesn't need to to send away. libcurl copies the provided data, so your application doesn't
keep it around after this function call. If the data isn't zero terminated need to keep it around after this function call. If the data isn't null
properly, or if you'd like it to contain zero bytes, you need to set the terminated, or if you'd like it to contain zero bytes, you must
length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. set the length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. The copied
data will be freed by \fIcurl_formfree(3)\fP.
.IP CURLFORM_PTRCONTENTS .IP CURLFORM_PTRCONTENTS
followed by a string is used for the contents of this part, the actual data to followed by a pointer to the contents of this part, the actual data
send away. libcurl will use the pointer and refer to the data in your to send away. libcurl will use the pointer and refer to the data in your
application, you must make sure it remains until curl no longer needs it. If application, so you must make sure it remains until curl no longer needs it.
the data isn't zero terminated properly, or if you'd like it to contain zero If the data isn't null terminated, or if you'd like it to contain zero bytes,
bytes, you need to set the length of the name with you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
\fBCURLFORM_CONTENTSLENGTH\fP.
.IP CURLFORM_CONTENTSLENGTH .IP CURLFORM_CONTENTSLENGTH
followed by a long setting the length of the contents. followed by a long giving the length of the contents.
.IP CURLFORM_FILECONTENT .IP CURLFORM_FILECONTENT
followed by a file name, makes that file read and the contents will be used in followed by a filename, causes that file to be read and its contents used
as data in this part. as data in this part. This part does \fInot\fP automatically become a file
upload part simply because its data was read from a file.
.IP CURLFORM_FILE .IP CURLFORM_FILE
followed by a file name, makes this part a file upload part. It sets the file followed by a filename, makes this part a file upload part. It sets the
name field to the actual file name used here, it gets the contents of the file \fIfilename\fP field to the basename of the provided filename, it reads the
and passes as data and sets the content-type if the given file match one of contents of the file and passes them as data and sets the content-type if the
the new internally known file extension. For \fBCURLFORM_FILE\fP the user may given file match one of the internally known file extensions. For
send one or more files in one part by providing multiple \fBCURLFORM_FILE\fP \fBCURLFORM_FILE\fP the user may send one or more files in one part by
arguments each followed by the filename (and each CURLFORM_FILE is allowed to providing multiple \fBCURLFORM_FILE\fP arguments each followed by the
have a CURLFORM_CONTENTTYPE). filename (and each CURLFORM_FILE is allowed to have a CURLFORM_CONTENTTYPE).
.IP CURLFORM_CONTENTTYPE .IP CURLFORM_CONTENTTYPE
followed by a pointer to a string with a content-type will make curl use this is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
given content-type for this file upload part, possibly instead of an string which provides the content-type for this part, possibly instead of an
internally chosen one. internally chosen one.
.IP CURLFORM_FILENAME .IP CURLFORM_FILENAME
followed by a pointer to a string to a name, will make libcurl use the given is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
name in the file upload part, instead of the actual file name given to string, it tells libcurl to use the given string as the \fIfilename\fP in the
\fICURLFORM_FILE\fP. file upload part instead of the actual file name.
.IP CURLFORM_BUFFER .IP CURLFORM_BUFFER
followed by a string, tells libcurl that a buffer is to be used to upload data is used for custom file upload parts without use of \fICURLFORM_FILE\fP. It
instead of using a file. The given string is used as the value of the file tells libcurl that the file contents are already present in a buffer. The
name field in the content header. parameter is a string which provides the \fIfilename\fP field in the content
header.
.IP CURLFORM_BUFFERPTR .IP CURLFORM_BUFFERPTR
followed by a pointer to a data area, tells libcurl the address of the buffer is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a pointer
containing data to upload (as indicated with \fICURLFORM_BUFFER\fP). The to the buffer to be uploaded. This buffer must not be freed until after
buffer containing this data must not be freed until after
\fIcurl_easy_cleanup(3)\fP is called. You must also use \fIcurl_easy_cleanup(3)\fP is called. You must also use
\fICURLFORM_BUFFERLENGTH\fP to set the length of the given buffer area. \fICURLFORM_BUFFERLENGTH\fP to set the number of bytes in the buffer.
.IP CURLFORM_BUFFERLENGTH .IP CURLFORM_BUFFERLENGTH
followed by a long with the size of the \fICURLFORM_BUFFERPTR\fP data area, is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a
tells libcurl the length of the buffer to upload. long which gives the length of the buffer.
.IP CURLFORM_ARRAY .IP CURLFORM_ARRAY
Another possibility to send options to curl_formadd() is the Another possibility to send options to curl_formadd() is the

View File

@@ -20,6 +20,11 @@ NULL is returned as a signal that there is no more to get at this point. The
integer pointed to with \fImsgs_in_queue\fP will contain the number of integer pointed to with \fImsgs_in_queue\fP will contain the number of
remaining messages after this function was called. remaining messages after this function was called.
When you fetch a message using this function, it is removed from the internal
queue so calling this function again will not return the same message
again. It will instead return new messages at each new invoke until the queue
is emptied.
The data the returned pointer points to will not survive calling The data the returned pointer points to will not survive calling
\fIcurl_multi_cleanup(3)\fP or \fIcurl_multi_remove_handle(3)\fP. \fIcurl_multi_cleanup(3)\fP or \fIcurl_multi_remove_handle(3)\fP.
@@ -37,6 +42,12 @@ present in that struct and can thus be used in subsequent regular
CURLcode result; /* return code for transfer */ CURLcode result; /* return code for transfer */
} data; } data;
}; };
When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that
is done, and then \fBresult\fP contains the return code for the easy handle
that just completed.
At this point, there is no other \fBmsg\fP types defined.
.SH "RETURN VALUE" .SH "RETURN VALUE"
A pointer to a filled-in struct, or NULL if it failed or ran out of A pointer to a filled-in struct, or NULL if it failed or ran out of
structs. It also writes the number of messages left in the queue (after this structs. It also writes the number of messages left in the queue (after this

View File

@@ -30,11 +30,15 @@ If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you
should call \fIcurl_multi_perform\fP again, before you select() on more should call \fIcurl_multi_perform\fP again, before you select() on more
actions. You don't have to do it immediately, but the return code means that actions. You don't have to do it immediately, but the return code means that
libcurl may have more data available to return or that there may be more data libcurl may have more data available to return or that there may be more data
to send off before it is "satisfied". to send off before it is "satisfied". Do note that \fIcurl_multi_perform(3)\fP
will return \fICURLM_CALL_MULTI_PERFORM\fP only when it wants to be called
again \fBimmediately\fP. When things are fine and there are nothing immediate
it wants done, it'll return \fICURLM_OK\fP and you need to wait for \&"action"
and then call this function again.
NOTE that this only returns errors etc regarding the whole multi stack. There NOTE that this only returns errors etc regarding the whole multi stack. There
might still have occurred problems on individual transfers even when this might still have occurred problems on individual transfers even when this
function returns OK. function returns \fICURLM_OK\fP.
.SH "TYPICAL USAGE" .SH "TYPICAL USAGE"
Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
file descriptors, then it'll wait for action on them using \fBselect(3)\fP and file descriptors, then it'll wait for action on them using \fBselect(3)\fP and
@@ -42,4 +46,5 @@ as soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
called. called.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " .BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3)" .BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
.BR libcurl-errors "(3)"

View File

@@ -1,6 +1,6 @@
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_multi_setopt 3 "8 Jan 2006" "libcurl 7.16.0" "libcurl Manual" .TH curl_multi_setopt 3 "10 Oct 2006" "libcurl 7.16.0" "libcurl Manual"
.SH NAME .SH NAME
curl_multi_setopt \- set options for a curl multi handle curl_multi_setopt \- set options for a curl multi handle
.SH SYNOPSIS .SH SYNOPSIS
@@ -9,7 +9,7 @@ curl_multi_setopt \- set options for a curl multi handle
CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param); CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param);
.SH DESCRIPTION .SH DESCRIPTION
curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By
using the appropriate options to \fIcurl_multi_setopt\fP, you can change using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change
libcurl's behaviour when using that multi handle. All options are set with libcurl's behaviour when using that multi handle. All options are set with
the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be
a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a
@@ -19,19 +19,43 @@ You can only set one option in each function call.
.SH OPTIONS .SH OPTIONS
.IP CURLMOPT_SOCKETFUNCTION .IP CURLMOPT_SOCKETFUNCTION
Pass a pointer to a function matching the curl_socket_callback prototype. The Pass a pointer to a function matching the \fBcurl_socket_callback\fP
\fIcurl_multi_socket(3)\fP functions inform the application about updates in prototype. The \fIcurl_multi_socket(3)\fP functions inform the application
the socket (file descriptor) status by doing none, one or multiple calls to about updates in the socket (file descriptor) status by doing none, one or
the curl_socket_callback given in the \fBparam\fP argument. They update the multiple calls to the curl_socket_callback given in the \fBparam\fP
status with changes since the previous time a \fIcurl_multi_socket(3)\fP argument. They update the status with changes since the previous time a
function was called. If the given callback pointer is NULL, no callback will \fIcurl_multi_socket(3)\fP function was called. If the given callback pointer
be called. Set the callback's \fBuserp\fP argument with is NULL, no callback will be called. Set the callback's \fBuserp\fP argument
\fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for more callback with \fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for more
details. callback details.
.IP CURLMOPT_SOCKETDATA .IP CURLMOPT_SOCKETDATA
Pass a pointer to whatever you want passed to the curl_socket_callback's forth Pass a pointer to whatever you want passed to the \fBcurl_socket_callback\fP's
argument, the userp pointer. This is not used by libcurl but only passed-thru forth argument, the userp pointer. This is not used by libcurl but only
as-is. Set the callback pointer with \fICURLMOPT_SOCKETFUNCTION\fP. passed-thru as-is. Set the callback pointer with
\fICURLMOPT_SOCKETFUNCTION\fP.
.IP CURLMOPT_PIPELINING
Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi
handle will make it attempt to perform HTTP Pipelining as far as possible for
transfers using this handle. This means that if you add a second request that
can use an already existing connection, the second request will be \&"piped"
on the same connection rather than being executed in parallell. (Added in
7.16.0)
.IP CURLMOPT_TIMERFUNCTION
Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP
prototype. This function will then be called when the timeout value
changes. The timeout value is at what latest time the application should call
one of the \&"performing" functions of the multi interface
(\fIcurl_multi_socket(3)\fP, \fIcurl_multi_socket_all(3)\fP and
\fIcurl_multi_perform(3)\fP) - to allow libcurl to keep timeouts and retries
etc to work. Libcurl attempts to limit calling this only when the fixed future
timeout time actually change. See also \fICURLMOPT_TIMERDATA\fP. This callback
can be used instead of, or in addition to, \fIcurl_multi_timeout(3)\fP. (Added
in 7.16.0)
.IP CURLMOPT_TIMERDATA
Pass a pointer to whatever you want passed to the
\fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is
not used by libcurl but only passed-thru as-is. Set the callback pointer with
\fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0)
.SH RETURNS .SH RETURNS
The standard CURLMcode for multi interface error codes. Note that it returns a The standard CURLMcode for multi interface error codes. Note that it returns a
CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl

View File

@@ -174,7 +174,7 @@ problem with the local client certificate
.IP "CURLE_SSL_CIPHER (59)" .IP "CURLE_SSL_CIPHER (59)"
couldn't use specified cipher couldn't use specified cipher
.IP "CURLE_SSL_CACERT (60)" .IP "CURLE_SSL_CACERT (60)"
problem with the CA cert (path? access rights?) peer certificate cannot be authenticated with known CA certificates
.IP "CURLE_BAD_CONTENT_ENCODING (61)" .IP "CURLE_BAD_CONTENT_ENCODING (61)"
Unrecognized transfer encoding Unrecognized transfer encoding
.IP "CURLE_LDAP_INVALID_URL (62)" .IP "CURLE_LDAP_INVALID_URL (62)"
@@ -208,6 +208,8 @@ No such TFTP user
Character conversion failed Character conversion failed
.IP "CURLE_CONV_REQD (76)" .IP "CURLE_CONV_REQD (76)"
Caller must register conversion callbacks Caller must register conversion callbacks
.IP "CURLE_SSL_CACERT_BADFILE (77)"
Problem with reading the SSL CA cert (path? access rights?)
.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)\fP. interface. Also consider \fIcurl_multi_strerror(3)\fP.
@@ -219,7 +221,9 @@ Things are fine.
.IP "CURLM_BAD_HANDLE (1)" .IP "CURLM_BAD_HANDLE (1)"
The passed-in handle is not a valid CURLM handle. The passed-in handle is not a valid CURLM handle.
.IP "CURLM_BAD_EASY_HANDLE (2)" .IP "CURLM_BAD_EASY_HANDLE (2)"
An easy handle was not good/valid. An easy handle was not good/valid. It could mean that it isn't an easy handle
at all, or possibly that the handle already is in used by this or another
multi handle.
.IP "CURLM_OUT_OF_MEMORY (3)" .IP "CURLM_OUT_OF_MEMORY (3)"
You are doomed. You are doomed.
.IP "CURLM_INTERNAL_ERROR (4)" .IP "CURLM_INTERNAL_ERROR (4)"

View File

@@ -74,7 +74,7 @@ struct fdinfo {
long timeout; /* as set by libcurl */ long timeout; /* as set by libcurl */
struct event ev; /* */ struct event ev; /* */
int evset; /* true if the 'ev' struct has been used in a event_set() call */ int evset; /* true if the 'ev' struct has been used in a event_set() call */
CURLMcode *multi; /* pointer to the multi handle */ CURLM *multi; /* pointer to the multi handle */
int *running_handles; /* pointer to the running_handles counter */ int *running_handles; /* pointer to the running_handles counter */
}; };
@@ -86,6 +86,8 @@ static int running_handles;
done, we can remove the timerevent as well */ done, we can remove the timerevent as well */
static struct event timerevent; static struct event timerevent;
static void update_timeout(CURLM *multi_handle);
/* called from libevent on action on a particular socket ("event") */ /* called from libevent on action on a particular socket ("event") */
static void eventcallback(int fd, short type, void *userp) static void eventcallback(int fd, short type, void *userp)
{ {
@@ -110,6 +112,8 @@ static void eventcallback(int fd, short type, void *userp)
if(evtimer_pending(&timerevent, NULL)) if(evtimer_pending(&timerevent, NULL))
evtimer_del(&timerevent); evtimer_del(&timerevent);
} }
else
update_timeout(fdp->multi);
} }
/* called from libevent when our timer event expires */ /* called from libevent when our timer event expires */
@@ -118,8 +122,6 @@ static void timercallback(int fd, short type, void *userp)
(void)fd; /* not used for this */ (void)fd; /* not used for this */
(void)type; /* ignored in here */ (void)type; /* ignored in here */
CURLM *multi_handle = (CURLM *)userp; CURLM *multi_handle = (CURLM *)userp;
long timeout_ms;
struct timeval timeout;
int running_handles; int running_handles;
CURLMcode rc; CURLMcode rc;
@@ -131,15 +133,9 @@ static void timercallback(int fd, short type, void *userp)
&running_handles); &running_handles);
} while (rc == CURLM_CALL_MULTI_PERFORM); } while (rc == CURLM_CALL_MULTI_PERFORM);
if(running_handles) { if(running_handles)
/* Get the current timeout value from libcurl and set a new timeout */ /* Get the current timeout value from libcurl and set a new timeout */
curl_multi_timeout(multi_handle, &timeout_ms); update_timeout(multi_handle);
/* convert ms to timeval */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
evtimer_add(&timerevent, &timeout);
}
} }
static void remsock(struct fdinfo *f) static void remsock(struct fdinfo *f)
@@ -266,6 +262,7 @@ writecallback(void *ptr, size_t size, size_t nmemb, void *data)
{ {
size_t realsize = size * nmemb; size_t realsize = size * nmemb;
struct connection *c = (struct connection *)data; struct connection *c = (struct connection *)data;
(void)ptr;
c->dlcounter += realsize; c->dlcounter += realsize;
c->global->dlcounter += realsize; c->global->dlcounter += realsize;
@@ -283,19 +280,28 @@ int num_total;
int num_idle; int num_idle;
int num_active; int num_active;
static void update_timeout(CURLM *multi_handle)
{
long timeout_ms;
struct timeval timeout;
/* Since we need a global timeout to occur after a given time of inactivity,
we use a single timeout-event. Get the timeout value from libcurl, and
update it after every call to libcurl. */
curl_multi_timeout(multi_handle, &timeout_ms);
/* convert ms to timeval */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
evtimer_add(&timerevent, &timeout);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
CURLM *multi_handle; CURLM *multi_handle;
CURLMsg *msg; CURLMsg *msg;
CURLcode code = CURLE_OK; CURLcode code = CURLE_OK;
CURLMcode mcode = CURLM_OK;
int rc;
int i; int i;
int selectmaxamount;
struct fdinfo *fdp;
char act;
long timeout_ms;
struct timeval timeout;
memset(&info, 0, sizeof(struct globalinfo)); memset(&info, 0, sizeof(struct globalinfo));
@@ -327,9 +333,11 @@ int main(int argc, char **argv)
/* init the multi stack */ /* init the multi stack */
multi_handle = curl_multi_init(); multi_handle = curl_multi_init();
/* initialize the timeout event */
evtimer_set(&timerevent, timercallback, multi_handle);
for(i=0; i< num_total; i++) { for(i=0; i< num_total; i++) {
CURL *e; CURL *e;
char *nl;
memset(&conns[i], 0, sizeof(struct connection)); memset(&conns[i], 0, sizeof(struct connection));
@@ -370,14 +378,8 @@ int main(int argc, char **argv)
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle, while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle,
&running_handles)); &running_handles));
/* Since we need a global timeout to occur after a given time of inactivity, /* update timeout */
we add a single timeout-event. Get the timeout value from libcurl */ update_timeout(multi_handle);
curl_multi_timeout(multi_handle, &timeout_ms);
/* convert ms to timeval */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
evtimer_set(&timerevent, timercallback, multi_handle);
evtimer_add(&timerevent, &timeout);
/* event_dispatch() runs the event main loop. It ends when no events are /* event_dispatch() runs the event main loop. It ends when no events are
left to wait for. */ left to wait for. */

View File

@@ -133,6 +133,49 @@ extern "C" {
#undef FILESIZEBITS #undef FILESIZEBITS
#endif #endif
#if defined(_WIN32) && !defined(WIN32)
/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
make this adjustment to catch this. */
#define WIN32 1
#endif
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
!defined(__CYGWIN__) || defined(__MINGW32__)
#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
/* The check above prevents the winsock2 inclusion if winsock.h already was
included, since they can't co-exist without problems */
#include <winsock2.h>
#endif
#else
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
libc5-based Linux systems. Only include it on system that are known to
require it! */
#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(__minix)
#include <sys/select.h>
#endif
#ifndef _WIN32_WCE
#include <sys/socket.h>
#endif
#ifndef __WATCOMC__
#include <sys/time.h>
#endif
#include <sys/types.h>
#endif
#ifndef curl_socket_typedef
/* socket typedef */
#ifdef WIN32
typedef SOCKET curl_socket_t;
#define CURL_SOCKET_BAD INVALID_SOCKET
#else
typedef int curl_socket_t;
#define CURL_SOCKET_BAD -1
#endif
#define curl_socket_typedef
#endif /* curl_socket_typedef */
struct curl_httppost { struct curl_httppost {
struct curl_httppost *next; /* next entry in the list */ struct curl_httppost *next; /* next entry in the list */
char *name; /* pointer to allocated name */ char *name; /* pointer to allocated name */
@@ -184,6 +227,14 @@ typedef size_t (*curl_read_callback)(char *buffer,
size_t nitems, size_t nitems,
void *instream); void *instream);
typedef enum {
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
CURLSOCKTYPE_LAST /* never use */
} curlsocktype;
typedef int (*curl_sockopt_callback)(void *clientp,
curl_socket_t curlfd,
curlsocktype purpose);
#ifndef CURL_NO_OLDIES #ifndef CURL_NO_OLDIES
/* not used since 7.10.8, will be removed in a future release */ /* not used since 7.10.8, will be removed in a future release */
@@ -339,6 +390,8 @@ typedef enum {
CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPT_CONV_FROM_NETWORK_FUNCTION,
CURLOPT_CONV_TO_NETWORK_FUNCTION, and CURLOPT_CONV_TO_NETWORK_FUNCTION, and
CURLOPT_CONV_FROM_UTF8_FUNCTION */ CURLOPT_CONV_FROM_UTF8_FUNCTION */
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
or wrong format */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;
@@ -436,7 +489,7 @@ typedef enum {
*/ */
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ #if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__SALFORDC__) defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__)
/* This compiler is believed to have an ISO compatible preprocessor */ /* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP #define CURL_ISOCPP
#else #else
@@ -890,22 +943,12 @@ typedef enum {
CINIT(TCP_NODELAY, LONG, 121), CINIT(TCP_NODELAY, LONG, 121),
/* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* 123 OBSOLETE. Gone in 7.16.0 */
/* When doing 3rd party transfer, set the source user and password with
this */
CINIT(SOURCE_USERPWD, OBJECTPOINT, 123),
/* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
/* 127 OBSOLETE. Gone in 7.16.0 */
/* When doing 3rd party transfer, set the source pre-quote linked list /* 128 OBSOLETE. Gone in 7.16.0 */
of commands with this */
CINIT(SOURCE_PREQUOTE, OBJECTPOINT, 127),
/* When doing 3rd party transfer, set the source post-quote linked list
of commands with this */
CINIT(SOURCE_POSTQUOTE, OBJECTPOINT, 128),
/* When FTP over SSL/TLS is selected (with CURLOPT_FTP_SSL), this option /* When FTP over SSL/TLS is selected (with CURLOPT_FTP_SSL), this option
can be used to change libcurl's default action which is to first try can be used to change libcurl's default action which is to first try
@@ -922,12 +965,8 @@ 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 */ /* 132 OBSOLETE. Gone in 7.16.0 */
CINIT(SOURCE_URL, OBJECTPOINT, 132), /* 133 OBSOLETE. Gone in 7.16.0 */
/* 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 /* zero terminated string for pass on to the FTP server when asked for
"account" info */ "account" info */
@@ -982,6 +1021,14 @@ typedef enum {
/* Pointer to command string to send if USER/PASS fails. */ /* Pointer to command string to send if USER/PASS fails. */
CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
/* callback function for setting socket options */
CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
/* set to 0 to disable session ID re-use for this transfer, default is
enabled (== 1) */
CINIT(SSL_SESSIONID_CACHE, LONG, 150),
CURLOPT_LASTENTRY /* the last unused */ CURLOPT_LASTENTRY /* the last unused */
} CURLoption; } CURLoption;
@@ -1000,18 +1047,6 @@ typedef enum {
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */ the obsolete stuff removed! */
#define CURLOPT_HTTPREQUEST -1
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
#define CURLOPT_MUTE -2
#define CURLOPT_PASSWDFUNCTION -3
#define CURLOPT_PASSWDDATA -4
#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 */

View File

@@ -28,13 +28,13 @@
/* 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.15.5-CVS" #define LIBCURL_VERSION "7.16.0-CVS"
/* 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 15 #define LIBCURL_VERSION_MINOR 16
#define LIBCURL_VERSION_PATCH 5 #define LIBCURL_VERSION_PATCH 0
/* 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
@@ -51,6 +51,6 @@
and it is always a greater number in a more recent release. It makes and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work. comparisons with greater than and less than work.
*/ */
#define LIBCURL_VERSION_NUM 0x070f05 #define LIBCURL_VERSION_NUM 0x071000
#endif /* __CURL_CURLVER_H */ #endif /* __CURL_CURLVER_H */

View File

@@ -37,34 +37,6 @@
file descriptors simultaneous easily. file descriptors simultaneous easily.
*/ */
#if defined(_WIN32) && !defined(WIN32)
/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
make this adjustment to catch this. */
#define WIN32 1
#endif
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
!defined(__CYGWIN__) || defined(__MINGW32__)
#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
/* The check above prevents the winsock2 inclusion if winsock.h already was
included, since they can't co-exist without problems */
#include <winsock2.h>
#endif
#else
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
libc5-based Linux systems. Only include it on system that are known to
require it! */
#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(_MINIX)
#include <sys/select.h>
#endif
#ifndef _WIN32_WCE
#include <sys/socket.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#endif
/* /*
* This header file should not really need to include "curl.h" since curl.h * This header file should not really need to include "curl.h" since curl.h
@@ -83,18 +55,6 @@ extern "C" {
typedef void CURLM; typedef void CURLM;
#ifndef curl_socket_typedef
/* Public socket typedef */
#ifdef WIN32
typedef SOCKET curl_socket_t;
#define CURL_SOCKET_BAD INVALID_SOCKET
#else
typedef int curl_socket_t;
#define CURL_SOCKET_BAD -1
#endif
#define curl_socket_typedef
#endif /* curl_socket_typedef */
typedef enum { typedef enum {
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
curl_multi_socket*() soon */ curl_multi_socket*() soon */
@@ -271,6 +231,20 @@ typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
pointer */ pointer */
void *socketp); /* private socket void *socketp); /* private socket
pointer */ pointer */
/*
* Name: curl_multi_timer_callback
*
* Desc: Called by libcurl whenever the library detects a change in the
* maximum number of milliseconds the app is allowed to wait before
* curl_multi_socket() or curl_multi_perform() must be called
* (to allow libcurl's timed events to take place).
*
* Returns: The callback should return zero.
*/
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
long timeout_ms, /* see above */
void *userp); /* private callback
pointer */
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
int *running_handles); int *running_handles);
@@ -310,6 +284,15 @@ typedef enum {
/* This is the argument passed to the socket callback */ /* This is the argument passed to the socket callback */
CINIT(SOCKETDATA, OBJECTPOINT, 2), CINIT(SOCKETDATA, OBJECTPOINT, 2),
/* set to 1 to enable pipelining for this multi handle */
CINIT(PIPELINING, LONG, 3),
/* This is the timer callback function pointer */
CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
/* This is the argument passed to the timer callback */
CINIT(TIMERDATA, OBJECTPOINT, 5),
CURLMOPT_LASTENTRY /* the last unused */ CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption; } CURLMoption;

View File

@@ -46,7 +46,7 @@ OBJS = $(OBJ_DIR)\transfer.obj $(OBJ_DIR)\file.obj &
$(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj & $(OBJ_DIR)\hostsyn.obj $(OBJ_DIR)\parsedate.obj &
$(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj & $(OBJ_DIR)\select.obj $(OBJ_DIR)\sslgen.obj &
$(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj & $(OBJ_DIR)\gtls.obj $(OBJ_DIR)\tftp.obj &
$(OBJ_DIR)\splay.obj $(OBJ_DIR)\splay.obj $(OBJ_DIR)\socks.obj
RESOURCE = $(OBJ_DIR)\libcurl.res RESOURCE = $(OBJ_DIR)\libcurl.res
@@ -93,282 +93,257 @@ $(LINK_ARG): $(__MAKEFILES__)
# #
# Dependencies based on "gcc -MM .." # Dependencies based on "gcc -MM .."
# #
$(OBJ_DIR)\file.obj: file.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\file.obj: file.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h progress.h sendf.h &
speedcheck.h getinfo.h transfer.h url.h memory.h ..\include\curl\mprintf.h & escape.h file.h speedcheck.h getinfo.h transfer.h url.h memory.h &
memdebug.h parsedate.h ..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\timeval.obj: timeval.c timeval.h setup.h config-win32.h setup_once.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 setup_once.h &
..\include\curl\mprintf.h ..\include\curl\curl.h &
$(OBJ_DIR)\base64.obj: base64.c setup.h config-win32.h ..\include\curl\mprintf.h & ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h base64.h memory.h ..\include\curl\curl.h & ..\include\curl\multi.h base64.h memory.h ..\include\curl\curl.h &
memdebug.h memdebug.h .\memory.h
$(OBJ_DIR)\hostip.obj: hostip.c setup.h config-win32.h setup_once.h urldata.h cookie.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
inet_ntop.h ..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h inet_ntop.h ..\include\curl\mprintf.h memory.h &
memdebug.h .\memory.h
$(OBJ_DIR)\progress.obj: progress.c setup.h config-win32.h ..\include\curl\curl.h & $(OBJ_DIR)\progress.obj: progress.c setup.h config-win32.h setup_once.h &
..\include\curl\curlver.h ..\include\curl\easy.h ..\include\curl\multi.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\curl.h urldata.h cookie.h formdata.h timeval.h http_chunks.h & ..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.h &
hostip.h hash.h llist.h sendf.h progress.h ..\include\curl\mprintf.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
sendf.h progress.h ..\include\curl\mprintf.h
$(OBJ_DIR)\formdata.obj: formdata.c setup.h config-win32.h ..\include\curl\curl.h & $(OBJ_DIR)\formdata.obj: formdata.c setup.h config-win32.h setup_once.h &
..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h strequal.h & ..\include\curl\multi.h ..\include\curl\curl.h formdata.h strequal.h &
memory.h ..\include\curl\mprintf.h memdebug.h memory.h ..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\cookie.obj: cookie.c setup.h config-win32.h setup_once.h &
$(OBJ_DIR)\cookie.obj: cookie.c setup.h config-win32.h urldata.h cookie.h & ..\include\curl\mprintf.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h urldata.h cookie.h ..\include\curl\curl.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
strequal.h strtok.h sendf.h memory.h share.h strtoofft.h memdebug.h &
.\memory.h
$(OBJ_DIR)\http.obj: http.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
memory.h memdebug.h progress.h base64.h strequal.h sslgen.h http_digest.h http_ntlm.h &
http_negotiate.h url.h share.h http.h memory.h select.h parsedate.h &
$(OBJ_DIR)\http.obj: http.c setup.h config-win32.h urldata.h cookie.h & strtoofft.h multiif.h ..\include\curl\mprintf.h memdebug.h .\memory.h
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & $(OBJ_DIR)\sendf.obj: sendf.c setup.h config-win32.h setup_once.h ..\include\curl\curl.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\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
if2ip.h progress.h transfer.h escape.h http.h ftp.h strtoofft.h & sendf.h connect.h sslgen.h ..\include\curl\mprintf.h memory.h &
strequal.h ssluse.h connect.h strerror.h memory.h inet_ntop.h select.h & strerror.h easyif.h memdebug.h .\memory.h
..\include\curl\mprintf.h memdebug.h $(OBJ_DIR)\ftp.obj: ftp.c setup.h config-win32.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
$(OBJ_DIR)\url.obj: url.c setup.h config-win32.h urldata.h cookie.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 splay.h &
sendf.h easyif.h if2ip.h progress.h transfer.h escape.h http.h ftp.h &
strtoofft.h strequal.h sslgen.h connect.h strerror.h memory.h &
inet_ntop.h select.h parsedate.h sockaddr.h multiif.h &
..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\url.obj: url.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h netrc.h base64.h sslgen.h &
transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h & transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h &
share.h content_encoding.h http_digest.h http_negotiate.h select.h multiif.h & share.h content_encoding.h http_digest.h http_negotiate.h select.h &
ftp.h dict.h telnet.h http.h file.h ldap.h url.h connect.h inet_ntop.h & multiif.h ftp.h dict.h telnet.h tftp.h http.h file.h ldap.h url.h &
./ca-bundle.h ..\include\curl\mprintf.h memory.h memdebug.h connect.h inet_ntop.h http_ntlm.h .\ca-bundle.h &
..\include\curl\mprintf.h memory.h memdebug.h .\memory.h
$(OBJ_DIR)\dict.obj: dict.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\dict.obj: dict.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
strequal.h dict.h ..\include\curl\mprintf.h progress.h strequal.h dict.h ..\include\curl\mprintf.h memdebug.h &
.\memory.h
$(OBJ_DIR)\if2ip.obj: if2ip.c setup.h config-win32.h $(OBJ_DIR)\if2ip.obj: if2ip.c setup.h config-win32.h setup_once.h if2ip.h inet_ntop.h &
memory.h ..\include\curl\curl.h ..\include\curl\curlver.h &
$(OBJ_DIR)\speedcheck.obj: speedcheck.c setup.h config-win32.h & ..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
memdebug.h .\memory.h
$(OBJ_DIR)\speedcheck.obj: speedcheck.c setup.h config-win32.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
speedcheck.h sendf.h multiif.h speedcheck.h
$(OBJ_DIR)\ldap.obj: ldap.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\ldap.obj: ldap.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\ssluse.obj: ssluse.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h url.h inet_pton.h &
strequal.h strtok.h ldap.h memory.h ..\include\curl\mprintf.h memdebug.h ssluse.h connect.h strequal.h select.h sslgen.h &
..\include\curl\mprintf.h
$(OBJ_DIR)\ssluse.obj: ssluse.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\version.obj: version.c setup.h config-win32.h setup_once.h ..\include\curl\curl.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\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memory.h memdebug.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 splay.h &
$(OBJ_DIR)\escape.obj: escape.c setup.h config-win32.h ..\include\curl\curl.h & sslgen.h ..\include\curl\mprintf.h
$(OBJ_DIR)\getenv.obj: getenv.c setup.h config-win32.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memory.h & ..\include\curl\multi.h ..\include\curl\curl.h memory.h memdebug.h &
..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\escape.obj: escape.c setup.h config-win32.h setup_once.h ..\include\curl\curl.h &
$(OBJ_DIR)\mprintf.obj: mprintf.c setup.h config-win32.h ..\include\curl\mprintf.h & ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\multi.h ..\include\curl\curl.h memory.h urldata.h &
..\include\curl\multi.h memory.h ..\include\curl\curl.h memdebug.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
splay.h easyif.h ..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\telnet.obj: telnet.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\mprintf.obj: mprintf.c setup.h config-win32.h setup_once.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 &
.\memory.h
$(OBJ_DIR)\telnet.obj: telnet.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
..\include\curl\mprintf.h arpa_telnet.h memory.h select.h memdebug.h telnet.h connect.h ..\include\curl\mprintf.h arpa_telnet.h memory.h &
select.h memdebug.h .\memory.h
$(OBJ_DIR)\netrc.obj: netrc.c setup.h config-win32.h ..\include\curl\curl.h & $(OBJ_DIR)\netrc.obj: netrc.c setup.h config-win32.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h netrc.h strequal.h & ..\include\curl\multi.h ..\include\curl\curl.h netrc.h strequal.h &
strtok.h memory.h ..\include\curl\mprintf.h memdebug.h strtok.h memory.h ..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\getinfo.obj: getinfo.c setup.h config-win32.h setup_once.h ..\include\curl\curl.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\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
getinfo.h memory.h ssluse.h memdebug.h getinfo.h memory.h sslgen.h memdebug.h .\memory.h
$(OBJ_DIR)\transfer.obj: transfer.c setup.h config-win32.h setup_once.h strtoofft.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h strequal.h urldata.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 & 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 & splay.h netrc.h content_encoding.h transfer.h sendf.h speedcheck.h &
http.h url.h getinfo.h ssluse.h http_digest.h http_ntlm.h & progress.h http.h url.h getinfo.h sslgen.h http_digest.h http_ntlm.h &
http_negotiate.h share.h memory.h select.h ..\include\curl\mprintf.h & http_negotiate.h share.h memory.h select.h multiif.h easyif.h &
memdebug.h ..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\strequal.obj: strequal.c setup.h config-win32.h setup_once.h strequal.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h ..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\easy.obj: easy.c setup.h config-win32.h setup_once.h strequal.h &
$(OBJ_DIR)\easy.obj: easy.c setup.h config-win32.h strequal.h ..\include\curl\curl.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
transfer.h ssluse.h url.h getinfo.h share.h memory.h progress.h & transfer.h sslgen.h url.h getinfo.h share.h strdup.h memory.h &
easyif.h ..\include\curl\mprintf.h memdebug.h progress.h easyif.h sendf.h ..\include\curl\mprintf.h memdebug.h &
.\memory.h
$(OBJ_DIR)\security.obj: security.c setup.h config-win32.h $(OBJ_DIR)\security.obj: security.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\krb4.obj: krb4.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\krb4.obj: krb4.c setup.h config-win32.h $(OBJ_DIR)\memdebug.obj: memdebug.c setup.h config-win32.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
$(OBJ_DIR)\memdebug.obj: memdebug.c setup.h config-win32.h ..\include\curl\curl.h & ..\include\curl\multi.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\easy.h ..\include\curl\multi.h & ..\include\curl\mprintf.h urldata.h cookie.h formdata.h timeval.h &
..\include\curl\curl.h ..\include\curl\mprintf.h urldata.h cookie.h & http_chunks.h hostip.h hash.h llist.h splay.h memory.h memdebug.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h memory.h memdebug.h .\memory.h
$(OBJ_DIR)\http_chunks.obj: http_chunks.c setup.h config-win32.h setup_once.h urldata.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 & cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
content_encoding.h http.h memory.h ..\include\curl\mprintf.h memdebug.h sendf.h content_encoding.h http.h memory.h ..\include\curl\mprintf.h &
memdebug.h .\memory.h
$(OBJ_DIR)\strtok.obj: strtok.c setup.h config-win32.h strtok.h $(OBJ_DIR)\strtok.obj: strtok.c setup.h config-win32.h setup_once.h strtok.h
$(OBJ_DIR)\connect.obj: connect.c setup.h config-win32.h setup_once.h urldata.h cookie.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h if2ip.h &
memory.h select.h memdebug.h strerror.h connect.h memory.h select.h url.h multiif.h sockaddr.h &
inet_ntop.h memdebug.h .\memory.h
$(OBJ_DIR)\llist.obj: llist.c setup.h config-win32.h llist.h memory.h & $(OBJ_DIR)\llist.obj: llist.c setup.h config-win32.h setup_once.h llist.h memory.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memdebug.h ..\include\curl\multi.h ..\include\curl\curl.h memdebug.h .\memory.h
$(OBJ_DIR)\hash.obj: hash.c setup.h config-win32.h setup_once.h hash.h llist.h memory.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memdebug.h ..\include\curl\multi.h ..\include\curl\curl.h memdebug.h .\memory.h
$(OBJ_DIR)\multi.obj: multi.c setup.h config-win32.h setup_once.h ..\include\curl\curl.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\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
transfer.h url.h connect.h progress.h memory.h easyif.h multiif.h & transfer.h url.h connect.h progress.h memory.h easyif.h multiif.h &
memdebug.h sendf.h memdebug.h .\memory.h
$(OBJ_DIR)\content_encoding.obj: content_encoding.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\content_encoding.obj: content_encoding.c setup.h config-win32.h urldata.h & $(OBJ_DIR)\share.obj: share.c setup.h config-win32.h setup_once.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 splay.h &
share.h memory.h memdebug.h .\memory.h
$(OBJ_DIR)\http_digest.obj: http_digest.c setup.h config-win32.h setup_once.h urldata.h &
cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h & cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.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 & formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
content_encoding.h memory.h memdebug.h sendf.h strequal.h base64.h md5.h http_digest.h strtok.h url.h memory.h &
..\include\curl\mprintf.h memdebug.h .\memory.h
$(OBJ_DIR)\share.obj: share.c setup.h config-win32.h ..\include\curl\curl.h & $(OBJ_DIR)\md5.obj: md5.c setup.h config-win32.h setup_once.h md5.h
..\include\curl\curlver.h ..\include\curl\easy.h ..\include\curl\multi.h & $(OBJ_DIR)\http_negotiate.obj: http_negotiate.c setup.h config-win32.h setup_once.h
..\include\curl\curl.h urldata.h cookie.h formdata.h timeval.h & $(OBJ_DIR)\http_ntlm.obj: http_ntlm.c setup.h config-win32.h setup_once.h
http_chunks.h hostip.h hash.h llist.h share.h memory.h memdebug.h $(OBJ_DIR)\inet_pton.obj: inet_pton.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\strtoofft.obj: strtoofft.c setup.h config-win32.h setup_once.h strtoofft.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h ..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\strerror.obj: strerror.c setup.h config-win32.h setup_once.h &
$(OBJ_DIR)\strerror.obj: strerror.c setup.h config-win32.h ..\include\curl\curl.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h strerror.h urldata.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 & cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
..\include\curl\mprintf.h splay.h ..\include\curl\mprintf.h
$(OBJ_DIR)\hostares.obj: hostares.c setup.h config-win32.h setup_once.h urldata.h cookie.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\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h connect.h ..\include\curl\mprintf.h memory.h &
memdebug.h .\memory.h
$(OBJ_DIR)\hostasyn.obj: hostasyn.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\hostasyn.obj: hostasyn.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h &
.\memory.h
$(OBJ_DIR)\hostip4.obj: hostip4.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\hostip4.obj: hostip4.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h inet_pton.h ..\include\curl\mprintf.h memory.h &
memdebug.h .\memory.h
$(OBJ_DIR)\hostip6.obj: hostip6.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\hostip6.obj: hostip6.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h inet_pton.h connect.h ..\include\curl\mprintf.h &
memory.h memdebug.h .\memory.h
$(OBJ_DIR)\hostsyn.obj: hostsyn.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\hostsyn.obj: hostsyn.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h memory.h memdebug.h strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h &
.\memory.h
$(OBJ_DIR)\hostthre.obj: hostthre.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\hostthre.obj: hostthre.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.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 & http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
..\include\curl\mprintf.h inet_ntop.h memory.h memdebug.h strerror.h url.h multiif.h ..\include\curl\mprintf.h inet_ntop.h &
memory.h memdebug.h .\memory.h
$(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h config-win32.h ..\include\curl\mprintf.h & $(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h config-win32.h setup_once.h
$(OBJ_DIR)\parsedate.obj: parsedate.c setup.h config-win32.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h 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 ..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h setup_once.h ..\include\curl\curl.h &
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h select.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.h &
$(OBJ_DIR)\gtls.obj: gtls.c setup.h config-win32.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
connect.h select.h
$(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h urldata.h cookie.h & $(OBJ_DIR)\gtls.obj: gtls.c setup.h config-win32.h setup_once.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sslgen.h & $(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h setup_once.h urldata.h cookie.h &
ssluse.h gtls.h sendf.h strequal.h url.h memory.h memdebug.h
$(OBJ_DIR)\tftp.obj: tftp.c setup.h config-win32.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h & ..\include\curl\curl.h ..\include\curl\curlver.h ..\include\curl\easy.h &
..\include\curl\multi.h formdata.h http_chunks.h hostip.h hash.h llist.h & ..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
transfer.h sendf.h tftp.h progress.h ..\include\curl\mprintf.h memory.h & http_chunks.h hostip.h hash.h llist.h splay.h sslgen.h ssluse.h gtls.h &
select.h memdebug.h sendf.h strequal.h url.h memory.h memdebug.h .\memory.h
$(OBJ_DIR)\tftp.obj: tftp.c setup.h config-win32.h setup_once.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 splay.h transfer.h sendf.h tftp.h &
progress.h connect.h strerror.h sockaddr.h ..\include\curl\mprintf.h &
memory.h select.h memdebug.h .\memory.h
$(OBJ_DIR)\splay.obj: splay.c splay.h $(OBJ_DIR)\splay.obj: splay.c splay.h
$(OBJ_DIR)\strdup.obj: strdup.c setup.h config-win32.h setup_once.h strdup.h

View File

@@ -30,7 +30,7 @@ DOCS = README.encoding README.memoryleak README.ares README.curlx \
EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos \ EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 Makefile.riscos \
$(DSP) curllib.dsw config-win32.h config-win32ce.h config-riscos.h \ $(DSP) curllib.dsw config-win32.h config-win32ce.h config-riscos.h \
config-mac.h config.h.in ca-bundle.crt makefile.dj config.dj \ config-mac.h config.h.in ca-bundle.crt makefile.dj config.dos \
libcurl.framework.make libcurl.plist libcurl.rc config-amigaos.h \ libcurl.framework.make libcurl.plist libcurl.rc config-amigaos.h \
amigaos.c amigaos.h makefile.amiga Makefile.netware nwlib.c \ amigaos.c amigaos.h makefile.amiga Makefile.netware nwlib.c \
libcurl.imp msvcproj.head msvcproj.foot config-win32ce.h \ libcurl.imp msvcproj.head msvcproj.foot config-win32ce.h \
@@ -43,9 +43,12 @@ lib_LTLIBRARIES = libcurl.la
# we use srcdir/include for the static global include files # we use srcdir/include for the static global include files
# we use builddir/lib for the generated lib/config.h file to get found # we use builddir/lib for the generated lib/config.h file to get found
# we use srcdir/lib for the lib-private header files # we use srcdir/lib for the lib-private header files
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/lib -I$(top_srcdir)/lib
VERSION=-version-info 3:0:0 INCLUDES = -I$(top_srcdir)/include \
-I$(top_builddir)/lib \
-I$(top_srcdir)/lib
VERSION=-version-info 4:0:0
# This flag accepts an argument of the form current[:revision[:age]]. So, # This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to

View File

@@ -8,7 +8,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
content_encoding.c share.c http_digest.c md5.c http_negotiate.c \ content_encoding.c share.c http_digest.c md5.c http_negotiate.c \
http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \ http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c \
hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \ hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c \
select.c gtls.c sslgen.c tftp.c splay.c strdup.c select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@@ -18,6 +18,6 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \
share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \ share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h \
inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \ inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h \
setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \ setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h \
gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h gtls.h tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h

View File

@@ -3,7 +3,7 @@
## Makefile for building libcurl.nlm (NetWare version - gnu make) ## Makefile for building libcurl.nlm (NetWare version - gnu make)
## Use: make -f Makefile.netware ## Use: make -f Makefile.netware
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf http://www.gknw.de/phpbb
# #
################################################################# #################################################################
@@ -19,7 +19,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8a OPENSSL_PATH = ../../openssl-0.9.8c
endif endif
ifndef INSTDIR ifndef INSTDIR
@@ -68,7 +68,7 @@ CP = cp -afv
# RM = rm -f # RM = rm -f
# if you want to mark the target as MTSAFE you will need a tool for # if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool: # generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.com/development/prgtools/mkxdc.zip # http://www.gknw.net/development/prgtools/mkxdc.zip
MPKXDC = mkxdc MPKXDC = mkxdc
# Global flags for all compilers # Global flags for all compilers
@@ -359,9 +359,10 @@ config.h: Makefile.netware
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ @echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@ @echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@ @echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ @echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ @echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
ifdef DISABLE_LDAP ifdef DISABLE_LDAP
@@ -414,6 +415,31 @@ ca-bundle.h: Makefile.netware
url.c: ca-bundle.h url.c: ca-bundle.h
info: $(OBJDIR)/version.inc
@echo Configured to build $(TARGET) with these options:
@echo curl version: $(LIBCURL_VERSION_STR)
@echo compiler/linker: $(CC) / $(LD)
ifdef WITH_SSL
@echo SSL support: enabled (OpenSSL)
else
@echo SSL support: no
endif
ifdef WITH_ZLIB
@echo zlib support: enabled
else
@echo zlib support: no
endif
ifdef WITH_ARES
@echo c-ares support: enabled
else
@echo c-ares support: no
endif
ifdef ENABLE_IPV6
@echo ipv6 support: enabled
else
@echo ipv6 support: no
endif
$(LIBCARES): $(LIBCARES):
$(MAKE) -C ../ares -f Makefile.netware lib $(MAKE) -C ../ares -f Makefile.netware lib

View File

@@ -132,8 +132,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) $(RTLIB) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
CC = $(CCNODBG) CC = $(CCNODBG) $(RTLIB)
CFGSET = TRUE CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF !ENDIF
@@ -481,6 +481,7 @@ X_OBJS= \
$(DIROBJ)\content_encoding.obj \ $(DIROBJ)\content_encoding.obj \
$(DIROBJ)\tftp.obj \ $(DIROBJ)\tftp.obj \
$(DIROBJ)\splay.obj \ $(DIROBJ)\splay.obj \
$(DIROBJ)\socks.obj \
$(RESOURCE) $(RESOURCE)
all : $(TARGET) all : $(TARGET)

View File

@@ -29,7 +29,7 @@ Modify Your Application
Add a line in your application code: Add a line in your application code:
curl_memdebug("filename"); curl_memdebug("dump");
This will make the malloc debug system output a full trace of all resource This will make the malloc debug system output a full trace of all resource
using functions to the given file name. Make sure you rebuild your program using functions to the given file name. Make sure you rebuild your program
@@ -45,9 +45,9 @@ Run Your Application
Analyze the Flow Analyze the Flow
Use the tests/memanalyze.pl perl script to analyze the memdump file: Use the tests/memanalyze.pl perl script to analyze the dump file:
tests/memanalyze.pl < memdump tests/memanalyze.pl dump
This now outputs a report on what resources that were allocated but never This now outputs a report on what resources that were allocated but never
freed etc. This report is very fine for posting to the list! freed etc. This report is very fine for posting to the list!

View File

@@ -1,8 +1,6 @@
Implementation of the curl_multi_socket API Implementation of the curl_multi_socket API
Most of the design decisions and debates about this new API have already The main ideas of the new API are simply:
been held on the curl-library mailing list a long time ago so I had a basic
idea on what approach to use. The main ideas of the new API are simply:
1 - The application can use whatever event system it likes as it gets info 1 - The application can use whatever event system it likes as it gets info
from libcurl about what file descriptors libcurl waits for what action from libcurl about what file descriptors libcurl waits for what action
@@ -38,62 +36,33 @@ Implementation of the curl_multi_socket API
is that we get a curl_multi_timeout() that should also work with old-style is that we get a curl_multi_timeout() that should also work with old-style
applications that use curl_multi_perform(). applications that use curl_multi_perform().
The easy handle argument was removed fom the curl_multi_socket() function We also added a timer callback that makes libcurl call the application when
because having it there would require the application to do a socket to easy the timeout value changes, and you set that with curl_multi_setopt().
handle conversion on its own. I find it very unlikely that applications
would want to do that and since libcurl would need such a lookup on its own
anyway since we didn't want to force applications to do that translation
code (it would be optional), it seemed like an unnecessary option.
Instead I created an internal "socket to easy handles" hash table that given We created an internal "socket to easy handles" hash table that given
a socket (file descriptor) return the easy handle that waits for action on a socket (file descriptor) return the easy handle that waits for action on
that socket. This hash is made using the already existing hash code that socket. This hash is made using the already existing hash code
(previously only used for the DNS cache). (previously only used for the DNS cache).
To make libcurl be able to report plain sockets in the socket callback, I To make libcurl able to report plain sockets in the socket callback, we had
had to re-organize the internals of the curl_multi_fdset() etc so that the to re-organize the internals of the curl_multi_fdset() etc so that the
conversion from sockets to fd_sets for that function is only done in the conversion from sockets to fd_sets for that function is only done in the
last step before the data is returned. I also had to extend c-ares to get a last step before the data is returned. I also had to extend c-ares to get a
function that can return plain sockets, as that library too returned only function that can return plain sockets, as that library too returned only
fd_sets and that is no longer good enough. The changes done to c-ares have fd_sets and that is no longer good enough. The changes done to c-ares have
been committed and are available in the c-ares CVS repository destined to be been committed and are available in the c-ares CVS repository destined to be
included in the upcoming c-ares 1.3.1 release. included in the c-ares 1.3.1 release.
The 'shiper' tool is the test application I wrote that uses the new We have done a test runs with up to 9000 connections (with a single active
curl_multi_socket() in its current state. It seems to be working and it uses one). The curl_multi_socket() invoke then takes less than 10 microseconds in
the API as it is documented and supposed to work. It is still using average (using the read-only-1-byte-at-a-time hack). We are now below the
select(), because I needed that during development (like until I had the 60 microseconds "per socket action" goal (the extra 50 is the time libevent
socket hash implemented etc) and because I haven't yet learned how to use needs).
libevent or similar.
The hiper/shiper tools are very simple and initiates lots of connections and
have them running for the test period and then kills them all.
Since I wasn't done with the implementation until early January I haven't
had time to run very many measurements and checks, but I have done a few
runs with up to a few hundred connections (with a single active one). The
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
add connections, it certainly matches my in my opinion very ambitious goal.
We are now below the 60 microseconds "per socket action" goal. It is
destined to be somewhat higher the more connections we have since the hash
table gets more populated and the splay tree will grow etc.
Some tests at 7000 and 9000 connections showed that the socket hash lookup
is somewhat of a bottle neck. Its current implementation may be a bit too
limiting. It simply has a fixed-size array, and on each entry in the array
it has a linked list with entries. So the hash only checks which list to
scan through. The code I had used so for used a list with merely 7 slots (as
that is what the DNS hash uses) but with 7000 connections that would make an
average of 1000 nodes in each list to run through. I upped that to 97 slots
(I believe a prime is suitable) and noticed a significant speed increase. I
need to reconsider the hash implementation or use a rather large default
value like this. At 9000 connections I was still below 10us per call.
Status Right Now Status Right Now
The curl_multi_socket() API is implemented according to how it is The curl_multi_socket() API is implemented according to how it is
documented. documented. We deem it ready to use.
http://curl.haxx.se/libcurl/c/curl_multi_socket.html http://curl.haxx.se/libcurl/c/curl_multi_socket.html
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
@@ -101,12 +70,4 @@ Status Right Now
What is Left for the curl_multi_socket API What is Left for the curl_multi_socket API
1 - More measuring with more extreme number of connections Real world usage!
2 - More testing with actual URLs and complete from start to end transfers.
I'm quite sure we don't set expire times all over in the code properly, so
there is bound to be some timeout bugs left.
What it really takes is for me to commit the code and to make an official
release with it so that we get people "out there" to help out testing it.

View File

@@ -1,34 +1,27 @@
Doing HTTP Pipelining with libcurl HTTP Pipelining with libcurl
================================== ============================
Background Background
Since pipelining implies that one or more requests are sent to a server before Since pipelining implies that one or more requests are sent to a server before
the previous response(s) have been received, it cannot be implemented easily the previous response(s) have been received, we only support it for multi
into libcurl's easy interface due to its synchronous nature. We therefore only interface use.
aim on adding it for multi interface use.
Considerations Considerations
When using the multi interface, you create one easy handle for each transfer. When using the multi interface, you create one easy handle for each transfer.
Bascially any number of handles can be created, added and used with the multi Bascially any number of handles can be created, added and used with the multi
interface - simultaneously. It is an interface designed to allow many interface - simultaneously. It is an interface designed to allow many
simultaneous transfers while still using a single thread. simultaneous transfers while still using a single thread. Pipelining does not
change any of these details.
Pipelining however, will force us to allow apps to somehow "connect" two (or
more) easy handles that are added to a multi handle. The first one sends a
request and receives a response, just as normal, while the second (and
subsequent) ones need to be attached to the first handle so that it can send
its request on the same connection and then sit and wait until its response
comes.
API API
We add a new option to curl_multi_setopt() called CURLMOPT_PIPELINING that We've added a new option to curl_multi_setopt() called CURLMOPT_PIPELINING
enables "attempted pipelining" and then all easy handles used on that handle that enables "attempted pipelining" and then all easy handles used on that
will attempt to use an existing pipeline. handle will attempt to use an existing pipeline.
Decisions Already Made Details
- A pipeline is only created if a previous connection exists to the same IP - A pipeline is only created if a previous connection exists to the same IP
address that the new request is being made to use. address that the new request is being made to use.
@@ -50,22 +43,9 @@ Decisions Already Made
be considered for pipelining. Also, asking for explicit pipelining on handle be considered for pipelining. Also, asking for explicit pipelining on handle
X may be tricky when handle X get a closed connection. X may be tricky when handle X get a closed connection.
To Ponder About
- We need options to control max pipeline length, and probably how to behave - We need options to control max pipeline length, and probably how to behave
if we reach that limit. As was discussed on the list, it can probably be if we reach that limit. As was discussed on the list, it can probably be
made very complicated, so perhaps we can think of a way to pass all made very complicated, so perhaps we can think of a way to pass all
variables involved to a callback and let the application decide how to act variables involved to a callback and let the application decide how to act
in specific situations. Either way, these fancy options are only interesting in specific situations. Either way, these fancy options are only interesting
to work on when everything is working and we have working apps to test with. to work on when everything is working and we have working apps to test with.
- Currently (before pipelining) we do not have any code or concept that lets
multiple handles share the same physical connection. We need to carefully
make sure that each easy handle knows exactly what they can do and when, on
the shared connection.
- We need to keep a linked list of each handle that is part of a single pipe
so that if it breaks, we know which handles that need to resend their
requests. The pipe linked-lists could very well be "held" in the multi
handle struct so that they won't "belong" to a particular easy handle that
happens to be part of the pipeline during a certain period.

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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
@@ -280,7 +280,7 @@ int main(int argc, char **argv, char **envp)
for(j=0; j < 0x10; j++) for(j=0; j < 0x10; j++)
if((j+i) < dataLen) if((j+i) < dataLen)
printf("%c", isgraph(data[i+j])?data[i+j]:'.'); printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
else else
break; break;
puts(""); puts("");

View File

@@ -39,6 +39,7 @@
#define HAVE_STRINGS_H 1 #define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
#define HAVE_STRSTR 1 #define HAVE_STRSTR 1
#define HAVE_STRUCT_TIMEVAL 1
#define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_SOCKET_H 1 #define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_SOCKIO_H 1 #define HAVE_SYS_SOCKIO_H 1

View File

@@ -15,6 +15,7 @@
#define HAVE_TIME_H 1 #define HAVE_TIME_H 1
#define HAVE_STDLIB_H 1 #define HAVE_STDLIB_H 1
#define HAVE_UTIME_H 1 #define HAVE_UTIME_H 1
#define HAVE_SYS_TIME_H 1
#define TIME_WITH_SYS_TIME 1 #define TIME_WITH_SYS_TIME 1
@@ -27,6 +28,7 @@
#define HAVE_MEMCPY 1 #define HAVE_MEMCPY 1
#define HAVE_SELECT 1 #define HAVE_SELECT 1
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
#define HAVE_STRUCT_TIMEVAL 1
//#define HAVE_STRICMP 1 //#define HAVE_STRICMP 1
#define HAVE_SIGACTION 1 #define HAVE_SIGACTION 1

View File

@@ -119,6 +119,9 @@
/* Define if you have the `gettimeofday' function. */ /* Define if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY #define HAVE_GETTIMEOFDAY
/* Define if you have the `timeval' struct. */
#define HAVE_STRUCT_TIMEVAL
/* Define if you have the `inet_addr' function. */ /* Define if you have the `inet_addr' function. */
#undef HAVE_INET_ADDR #undef HAVE_INET_ADDR

View File

@@ -475,6 +475,9 @@
/* if struct sockaddr_storage is defined */ /* if struct sockaddr_storage is defined */
/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */ /* #undef HAVE_STRUCT_SOCKADDR_STORAGE */
/* Define this if you have struct timeval */
#define HAVE_STRUCT_TIMEVAL 1
/* Define to 1 if you have the <sys/filio.h> header file. */ /* Define to 1 if you have the <sys/filio.h> header file. */
#define HAVE_SYS_FILIO_H 1 #define HAVE_SYS_FILIO_H 1

View File

@@ -81,6 +81,9 @@
/* Define if you have the <sys/stat.h> header file. */ /* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file */
/* #define HAVE_SYS_TIME_H 1 */
/* Define if you have the <sys/types.h> header file. */ /* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_TYPES_H 1
@@ -335,6 +338,9 @@
#define HAVE_STRUCT_SOCKADDR_STORAGE 1 #define HAVE_STRUCT_SOCKADDR_STORAGE 1
#endif #endif
/* Define this if you have struct timeval */
#define HAVE_STRUCT_TIMEVAL 1
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* COMPILER SPECIFIC */ /* COMPILER SPECIFIC */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */

View File

@@ -75,6 +75,9 @@
/* Define if you have the <sys/stat.h> header file. */ /* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file */
/* #define HAVE_SYS_TIME_H 1 */
/* Define if you have the <sys/types.h> header file. */ /* Define if you have the <sys/types.h> header file. */
/* #define HAVE_SYS_TYPES_H 1 */ /* #define HAVE_SYS_TYPES_H 1 */
@@ -307,6 +310,9 @@
/* Define this if you have struct sockaddr_storage */ /* Define this if you have struct sockaddr_storage */
/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */ /* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */
/* Define this if you have struct timeval */
#define HAVE_STRUCT_TIMEVAL 1
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* COMPILER SPECIFIC */ /* COMPILER SPECIFIC */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */

View File

@@ -1,22 +1,24 @@
#ifndef _CURL_CONFIG_DJGPP_H #ifndef _CURL_CONFIG_DOS_H
#define _CURL_CONFIG_DJGPP_H #define _CURL_CONFIG_DOS_H
/* lib/config.dj - Hand crafted config file for DJGPP. /* lib/config.dos - Hand crafted config file for MSDOS.
* *
* $Id$ * $Id$
*/ */
#define OS "MSDOS/djgpp" #if defined(DJGPP)
#define PACKAGE "curl" #define OS "MSDOS/djgpp"
#elif defined(__HIGHC__)
#define CURL_CA_BUNDLE "/dev/env/CURL_CA_BUNDLE" #define OS "MSDOS/HighC"
#elif defined(__WATCOMC__)
#if (DJGPP_MINOR >= 4) #define OS "MSDOS/Watcom"
/* #define HAVE_DLOPEN 1 maybe not (DXE3) */ #else
#define OS "MSDOS/?"
#endif #endif
#define PACKAGE "curl"
#define HAVE_ASSERT_T 1 #define HAVE_ASSERT_T 1
#define HAVE_ARPA_INET_H 1 #define HAVE_ARPA_INET_H 1
#define HAVE_BASENAME 1
#define HAVE_CLOSESOCKET 1 #define HAVE_CLOSESOCKET 1
#define HAVE_FCNTL_H 1 #define HAVE_FCNTL_H 1
#define HAVE_FIONBIO 1 #define HAVE_FIONBIO 1
@@ -42,21 +44,21 @@
#define HAVE_NET_IF_H 1 #define HAVE_NET_IF_H 1
#define HAVE_PROCESS_H 1 #define HAVE_PROCESS_H 1
#define HAVE_PERROR 1 #define HAVE_PERROR 1
#define HAVE_RECV 1
#define HAVE_SELECT 1 #define HAVE_SELECT 1
#define HAVE_SEND 1
#define HAVE_SETJMP_H 1 #define HAVE_SETJMP_H 1
#define HAVE_SETLOCALE 1 #define HAVE_SETLOCALE 1
#define HAVE_SETVBUF 1 #define HAVE_SETVBUF 1
#define HAVE_SIGNAL 1 #define HAVE_SIGNAL 1
#define HAVE_SIGACTION 1
#define HAVE_SIGSETJMP 1
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
#define HAVE_SPNEGO 1 #define HAVE_SPNEGO 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1 #define HAVE_STRDUP 1
#define HAVE_STRFTIME 1 #define HAVE_STRFTIME 1
#define HAVE_STRICMP 1 #define HAVE_STRICMP 1
#define HAVE_STRSTR 1 #define HAVE_STRSTR 1
#define HAVE_STRTOLL 1 #define HAVE_STRTOLL 1
#define HAVE_STRUCT_TIMEVAL 1
#define HAVE_SYS_IOCTL_H 1 #define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_SOCKET_H 1 #define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
@@ -69,16 +71,28 @@
#define NEED_MALLOC_H 1 #define NEED_MALLOC_H 1
#if (DJGPP_MINOR >= 4)
#define HAVE_STRLCAT 1
#endif
#define RETSIGTYPE void #define RETSIGTYPE void
#define SIZEOF_LONG_DOUBLE 16 #define SIZEOF_LONG_DOUBLE 16
#define SIZEOF_CURL_OFF_T 4 /* no huge file support */ #define SIZEOF_CURL_OFF_T 4 /* no huge file support */
#define STDC_HEADERS 1 #define STDC_HEADERS 1
#define TIME_WITH_SYS_TIME 1 #define TIME_WITH_SYS_TIME 1
/* Qualifiers for send() and recv().
*/
#define SEND_TYPE_ARG1 int
#define SEND_QUAL_ARG2 const
#define SEND_TYPE_ARG2 void *
#define SEND_TYPE_ARG3 int
#define SEND_TYPE_ARG4 int
#define SEND_TYPE_RETV int
#define RECV_TYPE_ARG1 int
#define RECV_TYPE_ARG2 void *
#define RECV_TYPE_ARG3 int
#define RECV_TYPE_ARG4 int
#define RECV_TYPE_RETV int
#define BSD #define BSD
/* #define MALLOCDEBUG */ /* #define MALLOCDEBUG */
@@ -105,19 +119,41 @@
/* to disable LDAP */ /* to disable LDAP */
#define CURL_DISABLE_LDAP 1 #define CURL_DISABLE_LDAP 1
/* Because djgpp <= 2.03 doesn't have snprintf() etc.
*/
#if (DJGPP_MINOR < 4)
#define _MPRINTF_REPLACE
#endif
#define in_addr_t u_long #define in_addr_t u_long
#define socklen_t int #define socklen_t int
#if __GNUC__ < 4 /* gcc 4.x built-in ? */ #if defined(__HIGHC__) || \
(defined(__GNUC__) && __GNUC__ < 4) /* gcc 4.x built-in ? */
#define ssize_t int #define ssize_t int
#endif #endif
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
/* Target HAVE_x section
*/
#if defined(DJGPP)
#define HAVE_BASENAME 1
#define HAVE_STRCASECMP 1
#define HAVE_SIGACTION 1
#define HAVE_SIGSETJMP 1
#define HAVE_SYS_TIME_H 1
#if (DJGPP_MINOR >= 4)
#define HAVE_STRLCAT 1
#endif
/* Because djgpp <= 2.03 doesn't have snprintf() etc. */
#if (DJGPP_MINOR < 4)
#define _MPRINTF_REPLACE
#endif
#elif defined(__WATCOMC__)
#define HAVE_STRCASECMP 1
#elif defined(__HIGHC__)
#define HAVE_SYS_TIME_H 1
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <tcp.h> /* Watt-32 API */ #include <tcp.h> /* Watt-32 API */
@@ -125,5 +161,5 @@
#undef word #undef word
#undef byte #undef byte
#endif /* _CURL_CONFIG_DJGPP_H */ #endif /* _CURL_CONFIG_DOS_H */

View File

@@ -25,7 +25,9 @@
#ifndef WIN32 #ifndef WIN32
/* headers for non-win32 */ /* headers for non-win32 */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
@@ -82,7 +84,7 @@
#define FALSE 0 #define FALSE 0
#endif #endif
#ifdef WIN32 #ifdef USE_WINSOCK
#define EINPROGRESS WSAEINPROGRESS #define EINPROGRESS WSAEINPROGRESS
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
#define EISCONN WSAEISCONN #define EISCONN WSAEISCONN
@@ -119,7 +121,7 @@ singleipconnect(struct connectdata *conn,
*/ */
int Curl_sockerrno(void) int Curl_sockerrno(void)
{ {
#ifdef WIN32 #ifdef USE_WINSOCK
return (int)WSAGetLastError(); return (int)WSAGetLastError();
#else #else
return errno; return errno;
@@ -702,6 +704,17 @@ singleipconnect(struct connectdata *conn,
nosigpipe(conn, sockfd); nosigpipe(conn, sockfd);
if(data->set.fsockopt) {
/* activate callback for setting socket options */
error = data->set.fsockopt(data->set.sockopt_client,
sockfd,
CURLSOCKTYPE_IPCXN);
if (error) {
sclose(sockfd); /* close the socket and bail out */
return CURL_SOCKET_BAD;
}
}
/* possibly bind the local end to an IP, interface or port */ /* possibly bind the local end to an IP, interface or port */
res = bindlocal(conn, sockfd); res = bindlocal(conn, sockfd);
if(res) { if(res) {

View File

@@ -62,9 +62,9 @@ enum zlibState {
}; };
static CURLcode static CURLcode
process_zlib_error(struct SessionHandle *data, process_zlib_error(struct connectdata *conn, z_stream *z)
z_stream *z)
{ {
struct SessionHandle *data = conn->data;
if (z->msg) if (z->msg)
failf (data, "Error while processing content unencoding: %s", failf (data, "Error while processing content unencoding: %s",
z->msg); z->msg);
@@ -84,7 +84,7 @@ exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
} }
static CURLcode static CURLcode
inflate_stream(struct SessionHandle *data, inflate_stream(struct connectdata *conn,
struct Curl_transfer_keeper *k) struct Curl_transfer_keeper *k)
{ {
int allow_restart = 1; int allow_restart = 1;
@@ -113,7 +113,7 @@ inflate_stream(struct SessionHandle *data,
if (status == Z_OK || status == Z_STREAM_END) { if (status == Z_OK || status == Z_STREAM_END) {
allow_restart = 0; allow_restart = 0;
if(DSIZ - z->avail_out) { if(DSIZ - z->avail_out) {
result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
DSIZ - z->avail_out); DSIZ - z->avail_out);
/* if !CURLE_OK, clean up, return */ /* if !CURLE_OK, clean up, return */
if (result) { if (result) {
@@ -128,7 +128,7 @@ inflate_stream(struct SessionHandle *data,
if (inflateEnd(z) == Z_OK) if (inflateEnd(z) == Z_OK)
return exit_zlib(z, &k->zlib_init, result); return exit_zlib(z, &k->zlib_init, result);
else else
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
} }
/* Done with these bytes, exit */ /* Done with these bytes, exit */
@@ -143,7 +143,7 @@ inflate_stream(struct SessionHandle *data,
inflateReset(z); inflateReset(z);
if (inflateInit2(z, -MAX_WBITS) != Z_OK) { if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
return process_zlib_error(data, z); return process_zlib_error(conn, z);
} }
z->next_in = orig_in; z->next_in = orig_in;
z->avail_in = nread; z->avail_in = nread;
@@ -152,14 +152,14 @@ inflate_stream(struct SessionHandle *data,
} }
else { /* Error; exit loop, handle below */ else { /* Error; exit loop, handle below */
free(decomp); free(decomp);
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
} }
} }
/* Will never get here */ /* Will never get here */
} }
CURLcode CURLcode
Curl_unencode_deflate_write(struct SessionHandle *data, Curl_unencode_deflate_write(struct connectdata *conn,
struct Curl_transfer_keeper *k, struct Curl_transfer_keeper *k,
ssize_t nread) ssize_t nread)
{ {
@@ -173,7 +173,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
z->next_in = NULL; z->next_in = NULL;
z->avail_in = 0; z->avail_in = 0;
if (inflateInit(z) != Z_OK) if (inflateInit(z) != Z_OK)
return process_zlib_error(data, z); return process_zlib_error(conn, z);
k->zlib_init = ZLIB_INIT; k->zlib_init = ZLIB_INIT;
} }
@@ -182,7 +182,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data,
z->avail_in = (uInt)nread; z->avail_in = (uInt)nread;
/* Now uncompress the data */ /* Now uncompress the data */
return inflate_stream(data, k); return inflate_stream(conn, k);
} }
#ifdef OLD_ZLIB_SUPPORT #ifdef OLD_ZLIB_SUPPORT
@@ -272,7 +272,7 @@ static enum {
#endif #endif
CURLcode CURLcode
Curl_unencode_gzip_write(struct SessionHandle *data, Curl_unencode_gzip_write(struct connectdata *conn,
struct Curl_transfer_keeper *k, struct Curl_transfer_keeper *k,
ssize_t nread) ssize_t nread)
{ {
@@ -289,14 +289,14 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
if (strcmp(zlibVersion(), "1.2.0.4") >= 0) { if (strcmp(zlibVersion(), "1.2.0.4") >= 0) {
/* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
if (inflateInit2(z, MAX_WBITS+32) != Z_OK) { if (inflateInit2(z, MAX_WBITS+32) != Z_OK) {
return process_zlib_error(data, z); return process_zlib_error(conn, z);
} }
k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
} else { } else {
/* we must parse the gzip header ourselves */ /* we must parse the gzip header ourselves */
if (inflateInit2(z, -MAX_WBITS) != Z_OK) { if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
return process_zlib_error(data, z); return process_zlib_error(conn, z);
} }
k->zlib_init = ZLIB_INIT; /* Initial call state */ k->zlib_init = ZLIB_INIT; /* Initial call state */
} }
@@ -307,7 +307,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
z->next_in = (Bytef *)k->str; z->next_in = (Bytef *)k->str;
z->avail_in = (uInt)nread; z->avail_in = (uInt)nread;
/* Now uncompress the data */ /* Now uncompress the data */
return inflate_stream(data, k); return inflate_stream(conn, k);
} }
#ifndef OLD_ZLIB_SUPPORT #ifndef OLD_ZLIB_SUPPORT
@@ -360,7 +360,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
case GZIP_BAD: case GZIP_BAD:
default: default:
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
} }
} }
@@ -398,7 +398,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
case GZIP_BAD: case GZIP_BAD:
default: default:
free(z->next_in); free(z->next_in);
return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
} }
} }
@@ -418,7 +418,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data,
} }
/* We've parsed the header, now uncompress the data */ /* We've parsed the header, now uncompress the data */
return inflate_stream(data, k); return inflate_stream(conn, k);
#endif #endif
} }
#endif /* HAVE_LIBZ */ #endif /* HAVE_LIBZ */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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,11 +31,11 @@
#define ALL_CONTENT_ENCODINGS "identity" #define ALL_CONTENT_ENCODINGS "identity"
#endif #endif
CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
struct Curl_transfer_keeper *k, struct Curl_transfer_keeper *k,
ssize_t nread); ssize_t nread);
CURLcode CURLcode
Curl_unencode_gzip_write(struct SessionHandle *data, Curl_unencode_gzip_write(struct connectdata *conn,
struct Curl_transfer_keeper *k, struct Curl_transfer_keeper *k,
ssize_t nread); ssize_t nread);

View File

@@ -958,7 +958,7 @@ int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
char *format_ptr; char *format_ptr;
fputs("# Netscape HTTP Cookie File\n" fputs("# Netscape HTTP Cookie File\n"
"# http://www.netscape.com/newsref/std/cookie_spec.html\n" "# http://curlm.haxx.se/rfc/cookie_spec.html\n"
"# This file was generated by libcurl! Edit at your own risk.\n\n", "# This file was generated by libcurl! Edit at your own risk.\n\n",
out); out);
co = c->cookies; co = c->cookies;

View File

@@ -24,11 +24,13 @@
***************************************************************************/ ***************************************************************************/
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #if defined(WIN32)
#include <time.h> #include <time.h>
#else #else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#endif
#include <curl/curl.h> #include <curl/curl.h>

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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

View File

@@ -38,7 +38,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #ifdef WIN32
#include <time.h> #include <time.h>
#include <io.h> #include <io.h>
#else #else
@@ -46,7 +46,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -104,7 +106,7 @@ static char *unescape_word(struct SessionHandle *data, char *inp)
/* According to RFC2229 section 2.2, these letters need to be escaped with /* According to RFC2229 section 2.2, these letters need to be escaped with
\[letter] */ \[letter] */
for(ptr = newp; for(ptr = newp;
(byte = (unsigned char)*ptr); (byte = (unsigned char)*ptr) != 0;
ptr++) { ptr++) {
if ((byte <= 32) || (byte == 127) || if ((byte <= 32) || (byte == 127) ||
(byte == '\'') || (byte == '\"') || (byte == '\\')) { (byte == '\'') || (byte == '\"') || (byte == '\\')) {
@@ -132,8 +134,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
char *path = conn->path; char *path = data->reqdata.path;
curl_off_t *bytecount = &conn->bytecount; curl_off_t *bytecount = &data->reqdata.keep.bytecount;
*done = TRUE; /* unconditionally */ *done = TRUE; /* unconditionally */
@@ -194,8 +196,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
if(result) if(result)
failf(data, "Failed sending DICT request"); failf(data, "Failed sending DICT request");
else else
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */ -1, NULL); /* no upload */
if(result) if(result)
return result; return result;
} }
@@ -241,8 +243,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
if(result) if(result)
failf(data, "Failed sending DICT request"); failf(data, "Failed sending DICT request");
else else
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */ -1, NULL); /* no upload */
if(result) if(result)
return result; return result;
@@ -266,8 +268,8 @@ CURLcode Curl_dict(struct connectdata *conn, bool *done)
if(result) if(result)
failf(data, "Failed sending DICT request"); failf(data, "Failed sending DICT request");
else else
result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); -1, NULL);
if(result) if(result)
return result; return result;
} }

View File

@@ -40,7 +40,7 @@
#include "strequal.h" #include "strequal.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #ifdef WIN32
#include <time.h> #include <time.h>
#include <io.h> #include <io.h>
#else #else
@@ -48,7 +48,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -104,7 +106,7 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #ifdef USE_WINSOCK
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
of win32_init() */ of win32_init() */
static void win32_cleanup(void) static void win32_cleanup(void)
@@ -120,12 +122,12 @@ static CURLcode win32_init(void)
WSADATA wsaData; WSADATA wsaData;
int err; int err;
#ifdef ENABLE_IPV6 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
wVersionRequested = MAKEWORD(2, 0); Error IPV6_requires_winsock2
#else
wVersionRequested = MAKEWORD(1, 1);
#endif #endif
wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
err = WSAStartup(wVersionRequested, &wsaData); err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) if (err != 0)
@@ -467,6 +469,13 @@ CURLcode curl_easy_perform(CURL *curl)
} }
if(!data->state.connc) {
/* oops, no connection cache, make one up */
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE);
if(!data->state.connc)
return CURLE_OUT_OF_MEMORY;
}
return Curl_perform(data); return Curl_perform(data);
} }
#endif #endif
@@ -494,6 +503,13 @@ void Curl_easy_addmulti(struct SessionHandle *data,
data->multi = multi; data->multi = multi;
} }
void Curl_easy_initHandleData(struct SessionHandle *data)
{
memset(&data->reqdata, 0, sizeof(struct HandleData));
data->reqdata.maxdownload = -1;
}
/* /*
* 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.
@@ -541,16 +557,14 @@ CURL *curl_easy_duphandle(CURL *incurl)
/* copy all userdefined values */ /* copy all userdefined values */
outcurl->set = data->set; outcurl->set = data->set;
outcurl->state.numconnects = data->state.numconnects;
outcurl->state.connects = (struct connectdata **)
malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
if(!outcurl->state.connects) { if(data->state.used_interface == Curl_if_multi)
outcurl->state.connc = data->state.connc;
else
outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE);
if(!outcurl->state.connc)
break; break;
}
memset(outcurl->state.connects, 0,
sizeof(struct connectdata *)*outcurl->state.numconnects);
outcurl->state.lastconnect = -1; outcurl->state.lastconnect = -1;
@@ -572,6 +586,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
#endif /* CURL_DISABLE_HTTP */ #endif /* CURL_DISABLE_HTTP */
/* duplicate all values in 'change' */ /* duplicate all values in 'change' */
if(data->change.url) { if(data->change.url) {
outcurl->change.url = strdup(data->change.url); outcurl->change.url = strdup(data->change.url);
if(!outcurl->change.url) if(!outcurl->change.url)
@@ -597,14 +612,25 @@ CURL *curl_easy_duphandle(CURL *incurl)
break; break;
#endif #endif
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_OF_NETWORK);
outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
CURL_ICONV_CODESET_OF_HOST);
outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8);
#endif
Curl_easy_initHandleData(outcurl);
fail = FALSE; /* we reach this point and thus we are OK */ fail = FALSE; /* we reach this point and thus we are OK */
} while(0); } while(0);
if(fail) { if(fail) {
if(outcurl) { if(outcurl) {
if(outcurl->state.connects) if(outcurl->state.connc->type == CONNCACHE_PRIVATE)
free(outcurl->state.connects); Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff) if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff); free(outcurl->state.headerbuff);
if(outcurl->change.proxy) if(outcurl->change.proxy)
@@ -629,12 +655,21 @@ void curl_easy_reset(CURL *curl)
{ {
struct SessionHandle *data = (struct SessionHandle *)curl; struct SessionHandle *data = (struct SessionHandle *)curl;
Curl_safefree(data->reqdata.pathbuffer);
data->reqdata.pathbuffer=NULL;
Curl_safefree(data->reqdata.proto.generic);
data->reqdata.proto.generic=NULL;
/* zero out UserDefined data: */ /* zero out UserDefined data: */
memset(&data->set, 0, sizeof(struct UserDefined)); memset(&data->set, 0, sizeof(struct UserDefined));
/* zero out Progress data: */ /* zero out Progress data: */
memset(&data->progress, 0, sizeof(struct Progress)); memset(&data->progress, 0, sizeof(struct Progress));
/* init Handle data */
Curl_easy_initHandleData(data);
/* The remainder of these calls have been taken from Curl_open() */ /* The remainder of these calls have been taken from Curl_open() */
data->set.out = stdout; /* default output to stdout */ data->set.out = stdout; /* default output to stdout */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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,6 +28,8 @@
*/ */
void Curl_easy_addmulti(struct SessionHandle *data, void *multi); void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
void Curl_easy_initHandleData(struct SessionHandle *data);
CURLcode Curl_convert_to_network(struct SessionHandle *data, CURLcode Curl_convert_to_network(struct SessionHandle *data,
char *buffer, size_t length); char *buffer, size_t length);
CURLcode Curl_convert_from_network(struct SessionHandle *data, CURLcode Curl_convert_from_network(struct SessionHandle *data,

View File

@@ -116,10 +116,6 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
return ns; return ns;
} }
#define ishex(in) ((in >= 'a' && in <= 'f') || \
(in >= 'A' && in <= 'F') || \
(in >= '0' && in <= '9'))
char *curl_easy_unescape(CURL *handle, const char *string, int length, char *curl_easy_unescape(CURL *handle, const char *string, int length,
int *olen) int *olen)
{ {
@@ -138,7 +134,7 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
while(--alloc > 0) { while(--alloc > 0) {
in = *string; in = *string;
if(('%' == in) && ishex(string[1]) && ishex(string[2])) { if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */ /* this is two hexadecimal digits following a '%' */
char hexstr[3]; char hexstr[3];
char *ptr; char *ptr;

View File

@@ -37,7 +37,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #ifdef WIN32
#include <time.h> #include <time.h>
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
@@ -48,7 +48,9 @@
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -100,7 +102,7 @@
*/ */
CURLcode Curl_file_connect(struct connectdata *conn) CURLcode Curl_file_connect(struct connectdata *conn)
{ {
char *real_path = curl_easy_unescape(conn->data, conn->path, 0, NULL); char *real_path = curl_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL);
struct FILEPROTO *file; struct FILEPROTO *file;
int fd; int fd;
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) #if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
@@ -117,7 +119,11 @@ CURLcode Curl_file_connect(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
conn->proto.file = file; if (conn->data->reqdata.proto.file) {
free(conn->data->reqdata.proto.file);
}
conn->data->reqdata.proto.file = file;
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) #if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
/* If the first character is a slash, and there's /* If the first character is a slash, and there's
@@ -158,7 +164,7 @@ CURLcode Curl_file_connect(struct connectdata *conn)
file->fd = fd; file->fd = fd;
if(!conn->data->set.upload && (fd == -1)) { if(!conn->data->set.upload && (fd == -1)) {
failf(conn->data, "Couldn't open file %s", conn->path); failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE); Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
return CURLE_FILE_COULDNT_READ_FILE; return CURLE_FILE_COULDNT_READ_FILE;
} }
@@ -169,7 +175,7 @@ CURLcode Curl_file_connect(struct connectdata *conn)
CURLcode Curl_file_done(struct connectdata *conn, CURLcode Curl_file_done(struct connectdata *conn,
CURLcode status) CURLcode status)
{ {
struct FILEPROTO *file = conn->proto.file; struct FILEPROTO *file = conn->data->reqdata.proto.file;
(void)status; /* not used */ (void)status; /* not used */
Curl_safefree(file->freepath); Curl_safefree(file->freepath);
@@ -187,7 +193,7 @@ CURLcode Curl_file_done(struct connectdata *conn,
static CURLcode file_upload(struct connectdata *conn) static CURLcode file_upload(struct connectdata *conn)
{ {
struct FILEPROTO *file = conn->proto.file; struct FILEPROTO *file = conn->data->reqdata.proto.file;
char *dir = strchr(file->path, DIRSEP); char *dir = strchr(file->path, DIRSEP);
FILE *fp; FILE *fp;
CURLcode res=CURLE_OK; CURLcode res=CURLE_OK;
@@ -204,7 +210,7 @@ static CURLcode file_upload(struct connectdata *conn)
*/ */
conn->fread = data->set.fread; conn->fread = data->set.fread;
conn->fread_in = data->set.in; conn->fread_in = data->set.in;
conn->upload_fromhere = buf; conn->data->reqdata.upload_fromhere = buf;
if(!dir) if(!dir)
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
@@ -295,7 +301,7 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
return file_upload(conn); return file_upload(conn);
/* get the fd from the connection phase */ /* get the fd from the connection phase */
fd = conn->proto.file->fd; fd = conn->data->reqdata.proto.file->fd;
/* VMS: This only works reliable for STREAMLF files */ /* VMS: This only works reliable for STREAMLF files */
if( -1 != fstat(fd, &statbuf)) { if( -1 != fstat(fd, &statbuf)) {
@@ -311,11 +317,11 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
CURLcode result; CURLcode result;
snprintf(buf, sizeof(data->state.buffer), snprintf(buf, sizeof(data->state.buffer),
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
if(result) if(result)
return result; return result;
result = Curl_client_write(data, CLIENTWRITE_BOTH, result = Curl_client_write(conn, CLIENTWRITE_BOTH,
(char *)"Accept-ranges: bytes\r\n", 0); (char *)"Accept-ranges: bytes\r\n", 0);
if(result) if(result)
return result; return result;
@@ -339,13 +345,13 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
tm->tm_hour, tm->tm_hour,
tm->tm_min, tm->tm_min,
tm->tm_sec); tm->tm_sec);
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
} }
return result; return result;
} }
if (conn->resume_from <= expected_size) if (data->reqdata.resume_from <= expected_size)
expected_size -= conn->resume_from; expected_size -= data->reqdata.resume_from;
else { else {
failf(data, "failed to resume file:// transfer"); failf(data, "failed to resume file:// transfer");
return CURLE_BAD_DOWNLOAD_RESUME; return CURLE_BAD_DOWNLOAD_RESUME;
@@ -361,8 +367,11 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
if(fstated) if(fstated)
Curl_pgrsSetDownloadSize(data, expected_size); Curl_pgrsSetDownloadSize(data, expected_size);
if(conn->resume_from) if(data->reqdata.resume_from) {
lseek(fd, conn->resume_from, SEEK_SET); if(data->reqdata.resume_from !=
lseek(fd, data->reqdata.resume_from, SEEK_SET))
return CURLE_BAD_DOWNLOAD_RESUME;
}
Curl_pgrsTime(data, TIMER_STARTTRANSFER); Curl_pgrsTime(data, TIMER_STARTTRANSFER);
@@ -377,7 +386,7 @@ CURLcode Curl_file(struct connectdata *conn, bool *done)
bytecount += nread; bytecount += nread;
res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread); res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
if(res) if(res)
return res; return res;

View File

@@ -528,8 +528,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if (current_form->value) { if (current_form->value) {
if (current_form->flags & HTTPPOST_FILENAME) { if (current_form->flags & HTTPPOST_FILENAME) {
if (filename) { if (filename) {
if (!(current_form = AddFormInfo(strdup(filename), if ((current_form = AddFormInfo(strdup(filename),
NULL, current_form))) NULL, current_form)) == NULL)
return_value = CURL_FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
@@ -562,8 +562,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if (current_form->value) { if (current_form->value) {
if (current_form->flags & HTTPPOST_BUFFER) { if (current_form->flags & HTTPPOST_BUFFER) {
if (filename) { if (filename) {
if (!(current_form = AddFormInfo(strdup(filename), if ((current_form = AddFormInfo(strdup(filename),
NULL, current_form))) NULL, current_form)) == NULL)
return_value = CURL_FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
@@ -614,9 +614,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if (current_form->contenttype) { if (current_form->contenttype) {
if (current_form->flags & HTTPPOST_FILENAME) { if (current_form->flags & HTTPPOST_FILENAME) {
if (contenttype) { if (contenttype) {
if (!(current_form = AddFormInfo(NULL, if ((current_form = AddFormInfo(NULL,
strdup(contenttype), strdup(contenttype),
current_form))) current_form)) == NULL)
return_value = CURL_FORMADD_MEMORY; return_value = CURL_FORMADD_MEMORY;
} }
else else
@@ -884,7 +884,7 @@ void Curl_formclean(struct FormData *form)
free(form->line); /* free the line */ free(form->line); /* free the line */
free(form); /* free the struct */ free(form); /* free the struct */
} while((form=next)); /* continue */ } while ((form = next) != NULL); /* continue */
} }
/* /*
@@ -961,7 +961,7 @@ void curl_formfree(struct curl_httppost *form)
free(form->showfilename); /* free the faked file name */ free(form->showfilename); /* free the faked file name */
free(form); /* free the struct */ free(form); /* free the struct */
} while((form=next)); /* continue */ } while ((form = next) != NULL); /* continue */
} }
#ifndef HAVE_BASENAME #ifndef HAVE_BASENAME
@@ -1231,7 +1231,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
*/ */
size_t nread; size_t nread;
char buffer[512]; char buffer[512];
while((nread = fread(buffer, 1, sizeof(buffer), fileread))) { while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
result = AddFormData(&form, FORM_DATA, buffer, nread, &size); result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
if (result) if (result)
break; break;
@@ -1268,7 +1268,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if (result) if (result)
break; break;
} }
} while((file = file->more)); /* for each specified file for this field */ } while ((file = file->more) != NULL); /* for each specified file for this field */
if (result) { if (result) {
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);
@@ -1286,7 +1286,7 @@ CURLcode Curl_getFormData(struct FormData **finalform,
break; break;
} }
} while((post=post->next)); /* for each field */ } while ((post = post->next) != NULL); /* for each field */
if (result) { if (result) {
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);

1243
lib/ftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -199,22 +199,27 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
break; break;
case CURLINFO_LASTSOCKET: case CURLINFO_LASTSOCKET:
if((data->state.lastconnect != -1) && if((data->state.lastconnect != -1) &&
(data->state.connects[data->state.lastconnect] != NULL)) { (data->state.connc->connects[data->state.lastconnect] != NULL)) {
*param_longp = data->state.connects[data->state.lastconnect]-> struct connectdata *c = data->state.connc->connects
sock[FIRSTSOCKET]; [data->state.lastconnect];
*param_longp = c->sock[FIRSTSOCKET];
/* we have a socket connected, let's determine if the server shut down */ /* we have a socket connected, let's determine if the server shut down */
/* determine if ssl */ /* determine if ssl */
if(data->state.connects[data->state.lastconnect]->ssl[FIRSTSOCKET].use) { if(c->ssl[FIRSTSOCKET].use) {
/* use the SSL context */ /* use the SSL context */
if (!Curl_ssl_check_cxn(data->state.connects[data->state.lastconnect])) if (!Curl_ssl_check_cxn(c))
*param_longp = -1; /* FIN received */ *param_longp = -1; /* FIN received */
} }
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
#ifdef MSG_PEEK
else { else {
/* use the socket */ /* use the socket */
if(recv((int)data->state.connects[data->state.lastconnect]-> if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
sock[FIRSTSOCKET], (void*)&buf, 1, MSG_PEEK) == 0) (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
*param_longp = -1; /* FIN received */ *param_longp = -1; /* FIN received */
}
} }
#endif
} }
else else
*param_longp = -1; *param_longp = -1;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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
@@ -168,8 +168,7 @@ static CURLcode handshake(struct connectdata *conn,
} while(1); } while(1);
if (rc < 0) { if (rc < 0) {
failf(data, "gnutls_handshake() failed: %d", rc); failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
/* gnutls_perror(ret); */
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
@@ -235,9 +234,12 @@ Curl_gtls_connect(struct connectdata *conn,
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred, rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
data->set.ssl.CAfile, data->set.ssl.CAfile,
GNUTLS_X509_FMT_PEM); GNUTLS_X509_FMT_PEM);
if(rc < 0) if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)\n", infof(data, "error reading ca cert file %s (%s)\n",
data->set.ssl.CAfile, gnutls_strerror(rc)); data->set.ssl.CAfile, gnutls_strerror(rc));
if (data->set.ssl.verifypeer)
return CURLE_SSL_CACERT_BADFILE;
}
else else
infof(data, "found %d certificates in %s\n", infof(data, "found %d certificates in %s\n",
rc, data->set.ssl.CAfile); rc, data->set.ssl.CAfile);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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
@@ -282,3 +282,34 @@ Curl_hash_destroy(struct curl_hash *h)
free(h); free(h);
} }
#if 0 /* useful function for debugging hashes and their contents */
void Curl_hash_print(struct curl_hash *h,
void (*func)(void *))
{
int i;
struct curl_llist_element *le;
struct curl_llist *list;
struct curl_hash_element *he;
if (!h)
return;
fprintf(stderr, "=Hash dump=\n");
for (i = 0; i < h->slots; i++) {
list = h->table[i];
le = list->head; /* get first list entry */
if(le) {
fprintf(stderr, "index %d:", i);
while(le) {
he = le->ptr;
if(func)
func(he->ptr);
else
fprintf(stderr, " [%p]", he->ptr);
le = le->next;
}
fprintf(stderr, "\n");
}
}
}
#endif

View File

@@ -75,6 +75,7 @@
#include "share.h" #include "share.h"
#include "strerror.h" #include "strerror.h"
#include "url.h" #include "url.h"
#include "multiif.h"
#include "connect.h" /* for the Curl_sockerrno() proto */ #include "connect.h" /* for the Curl_sockerrno() proto */
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
@@ -109,9 +110,20 @@ int Curl_resolv_getsock(struct connectdata *conn,
int numsocks) int numsocks)
{ {
struct timeval maxtime;
struct timeval timeout;
int max = ares_getsock(conn->data->state.areschannel, int max = ares_getsock(conn->data->state.areschannel,
(int *)socks, numsocks); (int *)socks, numsocks);
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
maxtime.tv_usec = 0;
ares_timeout(conn->data->state.areschannel, &maxtime, &timeout);
Curl_expire(conn->data,
(timeout.tv_sec * 1000) + (timeout.tv_usec/1000) );
return max; return max;
} }

View File

@@ -409,10 +409,12 @@ int Curl_resolv(struct connectdata *conn,
#ifdef HAVE_SIGSETJMP #ifdef HAVE_SIGSETJMP
/* this allows us to time-out from the name resolver, as the timeout /* this allows us to time-out from the name resolver, as the timeout
will generate a signal and we will siglongjmp() from that here */ will generate a signal and we will siglongjmp() from that here */
if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) { if(!data->set.no_signal) {
/* this is coming from a siglongjmp() */ if (sigsetjmp(curl_jmpenv, 1)) {
failf(data, "name lookup timed out"); /* this is coming from a siglongjmp() */
return CURLRESOLV_ERROR; failf(data, "name lookup timed out");
return CURLRESOLV_ERROR;
}
} }
#endif #endif
@@ -607,7 +609,14 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
h = &buf->hostentry; h = &buf->hostentry;
h->h_addr_list = &buf->h_addr_list[0]; h->h_addr_list = &buf->h_addr_list[0];
addrentry = &buf->addrentry; addrentry = &buf->addrentry;
#ifdef _CRAYC
/* On UNICOS, s_addr is a bit field and for some reason assigning to it
* doesn't work. There must be a better fix than this ugly hack.
*/
memcpy(addrentry, &num, SIZEOF_in_addr);
#else
addrentry->s_addr = num; addrentry->s_addr = num;
#endif
h->h_addr_list[0] = (char*)addrentry; h->h_addr_list[0] = (char*)addrentry;
h->h_addr_list[1] = NULL; h->h_addr_list[1] = NULL;
h->h_addrtype = AF_INET; h->h_addrtype = AF_INET;

View File

@@ -26,6 +26,11 @@
#include "setup.h" #include "setup.h"
#include "hash.h" #include "hash.h"
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t uint32_t
#endif
/* /*
* Setup comfortable CURLRES_* defines to use in the host*.c sources. * Setup comfortable CURLRES_* defines to use in the host*.c sources.
*/ */
@@ -82,7 +87,8 @@
#define CURL_ASYNC_SUCCESS ARES_SUCCESS #define CURL_ASYNC_SUCCESS ARES_SUCCESS
#else #else
#define CURL_ASYNC_SUCCESS CURLE_OK #define CURL_ASYNC_SUCCESS CURLE_OK
#define ares_cancel(x) #define ares_cancel(x) do {} while(0)
#define ares_destroy(x) do {} while(0)
#endif #endif
/* /*

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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
@@ -64,11 +64,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"
@@ -353,7 +348,7 @@ Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
/* no input == no output! */ /* no input == no output! */
return NULL; return NULL;
for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]); i++) { for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]) != NULL; i++) {
ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in)); ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in));

View File

@@ -208,7 +208,7 @@ BOOL init_thread_sync_data(struct thread_data * td,
{ {
HANDLE curr_proc = GetCurrentProcess(); HANDLE curr_proc = GetCurrentProcess();
memset(tsd, 0, sizeof(tsd)); memset(tsd, 0, sizeof(*tsd));
if (!DuplicateHandle(curr_proc, td->mutex_waiting, if (!DuplicateHandle(curr_proc, td->mutex_waiting,
curr_proc, &tsd->mutex_waiting, 0, FALSE, curr_proc, &tsd->mutex_waiting, 0, FALSE,
DUPLICATE_SAME_ACCESS)) { DUPLICATE_SAME_ACCESS)) {

View File

@@ -37,7 +37,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) #ifdef WIN32
#include <time.h> #include <time.h>
#include <io.h> #include <io.h>
#else #else
@@ -47,7 +47,9 @@
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#ifdef HAVE_TIME_H #ifdef HAVE_TIME_H
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
@@ -218,8 +220,9 @@ static bool pickoneauth(struct auth *pick)
*/ */
static CURLcode perhapsrewind(struct connectdata *conn) static CURLcode perhapsrewind(struct connectdata *conn)
{ {
struct HTTP *http = conn->proto.http;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct HTTP *http = data->reqdata.proto.http;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
curl_off_t bytessent; curl_off_t bytessent;
curl_off_t expectsend = -1; /* default is unknown */ curl_off_t expectsend = -1; /* default is unknown */
@@ -274,14 +277,14 @@ static CURLcode perhapsrewind(struct connectdata *conn)
/* this is already marked to get closed */ /* this is already marked to get closed */
return CURLE_OK; return CURLE_OK;
infof(data, "NTLM send, close instead of sending %ld bytes\n", infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
expectsend - bytessent); " bytes\n", (curl_off_t)(expectsend - bytessent));
} }
/* This is not NTLM or NTLM with many bytes left to send: close /* This is not NTLM or NTLM with many bytes left to send: close
*/ */
conn->bits.close = TRUE; conn->bits.close = TRUE;
conn->size = 0; /* don't download any more than 0 bytes */ k->size = 0; /* don't download any more than 0 bytes */
} }
if(bytessent) if(bytessent)
@@ -304,7 +307,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
bool pickproxy = FALSE; bool pickproxy = FALSE;
CURLcode code = CURLE_OK; CURLcode code = CURLE_OK;
if(100 == conn->keep.httpcode) if(100 == data->reqdata.keep.httpcode)
/* this is a transient response code, ignore */ /* this is a transient response code, ignore */
return CURLE_OK; return CURLE_OK;
@@ -312,22 +315,22 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
if(conn->bits.user_passwd && if(conn->bits.user_passwd &&
((conn->keep.httpcode == 401) || ((data->reqdata.keep.httpcode == 401) ||
(conn->bits.authneg && conn->keep.httpcode < 300))) { (conn->bits.authneg && data->reqdata.keep.httpcode < 300))) {
pickhost = pickoneauth(&data->state.authhost); pickhost = pickoneauth(&data->state.authhost);
if(!pickhost) if(!pickhost)
data->state.authproblem = TRUE; data->state.authproblem = TRUE;
} }
if(conn->bits.proxy_user_passwd && if(conn->bits.proxy_user_passwd &&
((conn->keep.httpcode == 407) || ((data->reqdata.keep.httpcode == 407) ||
(conn->bits.authneg && conn->keep.httpcode < 300))) { (conn->bits.authneg && data->reqdata.keep.httpcode < 300))) {
pickproxy = pickoneauth(&data->state.authproxy); pickproxy = pickoneauth(&data->state.authproxy);
if(!pickproxy) if(!pickproxy)
data->state.authproblem = TRUE; data->state.authproblem = TRUE;
} }
if(pickhost || pickproxy) { if(pickhost || pickproxy) {
conn->newurl = strdup(data->change.url); /* clone URL */ data->reqdata.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) &&
@@ -338,7 +341,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
} }
} }
else if((conn->keep.httpcode < 300) && else if((data->reqdata.keep.httpcode < 300) &&
(!data->state.authhost.done) && (!data->state.authhost.done) &&
conn->bits.authneg) { conn->bits.authneg) {
/* no (known) authentication available, /* no (known) authentication available,
@@ -347,13 +350,13 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
we didn't try HEAD or GET */ we didn't try HEAD or GET */
if((data->set.httpreq != HTTPREQ_GET) && if((data->set.httpreq != HTTPREQ_GET) &&
(data->set.httpreq != HTTPREQ_HEAD)) { (data->set.httpreq != HTTPREQ_HEAD)) {
conn->newurl = strdup(data->change.url); /* clone URL */ data->reqdata.newurl = strdup(data->change.url); /* clone URL */
data->state.authhost.done = TRUE; data->state.authhost.done = TRUE;
} }
} }
if (Curl_http_should_fail(conn)) { if (Curl_http_should_fail(conn)) {
failf (data, "The requested URL returned error: %d", failf (data, "The requested URL returned error: %d",
conn->keep.httpcode); data->reqdata.keep.httpcode);
code = CURLE_HTTP_RETURNED_ERROR; code = CURLE_HTTP_RETURNED_ERROR;
} }
@@ -452,7 +455,7 @@ Curl_http_output_auth(struct connectdata *conn,
if(auth) { if(auth) {
infof(data, "Proxy auth using %s with user '%s'\n", infof(data, "Proxy auth using %s with user '%s'\n",
auth, conn->proxyuser?conn->proxyuser:""); auth, conn->proxyuser?conn->proxyuser:"");
authproxy->multi = !authproxy->done; authproxy->multi = (bool)(!authproxy->done);
} }
else else
authproxy->multi = FALSE; authproxy->multi = FALSE;
@@ -522,7 +525,7 @@ Curl_http_output_auth(struct connectdata *conn,
infof(data, "Server auth using %s with user '%s'\n", infof(data, "Server auth using %s with user '%s'\n",
auth, conn->user); auth, conn->user);
authhost->multi = !authhost->done; authhost->multi = (bool)(!authhost->done);
} }
else else
authhost->multi = FALSE; authhost->multi = FALSE;
@@ -566,15 +569,15 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
} }
/* pass all white spaces */ /* pass all white spaces */
while(*start && isspace((int)*start)) while(*start && ISSPACE(*start))
start++; start++;
/* /*
* Here we check if we want the specific single authentiction (using ==) and * Here we check if we want the specific single authentication (using ==) and
* if we do, we initiate usage of it. * if we do, we initiate usage of it.
* *
* If the provided authentication is wanted as one out of several accepted * If the provided authentication is wanted as one out of several accepted
* types (using &), we OR this authenticaion type to the authavail * types (using &), we OR this authentication type to the authavail
* variable. * variable.
*/ */
@@ -587,8 +590,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
/* if exactly this is wanted, go */ /* if exactly this is wanted, go */
int neg = Curl_input_negotiate(conn, start); int neg = Curl_input_negotiate(conn, start);
if (neg == 0) { if (neg == 0) {
conn->newurl = strdup(data->change.url); data->reqdata.newurl = strdup(data->change.url);
data->state.authproblem = (conn->newurl == NULL); data->state.authproblem = (data->reqdata.newurl == NULL);
} }
else { else {
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
@@ -679,7 +682,7 @@ int Curl_http_should_fail(struct connectdata *conn)
/* /*
** For readability ** For readability
*/ */
k = &conn->keep; k = &data->reqdata.keep;
/* /*
** If we haven't been asked to fail on error, ** If we haven't been asked to fail on error,
@@ -694,7 +697,7 @@ int Curl_http_should_fail(struct connectdata *conn)
if (k->httpcode < 400) if (k->httpcode < 400)
return 0; return 0;
if (conn->resume_from && if (data->reqdata.resume_from &&
(data->set.httpreq==HTTPREQ_GET) && (data->set.httpreq==HTTPREQ_GET) &&
(k->httpcode == 416)) { (k->httpcode == 416)) {
/* "Requested Range Not Satisfiable", just proceed and /* "Requested Range Not Satisfiable", just proceed and
@@ -734,7 +737,7 @@ int Curl_http_should_fail(struct connectdata *conn)
infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail); infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail);
infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode); infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode);
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone); infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
infof(data,"%s: newurl = %s\n",__FUNCTION__,conn->newurl ? conn->newurl : "(null)"); infof(data,"%s: newurl = %s\n",__FUNCTION__,data->reqdata.newurl ? data->reqdata.newurl : "(null)");
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem); infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
#endif #endif
@@ -764,7 +767,7 @@ static size_t readmoredata(char *buffer,
void *userp) void *userp)
{ {
struct connectdata *conn = (struct connectdata *)userp; struct connectdata *conn = (struct connectdata *)userp;
struct HTTP *http = conn->proto.http; struct HTTP *http = conn->data->reqdata.proto.http;
size_t fullsize = size * nitems; size_t fullsize = size * nitems;
if(0 == http->postsize) if(0 == http->postsize)
@@ -772,7 +775,7 @@ static size_t readmoredata(char *buffer,
return 0; return 0;
/* make sure that a HTTP request is never sent away chunked! */ /* make sure that a HTTP request is never sent away chunked! */
conn->bits.forbidchunk= (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; conn->bits.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
if(http->postsize <= (curl_off_t)fullsize) { if(http->postsize <= (curl_off_t)fullsize) {
memcpy(buffer, http->postdata, (size_t)http->postsize); memcpy(buffer, http->postdata, (size_t)http->postsize);
@@ -837,7 +840,8 @@ send_buffer *add_buffer_init(void)
} }
/* /*
* add_buffer_send() sends a buffer and frees all associated memory. * add_buffer_send() sends a header buffer and frees all associated memory.
* Body data may be appended to the header data if desired.
* *
* Returns CURLcode * Returns CURLcode
*/ */
@@ -846,13 +850,16 @@ CURLcode add_buffer_send(send_buffer *in,
struct connectdata *conn, struct connectdata *conn,
long *bytes_written, /* add the number of sent long *bytes_written, /* add the number of sent
bytes to this counter */ bytes to this counter */
size_t included_body_bytes, /* how much of the buffer
contains body data (for log tracing) */
int socketindex) int socketindex)
{ {
ssize_t amount; ssize_t amount;
CURLcode res; CURLcode res;
char *ptr; char *ptr;
size_t size; size_t size;
struct HTTP *http = conn->proto.http; struct HTTP *http = conn->data->reqdata.proto.http;
size_t sendsize; size_t sendsize;
curl_socket_t sockfd; curl_socket_t sockfd;
@@ -891,9 +898,15 @@ CURLcode add_buffer_send(send_buffer *in,
if(CURLE_OK == res) { if(CURLE_OK == res) {
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, conn); Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr,
(size_t)(amount-included_body_bytes), conn);
if (included_body_bytes)
Curl_debug(conn->data, CURLINFO_DATA_OUT,
ptr+amount-included_body_bytes,
(size_t)included_body_bytes, conn);
}
*bytes_written += amount; *bytes_written += amount;
@@ -937,6 +950,8 @@ CURLcode add_buffer_send(send_buffer *in,
This needs FIXing. This needs FIXing.
*/ */
return CURLE_SEND_ERROR; return CURLE_SEND_ERROR;
else
conn->writechannel_inuse = FALSE;
} }
} }
if(in->buffer) if(in->buffer)
@@ -1036,7 +1051,7 @@ Curl_compareheader(char *headerline, /* line to check */
start = &headerline[hlen]; start = &headerline[hlen];
/* pass all white spaces */ /* pass all white spaces */
while(*start && isspace((int)*start)) while(*start && ISSPACE(*start))
start++; start++;
/* find the end of the header line */ /* find the end of the header line */
@@ -1080,7 +1095,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
{ {
int subversion=0; int subversion=0;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
struct Curl_transfer_keeper *k = &conn->keep; struct Curl_transfer_keeper *k = &data->reqdata.keep;
CURLcode result; CURLcode result;
int res; int res;
size_t nread; /* total size read */ size_t nread; /* total size read */
@@ -1104,12 +1119,12 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
do { do {
if(conn->newurl) { if(data->reqdata.newurl) {
/* This only happens if we've looped here due to authentication reasons, /* This only happens if we've looped here due to authentication reasons,
and we don't really use the newly cloned URL here then. Just free() and we don't really use the newly cloned URL here then. Just free()
it. */ it. */
free(conn->newurl); free(data->reqdata.newurl);
conn->newurl = NULL; data->reqdata.newurl = NULL;
} }
/* initialize a dynamic send-buffer */ /* initialize a dynamic send-buffer */
@@ -1168,7 +1183,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
if(CURLE_OK == result) if(CURLE_OK == result)
/* Now send off the request */ /* Now send off the request */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
&data->info.request_size, sockindex); &data->info.request_size, 0, sockindex);
} }
if(result) if(result)
failf(data, "Failed sending CONNECT to proxy"); failf(data, "Failed sending CONNECT to proxy");
@@ -1243,15 +1258,15 @@ CURLcode Curl_proxyCONNECT(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,
conn); line_start, (size_t)perline, conn);
/* send the header to the callback */ /* send the header to the callback */
writetype = CLIENTWRITE_HEADER; writetype = CLIENTWRITE_HEADER;
if(data->set.include_header) if(data->set.include_header)
writetype |= CLIENTWRITE_BODY; writetype |= CLIENTWRITE_BODY;
result = Curl_client_write(data, writetype, line_start, perline); result = Curl_client_write(conn, writetype, line_start, perline);
if(result) if(result)
return result; return result;
@@ -1321,7 +1336,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
headers. 'newurl' is set to a new URL if we must loop. */ headers. 'newurl' is set to a new URL if we must loop. */
Curl_http_auth_act(conn); Curl_http_auth_act(conn);
} while(conn->newurl); } while(data->reqdata.newurl);
if(200 != k->httpcode) { if(200 != k->httpcode) {
failf(data, "Received HTTP code %d from proxy after CONNECT", failf(data, "Received HTTP code %d from proxy after CONNECT",
@@ -1355,7 +1370,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
/* If we are not using a proxy and we want a secure connection, perform SSL /* If we are not using a proxy and we want a secure connection, perform SSL
* initialization & connection now. If using a proxy with https, then we * initialization & connection now. If using a proxy with https, then we
* must tell the proxy to CONNECT to the host we want to talk to. Only * must tell the proxy to CONNECT to the host we want to talk to. Only
* after the connect has occured, can we start talking SSL * after the connect has occurred, can we start talking SSL
*/ */
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
@@ -1460,11 +1475,9 @@ int Curl_https_getsock(struct connectdata *conn,
CURLcode Curl_http_done(struct connectdata *conn, CURLcode Curl_http_done(struct connectdata *conn,
CURLcode status) CURLcode status)
{ {
struct SessionHandle *data; struct SessionHandle *data = conn->data;
struct HTTP *http; struct HTTP *http =data->reqdata.proto.http;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
data=conn->data;
http=conn->proto.http;
/* set the proper values (possibly modified on POST) */ /* set the proper values (possibly modified on POST) */
conn->fread = data->set.fread; /* restore */ conn->fread = data->set.fread; /* restore */
@@ -1482,7 +1495,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
} }
if(HTTPREQ_POST_FORM == data->set.httpreq) { if(HTTPREQ_POST_FORM == data->set.httpreq) {
conn->bytecount = http->readbytecount + http->writebytecount; k->bytecount = http->readbytecount + http->writebytecount;
Curl_formclean(http->sendit); /* Now free that whole lot */ Curl_formclean(http->sendit); /* Now free that whole lot */
if(http->form.fp) { if(http->form.fp) {
@@ -1492,15 +1505,15 @@ 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; k->bytecount = http->readbytecount + http->writebytecount;
if (status != CURLE_OK) if (status != CURLE_OK)
return (status); return (status);
if(!conn->bits.retry && if(!conn->bits.retry &&
((http->readbytecount + ((http->readbytecount +
conn->headerbytecount - k->headerbytecount -
conn->deductheadercount)) <= 0) { k->deductheadercount)) <= 0) {
/* If this connection isn't simply closed to be retried, AND nothing was /* If this connection isn't simply closed to be retried, AND nothing was
read from the HTTP server (that counts), this can't be right so we read from the HTTP server (that counts), this can't be right so we
return an error here */ return an error here */
@@ -1516,6 +1529,8 @@ static CURLcode expect100(struct SessionHandle *data,
send_buffer *req_buffer) send_buffer *req_buffer)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */
if((data->set.httpversion != CURL_HTTP_VERSION_1_0) && if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
!checkheaders(data, "Expect:")) { !checkheaders(data, "Expect:")) {
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect: /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
@@ -1525,7 +1540,7 @@ static CURLcode expect100(struct SessionHandle *data,
result = add_bufferf(req_buffer, result = add_bufferf(req_buffer,
"Expect: 100-continue\r\n"); "Expect: 100-continue\r\n");
if(result == CURLE_OK) if(result == CURLE_OK)
data->set.expect100header = TRUE; data->state.expect100header = TRUE;
} }
return result; return result;
} }
@@ -1543,7 +1558,7 @@ static CURLcode add_custom_headers(struct connectdata *conn,
/* we require a colon for this to be a true header */ /* we require a colon for this to be a true header */
ptr++; /* pass the colon */ ptr++; /* pass the colon */
while(*ptr && isspace((int)*ptr)) while(*ptr && ISSPACE(*ptr))
ptr++; ptr++;
if(*ptr) { if(*ptr) {
@@ -1582,32 +1597,33 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
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 */
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
struct HTTP *http; struct HTTP *http;
char *ppath = conn->path; char *ppath = data->reqdata.path;
char *host = conn->host.name; char *host = conn->host.name;
const char *te = ""; /* tranfer-encoding */ const char *te = ""; /* tranfer-encoding */
char *ptr; char *ptr;
char *request; char *request;
Curl_HttpReq httpreq = data->set.httpreq; Curl_HttpReq httpreq = data->set.httpreq;
char *addcookies = NULL; char *addcookies = NULL;
curl_off_t included_body = 0;
/* Always consider the DO phase done after this function call, even if there /* 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 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. */ the rest of the request in the PERFORM phase. */
*done = TRUE; *done = TRUE;
if(!conn->proto.http) { if(!data->reqdata.proto.http) {
/* Only allocate this struct if we don't already have it! */ /* Only allocate this struct if we don't already have it! */
http = (struct HTTP *)malloc(sizeof(struct HTTP)); http = (struct HTTP *)malloc(sizeof(struct HTTP));
if(!http) if(!http)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
memset(http, 0, sizeof(struct HTTP)); memset(http, 0, sizeof(struct HTTP));
conn->proto.http = http; data->reqdata.proto.http = http;
} }
else else
http = conn->proto.http; http = data->reqdata.proto.http;
/* We default to persistant connections */ /* We default to persistent connections */
conn->bits.close = FALSE; conn->bits.close = FALSE;
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) && if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
@@ -1709,12 +1725,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
redirected request is being out on thin ice. Except if the host name redirected request is being out on thin ice. Except if the host name
is the same as the first one! */ is the same as the first one! */
char *start = ptr+strlen("Host:"); char *start = ptr+strlen("Host:");
while(*start && isspace((int)*start )) while(*start && ISSPACE(*start ))
start++; start++;
ptr = start; /* start host-scanning here */ ptr = start; /* start host-scanning here */
/* scan through the string to find the end (space or colon) */ /* scan through the string to find the end (space or colon) */
while(*ptr && !isspace((int)*ptr) && !(':'==*ptr)) while(*ptr && !ISSPACE(*ptr) && !(':'==*ptr))
ptr++; ptr++;
if(ptr != start) { if(ptr != start) {
@@ -1821,7 +1837,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(( (HTTPREQ_POST == httpreq) || if(( (HTTPREQ_POST == httpreq) ||
(HTTPREQ_POST_FORM == httpreq) || (HTTPREQ_POST_FORM == httpreq) ||
(HTTPREQ_PUT == httpreq) ) && (HTTPREQ_PUT == httpreq) ) &&
conn->resume_from) { data->reqdata.resume_from) {
/********************************************************************** /**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have * Resuming upload in HTTP means that we PUT or POST and that we have
* got a resume_from value set. The resume value has already created * got a resume_from value set. The resume value has already created
@@ -1830,15 +1846,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
* file size before we continue this venture in the dark lands of HTTP. * file size before we continue this venture in the dark lands of HTTP.
*********************************************************************/ *********************************************************************/
if(conn->resume_from < 0 ) { if(data->reqdata.resume_from < 0 ) {
/* /*
* This is meant to get the size of the present remote-file by itself. * This is meant to get the size of the present remote-file by itself.
* We don't support this now. Bail out! * We don't support this now. Bail out!
*/ */
conn->resume_from = 0; data->reqdata.resume_from = 0;
} }
if(conn->resume_from) { if(data->reqdata.resume_from) {
/* do we still game? */ /* do we still game? */
curl_off_t passed=0; curl_off_t passed=0;
@@ -1846,7 +1862,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
input. If we knew it was a proper file we could've just input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */ fseek()ed but we only have a stream here */
do { do {
size_t readthisamountnow = (size_t)(conn->resume_from - passed); size_t readthisamountnow = (size_t)(data->reqdata.resume_from - passed);
size_t actuallyread; size_t actuallyread;
if(readthisamountnow > BUFSIZE) if(readthisamountnow > BUFSIZE)
@@ -1863,11 +1879,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
passed); passed);
return CURLE_READ_ERROR; return CURLE_READ_ERROR;
} }
} while(passed != conn->resume_from); /* loop until done */ } while(passed != data->reqdata.resume_from); /* loop until done */
/* now, decrease the size of the read */ /* now, decrease the size of the read */
if(data->set.infilesize>0) { if(data->set.infilesize>0) {
data->set.infilesize -= conn->resume_from; data->set.infilesize -= data->reqdata.resume_from;
if(data->set.infilesize <= 0) { if(data->set.infilesize <= 0) {
failf(data, "File already completely uploaded"); failf(data, "File already completely uploaded");
@@ -1877,7 +1893,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* we've passed, proceed as normal */ /* we've passed, proceed as normal */
} }
} }
if(conn->bits.use_range) { if(data->reqdata.use_range) {
/* /*
* A range is selected. We use different headers whether we're downloading * A range is selected. We use different headers whether we're downloading
* or uploading and we always let customized headers override our internal * or uploading and we always let customized headers override our internal
@@ -1888,19 +1904,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* if a line like this was already allocated, free the previous one */ /* if a line like this was already allocated, free the previous one */
if(conn->allocptr.rangeline) if(conn->allocptr.rangeline)
free(conn->allocptr.rangeline); free(conn->allocptr.rangeline);
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range); conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->reqdata.range);
} }
else if((httpreq != HTTPREQ_GET) && else if((httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) { !checkheaders(data, "Content-Range:")) {
if(conn->resume_from) { if(data->reqdata.resume_from) {
/* This is because "resume" was selected */ /* This is because "resume" was selected */
curl_off_t total_expected_size= curl_off_t total_expected_size=
conn->resume_from + data->set.infilesize; data->reqdata.resume_from + data->set.infilesize;
conn->allocptr.rangeline = conn->allocptr.rangeline =
aprintf("Content-Range: bytes %s%" FORMAT_OFF_T aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
"/%" FORMAT_OFF_T "\r\n", "/%" FORMAT_OFF_T "\r\n",
conn->range, total_expected_size-1, data->reqdata.range, total_expected_size-1,
total_expected_size); total_expected_size);
} }
else { else {
@@ -1908,7 +1924,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
append total size */ append total size */
conn->allocptr.rangeline = conn->allocptr.rangeline =
aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n", aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
conn->range, data->set.infilesize); data->reqdata.range, data->set.infilesize);
} }
} }
} }
@@ -1950,7 +1966,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
conn->allocptr.proxyuserpwd? conn->allocptr.proxyuserpwd?
conn->allocptr.proxyuserpwd:"", conn->allocptr.proxyuserpwd:"",
conn->allocptr.userpwd?conn->allocptr.userpwd:"", conn->allocptr.userpwd?conn->allocptr.userpwd:"",
(conn->bits.use_range && conn->allocptr.rangeline)? (data->reqdata.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"", conn->allocptr.rangeline:"",
(data->set.useragent && *data->set.useragent && conn->allocptr.uagent)? (data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
conn->allocptr.uagent:"", conn->allocptr.uagent:"",
@@ -1979,7 +1995,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
co = Curl_cookie_getlist(data->cookies, co = Curl_cookie_getlist(data->cookies,
conn->allocptr.cookiehost? conn->allocptr.cookiehost?
conn->allocptr.cookiehost:host, conn->path, conn->allocptr.cookiehost:host, data->reqdata.path,
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE)); (bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
} }
@@ -2091,14 +2107,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result; return result;
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
&data->info.request_size, FIRSTSOCKET); &data->info.request_size, 0, FIRSTSOCKET);
if(result) if(result)
failf(data, "Failed sending POST request"); failf(data, "Failed sending POST request");
else else
/* setup variables for the upcoming transfer */ /* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
-1, NULL); -1, NULL);
break; break;
} }
@@ -2154,15 +2170,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* fire away the whole request to the server */ /* fire away the whole request to the server */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
&data->info.request_size, FIRSTSOCKET); &data->info.request_size, 0, FIRSTSOCKET);
if(result) if(result)
failf(data, "Failed sending POST request"); failf(data, "Failed sending POST request");
else else
/* setup variables for the upcoming transfer */ /* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
FIRSTSOCKET, FIRSTSOCKET,
&http->writebytecount); &http->writebytecount);
if(result) { if(result) {
Curl_formclean(http->sendit); /* free that whole lot */ Curl_formclean(http->sendit); /* free that whole lot */
return result; return result;
@@ -2198,15 +2214,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* this sends the buffer and frees all the buffer resources */ /* this sends the buffer and frees all the buffer resources */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
&data->info.request_size, FIRSTSOCKET); &data->info.request_size, 0, FIRSTSOCKET);
if(result) if(result)
failf(data, "Failed sending PUT request"); failf(data, "Failed sending PUT request");
else else
/* prepare for transfer */ /* prepare for transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
postsize?FIRSTSOCKET:-1, postsize?FIRSTSOCKET:-1,
postsize?&http->writebytecount:NULL); postsize?&http->writebytecount:NULL);
if(result) if(result)
return result; return result;
break; break;
@@ -2247,16 +2263,24 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(data->set.postfields) { if(data->set.postfields) {
if((data->state.authhost.done || data->state.authproxy.done ) /* for really small posts we don't use Expect: headers at all, and for
&& (postsize < MAX_INITIAL_POST_SIZE)) { the somewhat bigger ones we allow the app to disable it */
/* If we're not done with the authentication phase, we don't expect if(postsize > TINY_INITIAL_POST_SIZE) {
to actually send off any data yet. Hence, we delay the sending of result = expect100(data, req_buffer);
the body until we receive that friendly 100-continue response */ if(result)
return result;
}
else
data->state.expect100header = FALSE;
/* The post data is less than MAX_INITIAL_PORT_SIZE, then append it if(!data->state.expect100header &&
to the header. This limit is no magic limit but only set to (postsize < MAX_INITIAL_POST_SIZE)) {
prevent really huge POSTs to get the data duplicated with /* if we don't use expect:-100 AND
malloc() and family. */ postsize is less than MAX_INITIAL_POST_SIZE
then append the post data to the HTTP request header. This limit
is no magic limit but only set to prevent really huge POSTs to
get the data duplicated with malloc() and family. */
result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
if(result) if(result)
@@ -2267,6 +2291,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
already now to reduce the number if send() calls */ already now to reduce the number if send() calls */
result = add_buffer(req_buffer, data->set.postfields, result = add_buffer(req_buffer, data->set.postfields,
(size_t)postsize); (size_t)postsize);
included_body = postsize;
} }
else { else {
/* Append the POST data chunky-style */ /* Append the POST data chunky-style */
@@ -2278,6 +2303,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
result = add_buffer(req_buffer, result = add_buffer(req_buffer,
"\r\n0\r\n\r\n", 7); /* end of a chunked "\r\n0\r\n\r\n", 7); /* end of a chunked
transfer stream */ transfer stream */
included_body = postsize + 7;
} }
if(result) if(result)
return result; return result;
@@ -2295,18 +2321,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize); Curl_pgrsSetUploadSize(data, http->postsize);
result = expect100(data, req_buffer);
if(result)
return result;
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
} }
} }
else { else {
result = expect100(data, req_buffer);
if(result)
return result;
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
if(data->set.postfieldsize) { if(data->set.postfieldsize) {
@@ -2319,14 +2337,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
} }
} }
/* issue the request */ /* issue the request */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn, &data->info.request_size,
&data->info.request_size, FIRSTSOCKET); (size_t)included_body, FIRSTSOCKET);
if(result) if(result)
failf(data, "Failed sending HTTP POST request"); failf(data, "Failed sending HTTP POST request");
else else
result = result =
Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
http->postdata?FIRSTSOCKET:-1, http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL); http->postdata?&http->writebytecount:NULL);
@@ -2337,13 +2355,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* issue the request */ /* issue the request */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
&data->info.request_size, FIRSTSOCKET); &data->info.request_size, 0, FIRSTSOCKET);
if(result) if(result)
failf(data, "Failed sending HTTP request"); failf(data, "Failed sending HTTP request");
else else
/* HTTP GET/HEAD download: */ /* HTTP GET/HEAD download: */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
http->postdata?FIRSTSOCKET:-1, http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL); http->postdata?&http->writebytecount:NULL);

View File

@@ -74,7 +74,11 @@ int Curl_http_should_fail(struct connectdata *conn);
It must not be greater than 64K to work on VMS. It must not be greater than 64K to work on VMS.
*/ */
#ifndef MAX_INITIAL_POST_SIZE #ifndef MAX_INITIAL_POST_SIZE
#define MAX_INITIAL_POST_SIZE 1024 #define MAX_INITIAL_POST_SIZE (64*1024)
#endif
#ifndef TINY_INITIAL_POST_SIZE
#define TINY_INITIAL_POST_SIZE 1024
#endif #endif
#endif #endif

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2006, 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
@@ -83,7 +83,7 @@
void Curl_httpchunk_init(struct connectdata *conn) void Curl_httpchunk_init(struct connectdata *conn)
{ {
struct Curl_chunker *chunk = &conn->proto.http->chunk; struct Curl_chunker *chunk = &conn->data->reqdata.proto.http->chunk;
chunk->hexindex=0; /* start at 0 */ chunk->hexindex=0; /* start at 0 */
chunk->dataleft=0; /* no data left yet! */ chunk->dataleft=0; /* no data left yet! */
chunk->state = CHUNK_HEX; /* we get hex first! */ chunk->state = CHUNK_HEX; /* we get hex first! */
@@ -103,8 +103,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
ssize_t *wrotep) ssize_t *wrotep)
{ {
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
struct Curl_chunker *ch = &conn->proto.http->chunk; struct SessionHandle *data = conn->data;
struct Curl_transfer_keeper *k = &conn->keep; struct Curl_chunker *ch = &data->reqdata.proto.http->chunk;
struct Curl_transfer_keeper *k = &data->reqdata.keep;
size_t piece; size_t piece;
size_t length = (size_t)datalen; size_t length = (size_t)datalen;
size_t *wrote = (size_t *)wrotep; size_t *wrote = (size_t *)wrotep;
@@ -114,7 +115,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
while(length) { while(length) {
switch(ch->state) { switch(ch->state) {
case CHUNK_HEX: case CHUNK_HEX:
if(isxdigit((int)*datap)) { if(ISXDIGIT(*datap)) {
if(ch->hexindex < MAXNUM_SIZE) { if(ch->hexindex < MAXNUM_SIZE) {
ch->hexbuffer[ch->hexindex] = *datap; ch->hexbuffer[ch->hexindex] = *datap;
datap++; datap++;
@@ -186,26 +187,26 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
/* Write the data portion available */ /* Write the data portion available */
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
switch (conn->keep.content_encoding) { switch (data->reqdata.keep.content_encoding) {
case IDENTITY: case IDENTITY:
#endif #endif
if(!k->ignorebody) if(!k->ignorebody)
result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap, result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
piece); piece);
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
break; break;
case DEFLATE: case DEFLATE:
/* update conn->keep.str to point to the chunk data. */ /* update data->reqdata.keep.str to point to the chunk data. */
conn->keep.str = datap; data->reqdata.keep.str = datap;
result = Curl_unencode_deflate_write(conn->data, &conn->keep, result = Curl_unencode_deflate_write(conn, &data->reqdata.keep,
(ssize_t)piece); (ssize_t)piece);
break; break;
case GZIP: case GZIP:
/* update conn->keep.str to point to the chunk data. */ /* update data->reqdata.keep.str to point to the chunk data. */
conn->keep.str = datap; data->reqdata.keep.str = datap;
result = Curl_unencode_gzip_write(conn->data, &conn->keep, result = Curl_unencode_gzip_write(conn, &data->reqdata.keep,
(ssize_t)piece); (ssize_t)piece);
break; break;
@@ -303,7 +304,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
return CHUNKE_STOP; return CHUNKE_STOP;
} }
else { else {
Curl_client_write(conn->data, CLIENTWRITE_HEADER, Curl_client_write(conn, CLIENTWRITE_HEADER,
conn->trailer, conn->trlPos); conn->trailer, conn->trlPos);
} }
ch->state = CHUNK_TRAILER; ch->state = CHUNK_TRAILER;

View File

@@ -75,7 +75,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
} }
/* skip initial whitespaces */ /* skip initial whitespaces */
while(*header && isspace((int)*header)) while(*header && ISSPACE(*header))
header++; header++;
if(checkprefix("Digest", header)) { if(checkprefix("Digest", header)) {
@@ -93,7 +93,7 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
char content[128]; char content[128];
size_t totlen=0; size_t totlen=0;
while(*header && isspace((int)*header)) while(*header && ISSPACE(*header))
header++; header++;
/* how big can these strings be? */ /* how big can these strings be? */

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