Compare commits

...

316 Commits

Author SHA1 Message Date
Daniel Stenberg
c96f7f13da 7.11.2 coming today 2004-04-26 06:05:49 +00:00
Daniel Stenberg
1bdc4b2006 updated the warning text when SSL is explicitly disabled 2004-04-25 15:23:23 +00:00
Daniel Stenberg
3915fecf80 USE_MANUAL is now defined by default 2004-04-25 15:21:16 +00:00
Daniel Stenberg
f94f06825c moved older changes to the CHANGES.2003 file 2004-04-25 08:33:06 +00:00
Daniel Stenberg
2ddbf8975a disable-manual 2004-04-25 08:19:55 +00:00
Daniel Stenberg
68a3cbe384 make the generated hugehelp.c file use the USE_MANUAL define so that it
will be properly built with configure --disable-manual even if the source
file is already present
2004-04-25 08:13:07 +00:00
Daniel Stenberg
b9432d1296 test164 HTTP range with multiple ranges 2004-04-24 09:33:25 +00:00
Daniel Stenberg
e202a29a9a removed a memory leak when doing a windows threaded resolve and it failed 2004-04-23 14:10:29 +00:00
Daniel Stenberg
3755bffcc2 Gisle Vanem found and fixed a memory leak when doing (failing) Windows
threaded name resolves.
2004-04-23 14:04:30 +00:00
Daniel Stenberg
2a0a305300 only a minor comment/format change 2004-04-23 11:00:47 +00:00
Daniel Stenberg
70e2aadc18 Replaced Curl_FormReadOneLine with Curl_formpostheader as that is the only use
for it. It saves one extra copy of the header.

I also added comments for several functions in formdata.c
2004-04-23 10:37:52 +00:00
Daniel Stenberg
a1c8aaf666 o --proxy-ntlm now checks if libcurl supports NTLM before using it
o minor --fail with authentication bugfix
2004-04-23 08:50:28 +00:00
Daniel Stenberg
8ee470aaeb --proxy-ntlm fix and test case 163 2004-04-23 08:47:20 +00:00
Daniel Stenberg
37e4858cd0 Made --proxy-ntlm check if the underlying library actually supports NTLM 2004-04-23 08:44:27 +00:00
Daniel Stenberg
a27072bebb minor format fix 2004-04-23 08:40:20 +00:00
Daniel Stenberg
47059f45fe added test 163 - a simple test case that use -F field<file, to verify that
we can pass on "odd" characters (newline, CR, tab) like this.
2004-04-23 08:40:11 +00:00
Daniel Stenberg
daced8041d No longer uses the valgrind option '--logfile-fd', we use the --logfile
option instead (even though it appends the pid to the file name, making it
harder to figure out its name to parse it after a test has run).

Also made sure we only use valgrind for the actual test command command lines,
not when for example running curl to detect if there are any already running
servers are present etc.
2004-04-23 08:38:43 +00:00
Daniel Stenberg
b053ae6a65 define the obsolete options to different values to prevent "duplicate case"
situtations in bindings that still have switch() cases for them
2004-04-23 06:29:41 +00:00
Daniel Stenberg
42f60ecb36 require SSL as otherwise NTLM doesn't work! 2004-04-23 06:04:52 +00:00
Daniel Stenberg
550862f41a missing brace 2004-04-22 21:27:32 +00:00
Daniel Stenberg
6838f74fe0 allow newlines in the contents when doing -F "var=[contents]"
Robert Marlow reported.
2004-04-22 20:09:33 +00:00
Daniel Stenberg
2ff30d067c - David Byron found and fixed a small bug with the --fail and authentication
stuff added a few weeks ago.  Turns out that if you specify --proxy-ntlm and
  communicate with a proxy that requires basic authentication, the proxy
  properly returns a 407, but the failure detection code doesn't realize it
  should give up, so curl returns with exit code 0. Test case 162 verifies
  this.
2004-04-22 20:07:41 +00:00
Daniel Stenberg
84406b3e2c allow newlines in the contents when doing -F "var=[contents]" 2004-04-22 15:26:30 +00:00
Daniel Stenberg
c323969bdd removed Curl_ftp_quit() as it was turned into a static in ftp.c 2004-04-22 13:15:17 +00:00
Daniel Stenberg
43cbbdbea0 If a transfer is found out to be only partial, libcurl will now treat that
as a problem serious enough to skip the final QUIT command before closing
the control connection. To avoid the risk that it will "hang" waiting for
the QUIT response. Added test case 161 to verify this.
2004-04-22 13:10:43 +00:00
Daniel Stenberg
1d3f76df71 If only a partial file was transfered, we consider that a fatal problem so
we won't try to QUIT the control connection and risk "hanging" waiting for
a response. Test case 161 verifies this. The quit-sending function was
also made static.
2004-04-22 13:09:00 +00:00
Daniel Stenberg
33cb93ad0b Added comments 2004-04-22 12:35:45 +00:00
Daniel Stenberg
4dc9179f4b modified how valgrind is run to make sure that file handle 3 exists when
we tell valgrind to use that to send the logfile to
2004-04-22 10:33:55 +00:00
Daniel Stenberg
26a5ec9aa0 danish mirror 2004-04-22 08:54:34 +00:00
Daniel Stenberg
883ea3113c Gisle's items 2004-04-21 19:35:06 +00:00
Daniel Stenberg
62b7c08bb3 include unistd.h as well for the close() proto on some platforms (like Tru64) 2004-04-21 11:18:42 +00:00
Daniel Stenberg
a85fa66cc8 typecast the tolower() argument to an int to prevent compiler warning 2004-04-21 11:15:35 +00:00
Daniel Stenberg
9ba010c629 typecast tolower/toupper arguments to int to make picky compilers complain
less
2004-04-21 11:15:02 +00:00
Daniel Stenberg
3ef3f2b6f0 test case 160 "should work" now 2004-04-21 08:56:02 +00:00
Daniel Stenberg
1401d909e8 Fix the "lingering close" problem when re-using a connection, as test case
160 shows.

We got no data and we attempted to re-use a connection. This might happen if
the connection was left alive when we were done using it before, but that was
closed when we wanted to read from it again. Bad luck. Retry the same request
on a fresh connect!

Deleted the sockerror variable again, it serves no purpose anymore.
2004-04-21 08:49:14 +00:00
Daniel Stenberg
3233322622 increase the headerbytecount for incoming "headers" 2004-04-21 08:47:57 +00:00
Daniel Stenberg
e373f1fd73 log the WAIT command 2004-04-21 06:56:54 +00:00
Daniel Stenberg
dc25cd6f3a cleanup leftovers 2004-04-20 09:46:10 +00:00
Daniel Stenberg
0e31d41d4e test160 - for a more controlled testing of the case where libcurl starts
to re-use a connection that is closed when re-used and libcurl should then
make a new fresh connection and use instead
2004-04-20 08:35:37 +00:00
Daniel Stenberg
b7a7600465 Cleaned up hostname/name/gname and path/ppath confusion. Removed the fixed-
length limit of the hostname part of the URL.
2004-04-20 07:53:24 +00:00
Daniel Stenberg
111a2f3057 new mirror and one that changed domain 2004-04-20 07:52:16 +00:00
Daniel Stenberg
760cecac8d make the first response get a "connection: close" header as that is how
most 1.1 connections will be closed. The case where it gets closed anyway
is subject for a new separate test.
2004-04-20 07:36:09 +00:00
Daniel Stenberg
6f8b4395ec changed the logging to work when the logfile is removed during testing 2004-04-19 15:20:30 +00:00
Daniel Stenberg
5506f8767c Make the server include "Connection: close" in the headers of the replies
it actually will close. This is after all what HTTP 1.1 says a server should
do.
2004-04-19 08:41:36 +00:00
Daniel Stenberg
5887945828 Gisle Vanem corrected a mistake in a recent progress fix 2004-04-19 07:18:26 +00:00
Daniel Stenberg
25e98179be Gisle Vanem: patches to make sws.c compile under MingW/MSVC is
attached. And some cosmetic fixes.
2004-04-17 11:38:41 +00:00
Daniel Stenberg
78ebe3fa5a Gisle made a failed connect output the reason for it 2004-04-17 11:33:47 +00:00
Daniel Stenberg
a8e8e51b14 NDEBUG should not be defined when CURLDEBUG is 2004-04-17 11:33:14 +00:00
Daniel Stenberg
f97d194934 adding issue 36 to be fixed before release 2004-04-16 07:33:53 +00:00
Daniel Stenberg
4661cc7403 don't display the . and .. files when dumping the log/ contents 2004-04-16 07:02:17 +00:00
Daniel Stenberg
bc11929395 remade the logging function to better deal with removed logfiles during
the execution of the tests
2004-04-16 07:01:47 +00:00
Daniel Stenberg
caf37bc92e issue 31 - fix windows multi interface is now corrected 2004-04-15 15:05:48 +00:00
Daniel Stenberg
5de447b0cb clarified that select() timeouts should always remain rather short 2004-04-15 15:05:12 +00:00
Daniel Stenberg
5dbaced4a2 my test suite edits 2004-04-15 14:53:47 +00:00
Daniel Stenberg
43f8a1f5de change the log format to look similar to sws
added various logging info
2004-04-15 13:55:37 +00:00
Daniel Stenberg
f57efa1899 clean the log directory between each single test, so that we can better
display all logs and only logs with relevant data when a test fails and -p
is used.
2004-04-15 13:37:19 +00:00
Daniel Stenberg
592522ceaf ftp->dirs[] is no longer terminated with a zero entry but ftp->dirdepth
should be used
2004-04-15 10:43:40 +00:00
Daniel Stenberg
4f84e6d9e2 removed the fixed dir depth limit in the FTP code 2004-04-15 07:52:39 +00:00
Daniel Stenberg
6f08903f07 two ipresolve fixes 2004-04-14 12:13:32 +00:00
Daniel Stenberg
220cd010bd format fix 2004-04-14 12:13:21 +00:00
Daniel Stenberg
68e8a0f0d9 asking for CURL_IPRESOLVE_V6 when ipv6 addresses can't be resolved will
now cause the resolve function to return NULL immediately
2004-04-14 12:10:44 +00:00
Daniel Stenberg
b23dbf9f34 Gisle Vanem made the -4/-6 actually get set too 2004-04-14 12:00:53 +00:00
Daniel Stenberg
1d0b5b507a Curl_wait_for_resolv() could hang due to the bad timeout timer resolution and
some bad thinking on my part.
2004-04-14 11:43:26 +00:00
Daniel Stenberg
b83d8104cd several changes 2004-04-14 07:07:30 +00:00
Daniel Stenberg
bf6e1053cf display interesting log files on failure, if -p is used 2004-04-14 07:04:45 +00:00
Daniel Stenberg
c3dd928e29 enable verbose as well 2004-04-14 06:53:34 +00:00
Daniel Stenberg
aba6c2b89d Added test case 511 in an attempt to repeat bug report #934666 "storage leak
in ftp.c", but it shows no leaking.
2004-04-14 06:30:37 +00:00
Daniel Stenberg
9c0a386246 minor format fix 2004-04-13 14:34:12 +00:00
Daniel Stenberg
bba3bb7556 eh, these can't be used for poll()! ;-) 2004-04-13 14:31:49 +00:00
Daniel Stenberg
c1422864b5 additional info 2004-04-13 14:27:47 +00:00
Daniel Stenberg
31a693b99a Gisle Vanem's fix that makes the multi interface work on Windows again even
when not using ares.
2004-04-13 13:59:12 +00:00
Daniel Stenberg
804534fbc9 spell fixes 2004-04-13 11:03:02 +00:00
Daniel Stenberg
1bc6532c16 more news 2004-04-13 10:58:44 +00:00
Daniel Stenberg
b48bf7470d proper typecast to prevent compiler warning 2004-04-13 10:42:32 +00:00
Daniel Stenberg
1ca9ce5ef4 removed the BUGS section since it offers nothing good 2004-04-13 09:08:52 +00:00
Daniel Stenberg
789f2ecbe7 1.2.0 2004-04-13 07:44:26 +00:00
Daniel Stenberg
ee7d1d0701 remove an long time #defined struct member and use the actual "real" name
instead to make it easier to find/read
2004-04-13 07:37:28 +00:00
Daniel Stenberg
4e3aa250c4 Moved the 'tcp_nodelay' member to the proper 'UserDefined' struct within the
sessionhandle to make the duphandle() function work as supposed. Also tried
to start document functions the doxygen way (in the headers of the functions).
Can't make it work though...
2004-04-13 07:16:26 +00:00
Daniel Stenberg
3647a6ddcd move issue 35 (hostip.c cleanup) forward, I don't feel like doing that now 2004-04-13 06:13:41 +00:00
Daniel Stenberg
79aaa85a51 full-test passes -p to runtests as well to get more details in case of failure 2004-04-13 05:58:19 +00:00
Daniel Stenberg
392a543eff Initial support for dumping the contents of the files in log/ when failing
when -p is used. For easier bug-hunting of autobuild failures. This still
only shows what files that are present in log/, as I believe we need to
filter which files we show on a failure.
2004-04-13 05:57:50 +00:00
Daniel Stenberg
eb6345de60 somewhat safer typecasting in case sizeof(long) != sizeof(void *) (is there
even such platforms?)
2004-04-12 06:55:25 +00:00
Daniel Stenberg
0fd3b7a00a David Byron's patch for MSVC builds with zlib 2004-04-11 20:25:10 +00:00
Daniel Stenberg
bd51b80fa5 updated to not include the msvc-generated files 2004-04-11 06:33:02 +00:00
Daniel Stenberg
15c900839b when checked out from CVS, run this to generate the proper scripts 2004-04-11 06:32:41 +00:00
Daniel Stenberg
2fd463e979 Dirk Manske increased the resolution for what the CURLINFO_*_TIME return. 2004-04-09 09:36:31 +00:00
Daniel Stenberg
de8660a96a we're working on 1.2.0 now 2004-04-08 18:10:03 +00:00
Daniel Stenberg
1e9cb272f1 added test 159, use --ntlm together with -0 2004-04-07 15:01:11 +00:00
Daniel Stenberg
72b1144b8c getting only a 100 Continue response and nothing else, when talking HTTP,
is now treated as an error by libcurl
2004-04-07 14:27:54 +00:00
Daniel Stenberg
348fe0e210 --limit-rate using -d or -F does not work 2004-04-07 14:03:13 +00:00
Daniel Stenberg
cf1f46e1ca renamed the strtoofft() macro to curlx_strtoofft() to adjust to the curlx_*
concept, and added lib/README.curlx to explain details about it
2004-04-07 07:30:40 +00:00
Daniel Stenberg
f052cbee19 Use curl_off_t for the limit rate values to support REALLY huge values on
such platforms that support large files.
2004-04-07 07:23:52 +00:00
Daniel Stenberg
1f5e8670e1 mention getting windows builds to work after rearrangements 2004-04-06 15:30:57 +00:00
Daniel Stenberg
3b491d0f73 Moved long-standing issues over from TODO-RELEASE to the more long-term TODO
file.
2004-04-06 15:29:01 +00:00
Daniel Stenberg
26a2b8d26d the memory leak on windows have been addressed 2004-04-06 15:22:21 +00:00
Daniel Stenberg
a7fd6f9007 require ssl since ntlm needs it 2004-04-06 15:16:07 +00:00
Daniel Stenberg
8ed44e8dfb New authentication code added, particularly noticable when doing POST or PUT
with Digest or NTLM. libcurl will now use HEAD to negotiate the authentication
and when done perform the requested POST.
2004-04-06 15:14:10 +00:00
Daniel Stenberg
f617c1131a mention the man page updates from the other day 2004-04-06 15:12:50 +00:00
Daniel Stenberg
5ca47f19d7 the pack_hostent() proto isn't used/needed with ipv6 is enabled.
time to restructure this source file!
2004-04-06 15:09:43 +00:00
Daniel Stenberg
9044fcbb5f Gisle Vanem's fix for bug item #927979 reported by Nathan O'Sullivan.
Good enough?
2004-04-06 14:51:14 +00:00
Daniel Stenberg
7a82810b59 Added the curl source header and changed some comments 2004-04-06 14:07:04 +00:00
Daniel Stenberg
0ccdf3d0e6 improved --limit-rate functionality, partly by the new use of curlx_tvnow() 2004-04-06 12:06:05 +00:00
Daniel Stenberg
ca7f0852df Gisle Vanem caught me breaking the windows version of Curl_strerror() 2004-04-06 12:02:36 +00:00
Daniel Stenberg
780b962336 provide these functions as curlx_* ones as this enables the curl app to
re-use these sources and functions for subsecond resolution timing
2004-04-06 10:15:10 +00:00
Daniel Stenberg
bbeb840916 up-to-date with reality 2004-04-06 07:59:11 +00:00
Daniel Stenberg
f4ec465bfc added HAVE_GETTIMEOFDAY, we need it for better time resolution 2004-04-06 07:49:57 +00:00
Daniel Stenberg
57c86a953d typecasts to please picky compilers checking the printf() format string 2004-04-06 07:48:29 +00:00
Daniel Stenberg
0fff8656e9 one change, three bugs, one credit 2004-04-06 06:24:37 +00:00
Daniel Stenberg
7b929636ee the last couple of days 2004-04-06 06:24:06 +00:00
Daniel Stenberg
76835a2e00 two issues to fix before 7.11.2, one issue to fix befor 7.12.0 2004-04-06 06:18:48 +00:00
Daniel Stenberg
1b171b02ac remove the general use of sys_nerr 2004-04-06 06:06:10 +00:00
Daniel Stenberg
a8dc362572 generated files, no need to keep in CVS 2004-04-05 12:38:54 +00:00
Daniel Stenberg
7c72f8ee6c prepend the man3 dir to the file name to work better.
Robin Kay pointed this out.
2004-04-02 11:04:34 +00:00
Daniel Stenberg
c39a54609b edits, mainly to make the generated html output nicer 2004-04-02 09:56:01 +00:00
Daniel Stenberg
ce6b767b47 minor edits 2004-04-02 09:50:42 +00:00
Daniel Stenberg
7ba4d3464f Dirk Manske's feedback:
* bring back subsecond resolution to CURLINFO_TOTAL_TIME
* Fix the Curl_pgrsDone() so that the final progress update is shown properly
2004-04-02 07:32:03 +00:00
Daniel Stenberg
03def138fe Andrs Garca's updated mingw makefiles 2004-04-02 07:18:13 +00:00
Daniel Stenberg
9d99af5329 if select returns -1, bail out of the loop 2004-04-02 06:40:31 +00:00
Daniel Stenberg
c8d850dbad Only check that the c-ares lib is valid if we don't use the "embedded"
directory. The provided ares dir is probably up-to-date, but more importantly
it is often not built yet at the time when this configure script runs.
2004-04-01 10:26:59 +00:00
Daniel Stenberg
01ea357744 When ares is enabled, we now check for the ares_cancel function to verify
that we use a library that is recent enough to build with the latest libcurl.
2004-04-01 09:10:33 +00:00
Daniel Stenberg
ad9e83a90f Dirk Manske's fix that makes sure we cancel the ares resolve when we time out
from a name resolve. Without this, we leak memory!
2004-04-01 08:40:36 +00:00
Daniel Stenberg
6c9d96e811 Dirk Manske's ares_cancel() function was added. 2004-04-01 08:25:58 +00:00
Daniel Stenberg
f840e5192c edited slightly, point out our new mailinglist 2004-04-01 08:25:23 +00:00
Daniel Stenberg
ba9272dd05 remind us about cvs tagging when we've built a release archive 2004-04-01 08:23:26 +00:00
Daniel Stenberg
675db3a211 removed my previously attempted fix for ares timeouts, not needed 2004-04-01 07:04:58 +00:00
Daniel Stenberg
1fc7ff878e Applied Joe Halpin's bugfixes to the NI_WITHSCOPEID test program. 2004-04-01 06:53:11 +00:00
Daniel Stenberg
b643d148b1 Dominick Meglio man page fixes 2004-04-01 06:10:56 +00:00
Daniel Stenberg
5804c995e1 Use the new HAVE_NI_WITHSCOPEID define instead of merely checking for the
existance of NI_WITHSCOPEID since some platforms have that define but still
can't function with it set.
2004-03-31 21:33:52 +00:00
Daniel Stenberg
13a6f85320 issue 30, digest re-negotiate works now! 2004-03-31 21:04:26 +00:00
Daniel Stenberg
8b4582f111 recent changes 2004-03-31 21:03:55 +00:00
Daniel Stenberg
cd3bf7c56f updates and David Byron's spellfix 2004-03-31 21:01:20 +00:00
Daniel Stenberg
ee1595dcd5 Roy Shan fixed a case that prevented ares name resolve timeouts to occur. 2004-03-31 20:50:01 +00:00
Daniel Stenberg
310086deed we're working on 7.11.2-CVS right now 2004-03-31 20:22:28 +00:00
Daniel Stenberg
5d27f50f2f HAVE_NI_WITHSCOPEID spelled right! 2004-03-31 20:13:53 +00:00
Daniel Stenberg
9d0330d5bd Remove the elapsed time from the most recent select() only. 2004-03-31 13:19:41 +00:00
Daniel Stenberg
d5074f74bb The asynch name resolve methods now all use CURL_TIMEOUT_RESOLVE for
the specific time to wait for a resolve. The definition is at the top of
this source file.
2004-03-31 12:55:24 +00:00
Daniel Stenberg
ea0cf7c87b Dirk Manske found out the Curl_wait_for_resolv() timed out too early. 2004-03-31 12:45:26 +00:00
Daniel Stenberg
a56164c8e0 added swsbounce 2004-03-31 12:24:08 +00:00
Daniel Stenberg
cd95bb22ea added include to fix warning 2004-03-31 11:55:56 +00:00
Daniel Stenberg
1745ecd8ac * Fixed a memory leak when doing repeated re-negotiations.
* Made the incoming line parser more forgiving to allow "name=contents" pairs
where the contents isn't within double quotes.
* Made the digest code return CURLDIGEST_BADALGO if a requested algorithm
isn't supported by the code.
2004-03-31 11:55:07 +00:00
Daniel Stenberg
75d66b9c62 test 153 tests Digest authorization and stale=true stuff 2004-03-31 11:51:21 +00:00
Daniel Stenberg
2ff9f55001 Added "swsbounce" magic: if this keyword is present in a <data> section it
sets the "swsbounce" magic mode. If there follows a request for the SAME
test number and the SAME part number, this mode will make the server bump
the part number internally and thus return a different <dataNUM> section
than it otherwise would.

Test case 153 uses this in case you need an example. It is pretty involved
and hard-to-use, but then the situation is pretty special over all. Enjoy.
2004-03-31 11:50:44 +00:00
Daniel Stenberg
ce446dbdc2 Moved the NI_WITHSCOPEID magic #ifdef to the top of the file and made sure
we use the NIFLAGS properly on both places in the code that use getnameinfo().
2004-03-31 10:59:48 +00:00
Daniel Stenberg
dd2add82ee Fixed how the user name is extracted from http_proxy environment variable
when set.
2004-03-31 10:46:06 +00:00
Daniel Stenberg
40d9855df2 Andrs Garca fixed a warning in the ioctlsocket() usage. 2004-03-31 10:34:53 +00:00
Daniel Stenberg
ecf7adba15 modified the NI_WITHSCOPEID to use an AF_INET6 socket immediately and
added some more debug output to make it easier to detect failure reasons
in the autobuild logs
2004-03-31 10:31:08 +00:00
Daniel Stenberg
931c847e2b CURLDIGEST_BADALGO is a new return code from the digest code 2004-03-31 09:20:27 +00:00
Daniel Stenberg
8230d9bff8 Dominick Meglio fixed a missing comma 2004-03-31 06:10:40 +00:00
Daniel Stenberg
64cc14e9e6 one issue less 2004-03-30 15:35:09 +00:00
Daniel Stenberg
d5b8971ff3 typecast setsockopt()'s 4th argument to void * to make compilers complain
less
2004-03-30 13:05:45 +00:00
Daniel Stenberg
7ea837a18c adjusted to the new dns cache function to hide more hostip internals 2004-03-30 13:02:31 +00:00
Daniel Stenberg
b8b8473b6d Lots of comments added an clarified. Added timeout for the ares version
of Curl_is_resolved() to address Roy Shan's reported problem.
2004-03-30 13:02:07 +00:00
Daniel Stenberg
894dbae455 added stale boolean to the digest struct 2004-03-30 13:00:53 +00:00
Daniel Stenberg
2c11425868 first attempt to support stale=true 2004-03-30 13:00:32 +00:00
Daniel Stenberg
a2ea0abf7f Added CURL_CHECK_NI_WITHSCOPEID that checks if NI_WITHSCOPEID exists and
works. No code actually uses the HAVE_NI_WITHSCOPEID (that a positive test
results in), but this is still only for testing purposes.
2004-03-30 10:35:54 +00:00
Daniel Stenberg
be8f8e66a4 Dominick Meglio's new ares_expand_string() function 2004-03-30 09:06:42 +00:00
Daniel Stenberg
9fadfffb9d when checking the automake version, cut off trailing "-p[whatever]" from the
version string before doing the version number checks.
2004-03-30 08:28:39 +00:00
Daniel Stenberg
76f23acfa1 if 0'ed out a code section that uses __FUNCTION__ etc, used for debugging
the new "fail with auth" code
2004-03-30 08:21:09 +00:00
Daniel Stenberg
6950aeafcc init the dns pointer to NULL for clarity 2004-03-30 08:14:37 +00:00
Daniel Stenberg
cd160a66c9 added more comments for what the functions return 2004-03-30 08:11:54 +00:00
Daniel Stenberg
a7376968d2 mention the fact that you can append a new CA cert to the existing bundle too 2004-03-30 06:46:36 +00:00
Daniel Stenberg
fd96a2af34 David Byron's patch was appplied to make CURLOPT_FAILONERROR work nicely
even with authentcations such as NTLM or Digest enabled. Test cases 150, 151
and 152 were added to verify the functionality.
2004-03-30 06:42:12 +00:00
Daniel Stenberg
a90cd1a45c David Byron's new test cases for the --fail and auth stuff. 2004-03-30 06:41:33 +00:00
Daniel Stenberg
8e92600ddd David Byron made CURLOPT_FAILONERROR work with authentications such as NTLM
or Digest.
2004-03-30 06:40:01 +00:00
Daniel Stenberg
5e75c310ba 'authdone' was added to the sessionhandle and thus was removed from the
argument to the NTLM function(s)
2004-03-30 06:39:24 +00:00
Daniel Stenberg
20cab07c29 David Byron added 'authdone' to the SessionHandle. 2004-03-30 06:38:52 +00:00
Daniel Stenberg
f466d7a6f1 these are now in the packages/vms dir 2004-03-29 22:45:14 +00:00
Daniel Stenberg
dc46f535ae The select() timeout is better not static since some implementation actually
might change it. I don't *think* it does it when the timeout is 0,0 but it
is better to be sure...
2004-03-29 21:29:24 +00:00
Daniel Stenberg
27fd5d6d6a issue 24 is fixed by making sure the time fields use a static width 2004-03-29 13:46:58 +00:00
Daniel Stenberg
18a3c3302f several noticable recent changes 2004-03-29 13:46:16 +00:00
Daniel Stenberg
97959a00d7 changes changes changes 2004-03-29 13:45:53 +00:00
Daniel Stenberg
5e92b2906b All test targets now run 'make all' before they prcoeed with the actual
testing so that all test files are build first properly. David Byron reported.
2004-03-29 12:38:41 +00:00
Daniel Stenberg
126ed14313 Gisle Vanem's djgpp/MS-DOS updates 2004-03-29 12:29:25 +00:00
Daniel Stenberg
712d0374f7 fix to figure out the "real" windows path when built and run with mingw
Andrs Garca helped out!
2004-03-29 09:26:31 +00:00
Daniel Stenberg
4b49b2e3cf re-indented to use curl-standard source formatting 2004-03-29 07:25:59 +00:00
Daniel Stenberg
d85c21994f netinet/tcp.h may require netinet/in.h to be include before 2004-03-29 06:22:57 +00:00
Daniel Stenberg
6b33a5f954 use the correct struct 2004-03-28 21:41:10 +00:00
Daniel Stenberg
ed22afe5fb Tor fixed a left-over from the ip argument to setnodelay 2004-03-27 11:15:50 +00:00
Daniel Stenberg
843391c745 Gisle Vanem:
A patch to bypass MS' sillyness with regard to IPv6 and getaddrinfo().

The CURLDEBUG part is to avoid redefinition warning caused by memdebug.h. If
ENABLE_IPV6 isn't enabled, it doesn't matter since we never call
getaddrinfo(). Allthough we could to support weird protocols like SOCK_RDM
that Win-2K/XP has.
2004-03-26 13:47:46 +00:00
Daniel Stenberg
ad6699e0c4 some more password blurb 2004-03-26 13:20:28 +00:00
Daniel Stenberg
43137cf595 check for netinet/tcp.h precense before actually including it 2004-03-26 07:10:15 +00:00
Daniel Stenberg
db6dc49b0b removed the ip number from the notcpdelay function 2004-03-26 07:03:30 +00:00
Daniel Stenberg
593170d1de get the version number from the new curlver.h header file 2004-03-25 16:03:41 +00:00
Daniel Stenberg
0eace2fefe localtime and gmtime are not thread-safe on newer AIXes either so we force
a check for there *_r-versions too
2004-03-25 15:48:54 +00:00
Daniel Stenberg
abd65e21c6 force recent AIX versions to check for strerror_r 2004-03-25 15:10:01 +00:00
Daniel Stenberg
e21104a865 only output one line about the nodelay even if it fails 2004-03-25 14:01:01 +00:00
Daniel Stenberg
3ecf63fa66 win32 doesn't need and even doesn't build if we extern declare sys_nerr 2004-03-25 13:43:19 +00:00
Daniel Stenberg
762dcf0780 include the strerror.h file without curl_ prefix 2004-03-25 13:42:23 +00:00
Daniel Stenberg
75ee9b5333 strerror without prefix 2004-03-25 13:40:57 +00:00
Daniel Stenberg
e161bdc5be cut off 'curl_' from the strerror file names 2004-03-25 13:40:24 +00:00
Daniel Stenberg
bb3d6e8552 tcp-nodelay patch by Joe Halpin 2004-03-25 13:37:18 +00:00
Daniel Stenberg
189c2f4989 so there are at least two different strerror_r() versions and our brand
new configure script detects them and now this code acts according to what
API that was detected
2004-03-25 12:45:01 +00:00
Daniel Stenberg
f28389c87b Tor Arntsen fixed how this is invoked 2004-03-25 12:16:42 +00:00
Daniel Stenberg
7461592a16 strerror_r() detection changes:
1. Try with _THREAD_SAFE instead of _REENTRANT, as AIX seems to require it
   and if _REENTRANT is required we should already have it set since one of
   the previous tests.
2. Added API-detection for what kind of strerror_r() that is provided. The
   POSIX style or the glibc style.

Tor Arntsen provided the necessary feedback these changes are based upon.
2004-03-25 12:15:00 +00:00
Daniel Stenberg
50b0e72f7b detect daily snapshots using the new path for this test 2004-03-25 11:39:29 +00:00
Daniel Stenberg
76e73cfec8 make clean now removes *dist files too that might be leftovers from
'maketgz'
2004-03-25 11:34:35 +00:00
Daniel Stenberg
5d8ec172a6 invoke this script via env, as it is more likely to exist at a fixed path
while perl often is installed in /usr/local/bin or elsewhere
2004-03-25 08:22:03 +00:00
Daniel Stenberg
0953140b53 added curl_strerror to the build 2004-03-25 07:53:37 +00:00
Daniel Stenberg
6c2825997a extern declare the sys_nerr variable. Required on Solaris at least. 2004-03-25 07:52:11 +00:00
Daniel Stenberg
accc6eb91a Always include setup.h as the first header file.
Added a more verbose comment about what strerror_r() can set errno to in
case of failure.
This file still doesn't build on Solaris due to a missing 'sys_nerr' symbol.
2004-03-25 07:33:11 +00:00
Daniel Stenberg
eab8cdc640 Added protos for the upcoming curl_*_strerror() functions 2004-03-24 22:53:42 +00:00
Daniel Stenberg
dc9d0f256d missed the new header file 2004-03-24 22:46:02 +00:00
Daniel Stenberg
b60d6404d8 Gisle Vanem's fix to replace the bad use of strerror(). This introduces
Curl_strerror() that attempts to be thread-safe _and_ works on Windows too!
2004-03-24 22:45:37 +00:00
Daniel Stenberg
08fe4b3210 new header file - for Curl_strerror() 2004-03-24 22:43:09 +00:00
Daniel Stenberg
0e60a118d0 better comments, added some more variable types we use in the font-lock 2004-03-24 22:24:03 +00:00
Daniel Stenberg
4b78b4124e Tor Arntsen's major ispell patch 2004-03-24 21:40:45 +00:00
Daniel Stenberg
0d6d9af7ab Tor Arntsen's mkdir-fix to make this run with perl 5.0005 2004-03-24 21:28:31 +00:00
Daniel Stenberg
41cd36b830 Avoid doing chdir .., as it breaks the ability to use symlinks properly.
chdir to absolute directory names instead. (this flaw exists in the shell
version too)
2004-03-24 10:52:21 +00:00
Daniel Stenberg
242be55771 added check for strerror_r() 2004-03-24 08:45:58 +00:00
Daniel Stenberg
7cf47ea5b5 include curl/curlver.h instead since this only needs the version defines 2004-03-24 07:27:58 +00:00
Daniel Stenberg
6fb0012833 error messages and new test script 2004-03-23 16:12:55 +00:00
Daniel Stenberg
9d1ce9c0df we are progressing 2004-03-23 16:12:37 +00:00
Daniel Stenberg
5947e4e9fd distribute testcurl.pl too starting now 2004-03-23 16:11:01 +00:00
Daniel Stenberg
e992aa6a54 Greg Hewgill's version of testcurl.sh rewritten in perl for greater
portability. I put it in this directory instead of the root since I think
perhaps it makes more sense.
2004-03-23 16:07:02 +00:00
Daniel Stenberg
2cf218610e keep current_speed as an curl_off_t for better precision at higher speeds
if large file support is available
2004-03-23 16:01:31 +00:00
Daniel Stenberg
fe6f0aeb26 switch() on the right variable! 2004-03-23 15:48:27 +00:00
Daniel Stenberg
bd04c6fb67 curl_strequal() returns int, keep return variables in an int 2004-03-23 15:30:12 +00:00
Daniel Stenberg
c5637baa06 make the variables that hold the result of strlen() size_t 2004-03-23 15:28:31 +00:00
Daniel Stenberg
f8426a2c44 stricter variable type usage 2004-03-23 15:25:54 +00:00
Daniel Stenberg
0c791d1e76 variable type usage cleanup to please picky compilers 2004-03-23 15:20:57 +00:00
Daniel Stenberg
c4a89d29f6 get strlen() results in a size_t, delete 'register' 2004-03-23 15:14:57 +00:00
Daniel Stenberg
306ff5649a made time2str() use longs internally instead to prevent compiler warnings
when converting to ints
2004-03-23 15:06:14 +00:00
Daniel Stenberg
1c652dfc5d added explicit typecasts to prevent compiler warnings on variable conversions 2004-03-23 15:01:19 +00:00
Daniel Stenberg
1f61e7f8f4 If localbind fails, provide a more portable error message. 2004-03-23 14:43:42 +00:00
Daniel Stenberg
1a5f190e47 minor update by Kevin 2004-03-23 14:34:09 +00:00
Daniel Stenberg
570033448c src/version.h was not properly made! 2004-03-23 14:29:21 +00:00
Daniel Stenberg
f44b655513 progress meter fix, CURLINFO_CONTENT_LENGTH_DOWNLOAD fix, cygwin package fix 2004-03-23 11:52:08 +00:00
Daniel Stenberg
0aa720fa26 it actually fits to make a NNNd NNh display so this can be used up to
999 days
2004-03-23 11:46:31 +00:00
Daniel Stenberg
d44f3f84f8 Fixed the time fields no never get wider than 8 letters. They can now switch
to a "days + hours" or even "just days" display if the time value is very
large. I also switched several calculations over to fixed-point instead of the
previous doubles.
2004-03-23 11:43:34 +00:00
Daniel Stenberg
d426db3d27 int/size_t cleanup 2004-03-23 09:12:51 +00:00
Daniel Stenberg
0fd88d7c8f minor variable type cleanups 2004-03-23 08:50:28 +00:00
Daniel Stenberg
4e84ac4db8 minor edits to make picky compilers whine less 2004-03-23 08:46:08 +00:00
Daniel Stenberg
da5c8a121f changed the long to int typecasts to see if icc 8.0 complains less on this 2004-03-23 08:42:01 +00:00
Daniel Stenberg
76c36688d0 Makes CURLINFO_CONTENT_LENGTH_DOWNLOAD work even if CURLOPT_NOBODY is set
true.
2004-03-22 22:38:12 +00:00
Daniel Stenberg
651c8d3bc4 Kevin Roth's updates to handle a new requirement from the Cygwin folks to
package man and doc files in a slightly different location.
2004-03-22 22:24:23 +00:00
Daniel Stenberg
a8a946d71d crap files to get the dirs made when checked out from CVS 2004-03-22 21:46:08 +00:00
Daniel Stenberg
c5c005609e container to get this dir made 2004-03-22 21:42:07 +00:00
Daniel Stenberg
97886f9353 Make the axp/README ia64/README vax/README files get included as well.
They're 0-bytes files, but make the dirs get created!
2004-03-22 21:37:02 +00:00
Daniel Stenberg
a784bd0797 fixed the ntlm problem with longish passwords 2004-03-22 13:56:48 +00:00
Daniel Stenberg
4aacf65678 vms fixes committed 2004-03-22 13:56:30 +00:00
Daniel Stenberg
dd1ba7633e Enabled 'NT responses' in the NTLM type-3 message. 2004-03-22 13:50:30 +00:00
Daniel Stenberg
a4ea5a4054 fixed /I "." for the debug build too 2004-03-22 11:32:22 +00:00
Daniel Stenberg
69060b1382 add /I "." to include ca-bundle.h properly 2004-03-22 11:26:40 +00:00
Daniel Stenberg
a6562ea77d issue 27 fixed, moved libcurl version defines to its own header file 2004-03-22 10:22:01 +00:00
Daniel Stenberg
ad3563096a include the new curlver instead, since all this wants is the version info 2004-03-22 08:54:26 +00:00
Daniel Stenberg
c5f02c1986 Introducing curl/curlver.h for keeping the curl version info only. 2004-03-22 08:37:38 +00:00
Daniel Stenberg
7ef5d20cad files moved here from the $ROOT/src dir 2004-03-21 22:50:53 +00:00
Daniel Stenberg
98b619c3a7 removed deleted files 2004-03-21 22:49:36 +00:00
Daniel Stenberg
5b75919f95 Marty Kuhrt's adjustments for a cleaner VMS build 2004-03-21 22:44:52 +00:00
Daniel Stenberg
20b76e09e3 Marty Kuhrt's VMS updates 2004-03-21 22:38:01 +00:00
Daniel Stenberg
67fca4cb01 recognize and use ACLOCAL_FLAGS if set (Thomas Schwinge patch) 2004-03-21 15:45:58 +00:00
Daniel Stenberg
606715b2cd use tabs, not spaces! 2004-03-21 15:32:15 +00:00
Daniel Stenberg
ce04b35032 Added the Version 7.11.1 marker 2004-03-19 13:22:48 +00:00
Daniel Stenberg
ec7f244ee9 starting a new cycle 2004-03-19 08:41:49 +00:00
Daniel Stenberg
a5b206f398 irix configure fix and a msvc project file update 2004-03-18 14:20:17 +00:00
Daniel Stenberg
306a05f9ff Mitz Wark's reported Digest re-negotiate problem is issue 30. 2004-03-18 12:59:03 +00:00
Daniel Stenberg
81f8350616 For IRIX systems we must pick the "correct" lib dirs for the particular
libs we want. $libsuff is the magic variable that contains a suffix (which
might be blank). Tor Arntsen brought details and verified this fix.
2004-03-18 10:03:34 +00:00
Daniel Stenberg
760ca6adc4 added http_ntlm.[ch] and inet_pton.[ch], pointed out by Watz 2004-03-17 21:30:26 +00:00
Daniel Stenberg
ffb35ff5c3 Gnter Knauf's update, mainly converted to plain old C comments. 2004-03-17 13:36:45 +00:00
Daniel Stenberg
8eda06131b new netware-related files added to the distribution 2004-03-17 12:48:41 +00:00
Daniel Stenberg
5b55f9ecb3 Gnter Knauf's NetWare changes. 2004-03-17 12:46:42 +00:00
Daniel Stenberg
3417e0b0fc nonsense comments removed 2004-03-17 07:22:04 +00:00
Daniel Stenberg
79ed144b0f mention yesterday's man page update frenzy 2004-03-16 10:41:14 +00:00
Daniel Stenberg
8e5cf6589c issue 29 has a bug report mentioning details 2004-03-16 10:40:48 +00:00
Daniel Stenberg
fc67cca882 removed the min() macro define 2004-03-16 09:16:38 +00:00
Daniel Stenberg
eea2287068 random updates 2004-03-16 07:56:51 +00:00
Daniel Stenberg
5fe5de7511 added the CA bundle default path, and mention the risk that the server you
try to talk to may be an imposter
2004-03-16 07:25:52 +00:00
Daniel Stenberg
4a6b9972dd ntlm and long passwords 2004-03-15 16:32:13 +00:00
Daniel Stenberg
256a16a8a3 if the global_init() is called from within curl_easy_init() and returns
an error code, we now make curl_easy_init fail and return NULL.
2004-03-15 16:28:36 +00:00
Daniel Stenberg
30e0891d3d ignore these files 2004-03-15 13:20:53 +00:00
Daniel Stenberg
8147ccdf76 automake file for this dir 2004-03-15 13:20:01 +00:00
Daniel Stenberg
26ab286630 provide URLs to two patches mentioned 2004-03-15 13:13:14 +00:00
Daniel Stenberg
738807883e NTLM fix 2004-03-15 13:09:59 +00:00
Daniel Stenberg
03a0988ce8 better formatting to create fine links in the web version 2004-03-15 12:42:19 +00:00
Daniel Stenberg
7de892eeb4 more formatting fixes 2004-03-15 12:41:24 +00:00
Daniel Stenberg
8c4e91a653 refer to function names better to enhance the HTML output 2004-03-15 11:56:07 +00:00
Daniel Stenberg
8f77030473 Initial commit of the first attempt to make three new *strerror() functions.
No protos in the headers yet and no docs.
2004-03-15 11:51:32 +00:00
Daniel Stenberg
546d0bd3d1 windows builds now report a slightly different "OS" string 2004-03-15 11:43:04 +00:00
Daniel Stenberg
5d53b544d3 check for m4 version in buildconf 2004-03-15 11:42:48 +00:00
Daniel Stenberg
6dc8fac122 random formatting updates to look better in HTML version 2004-03-15 11:37:37 +00:00
Daniel Stenberg
8114f8562b use .NF for the struct part to looke better in HTML
format some function references properly
2004-03-15 11:30:29 +00:00
Daniel Stenberg
c79fa187b9 more fixes 2004-03-15 11:26:53 +00:00
Daniel Stenberg
237ec68b0e better formatting of functions to get better links in the web version 2004-03-15 10:26:08 +00:00
Daniel Stenberg
4ebf4f6e55 better mentioning of other functions to create proper hrefs in the web
version
2004-03-15 10:23:14 +00:00
Daniel Stenberg
4d86593f3c build_vms.com is removed from here 2004-03-15 10:18:38 +00:00
Daniel Stenberg
ec050ccbc4 Marty Kuhrt's VMS updates 2004-03-15 10:11:34 +00:00
Daniel Stenberg
f19cade50f Added the new vms subdir in the packages dir 2004-03-15 10:10:24 +00:00
Daniel Stenberg
a2f35aaf67 new vms subdir 2004-03-15 10:08:32 +00:00
Daniel Stenberg
e5c4b6b345 not used anymore since Marty Kuhrt's recent VMS updates 2004-03-15 10:03:58 +00:00
Daniel Stenberg
bad978feb2 Marty Kuhrt's provided files for the VMS package 2004-03-15 10:03:05 +00:00
Daniel Stenberg
bea9152aa8 Check for a GNU version of m4, since autoconf won't run nicely without one. 2004-03-15 07:47:13 +00:00
Daniel Stenberg
f788f988ea fix signed and unsigned warnings 2004-03-14 18:15:04 +00:00
Daniel Stenberg
d04ffd258b postsize is off_t now, so we typecase it to int before doing normal printf
with it (knowing it won't be larger than what fits in an int)
2004-03-13 17:11:42 +00:00
Daniel Stenberg
24cfa7f1bb the postsize is an off_t so use the proper printf format to output the
content-length when doing multipart posts
2004-03-13 17:03:17 +00:00
Daniel Stenberg
94a1d09ac7 more variable type fixing for the huge posts 2004-03-12 14:22:16 +00:00
Daniel Stenberg
230a75091b newer c-ares release 2004-03-12 13:17:46 +00:00
Daniel Stenberg
4ad68ec305 more variable type fixes for the large POST support 2004-03-12 13:06:01 +00:00
Daniel Stenberg
ef776ab893 Made the 'postsize' variable an off_t type to be able to hold large file
sizes if desired
2004-03-12 12:07:01 +00:00
Daniel Stenberg
f8ff0f6bef minor variable type fix 2004-03-12 12:05:33 +00:00
Daniel Stenberg
bc7122f6e2 CURLOPT_POSTFIELDSIZE_LARGE is added in 7.11.1 2004-03-12 09:14:45 +00:00
Daniel Stenberg
e5963dae48 ignore aclocal.m4 2004-03-12 08:57:10 +00:00
Daniel Stenberg
1ebda8fa0e Added CURLOPT_POSTFIELDSIZE_LARGE to offer a large file version of the
CURLOPT_POSTFIELDSIZE option to allow really big HTTP POSTs.
2004-03-12 08:55:47 +00:00
Daniel Stenberg
9af532e662 David Byron's fix to clear outs.filename 2004-03-12 08:03:31 +00:00
Daniel Stenberg
9d064a3927 dl and ulspeed are now curl_off_t so typecast them to double when we
return their values
2004-03-11 21:51:55 +00:00
Daniel Stenberg
d6edcfb486 Optimize the way libcurl uses CWD 2004-03-11 21:49:56 +00:00
Daniel Stenberg
1d5a914c1c Made max5data() take a curl_off_t size as argument instead of double. Should
make the progress meter more accurate for large files. Also made the sprintf
usage in that function avoid floating point.
2004-03-11 21:48:15 +00:00
Daniel Stenberg
666bc9ee4e added that header fiddling the msvc users will enjoy 2004-03-11 13:15:14 +00:00
Daniel Stenberg
e545e33d5f Gisle Vanem's fixes to use CURL_SOCKET_BAD more instead of -1 for sockets. 2004-03-11 13:13:35 +00:00
Daniel Stenberg
326e8b9fc1 don't let the EINTR stuff build on windows 2004-03-11 12:57:04 +00:00
Daniel Stenberg
0d1fc73f21 Use more curl_off_t variables when doing the progress meter calculations and
argument passing and try to convert to double only when providing data to the
external world.
2004-03-10 16:20:33 +00:00
Daniel Stenberg
50a1853560 use the new OS define from lib/config-win32.h 2004-03-10 16:07:19 +00:00
Daniel Stenberg
35e158d80b make loop variable size_t as well when looping to a size_t limit 2004-03-10 16:03:12 +00:00
Daniel Stenberg
7225b14002 curl_socket_t mistakes cleanup 2004-03-10 16:01:47 +00:00
Daniel Stenberg
85838a8966 turn niflags into a define named NIFLAGS 2004-03-10 15:24:56 +00:00
Daniel Stenberg
d29590f583 added the Estonian one, removed the cyberservers one since it is dead and
they don't respond to email
2004-03-10 11:30:19 +00:00
Daniel Stenberg
467c3e3a1f fixing 2004-03-10 11:28:45 +00:00
210 changed files with 10328 additions and 3379 deletions

1935
CHANGES

File diff suppressed because it is too large Load Diff

1572
CHANGES.2003 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -24,8 +24,7 @@
AUTOMAKE_OPTIONS = foreign AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \ EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist \
curl-config.in build_vms.com curl-style.el sample.emacs testcurl.sh \ curl-config.in curl-style.el sample.emacs testcurl.sh RELEASE-NOTES
RELEASE-NOTES
bin_SCRIPTS = curl-config bin_SCRIPTS = curl-config

View File

@@ -81,7 +81,9 @@ amiga:
cd ./lib && make -f makefile.amiga cd ./lib && make -f makefile.amiga
cd ./src && make -f makefile.amiga cd ./src && make -f makefile.amiga
netware:
cd lib && make -f Makefile.netware
cd src && make -f Makefile.netware
unix: all unix: all

17
README
View File

@@ -32,25 +32,30 @@ WEB SITE
Sweden -- http://curl.haxx.se/ Sweden -- http://curl.haxx.se/
Australia -- http://curl.planetmirror.com/ Australia -- http://curl.planetmirror.com/
Denmark -- http://curl.cofman.dk/
Estonia -- http://curl.wildyou.net/
Germany -- http://curl.mirror.at.stealer.net/ Germany -- http://curl.mirror.at.stealer.net/
Germany -- http://curl.netmirror.org/
Russia -- http://curl.tsuren.net/ Russia -- http://curl.tsuren.net/
Thailand -- http://curl.siamu.ac.th/ Thailand -- http://curl.siamu.ac.th/
US (CA) -- http://curl.mirror.redwire.net/ US (CA) -- http://curl.mirror.redwire.net/
US (TX) -- http://curl.cyberservers.net/ US -- http://curl.signal42.com/
DOWNLOAD DOWNLOAD
The official download mirror sites are: The official download mirror sites are:
Australia -- http://curl.planetmirror.com/download/ Australia -- http://curl.planetmirror.com/download.html
Estonia -- http://curl.wildyou.net/download.html
Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/ Germany -- ftp://ftp.fu-berlin.de/pub/unix/network/curl/
Germany -- http://curl.mirror.at.stealer.net/download.html
Germany -- http://curl.netmirror.org/download.html
Hongkong -- http://www.execve.net/curl/ Hongkong -- http://www.execve.net/curl/
Russia -- http://curl.tsuren.net/download/ Russia -- http://curl.tsuren.net/download.html
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/ Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Sweden -- http://cool.haxx.se/curl/ Sweden -- http://cool.haxx.se/curl/
Thailand -- http://curl.siamu.ac.th/download/ Thailand -- http://curl.siamu.ac.th/download.html
US (CA) -- http://curl.mirror.redwire.net/download/ US (CA) -- http://curl.mirror.redwire.net/download.html
US (TX) -- http://curl.cyberservers.net/download/
CVS CVS

View File

@@ -1,85 +1,74 @@
Curl and libcurl 7.11.1. A bugfix release. Curl and libcurl 7.11.2. A bugfix release.
Public curl release number: 79 Public curl release number: 80
Releases counted from the very beginning: 106 Releases counted from the very beginning: 107
Available command line options: 94 Available command line options: 94
Available curl_easy_setopt() options: 111 Available curl_easy_setopt() options: 113
This release includes the following changes: This release includes the following changes:
o CURL_VERSION_LARGEFILE is a feature bit returned by libcurls that feature o removed maximum user+password+hostname size limit
large file support o removed maximum dir depth limit for FTP
o libcurl only requires winsock 1.1 on windows now o the ares build now requires c-ares 1.2.0 or later
o when doing FTP, curl now sends QUIT before disconnecting o --tcp-nodelay and CURLOPT_TCP_NODELAY were added
o name resolves can now timeout on windows too o curl/curlver.h contains the libcurl version info now
o $HOME is now recognized better when looking for .netrc files
o now re-uses the ares handle when re-using curl handles
o SO_BINDTODEVICE is used for network interface binding
o configure --disable-manual disables the built-in huge manual from the
command line tool
o the default Accept: header used in HTTP requests changed
o asynch dns lookups now require the c-ares library
o curl --socks can be used to set a SOCKS5 proxy to use
o response-headers received after a (proxy) CONNECT request are now passed
to the header callback just like other headers
This release includes the following bugfixes: This release includes the following bugfixes:
o Improved PUT/POST with NTLM/Digest authentication o configure --disable-manual works better
o following redirects and doing NTLM/Digest (where the first connection gets o removed a memory leak when doing a windows threaded resolve and it failed
closed) with the multi interface work better now o --proxy-ntlm now checks if libcurl supports NTLM before using it
o file: progress meter and getinfo variables work now o minor --fail with authentication bugfix
o CURLOPT_FRESH_CONNECT and CURLAUTH_NTLM now work when set together o CURLOPT_IPRESOLVE set to CURL_IPRESOLVE_V6 will now cause a returned error
o share interface usage without (un)lock functions segfaulted if the host only can resolve ipv4 addresses
o --limit-rate no longer cripples the --speed-limit feature o curl -4/-6 now actually sets the requested option in libcurl
o fixed verbose output problem with ipv6-enabled re-used connections o multi interface on Windows without ares works again
o fixed the socks5 code to check version in the socks response properly o improved resolution for the CURLINFO_*_TIME info variables
o dns cache bug - fixed the 'inuse' counter o getting only a 100 Continue response and nothing else, when talking HTTP,
o large file fix for Content-Length is now treated as an error by libcurl
o better docs for the share interface o fixed minor memory leak in libcurl for Windows when statically linked
o several configure fixes for mingw/msys o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better
o setting a Host: header is no longer affecting the Host: header used when o --limit-rate with high speed rates is a lot more accurate now, and supports
libcurl follows a Location: limiting to speeds >2GB/sec on systems with Large File support.
o fixed numerous compiler warnings on several operating systems and compilers o curl_strnqual.3 "refer-to" man page fix
o PUTing from stdin couldn't disable chunked transfer-encoding o fixed a minor very old progress meter final update bug
o corrected the mingw makefiles o added checks for a working NI_WITHSCOPEID before that is used
o improved the configure libz detection o fixed a flaw that prevented ares name resolve timeouts to occur
o fixed EPRT/PORT use when doing FTP on ipv6-enabled AIX hosts o getting user name from http_proxy env variable works now
o *nroff commands that only support -mandoc and not -man are now supported o fixed too early name resolve timeouts with ares
(for the built-in manual text in the command line tool) o HTTP Digest "re-negotiation" works now
o fixed the unconditional #include of config.h in hugehelp.c o CURLOPT_FAILONERROR (-f/--fail) works with all kinds of authentication
o builds fine on MPE/iX o better thread-safety thanks to the internal strerror() replacement
o upload using chunked transfer-encoding now sends the last chunk properly o better thread-safety on AIX thanks to better function detection
teriminated with an extra CRLF o minor ipv6 build fix for windows
o Fixed the progress meter display for files >2GB o the test suite runs fine with mingw-built curl
o persistant connections over a proxy messed up the proxy name/password o the postit2.c example works now
o the socks5 code segfaulted if no username/password was set o better error message when --interface fails on windows
o the *_LARGE options now take curl_off_t types as parameters and this will o the progress meter now displays very long times better
make it possible to handle large files on windows too o CURLINFO_CONTENT_LENGTH_DOWNLOAD with CURLOPT_NOBODY set TRUE now works
o builds with large file support even on systems without strtoll() o passwords longer than 14 letters work with NTLM
o 'make netware' in the root dir works now
o builds fine on VMS again and even nicer than before
Other curl-related news since the previous public release: Other curl-related news since the previous public release:
o Many platforms are being used to autobuild and autotest curl on a daily o PycURL 7.11.1 was released: http://pycurl.sf.net/
basis. Please join in and test curl on your systems: o CURLHandle 1.9 was released: http://curlhandle.sourceforge.net/
http://curl.haxx.se/auto/ o A curl module for the Q language was announced:
o the curl mailing lists moved, (re-)subscribe to the new ones from here: http://q-lang.sourceforge.net/
http://curl.haxx.se/mail/ o c-ares 1.2.0 was released: http://daniel.haxx.se/projects/c-ares/
o c-ares 1.0.0 was relased: http://daniel.haxx.se/projects/c-ares/ o New curl web mirrors:
o TclCurl 0.11.0 was released: Germany http://curl.netmirror.org/
http://personal1.iddeo.es/andresgarci/tclcurl/english/ USA http://curl.signal42.com/
o PycURL 7.11.0 was released: http://pycurl.sourceforge.net/ Denmark http://curl.cofman.dk/
o the libcurl D binding was released:
http://www.atari-soldiers.com/libcurl.html
o new Estonian web site mirror: http://curl.dope-brothers.com/
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:
Gisle Vanem, Vincent Bronner, Richard Bramante, Dirk Manske, Dan Fandrich, Thomas Schwinge, Marty Kuhrt, G<>nter Knauf, Kevin Roth, Glen Nakamura, Gisle
Ken Hirsch, Stadler Stephan, Domenico Andreoli, Patrick Smith, Tor Arntsen, Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz
Andr<64>s Garc<72>a, Tim Baker, Len Krause, Gilad, Ken Rastatter, P R Schaffner, Wark, Andr<64>s Garc<72>a, Robin Kay, Alan Pinstein, David Byron, Nathan
Greg Hewgill, Ben Greear, Jeff Lawson, Grigory Entin, Doug Porter, David O'Sullivan, Erwin Authried
Byron, Andy Serpa, Joe Halpin, Christopher R. Palmer
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@@ -3,31 +3,35 @@ Issues not sorted in any particular order.
UNASSIGNED means that no person has publicly stated to work on the issue. UNASSIGNED means that no person has publicly stated to work on the issue.
DELETE means the issue is subject for dismissal DELETE means the issue is subject for dismissal
To get fixed in 7.11.1 (planned release in March 2004) To get fixed in 7.11.2 (planned release late April 2004)
====================== ======================
To get fixed in 7.11.2 (planned release May/June 2004)
To get fixed in 7.12.0 (no date)
====================== ======================
6. REST fix for servers not behaving well on >2GB requests. This should fail 25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
if the server doesn't set the pointer to the requested index. The tricky Code already in CVS. Messages need overview/improvements.
part is to figure out if the server did the right thing or not. Medium prio.
UNASSIGNED
10. Anton Fedorov's "dumpcert" patch (only mailed to me privately) UNASSIGNED 26. i18n of error messages?
Low prio. Nobody has volunteered. Subject for removal.
14. Evaluate/apply Gertjan van Wingerde's SSL patches, UNASSIGNED 33. Add a function to replace the malloc-calls within libcurl.
Low prio. Seshubabu Pasam works on this.
23. Peter Sylvester's "Most Significant Common Name" patch. Feedback welcome. 35. Rearrange lib/hostip.c to reduce the amount of #ifdefs and make it easier
At least the UTF8 conversion and comparison should be done. Patch? to understand and edit. Daniel works on this. See
UNASSIGNED http://curl.haxx.se/beta/hostip-cleanup1.patch
Medium prio.
24. Make the progress meter use one digit more for the hour time fields. 36. Add support for a threaded getaddrinfo() on Windows and IPv6 enabled
Accomplish this by removing one of the times displayed. libcurl.
To get fixed in 7.12.0 37. Configure option "--with-libidn" to support IDNA (Internationalising
====================== Domain Names in Applications). Translate to/from ACE encoded domain
names as needed.
25. curl_strerror() 38. Make the ldap protocol work with Windows' built-in LDAP-client.
I.e. dynamically link to WLDAP32.DLL and add ldap URL parsing
26. i18n of error messages (WLDAP32.DLL doesn't have an UTF-8 ldap_url_parse).

View File

@@ -64,7 +64,7 @@ dnl the code was bad, try a different program now, test 3
],[ ],[
/* ioctlsocket source code */ /* ioctlsocket source code */
int socket; int socket;
int flags = ioctlsocket(socket, FIONBIO, &flags); unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
],[ ],[
dnl ioctlsocket test was good dnl ioctlsocket test was good
nonblock="ioctlsocket" nonblock="ioctlsocket"
@@ -245,7 +245,8 @@ AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
void main(void) { int main(void)
{
struct addrinfo hints, *ai; struct addrinfo hints, *ai;
int error; int error;
@@ -254,11 +255,9 @@ void main(void) {
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai); error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
if (error) { if (error) {
exit(1); return 1;
}
else {
exit(0);
} }
return 0;
} }
],[ ],[
ac_cv_working_getaddrinfo="yes" ac_cv_working_getaddrinfo="yes"
@@ -276,10 +275,72 @@ if test "$ac_cv_working_getaddrinfo" = "yes"; then
fi fi
]) ])
dnl ************************************************************
dnl check for working NI_WITHSCOPEID in getnameinfo()
dnl
AC_DEFUN([CURL_CHECK_NI_WITHSCOPEID],[
AC_CACHE_CHECK(for working NI_WITHSCOPEID, ac_cv_working_ni_withscopeid,[
AC_RUN_IFELSE([[
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main()
{
#ifdef NI_WITHSCOPEID
struct sockaddr_storage ss;
int sslen = sizeof(ss);
int rc;
char hbuf[NI_MAXHOST];
int fd = socket(AF_INET6, SOCK_STREAM, 0);
if(fd < 0) {
perror("socket()");
return 1; /* couldn't create socket of either kind */
}
rc = getsockname(fd, (struct sockaddr *)&ss, &sslen);
if(rc) {
perror("getsockname()");
return 2;
}
rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf),
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID);
if(rc) {
printf("rc = %s\n", gai_strerror(rc));
return 3;
}
return 0; /* everything works fine, use NI_WITHSCOPEID! */
#else
return 4; /* we don't seem to have the definition, don't use it */
#endif
}
]],
dnl program worked:
[ ac_cv_working_ni_withscopeid="yes" ],
dnl program failed:
[ ac_cv_working_ni_withscopeid="no" ],
dnl we cross-compile:
[ ac_cv_working_ni_withscopeid="yes" ]
) dnl end of AC_RUN_IFELSE
]) dnl end of AC_CACHE_CHECK
if test "$ac_cv_working_ni_withscopeid" = "yes"; then
AC_DEFINE(HAVE_NI_WITHSCOPEID, 1,
[Define if NI_WITHSCOPEID exists and works])
fi
]) dnl end of AC_DEFUN
AC_DEFUN([CURL_CHECK_LOCALTIME_R], AC_DEFUN([CURL_CHECK_LOCALTIME_R],
[ [
dnl check for a few thread-safe functions dnl check for localtime_r
AC_CHECK_FUNCS(localtime_r,[ AC_CHECK_FUNCS(localtime_r,[
AC_MSG_CHECKING(whether localtime_r is declared) AC_MSG_CHECKING(whether localtime_r is declared)
AC_EGREP_CPP(localtime_r,[ AC_EGREP_CPP(localtime_r,[
@@ -295,6 +356,92 @@ AC_DEFUN([CURL_CHECK_LOCALTIME_R],
AC_MSG_RESULT(no))])]) AC_MSG_RESULT(no))])])
]) ])
dnl
dnl This function checks for strerror_r(). If it isn't found at first, it
dnl retries with _THREAD_SAFE defined, as that is what AIX seems to require
dnl in order to find this function.
dnl
dnl If the function is found, it will then proceed to check how the function
dnl actually works: glibc-style or POSIX-style.
dnl
dnl glibc:
dnl char *strerror_r(int errnum, char *buf, size_t n);
dnl
dnl What this one does is to return the error string (no surprises there),
dnl but it doesn't usually copy anything into buf! The 'buf' and 'n'
dnl parameters are only meant as an optional working area, in case strerror_r
dnl needs it. A quick test on a few systems shows that it's generally not
dnl touched at all.
dnl
dnl POSIX:
dnl int strerror_r(int errnum, char *buf, size_t n);
dnl
AC_DEFUN([CURL_CHECK_STRERROR_R],
[
dnl determine of strerror_r is present
AC_CHECK_FUNCS(strerror_r,[
AC_MSG_CHECKING(whether strerror_r is declared)
AC_EGREP_CPP(strerror_r,[
#include <string.h>],[
strerror_r="yes"
AC_MSG_RESULT(yes)],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING(whether strerror_r with -D_THREAD_SAFE is declared)
AC_EGREP_CPP(strerror_r,[
#define _THREAD_SAFE
#include <string.h>],[
strerror_r="yes"
CPPFLAGS="-D_THREAD_SAFE $CPPFLAGS"
AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))])])
if test "x$strerror_r" = "xyes"; then
dnl determine if this strerror_r() is glibc or POSIX
AC_MSG_CHECKING([for a glibc strerror_r API])
AC_TRY_RUN([
#include <string.h>
#include <errno.h>
int
main () {
char buffer[1024]; /* big enough to play with */
char *string =
strerror_r(EACCES, buffer, sizeof(buffer));
/* this should've returned a string */
if(!string || !string[0])
return 99;
return 0;
}
],
AC_DEFINE(HAVE_GLIBC_STRERROR_R, 1, [we have a glibc-style strerror_r()])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
)
AC_MSG_CHECKING([for a POSIX strerror_r API])
AC_TRY_RUN([
#include <string.h>
#include <errno.h>
int
main () {
char buffer[1024]; /* big enough to play with */
int error =
strerror_r(EACCES, buffer, sizeof(buffer));
/* This should've returned zero, and written an error string in the
buffer.*/
if(!buffer[0] || error)
return 99;
return 0;
}
],
AC_DEFINE(HAVE_POSIX_STRERROR_R, 1, [we have a POSIX-style strerror_r()])
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
)
fi
])
AC_DEFUN([CURL_CHECK_INET_NTOA_R], AC_DEFUN([CURL_CHECK_INET_NTOA_R],
[ [
dnl determine if function definition for inet_ntoa_r exists. dnl determine if function definition for inet_ntoa_r exists.

View File

@@ -5,3 +5,4 @@ adig
ahost ahost
config.log config.log
config.status config.status
aclocal.m4

View File

@@ -1,3 +1,27 @@
Changelog for the c-ares project
Version 1.2.0 (April 13, 2004)
* April 2, 2004
- Updated various man pages to look nicer when converted to HTML on the web
site.
* April 1, 2004
- Dirk Manske provided a new function that is now named ares_cancel(). It is
used to cancel/cleanup a resolve/request made using ares functions on the
given ares channel. It does not destroy/kill the ares channel itself.
- Dominick Meglio cleaned up the formatting in several man pages.
* March 30, 2004
- Dominick Meglio's new ares_expand_string. A helper function when decoding
incoming DNS packages.
- Daniel Stenberg modified the Makefile.in to use a for loop for the man page
installation to improve overview and make it easier to add man pages.
Version 1.1.0 (March 11, 2004)
* March 9, 2004 * March 9, 2004
- Gisle Vanem improved build on Windows. - Gisle Vanem improved build on Windows.
@@ -74,3 +98,5 @@ Version 1.0-pre1 (8 October 2003)
- Daniel Stenberg adjusted the windows port - Daniel Stenberg adjusted the windows port
- liren at vivisimo.com made the initial windows port - liren at vivisimo.com made the initial windows port
* Imported the sources from ares 1.1.1

View File

@@ -21,8 +21,6 @@ vc/adig/adig.dsp
vc/adig/adig.mak vc/adig/adig.mak
vc/adig/adig.plg vc/adig/adig.plg
vc/vc.dsw vc/vc.dsw
vc/vc.ncb
vc/vc.opt
vc/ahost/ahost.dep vc/ahost/ahost.dep
vc/ahost/ahost.dsp vc/ahost/ahost.dsp
vc/ahost/ahost.mak vc/ahost/ahost.mak

View File

@@ -25,7 +25,15 @@ OBJS= ares__close_sockets.o ares__get_hostent.o ares__read_line.o \
ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \ ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \
ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \ ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \
ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \ ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \
ares_send.o ares_strerror.o ares_timeout.o ares_version.o ares_send.o ares_strerror.o ares_timeout.o ares_version.o \
ares_expand_string.o ares_cancel.o
MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \
ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3
$(LIB): ${OBJS} $(LIB): ${OBJS}
ar cru $@ ${OBJS} ar cru $@ ${OBJS}
@@ -60,31 +68,9 @@ install:
chmod u-w ${DESTDIR}${libdir}/$(LIB) chmod u-w ${DESTDIR}${libdir}/$(LIB)
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir} ${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir} ${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir}
${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3 (for man in $(MANPAGES); do \
${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3 ${INSTALL} -m 444 ${srcdir}/$${man} ${DESTDIR}${mandir}/man3; \
${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3 done)
${INSTALL} -m 444 ${srcdir}/ares_free_hostent.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_free_string.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_gethostbyaddr.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_gethostbyname.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_init.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_init_options.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_mkquery.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_parse_a_reply.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_parse_ptr_reply.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_process.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_query.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_search.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_send.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_strerror.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_timeout.3 ${DESTDIR}${mandir}/man3
clean: clean:
rm -f ${OBJS} $(LIB) adig.o adig ahost.o ahost rm -f ${OBJS} $(LIB) adig.o adig ahost.o ahost

View File

@@ -1,19 +1,21 @@
c-ares
======
This package is based on ares 1.1.1 (written by Greg Hudson). I've decided to This package is based on ares 1.1.1 (written by Greg Hudson). I decided to
put together and release my own ares archives since the ares maintainer fork and release a separate project since the ares author didn't want the
doesn't want these improvements. improvements that were vital for our use of it.
The package is thus dubbed 'c-ares' since I (Daniel Stenberg) want this for This package is dubbed 'c-ares' since I (Daniel Stenberg) wanted this for use
use within the curl project (hence the letter C) and it makes a nice within the curl project (hence the letter C) and it makes a nice pun. Also,
pun. Also, c-ares will not remain API compatible with the original ares, so c-ares is not API compatible with ares: a new name makes that more obvious to
picking a new name makes it more obvious to the public. the public.
The full source code is available in the 'c-ares' release archives, and in the The full source code is available in the 'c-ares' release archives, and in the
'ares' subdir of the curl CVS source repostitory. 'ares' subdir of the curl CVS source repostitory.
If you find bugs, correct flaws, have questions or have comments in general in If you find bugs, correct flaws, have questions or have comments in general in
regard to c-ares (or by all means the original ares too), get in touch with us regard to c-ares (or by all means the original ares too), get in touch with us
on the curl-library mailing list. on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares
c-ares is of course distributed under the same MIT-style license as the c-ares is of course distributed under the same MIT-style license as the
original ares. original ares.

View File

@@ -55,6 +55,7 @@
#define ARES_EFILE 14 #define ARES_EFILE 14
#define ARES_ENOMEM 15 #define ARES_ENOMEM 15
#define ARES_EDESTRUCTION 16 #define ARES_EDESTRUCTION 16
#define ARES_EBADSTR 17
/* Flag values */ /* Flag values */
#define ARES_FLAG_USEVC (1 << 0) #define ARES_FLAG_USEVC (1 << 0)
@@ -104,7 +105,7 @@ int ares_init(ares_channel *channelptr);
int ares_init_options(ares_channel *channelptr, struct ares_options *options, int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int optmask); int optmask);
void ares_destroy(ares_channel channel); void ares_destroy(ares_channel channel);
void ares_cancel(ares_channel channel);
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
ares_callback callback, void *arg); ares_callback callback, void *arg);
void ares_query(ares_channel channel, const char *name, int dnsclass, void ares_query(ares_channel channel, const char *name, int dnsclass,
@@ -125,6 +126,8 @@ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
int rd, unsigned char **buf, int *buflen); int rd, unsigned char **buf, int *buflen);
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
int alen, char **s, long *enclen); int alen, char **s, long *enclen);
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
int alen, unsigned char **s, long *enclen);
int ares_parse_a_reply(const unsigned char *abuf, int alen, int ares_parse_a_reply(const unsigned char *abuf, int alen,
struct hostent **host); struct hostent **host);
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,

37
ares/ares_cancel.3 Normal file
View File

@@ -0,0 +1,37 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_CANCEL 3 "31 March 2004"
.SH NAME
ares_cancel \- Cancel a resolve
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_cancel(ares_channel \fIchannel\fP)
.fi
.SH DESCRIPTION
The \fBares_cancel\fP function cancels all lookups/requests made on the the
name service channel identified by \fIchannel\fP. \fBares_cancel\fP invokes
the callbacks for each pending query on the channel, passing a status of
.BR ARES_ETIMEOUT .
These calls give the callbacks a chance to clean up any state which
might have been stored in their arguments.
.SH SEE ALSO
.BR ares_init (3)
.BR ares_destroy (3)
.SH AUTHOR
Dirk Manske

44
ares/ares_cancel.c Normal file
View File

@@ -0,0 +1,44 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include <stdlib.h>
#include "ares.h"
#include "ares_private.h"
/*
* ares_cancel() cancels a ongoing request/resolve that might be going on on
* the given channel. It does NOT kill the channel, use ares_destroy() for
* that.
*/
void ares_cancel(ares_channel channel)
{
struct query *query, *next;
int i;
for (query = channel->queries; query; query = next)
{
next = query->next;
query->callback(query->arg, ARES_ETIMEOUT, NULL, 0);
free(query->tcpbuf);
free(query->skip_server);
free(query);
}
channel->queries = NULL;
if (!(channel->flags & ARES_FLAG_STAYOPEN))
{
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(&channel->servers[i]);
}
}

View File

@@ -36,7 +36,8 @@ status of
These calls give the callbacks a chance to clean up any state which These calls give the callbacks a chance to clean up any state which
might have been stored in their arguments. might have been stored in their arguments.
.SH SEE ALSO .SH SEE ALSO
.BR ares_init (3) .BR ares_init (3),
.BR ares_cancel (3)
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

62
ares/ares_expand_string.3 Normal file
View File

@@ -0,0 +1,62 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_EXPAND_NAME 3 "23 July 1998"
.SH NAME
ares_expand_string \- Expand a length encoded string
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_expand_string(const unsigned char *\fIencoded\fP,
.B const unsigned char *\fIabuf\fP, int \fIalen\fP, unsigned char **\fIs\fP,
.B int *\fIenclen\fP)
.fi
.SH DESCRIPTION
The
.B ares_expand_string
function converts a length encoded string to a NULL terminated C
string. The argument
.I encoded
gives the beginning of the encoded string, and the arguments
.I abuf
and
.I alen
give the containing message buffer (necessary for the processing of
indirection pointers within the encoded domain name). The result is
placed in a NUL-terminated allocated buffer, a pointer to which is
stored in the variable pointed to by
.IR s .
The length of the encoded string is stored in the variable pointed to by
.I enclen
so that the caller can advance past the encoded string to read
further data in the message.
.SH RETURN VALUES
.B ares_expand_string
can return any of the following values:
.TP 15
.B ARES_SUCCESS
Expansion of the encoded string succeeded.
.TP 15
.B ARES_EBADSTR
The encoded string was malformed and could not be expanded.
.TP 15
.B ARES_ENOMEM
Memory was exhausted.
.SH SEE ALSO
.BR ares_free_string (3)
.SH AUTHOR
Dominick Meglio

65
ares/ares_expand_string.c Normal file
View File

@@ -0,0 +1,65 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#include <sys/types.h>
#ifdef WIN32
#include "nameser.h"
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "ares.h"
#include "ares_private.h" /* for the memdebug */
/* Simply decodes a length-encoded character string. The first byte of the
* input is the length of the string to be returned and the bytes thereafter
* are the characters of the string. The returned result will be NULL
* terminated.
*/
int ares_expand_string(const unsigned char *encoded,
const unsigned char *abuf,
int alen,
unsigned char **s,
long *enclen)
{
unsigned char *q;
long len;
if (encoded == abuf+alen)
return ARES_EBADSTR;
len = *encoded;
if (encoded+len+1 > abuf+alen)
return ARES_EBADSTR;
encoded++;
*s = malloc(len+1);
if (*s == NULL)
return ARES_ENOMEM;
q = *s;
strncpy((char *)q, (char *)encoded, len);
q[len] = '\0';
*s = q;
*enclen = len+1;
return ARES_SUCCESS;
}

View File

@@ -28,21 +28,16 @@ The
.I ares_free_hostent .I ares_free_hostent
function frees a function frees a
.B struct hostent .B struct hostent
allocated by one of the functions allocated by one of the functions \fIares_parse_a_reply(3)\fP or
.I ares_parse_a_reply \fIares_parse_ptr_reply(3)\fP.
or .SH NOTES
.IR ares_parse_ptr_reply . It is not necessary (and is not correct) to free the host structure passed to
the callback functions for \fIares_gethostbyname(3)\fP or
\fIares_gethostbyaddr(3)\fP. The ares library will automatically free such
host structures when the callback returns.
.SH SEE ALSO .SH SEE ALSO
.BR ares_parse_a_reply (3), .BR ares_parse_a_reply (3),
.BR ares_parse_ptr_reply (3) .BR ares_parse_ptr_reply (3)
.SH NOTES
It is not necessary (and is not correct) to free the host structure
passed to the callback functions for
.I ares_gethostbyname
or
.IR ares_gethostbyaddr .
The ares library will automatically free such host structures when the
callback returns.
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

View File

@@ -26,11 +26,10 @@ ares_free_string \- Free strings allocated by ares functions
.SH DESCRIPTION .SH DESCRIPTION
The The
.I ares_free_string .I ares_free_string
function frees a string allocated by the function frees a string allocated by an ares function.
.I ares_mkquery
function.
.SH SEE ALSO .SH SEE ALSO
.BR ares_mkquery (3) .BR ares_mkquery (3)
.BR ares_expand_string (3)
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

View File

@@ -40,14 +40,10 @@ and
.I addrlen .I addrlen
give the address as a series of bytes, and give the address as a series of bytes, and
.I family .I family
gives the type of address. When the query is complete or has failed, gives the type of address. When the query is complete or has failed, the ares
the ares library will invoke library will invoke \fIcallback\fP. Completion or failure of the query may
.IR callback . happen immediately, or may happen during a later call to
Completion or failure of the query may happen immediately, or may \fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP.
happen during a later call to
.BR ares_process (3)
or
.BR ares_destroy (3).
.PP .PP
The callback argument The callback argument
.I arg .I arg
@@ -93,7 +89,8 @@ did not complete successfully,
will be will be
.BR NULL . .BR NULL .
.SH SEE ALSO .SH SEE ALSO
.BR ares_process (3) .BR ares_process (3),
.BR ares_gethostbyname (3)
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

View File

@@ -87,10 +87,10 @@ static void next_lookup(struct addr_query *aquery)
{ {
case 'b': case 'b':
addr = ntohl(aquery->addr.s_addr); addr = ntohl(aquery->addr.s_addr);
a1 = (int)(addr >> 24) & 0xff; a1 = (int)((addr >> 24) & 0xff);
a2 = (int)(addr >> 16) & 0xff; a2 = (int)((addr >> 16) & 0xff);
a3 = (int)(addr >> 8) & 0xff; a3 = (int)((addr >> 8) & 0xff);
a4 = (int)addr & 0xff; a4 = (int)(addr & 0xff);
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1); sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1);
aquery->remaining_lookups = p + 1; aquery->remaining_lookups = p + 1;
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,

View File

@@ -37,14 +37,11 @@ The parameter
.I name .I name
gives the hostname as a NUL-terminated C string, and gives the hostname as a NUL-terminated C string, and
.I family .I family
gives the desired type of address for the resulting host entry. When gives the desired type of address for the resulting host entry. When the
the query is complete or has failed, the ares library will invoke query is complete or has failed, the ares library will invoke \fIcallback\fP.
.IR callback . Completion or failure of the query may happen immediately, or may happen
Completion or failure of the query may happen immediately, or may during a later call to \fIares_process(3)\fP, \fIares_destroy(3)\fP or
happen during a later call to \fIares_cancel(3)\fP.
.BR ares_process (3)
or
.BR ares_destroy (3).
.PP .PP
The callback argument The callback argument
.I arg .I arg
@@ -96,7 +93,8 @@ did not complete successfully,
will be will be
.BR NULL . .BR NULL .
.SH SEE ALSO .SH SEE ALSO
.BR ares_process (3) .BR ares_process (3),
.BR ares_gethostbyaddr (3)
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

View File

@@ -21,11 +21,9 @@ ares_mkquery \- Compose a single-question DNS query buffer
.nf .nf
.B #include <ares.h> .B #include <ares.h>
.PP .PP
.B .B int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP, .B unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
.B .B int *\fIbuflen\fP)
unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
int *\fIbuflen\fP)
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
The The
@@ -52,8 +50,7 @@ stored in the variable pointed to by
and the length of which will be stored in the variable pointed to by and the length of which will be stored in the variable pointed to by
.IR buflen . .IR buflen .
It is the caller's responsibility to free this buffer using It is the caller's responsibility to free this buffer using
.B ares_free_string \fIares_free_string(3)\fP when it is no longer needed.
when it is no longer needed.
.SH RETURN VALUES .SH RETURN VALUES
.B ares_mkquery .B ares_mkquery
can return any of the following values: can return any of the following values:

View File

@@ -21,9 +21,8 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent
.nf .nf
.B #include <ares.h> .B #include <ares.h>
.PP .PP
.B .B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, .B struct hostent **\fIhost\fP);
.B struct hostent **\fIhost\fB);
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
The The

View File

@@ -21,11 +21,9 @@ ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent
.nf .nf
.B #include <ares.h> .B #include <ares.h>
.PP .PP
.B .B int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
int ares_parse_ptr_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, .B const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
.B .B struct hostent **\fIhost\fP);
const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
.B struct hostent **\fIhost\fB);
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
The The

View File

@@ -35,13 +35,10 @@ The file descriptor sets pointed to by
and and
.I write_fds .I write_fds
should have file descriptors set in them according to whether the file should have file descriptors set in them according to whether the file
descriptors specified by descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
.BR ares_fds (3) (The easiest way to determine this information is to invoke
are ready for reading and writing. (The easiest way to determine this
information is to invoke
.B select .B select
with a timeout no greater than the timeout given by with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ).
.BR ares_timeout (3)).
.PP .PP
The The
.B ares_process .B ares_process

View File

@@ -24,8 +24,7 @@ ares_send \- Initiate a DNS query
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, .B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
.B unsigned char *\fIabuf\fP, int \fIalen\fP) .B unsigned char *\fIabuf\fP, int \fIalen\fP)
.PP .PP
.B .B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP) .B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION

View File

@@ -35,7 +35,9 @@ const char *ares_strerror(int code)
"Timeout while contacting DNS servers", "Timeout while contacting DNS servers",
"End of file", "End of file",
"Error reading file", "Error reading file",
"Out of memory" "Out of memory",
"Channel is being destroyed",
"Misformatted string"
}; };
assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext))); assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext)));

View File

@@ -27,10 +27,8 @@ ares_fds \- Get file descriptors to select on for name service
.SH DESCRIPTION .SH DESCRIPTION
The The
.B ares_timeout .B ares_timeout
function determines the maximum time for which the caller should wait function determines the maximum time for which the caller should wait before
before invoking invoking \fIares_process(3)\fP to process timeouts. The parameter
.BR ares_process (3)
to process timeouts. The parameter
.I maxtv .I maxtv
specifies a existing maximum timeout, or specifies a existing maximum timeout, or
.B NULL .B NULL

View File

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

4
ares/buildconf Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
aclocal
autoconf

View File

@@ -96,3 +96,5 @@ for(@entries) {
`gzip -9 $name-$version.tar`; `gzip -9 $name-$version.tar`;
# remove the dir # remove the dir
`rm -rf $name-$version`; `rm -rf $name-$version`;
print "NOTE: now cvs tag this release!\n";

Binary file not shown.

Binary file not shown.

View File

@@ -1,69 +0,0 @@
$!
$
$ on control_y then goto Common_Exit!
$ orig = f$environment("DEFAULT")
$ loc = f$environment("PROCEDURE")
$ def = f$parse("X.X;1",loc) - "X.X;1"
$
$ set def 'def'
$ cc_qual = "/define=HAVE_CONFIG_H=1/include=(""../include/"",""../"",""../../openssl-0_9_7/include/"")"
$ if p1 .eqs. "LISTING" then cc_qual = cc_qual + "/LIST/MACHINE"
$ if p1 .eqs. "DEBUG" then cc_qual = cc_qual + "/LIST/MACHINE/DEBUG"
$ msg_qual = ""
$ call build "[.lib]" "*.c"
$ call build "[.src]" "*.c"
$ call build "[.src]" "*.msg"
$ link /exe=curl.exe [.src]curl/lib/include=main,[.lib]curl/lib, -
[-.openssl-0_9_7.axp.exe.ssl]libssl/lib, -
[-.openssl-0_9_7.axp.exe.crypto]libcrypto/lib
$
$
$ goto Common_Exit
$build: subroutine
$ set noon
$ set default 'p1'
$ search = p2
$ reset = f$search("reset")
$ if f$search("CURL.OLB") .eqs. ""
$ then
$ LIB/CREATE/OBJECT CURL.OLB
$ endif
$ reset = f$search("reset",1)
$Loop:
$ file = f$search(search,1)
$ if file .eqs. "" then goto EndLoop
$ obj = f$search(f$parse(".OBJ;",file),2)
$ if (obj .nes. "")
$ then
$ if (f$cvtime(f$file(file,"rdt")) .gts. f$cvtime(f$file(obj,"rdt")))
$ then
$ call compile 'file'
$ lib/object curl.OLB 'f$parse(".obj;",file)'
$ else
$! write sys$output "File: ''file' is up to date"
$ endif
$ else
$! write sys$output "Object for file: ''file' does not exist"
$ call compile 'file'
$ lib/object curl.OLB 'f$parse(".obj;",file)'
$ endif
$ goto Loop
$EndLoop:
$ purge
$ set def 'def'
$ endsubroutine ! Build
$
$compile: subroutine
$ set noon
$ file = p1
$ qual = p2+p3+p4+p5+p6+p7+p8
$ typ = f$parse(file,,,"TYPE") - "."
$ cmd_c = "CC "+cc_qual
$ cmd_msg = "MESSAGE "+msg_qual
$ x = cmd_'typ'
$ 'x' 'file'
$ ENDSUBROUTINE ! Compile
$
$Common_Exit:
$ set default 'orig'
$ exit

View File

@@ -67,7 +67,7 @@ echo "buildconf: autoheader version $ah_version (ok)"
# automake 1.7 or newer # automake 1.7 or newer
# #
need_automake="1.7" need_automake="1.7"
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'` am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
if test -z "$am_version"; then if test -z "$am_version"; then
echo "buildconf: automake not found." echo "buildconf: automake not found."
echo " You need automake version $need_automake or newer installed." echo " You need automake version $need_automake or newer installed."
@@ -138,6 +138,20 @@ fi
echo "buildconf: libtool version $lt_version (ok)" echo "buildconf: libtool version $lt_version (ok)"
#--------------------------------------------------------------------------
# m4 check
#
m4=`${M4:-m4} --version 2>/dev/null|head -1`;
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
echo "buildconf: GNU m4 version $m4_version (ok)"
else
echo "buildconf: m4 version $m4 found. You need a GNU m4 installed!"
exit 1
fi
# ------------------------------------------------------------ # ------------------------------------------------------------
# run the correct scripts now # run the correct scripts now
@@ -145,7 +159,7 @@ echo "buildconf: libtool version $lt_version (ok)"
echo "buildconf: running libtoolize" echo "buildconf: running libtoolize"
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed" ${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
echo "buildconf: running aclocal" echo "buildconf: running aclocal"
${ACLOCAL:-aclocal} || die "The command '${AUTOHEADER:-aclocal}' failed" ${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
echo "buildconf: running aclocal hack to convert all mv to mv -f" echo "buildconf: running aclocal hack to convert all mv to mv -f"
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
echo "buildconf: running autoheader" echo "buildconf: running autoheader"
@@ -156,7 +170,7 @@ ${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
if test -d ares; then if test -d ares; then
cd ares cd ares
echo "buildconf: running aclocal in the ares directory" echo "buildconf: running aclocal in the ares directory"
${ACLOCAL:-aclocal} || die "The command '${ACLOCAL:-aclocal}' failed" ${ACLOCAL:-aclocal} $ACLOCAL_FLAGS || die "The command '${ACLOCAL:-aclocal}${ACLOCAL_FLAGS:+" $ACLOCAL_FLAGS"}' failed"
echo "buildconf: running autoconf in the ares directory" echo "buildconf: running autoconf in the ares directory"
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed" ${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
cd .. cd ..

View File

@@ -24,14 +24,14 @@ AC_PATH_PROG( AR, ar, , $PATH:/usr/bin:/usr/local/bin:/usr/ccs/bin)
AC_SUBST(AR) AC_SUBST(AR)
dnl figure out the libcurl version dnl figure out the libcurl version
VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curl.h` VERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
AM_INIT_AUTOMAKE(curl,$VERSION) AM_INIT_AUTOMAKE(curl,$VERSION)
AC_MSG_CHECKING([curl version]) AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($VERSION) AC_MSG_RESULT($VERSION)
dnl dnl
dnl we extract the numerical version for curl-config only dnl we extract the numerical version for curl-config only
VERSIONNUM=`$SED -ne 's/^#define LIBCURL_VERSION_NUM 0x\(.*\)/\1/p' ${srcdir}/include/curl/curl.h` VERSIONNUM=`$SED -ne 's/^#define LIBCURL_VERSION_NUM 0x\(.*\)/\1/p' ${srcdir}/include/curl/curlver.h`
AC_SUBST(VERSIONNUM) AC_SUBST(VERSIONNUM)
dnl Solaris pkgadd support definitions dnl Solaris pkgadd support definitions
@@ -384,6 +384,8 @@ main()
if test "$ipv6" = "yes"; then if test "$ipv6" = "yes"; then
CURL_CHECK_WORKING_GETADDRINFO CURL_CHECK_WORKING_GETADDRINFO
CURL_CHECK_NI_WITHSCOPEID
fi fi
dnl ********************************************************************** dnl **********************************************************************
@@ -490,8 +492,8 @@ AC_HELP_STRING([--with-krb4=DIR],[where to look for Kerberos4]),[
OPT_KRB4="$withval" OPT_KRB4="$withval"
if test X"$OPT_KRB4" != Xyes if test X"$OPT_KRB4" != Xyes
then then
LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib" LDFLAGS="$LDFLAGS -L$OPT_KRB4/lib$libsuff"
KRB4LIB="$OPT_KRB4/lib" KRB4LIB="$OPT_KRB4/lib$libsuff"
CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include" CPPFLAGS="$CPPFLAGS -I$OPT_KRB4/include"
KRB4INC="$OPT_KRB4/include" KRB4INC="$OPT_KRB4/include"
fi fi
@@ -627,7 +629,7 @@ if test x"$want_gss" = xyes; then
gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi` gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
LDFLAGS="$LDFLAGS $gss_ldflags" LDFLAGS="$LDFLAGS $gss_ldflags"
else else
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib -lgssapi" LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff -lgssapi"
fi fi
else else
LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR" LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
@@ -693,7 +695,7 @@ AC_HELP_STRING([--without-ssl], [disable SSL]),
if test X"$OPT_SSL" = Xno if test X"$OPT_SSL" = Xno
then then
AC_MSG_WARN(SSL/https support disabled) AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more])
else else
dnl Check for and handle argument to --with-ssl. dnl Check for and handle argument to --with-ssl.
@@ -710,7 +712,7 @@ else
*) *)
dnl check the given spot right away! dnl check the given spot right away!
EXTRA_SSL=$OPT_SSL EXTRA_SSL=$OPT_SSL
LDFLAGS="$LDFLAGS -L$EXTRA_SSL/lib" LDFLAGS="$LDFLAGS -L$EXTRA_SSL/lib$libsuff"
CPPFLAGS="$CPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include" CPPFLAGS="$CPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
;; ;;
esac esac
@@ -720,7 +722,7 @@ else
],[ ],[
OLDLDFLAGS="$LDFLAGS" OLDLDFLAGS="$LDFLAGS"
OLDCPPFLAGS="$CPPFLAGS" OLDCPPFLAGS="$CPPFLAGS"
LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib" LDFLAGS="$CLEANLDFLAGS -L$EXTRA_SSL/lib$libsuff"
CPPFLAGS="$CLEANCPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include" CPPFLAGS="$CLEANCPPFLAGS -I$EXTRA_SSL/include/openssl -I$EXTRA_SSL/include"
AC_CHECK_LIB(crypto, CRYPTO_add_lock,[ AC_CHECK_LIB(crypto, CRYPTO_add_lock,[
HAVECRYPTO="yes" ], [ HAVECRYPTO="yes" ], [
@@ -852,7 +854,7 @@ case "$OPT_ZLIB" in
dnl if no lib found, try to add the given library dnl if no lib found, try to add the given library
[if test -d "$OPT_ZLIB"; then [if test -d "$OPT_ZLIB"; then
CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include" CPPFLAGS="$CPPFLAGS -I$OPT_ZLIB/include"
LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib" LDFLAGS="$LDFLAGS -L$OPT_ZLIB/lib$libsuff"
fi]) fi])
AC_CHECK_HEADER(zlib.h, AC_CHECK_HEADER(zlib.h,
@@ -915,6 +917,7 @@ printf("just fine");
#endif #endif
], ],
[ AC_MSG_RESULT([yes]) [ AC_MSG_RESULT([yes])
RECENTAIX=yes
OPT_THREAD=off ], OPT_THREAD=off ],
[ AC_MSG_RESULT([no]) ] [ AC_MSG_RESULT([no]) ]
) )
@@ -952,10 +955,31 @@ else
dnl is there a localtime_r() dnl is there a localtime_r()
CURL_CHECK_LOCALTIME_R() CURL_CHECK_LOCALTIME_R()
AC_CHECK_FUNCS( gmtime_r ) dnl is there a strerror_r()
CURL_CHECK_STRERROR_R()
AC_CHECK_FUNCS( gmtime_r )
fi fi
dnl for recent AIX versions, we skip all the thread-safe checks above since
dnl they claim a thread-safe libc using the standard API. But there are
dnl some functions still not thread-safe. Check for these!
dnl Let's hope this split URL remains working:
dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
dnl genprogc/thread_quick_ref.htm
if test "x$RECENTAIX" = "xyes"; then
dnl is there a localtime_r()
CURL_CHECK_LOCALTIME_R()
dnl is there a strerror_r()
CURL_CHECK_STRERROR_R()
AC_CHECK_FUNCS( gmtime_r )
fi
dnl ********************************************************************** dnl **********************************************************************
dnl Back to "normal" configuring dnl Back to "normal" configuring
dnl ********************************************************************** dnl **********************************************************************
@@ -979,6 +1003,7 @@ AC_CHECK_HEADERS(
arpa/inet.h \ arpa/inet.h \
net/if.h \ net/if.h \
netinet/in.h \ netinet/in.h \
netinet/tcp.h \
netdb.h \ netdb.h \
sys/sockio.h \ sys/sockio.h \
sys/stat.h \ sys/stat.h \
@@ -1015,6 +1040,9 @@ dnl default includes
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
] ]
) )
@@ -1226,6 +1254,7 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
dnl ares so it should not be a problem. dnl ares so it should not be a problem.
if test "x$enableval" = "xyes" ; then if test "x$enableval" = "xyes" ; then
if test -d "$srcdir/ares"; then if test -d "$srcdir/ares"; then
aresembedded="yes"
AC_CONFIG_SUBDIRS(ares) AC_CONFIG_SUBDIRS(ares)
aresinc=`cd $srcdir/ares && pwd` aresinc=`cd $srcdir/ares && pwd`
CPPFLAGS="$CPPFLAGS -I$aresinc" CPPFLAGS="$CPPFLAGS -I$aresinc"
@@ -1240,6 +1269,31 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
CPPFLAGS="$CPPFLAGS -I$enableval/include" CPPFLAGS="$CPPFLAGS -I$enableval/include"
LDFLAGS="$LDFLAGS -L$enableval/lib" LDFLAGS="$LDFLAGS -L$enableval/lib"
fi fi
if test -z "$aresembedded"; then
dnl verify that a sufficient c-ares is here if we have pointed one
dnl out and don't use the "embedded" ares dir (in which case we don't
dnl check it because it might not have been built yet)
AC_MSG_CHECKING([that c-ares is good and recent enough])
AC_LINK_IFELSE( [
#include <ares.h>
/* provide a set of dummy functions in case c-ares was built with debug */
void curl_dofree() { }
void curl_sclose() { }
void curl_domalloc() { }
int main(void)
{
ares_channel channel;
ares_cancel(channel);
return 0;
}
],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no)
AC_MSG_ERROR([c-ares library defective or too old])
)
fi
;; ;;
esac ], esac ],
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
@@ -1268,6 +1322,7 @@ AC_CONFIG_FILES([Makefile \
packages/DOS/Makefile \ packages/DOS/Makefile \
packages/EPM/curl.list \ packages/EPM/curl.list \
packages/EPM/Makefile \ packages/EPM/Makefile \
packages/vms/Makefile \
curl-config curl-config
]) ])
AC_OUTPUT AC_OUTPUT

View File

@@ -2,17 +2,8 @@
;;;; $Id$ ;;;; $Id$
;;; The curl hacker's C conventions. ;;; The curl hacker's C conventions.
;;; See the sample.emacs file on how this file can be made to take
;;; After loading this file and added the mode-hook you can in C ;;; effect automatically when editing curl source files.
;;; files, put something like this to use the curl style
;;; automatically:
;;
;; /* -----------------------------------------------------------------
;; * local variables:
;; * eval: (set c-file-style "curl")
;; * end:
;; */
;;
(defconst curl-c-style (defconst curl-c-style
'((c-basic-offset . 2) '((c-basic-offset . 2)
@@ -37,7 +28,7 @@
(setq tab-width 8 (setq tab-width 8
indent-tabs-mode nil ; Use spaces. Not tabs. indent-tabs-mode nil ; Use spaces. Not tabs.
comment-column 40 comment-column 40
c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t" "curl_off_t" "curl_socket_t")) c-font-lock-extra-types (append '("bool" "CURL" "CURLcode" "ssize_t" "size_t" "socklen_t" "fd_set" "time_t" "curl_off_t" "curl_socket_t" "in_addr_t" "CURLSHcode" "CURLMcode"))
) )
;; keybindings for C, C++, and Objective-C. We can put these in ;; keybindings for C, C++, and Objective-C. We can put these in
;; c-mode-base-map because of inheritance ... ;; c-mode-base-map because of inheritance ...

View File

@@ -1,4 +1,4 @@
Updated: December 22, 2003 (http://curl.haxx.se/docs/faq.html) Updated: March 16, 2004 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
@@ -90,7 +90,7 @@ FAQ
with URL spelled in uppercase to make it obvious it deals with URLs. The with URL spelled in uppercase to make it obvious it deals with URLs. The
fact it can also be pronounced 'see URL' also helped, it works as an fact it can also be pronounced 'see URL' also helped, it works as an
abbrivation for "Client URL Request Library" or why not the recursive abbrivation for "Client URL Request Library" or why not the recursive
version: "Curl is a URL Request Library". version: "Curl URL Request Library".
Curl supports a range of common Internet protocols, currently including Curl supports a range of common Internet protocols, currently including
HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE. HTTP, HTTPS, FTP, FTPS, GOPHER, LDAP, DICT, TELNET and FILE.
@@ -101,7 +101,7 @@ FAQ
NOTE: there are numerous sub-projects and related projects that also use the NOTE: there are numerous sub-projects and related projects that also use the
word curl in the project names in various combinations, but you should take word curl in the project names in various combinations, but you should take
notice that this FAQ is directed at the command-line tool named curl (and notice that this FAQ is directed at the command-line tool named curl (and
libcurl the library), and may therefore not be valid for other curl libcurl the library), and may therefore not be valid for other curl-related
projects. projects.
1.2 What is libcurl? 1.2 What is libcurl?
@@ -109,16 +109,16 @@ FAQ
libcurl is a reliable and portable library which provides you with an easy libcurl is a reliable and portable library which provides you with an easy
interface to a range of common Internet protocols. interface to a range of common Internet protocols.
You can use libcurl for free in your application even if it is commercial You can use libcurl for free in your application, be it open source,
or closed-source. commercial or closed-source.
1.3 What is cURL not? 1.3 What is cURL not?
Curl is *not* a wget clone even though that is a very common misconception. Curl is *not* a wget clone. That is a common misconception. Never, during
Never, during curl's development, have we intended curl to replace wget or curl's development, have we intended curl to replace wget or compete on its
compete on its market. Curl is targeted at single-shot file transfers. market. Curl is targeted at single-shot file transfers.
Curl is not a web site mirroring program. If you wanna use curl to mirror Curl is not a web site mirroring program. If you want to use curl to mirror
something: fine, go ahead and write a script that wraps around curl to make something: fine, go ahead and write a script that wraps around curl to make
it reality (like curlmirror.pl does). it reality (like curlmirror.pl does).
@@ -181,9 +181,8 @@ FAQ
curl. We do this voluntarily on our spare time. curl. We do this voluntarily on our spare time.
We get some help from companies. Contactor Data hosts the curl web site, We get some help from companies. Contactor Data hosts the curl web site,
Haxx owns the curl web site's domain and sourceforge.net hosts several Haxx owns the curl web site's domain and sourceforge.net hosts project
project services we take advantage from, like the bug tracker, mailing lists services we take advantage from, like the bug tracker.
and more.
If you want to support our project with a donation or similar, one way of If you want to support our project with a donation or similar, one way of
doing that would be to buy "gift certificates" at useful online shopping doing that would be to buy "gift certificates" at useful online shopping
@@ -281,8 +280,7 @@ FAQ
2.4. Does cURL support Socks (RFC 1928) ? 2.4. Does cURL support Socks (RFC 1928) ?
There is limited support for SOCKS5 for curl built with IPv6 support Yes, SOCKS5 is supported when curl is built with IPv6 support disabled.
disabled.
3. Usage problems 3. Usage problems
@@ -478,7 +476,7 @@ FAQ
requests properly. To correct this problem, tell curl to select SSLv2 from requests properly. To correct this problem, tell curl to select SSLv2 from
the command line (-2/--sslv2). the command line (-2/--sslv2).
There has also been examples where the remote server didn't like the SSLv2 There have also been examples where the remote server didn't like the SSLv2
request and instead you had to force curl to use SSLv3 with -3/--sslv3. request and instead you had to force curl to use SSLv3 with -3/--sslv3.
4.2. Why do I get problems when I use & or % in the URL? 4.2. Why do I get problems when I use & or % in the URL?
@@ -577,21 +575,26 @@ FAQ
The first part is to avoid having clear-text passwords in the command line The first part is to avoid having clear-text passwords in the command line
so that they don't appear in 'ps' outputs and similar. That is easily so that they don't appear in 'ps' outputs and similar. That is easily
avoided by using the "-K" option to tell curl to read parameters from a avoided by using the "-K" option to tell curl to read parameters from a file
file or stdin to which you can pass the secret info. or stdin to which you can pass the secret info. curl itself will also
attempt to "hide" the given password by blanking out the option - this
doesn't work on all platforms.
To keep the passwords in your account secret from the rest of the world is To keep the passwords in your account secret from the rest of the world is
not a task that curl addresses. You could of course encrypt them somehow to not a task that curl addresses. You could of course encrypt them somehow to
at least hide them from being read by human eyes, but that is not what at least hide them from being read by human eyes, but that is not what
anyone would call security. anyone would call security.
Also note that regular HTTP and FTP passwords are sent in clear across the Also note that regular HTTP (using Basic authentication) and FTP passwords
network. All it takes for anyone to fetch them is to listen on the network. are sent in clear across the network. All it takes for anyone to fetch them
Eavesdropping is very easy. is to listen on the network. Eavesdropping is very easy. Use more secure
authentication methods (like Digest, Negotiate or even NTLM) or consider the
SSL-based alternatives HTTPS and FTPS.
4.8 I found a bug! 4.8 I found a bug!
It is not a bug if the behavior is documented. Read the docs first. It is not a bug if the behavior is documented. Read the docs first.
Especially check out the KNOWN_BUGS file, it may be a documented bug!
If it is a problem with a binary you've downloaded or a package for your If it is a problem with a binary you've downloaded or a package for your
particular platform, try contacting the person who built the package/archive particular platform, try contacting the person who built the package/archive

View File

@@ -511,6 +511,7 @@ PORTS
- i386 HURD - i386 HURD
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4 - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4
- i386 NetBSD - i386 NetBSD
- i386 Novell NetWare
- i386 OS/2 - i386 OS/2
- i386 OpenBSD - i386 OpenBSD
- i386 SCO unix - i386 SCO unix

View File

@@ -3,6 +3,10 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems 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!
* --limit-rate using -d or -F does not work. This is because the limit logic
is provided by the curl app in its read/write callbacks, and when doing
-d/-F the callbacks aren't used!
* Doing resumed upload over HTTP does not work with '-C -', because curl * Doing resumed upload over HTTP does not work with '-C -', because curl
doesn't do a HEAD first to get the initial size. This needs to be done doesn't do a HEAD first to get the initial size. This needs to be done
manually for HTTP PUT resume to work, and then '-C [index]'. manually for HTTP PUT resume to work, and then '-C [index]'.
@@ -19,13 +23,6 @@ may have been fixed since this was written!
indicate that the user wants to reach the root dir (this exception SHALL indicate that the user wants to reach the root dir (this exception SHALL
remain even when this bug is fixed). remain even when this bug is fixed).
* 1) libcurl does a POST
2) receives a 100-continue
3) sends away the POST
Now, if nothing else is returned from the server, libcurl MUST return
CURLE_GOT_NOTHING, but it seems it returns CURLE_OK as it seems to count
the 100-continue reply as a good enough reply.
* libcurl doesn't treat the content-length of compressed data properly, as * libcurl doesn't treat the content-length of compressed data properly, as
it seems HTTP servers send the *uncompressed* length in that header and it seems HTTP servers send the *uncompressed* length in that header and
libcurl thinks of it as the *compressed* lenght. Some explanations are here: libcurl thinks of it as the *compressed* lenght. Some explanations are here:
@@ -35,9 +32,6 @@ may have been fixed since this was written!
locally, which is because libcurl doesn't call the write callback with zero locally, which is because libcurl doesn't call the write callback with zero
bytes. Explained here: http://curl.haxx.se/mail/archive-2003-04/0143.html bytes. Explained here: http://curl.haxx.se/mail/archive-2003-04/0143.html
* Using CURLOPT_FAILONERROR (-f/--fail) will make authentication to stop
working if you use anything but plain Basic auth.
* IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage * IPv6 support on AIX 4.3.3 doesn't work due to a missing sockaddr_storage
struct. It has been reported to work on AIX 5.1 though. struct. It has been reported to work on AIX 5.1 though.

View File

@@ -63,6 +63,11 @@ USING PASSWORDS
curl -u name:passwd ftp://machine.domain:port/full/path/to/file curl -u name:passwd ftp://machine.domain:port/full/path/to/file
FTPS
It is just like for FTP, but you may also want to specify and use
SSL-specific options for certificates etc.
HTTP 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
@@ -75,6 +80,12 @@ USING PASSWORDS
curl -u name:passwd http://machine.domain/full/path/to/file curl -u name:passwd http://machine.domain/full/path/to/file
HTTP offers many different methods of authentication and curl supports
several: Basic, Digest, NTLM and Negotiate. Without telling which method to
use, curl defaults to Basic. You can also ask curl to pick the most secure
ones out of the ones that the server accepts for the given URL, by using
--anyauth.
NOTE! Since HTTP URLs don't support user and password, you can't use that NOTE! Since HTTP URLs don't support user and password, you can't use that
style when using Curl via a proxy. You _must_ use the -u style fetch style when using Curl via a proxy. You _must_ use the -u style fetch
during such circumstances. during such circumstances.

View File

@@ -1,7 +1,7 @@
Peer SSL Certificate Verification Peer SSL Certificate Verification
================================= =================================
Starting in 7.10, libcurl performs peer SSL certificate verification by Since version 7.10, libcurl performs peer SSL certificate verification by
default. This is done by installing a default CA cert bundle on 'make install' default. This is done by installing a default CA cert bundle on 'make install'
(or similar), that CA bundle package is used by default on operations against (or similar), that CA bundle package is used by default on operations against
SSL servers. SSL servers.
@@ -11,9 +11,11 @@ by CAs present in the bundle, you will not notice any changed behavior and you
will seamlessly get a higher security level on your SSL connections since you will seamlessly get a higher security level on your SSL connections since you
can be sure that the remote server really is the one it claims to be. can be sure that the remote server really is the one it claims to be.
If the remote server uses a self-signed certificate, or if you don't install If the remote server uses a self-signed certificate, if you don't install
curl's CA cert bundle or if it uses a certificate signed by a CA that isn't curl's CA cert bundle, if the server uses a certificate signed by a CA that
included in the bundle, then you need to do one of the following: isn't included in the bundle or if the remoste host is an imposter
impersonating your favourite site, and you want to transfer files from this
server, do one of the following:
1. Tell libcurl to *not* verify the peer. With libcurl you disable with with 1. Tell libcurl to *not* verify the peer. With libcurl you disable with with
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
@@ -26,6 +28,12 @@ included in the bundle, then you need to do one of the following:
With the curl command tool: --cacert [file] With the curl command tool: --cacert [file]
3. Add the CA cert for your server to the existing default CA cert bundle.
The default path of the CA bundle installed with the curl package is:
/usr/local/share/curl/curl-ca-bundle.crt, which can be changed by running
configure with the --with-ca-bundle option pointing out the path of your
choice.
Neglecting to use one of the above menthods when dealing with a server using a Neglecting to use one of the above menthods when dealing with a server using a
certficate that isn't signed by one of the certficates in the installed CA certficate that isn't signed by one of the certficates in the installed CA
cert bundle, will cause SSL to report an error ("certificate verify failed") cert bundle, will cause SSL to report an error ("certificate verify failed")
@@ -37,3 +45,4 @@ trouble for some users, since it adds security to a majority of the SSL
connections that previously weren't really secure. It turned out many people connections that previously weren't really secure. It turned out many people
were using previous versions of curl/libcurl without realizing the need for were using previous versions of curl/libcurl without realizing the need for
the CA cert options to get truly secure SSL connections. the CA cert options to get truly secure SSL connections.

View File

@@ -57,6 +57,13 @@ TODO
FTP FTP
* Optimize the way libcurl uses CWD on each new request over a persistent
connection (on FTP) even if it doesn't have to.
* REST fix for servers not behaving well on >2GB requests. This should fail
if the server doesn't set the pointer to the requested index. The tricky
part is to figure out if the server did the right thing or not.
* Support the most common FTP proxies, Philip Newton provided a list * Support the most common FTP proxies, Philip Newton provided a list
allegedly from ncftp: allegedly from ncftp:
http://curl.haxx.se/mail/archive-2003-04/0126.html http://curl.haxx.se/mail/archive-2003-04/0126.html
@@ -91,6 +98,15 @@ TODO
SSL SSL
* Anton Fedorov's "dumpcert" patch:
http://curl.haxx.se/mail/lib-2004-03/0088.html
* Evaluate/apply Gertjan van Wingerde's SSL patches:
http://curl.haxx.se/mail/lib-2004-03/0087.html
* Peter Sylvester's "Most Significant Common Name" change. Feedback welcome.
At least the UTF8 conversion and comparison should be done. Patch?
* If you really want to improve the SSL situation, you should probably have a * If you really want to improve the SSL situation, you should probably have a
look at SSL cafile loading as well - quick traces look to me like these are look at SSL cafile loading as well - quick traces look to me like these are
done on every request as well, when they should only be necessary once per done on every request as well, when they should only be necessary once per

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1 .\" nroff -man curl.1
.\" Written by Daniel Stenberg .\" Written by Daniel Stenberg
.\" .\"
.TH curl 1 "5 Mar 2004" "Curl 7.11.1" "Curl Manual" .TH curl 1 "25 Mar 2004" "Curl 7.11.2" "Curl Manual"
.SH NAME .SH NAME
curl \- transfer a URL curl \- transfer a URL
.SH SYNOPSIS .SH SYNOPSIS
@@ -707,6 +707,11 @@ is a plain '-', it is instead written to stdout. This option has no point when
you're using a shell with decent redirecting capabilities. you're using a shell with decent redirecting capabilities.
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 "--tcp-nodelay"
Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
details about this option. (Added in 7.11.2)
If this option is used several times, each occurance toggles this on/off.
.IP "-t/--telnet-option <OPT=val>" .IP "-t/--telnet-option <OPT=val>"
Pass options to the telnet protocol. Supported options are: Pass options to the telnet protocol. Supported options are:

View File

@@ -70,6 +70,8 @@ int main(int argc, char **argv)
switch(rc) { switch(rc) {
case -1: case -1:
/* select error */ /* select error */
still_running = 0;
printf("select() returns error, this is badness\n");
break; break;
case 0: case 0:
default: default:

View File

@@ -33,8 +33,8 @@ int main(int argc, char *argv[])
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct HttpPost *formpost=NULL; struct curl_httppost *formpost=NULL;
struct HttpPost *lastptr=NULL; struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL; struct curl_slist *headerlist=NULL;
char buf[] = "Expect:"; char buf[] = "Expect:";

View File

@@ -31,5 +31,4 @@ If this function returns NULL, something went wrong and no valid handle was
returned. returned.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3) .BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
.SH BUGS
Surely there are some, you tell me!

View File

@@ -20,7 +20,7 @@ filled in accordingly and can be relied upon only if the function returns
CURLE_OK. This function is intended to get used *AFTER* a performed transfer, CURLE_OK. This function is intended to get used *AFTER* a performed transfer,
all results from this function are undefined until the transfer is completed. all results from this function are undefined until the transfer is completed.
.SH AVAILABLE INFORMATION .SH AVAILABLE INFORMATION
These are informations that can be extracted: The following information can be extracted:
.IP CURLINFO_EFFECTIVE_URL .IP CURLINFO_EFFECTIVE_URL
Pass a pointer to a 'char *' to receive the last used effective URL. Pass a pointer to a 'char *' to receive the last used effective URL.
.IP CURLINFO_RESPONSE_CODE .IP CURLINFO_RESPONSE_CODE
@@ -51,7 +51,7 @@ pre-transfer commands and negotiations that are specific to the particular
protocol(s) involved. protocol(s) involved.
.IP CURLINFO_STARTTRANSFER_TIME .IP CURLINFO_STARTTRANSFER_TIME
Pass a pointer to a double to receive the time, in seconds, it took from the Pass a pointer to a double to receive the time, in seconds, it took from the
start until the first byte is just about to be transfered. This includes start until the first byte is just about to be transferred. This includes
CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate
the result. the result.
.IP CURLINFO_REDIRECT_TIME .IP CURLINFO_REDIRECT_TIME
@@ -106,7 +106,7 @@ method(s) available. The meaning of the bits is explained in the
CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8) CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8)
.IP CURLINFO_PROXYAUTH_AVAIL .IP CURLINFO_PROXYAUTH_AVAIL
Pass a pointer to a long to receive a bitmask indicating the authentication Pass a pointer to a long to receive a bitmask indicating the authentication
method(s) available for your proxy athentication. (Added in 7.10.8) method(s) available for your proxy authentication. (Added in 7.10.8)
.SH RETURN VALUE .SH RETURN VALUE
If the operation was successful, CURLE_OK is returned. Otherwise an If the operation was successful, CURLE_OK is returned. Otherwise an
appropriate error code will be returned. appropriate error code will be returned.

View File

@@ -13,7 +13,7 @@ curl_easy_init - Start a libcurl easy session
.SH DESCRIPTION .SH DESCRIPTION
This function must be the first function to call, and it returns a CURL easy This function must be the first function to call, and it returns a CURL easy
handle that you must use as input to other easy-functions. curl_easy_init handle that you must use as input to other easy-functions. curl_easy_init
intializes curl and this call \fBMUST\fP have a corresponding call to initializes curl and this call \fBMUST\fP have a corresponding call to
\fIcurl_easy_cleanup(3)\fP when the operation is complete. \fIcurl_easy_cleanup(3)\fP when the operation is complete.
.SH RETURN VALUE .SH RETURN VALUE
@@ -21,5 +21,3 @@ If this function returns NULL, something went wrong and you cannot use the
other curl functions. other curl functions.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_easy_cleanup "(3), " curl_global_init "(3) .BR curl_easy_cleanup "(3), " curl_global_init "(3)
.SH BUGS
Surely there are some, you tell me!

View File

@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl_easy_setopt 3 "27 Feb 2004" "libcurl 7.11.1" "libcurl Manual" .TH curl_easy_setopt 3 "12 Mar 2004" "libcurl 7.11.1" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_setopt - set options for a curl easy handle curl_easy_setopt - set options for a curl easy handle
.SH SYNOPSIS .SH SYNOPSIS
@@ -85,7 +85,7 @@ lookups. It enables nice timeouts for name resolves without signals.
.IP CURLOPT_WRITEFUNCTION .IP CURLOPT_WRITEFUNCTION
Function pointer that should match the following prototype: \fBsize_t Function pointer that should match the following prototype: \fBsize_t
function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This function( void *ptr, size_t size, size_t nmemb, void *stream);\fP This
function gets called by libcurl as soon as there is data reveiced that needs function gets called by libcurl as soon as there is data received that needs
to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP
multiplied with \fInmemb\fP, it will not be zero terminated. Return the number multiplied with \fInmemb\fP, it will not be zero terminated. Return the number
of bytes actually taken care of. If that amount differs from the amount passed of bytes actually taken care of. If that amount differs from the amount passed
@@ -165,7 +165,7 @@ Function pointer that should match the following prototype: \fIint
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when \fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
\fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information, \fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information,
as specified with the \fBcurl_infotype\fP argument. This funtion must return as specified with the \fBcurl_infotype\fP argument. This function must return
0. The data pointed to by the char * passed to this function WILL NOT be zero 0. The data pointed to by the char * passed to this function WILL NOT be zero
terminated, but will be exactly of the size as told by the size_t argument. terminated, but will be exactly of the size as told by the size_t argument.
@@ -191,7 +191,7 @@ Function pointer that should match the following prototype: \fBCURLcode
sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function gets called
by libcurl just before the initialization of an SSL connection after having by libcurl just before the initialization of an SSL connection after having
processed all other SSL related options to give a last chance to an processed all other SSL related options to give a last chance to an
application to modify the behaviour of openssl's ssl initilaization. The application to modify the behaviour of openssl's ssl initialization. The
\fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If \fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If
an error is returned no attempt to establish a connection is made and the an error is returned no attempt to establish a connection is made and the
perform operation will return the error code from this callback function. Set perform operation will return the error code from this callback function. Set
@@ -249,8 +249,8 @@ be prefixed with [protocol]:// since any such prefix will be ignored. The
proxy's port number may optionally be specified with the separate option proxy's port number may optionally be specified with the separate option
\fICURLOPT_PROXYPORT\fP. \fICURLOPT_PROXYPORT\fP.
\fBNOTE:\fP when you tell the library to use a HTTP proxy, libcurl will \fBNOTE:\fP when you tell the library to use an HTTP proxy, libcurl will
transparently convert operations to HTTP even if you specify a FTP URL transparently convert operations to HTTP even if you specify an FTP URL
etc. This may have an impact on what other features of the library you can etc. This may have an impact on what other features of the library you can
use, such as \fICURLOPT_QUOTE\fP and similar FTP specifics that don't work use, such as \fICURLOPT_QUOTE\fP and similar FTP specifics that don't work
unless you tunnel through the HTTP proxy. Such tunneling is activated with unless you tunnel through the HTTP proxy. Such tunneling is activated with
@@ -282,19 +282,35 @@ libcurl caches this info for 60 seconds.
.IP CURLOPT_DNS_USE_GLOBAL_CACHE .IP CURLOPT_DNS_USE_GLOBAL_CACHE
Pass a long. If the value is non-zero, it tells curl to use a global DNS cache Pass a long. If the value is non-zero, it tells curl to use a global DNS cache
that will survive between easy handle creations and deletions. This is not that will survive between easy handle creations and deletions. This is not
thread-safe and this will use a global varible. thread-safe and this will use a global variable.
\fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over \fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over
to using the share interface instead! See \fICURLOPT_SHARE\fP and to using the share interface instead! See \fICURLOPT_SHARE\fP and
\fIcurl_share_init(3)\fP. \fIcurl_share_init(3)\fP.
.IP CURLOPT_BUFFERSIZE .IP CURLOPT_BUFFERSIZE
Pass a long specifying your prefered size for the receive buffer in libcurl. Pass a long specifying your preferred size for the receive buffer in libcurl.
The main point of this would be that the write callback gets called more often The main point of this would be that the write callback gets called more often
and with smaller chunks. This is just treated as a request, not an order. You and with smaller chunks. This is just treated as a request, not an order. You
cannot be guaranteed to actually get the given size. (Added in 7.10) cannot be guaranteed to actually get the given size. (Added in 7.10)
.IP CURLOPT_PORT .IP CURLOPT_PORT
Pass a long specifying what remote port number to connect to, instead of the Pass a long specifying what remote port number to connect to, instead of the
one specified in the URL or the default port for the used protocol. one specified in the URL or the default port for the used protocol.
.IP CURLOPT_TCP_NODELAY
Pass a long specifying whether the TCP_NODELAY option should be set or
cleared (1 = set, 0 = clear). The option is cleared by default. This
will have no effect after the connection has been established.
Setting this option will disable TCP's Nagle algorithm. The purpose of
this algorithm is to try to minimize the number of small packets on
the network (where "small packets" means TCP segments less than the
Maximum Segment Size (MSS) for the network).
Maximizing the amount of data sent per TCP segment is good because it
amortizes the overhead of the send. However, in some cases (most
notably telnet or rlogin) small segments may need to be sent
without delay. This is less efficient than sending larger amounts of
data at a time, and can contribute to congestion on the network if
overdone.
.SH NAMES and PASSWORDS OPTIONS (Authentication) .SH NAMES and PASSWORDS OPTIONS (Authentication)
.IP CURLOPT_NETRC .IP CURLOPT_NETRC
This parameter controls the preference of libcurl between using user names and This parameter controls the preference of libcurl between using user names and
@@ -370,7 +386,7 @@ regular old-fashioned Basic method.
.IP CURLAUTH_GSSNEGOTIATE .IP CURLAUTH_GSSNEGOTIATE
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
"Negotiate") method was designed by Microsoft and is used in their web "Negotiate") method was designed by Microsoft and is used in their web
aplications. It is primarily meant as a support for Kerberos5 authentication applications. It is primarily meant as a support for Kerberos5 authentication
but may be also used along with another authentication methods. For more but may be also used along with another authentication methods. For more
information see IETF draft draft-brezak-spnego-http-04.txt. information see IETF draft draft-brezak-spnego-http-04.txt.
@@ -379,17 +395,17 @@ this to work.
.IP CURLAUTH_NTLM .IP CURLAUTH_NTLM
HTTP NTLM authentication. A proprietary protocol invented and used by HTTP NTLM authentication. A proprietary protocol invented and used by
Microsoft. It uses a challenge-response and hash concept similar to Digest, to Microsoft. It uses a challenge-response and hash concept similar to Digest, to
prevent the password from being evesdropped. prevent the password from being eavesdropped.
\fBNOTE\fP that you need to build libcurl with SSL support for this option to \fBNOTE\fP that you need to build libcurl with SSL support for this option to
work. work.
.IP CURLAUTH_ANY .IP CURLAUTH_ANY
This is a convenience macro that sets all bits and thus makes libcurl pick any This is a convenience macro that sets all bits and thus makes libcurl pick any
it finds suitable. libcurl will automaticly select the one it finds most it finds suitable. libcurl will automatically select the one it finds most
secure. secure.
.IP CURLAUTH_ANYSAFE .IP CURLAUTH_ANYSAFE
This is a convenience macro that sets all bits except Basic and thus makes This is a convenience macro that sets all bits except Basic and thus makes
libcurl pick any it finds suitable. libcurl will automaticly select the one it libcurl pick any it finds suitable. libcurl will automatically select the one it
finds most secure. finds most secure.
.RE .RE
.IP CURLOPT_PROXYAUTH .IP CURLOPT_PROXYAUTH
@@ -405,7 +421,7 @@ this writing, only Basic and NTLM work. (Added in 7.10.7)
.SH HTTP OPTIONS .SH HTTP OPTIONS
.IP CURLOPT_AUTOREFERER .IP CURLOPT_AUTOREFERER
Pass a non-zero parameter to enable this. When enabled, libcurl will Pass a non-zero parameter to enable this. When enabled, libcurl will
automaticly set the Referer: field in requests where it follows a Location: automatically set the Referer: field in requests where it follows a Location:
redirect. redirect.
.IP CURLOPT_ENCODING .IP CURLOPT_ENCODING
Sets the contents of the Accept-Encoding: header sent in an HTTP Sets the contents of the Accept-Encoding: header sent in an HTTP
@@ -422,7 +438,7 @@ encoding done by the server is ignored. See the special file
lib/README.encoding for details. lib/README.encoding for details.
.IP CURLOPT_FOLLOWLOCATION .IP CURLOPT_FOLLOWLOCATION
A non-zero parameter tells the library to follow any Location: header that the A non-zero parameter tells the library to follow any Location: header that the
server sends as part of a HTTP header. server sends as part of an HTTP header.
\fBNOTE:\fP this means that the library will re-send the same request on the \fBNOTE:\fP this means that the library will re-send the same request on the
new location and follow new Location: headers all the way until no more such new location and follow new Location: headers all the way until no more such
@@ -447,7 +463,7 @@ one by HTML forms. See the \fICURLOPT_POSTFIELDS\fP option for how to specify
the data to post and \fICURLOPT_POSTFIELDSIZE\fP in how to set the data the data to post and \fICURLOPT_POSTFIELDSIZE\fP in how to set the data
size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option. size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option.
.IP CURLOPT_POSTFIELDS .IP CURLOPT_POSTFIELDS
Pass a char * as parameter, which should be the full data to post in a HTTP Pass a char * as parameter, which should be the full data to post in an HTTP
post operation. You need to make sure that the data is formatted the way you post operation. You need to make sure that the data is formatted the way you
want the server to receive it. libcurl will not convert or encode it for want the server to receive it. libcurl will not convert or encode it for
you. Most web servers will assume this data to be url-encoded. Take note. you. Most web servers will assume this data to be url-encoded. Take note.
@@ -464,6 +480,11 @@ If you want to post data to the server without letting libcurl do a strlen()
to measure the data size, this option must be used. When this option is used to measure the data size, this option must be used. When this option is used
you can post fully binary data, which otherwise is likely to fail. If this you can post fully binary data, which otherwise is likely to fail. If this
size is set to zero, the library will use strlen() to get the size. size is set to zero, the library will use strlen() to get the size.
.IP CURLOPT_POSTFIELDSIZE_LARGE
Pass a curl_off_t as parameter. Use this to set the size of the
\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the
data to figure out the size. This is the large file version of the
\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1)
.IP CURLOPT_HTTPPOST .IP CURLOPT_HTTPPOST
Tells libcurl you want a multipart/formdata HTTP POST to be made and you Tells libcurl you want a multipart/formdata HTTP POST to be made and you
instruct what data to pass on to the server. Pass a pointer to a linked list instruct what data to pass on to the server. Pass a pointer to a linked list
@@ -524,9 +545,10 @@ set a cookie in the http request. The format of the string should be
NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie
should contain. should contain.
If you need to set mulitple cookies, you need to set them all using a single If you need to set multiple cookies, you need to set them all using a single
option and thus you need to concat them all in one single string. Set multiple option and thus you need to concatenate them all in one single string. Set
cookies in one string like this: "name1=content1; name2=content2;" etc. multiple cookies in one string like this: "name1=content1; name2=content2;"
etc.
Using this option multiple times will only make the latest string override the Using this option multiple times will only make the latest string override the
previously ones. previously ones.
@@ -617,7 +639,7 @@ only files in their response to NLST; they might not include subdirectories
and symbolic links. and symbolic links.
.IP CURLOPT_FTPAPPEND .IP CURLOPT_FTPAPPEND
A non-zero parameter tells the library to append to the remote file instead of A non-zero parameter tells the library to append to the remote file instead of
overwrite it. This is only useful when uploading to a ftp site. overwrite it. This is only useful when uploading to an ftp site.
.IP CURLOPT_FTP_USE_EPRT .IP CURLOPT_FTP_USE_EPRT
Pass a long. If the value is non-zero, it tells curl to use the EPRT (and Pass a long. If the value is non-zero, it tells curl to use the EPRT (and
LPRT) command when doing active FTP downloads (which is enabled by LPRT) command when doing active FTP downloads (which is enabled by
@@ -679,7 +701,7 @@ Pass an curl_off_t as parameter. It contains the offset in number of bytes
that you want the transfer to start from. (Added in 7.11.0) that you want the transfer to start from. (Added in 7.11.0)
.IP CURLOPT_CUSTOMREQUEST .IP CURLOPT_CUSTOMREQUEST
Pass a pointer to a zero terminated string as parameter. It will be user Pass a pointer to a zero terminated string as parameter. It will be user
instead of GET or HEAD when doing a HTTP request, or instead of LIST or NLST instead of GET or HEAD when doing an HTTP request, or instead of LIST or NLST
when doing an ftp directory listing. This is useful for doing DELETE or other when doing an ftp directory listing. This is useful for doing DELETE or other
more or less obscure HTTP requests. Don't do this at will, make sure your more or less obscure HTTP requests. Don't do this at will, make sure your
server supports the command first. server supports the command first.
@@ -858,7 +880,7 @@ key.
\fBNOTE:\fPIf the crypto device cannot be loaded, \fBNOTE:\fPIf the crypto device cannot be loaded,
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned. \fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
.IP CURLOPT_SSLENGINE_DEFAULT .IP CURLOPT_SSLENGINE_DEFAULT
Sets the actual crypto engine as the default for (asymetric) crypto Sets the actual crypto engine as the default for (asymmetric) crypto
operations. operations.
\fBNOTE:\fPIf the crypto device cannot be set, \fBNOTE:\fPIf the crypto device cannot be set,
@@ -899,8 +921,8 @@ in the SSL handshake, set 1 to check existence, 2 to ensure that it matches
the provided hostname. This is by default set to 2. (default changed in 7.10) the provided hostname. This is by default set to 2. (default changed in 7.10)
.IP CURLOPT_SSL_CIPHER_LIST .IP CURLOPT_SSL_CIPHER_LIST
Pass a char *, pointing to a zero terminated string holding the list of Pass a char *, pointing to a zero terminated string holding the list of
ciphers to use for the SSL connection. The list must be syntactly correct, it ciphers to use for the SSL connection. The list must be syntactically correct,
consists of one or more cipher strings separated by colons. Commas or spaces it consists of one or more cipher strings separated by colons. Commas or spaces
are also acceptable separators but colons are normally used, \!, \- and \+ can are also acceptable separators but colons are normally used, \!, \- and \+ can
be used as operators. Valid examples of cipher lists include 'RC4-SHA', be used as operators. Valid examples of cipher lists include 'RC4-SHA',
\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you \'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you

View File

@@ -13,7 +13,7 @@ curl_formadd - add a section to a multipart/formdata HTTP POST
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
curl_formadd() is used to append sections when building a multipart/formdata curl_formadd() is used to append sections when building a multipart/formdata
HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at HTTP POST (sometimes referred to as rfc1867-style posts). Append one section at
a time until you've added all the sections you want included and then you pass a time until you've added all the sections you want included and then you pass
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP. the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
\fIlastitem\fP is set after each call and on repeated invokes it should be \fIlastitem\fP is set after each call and on repeated invokes it should be
@@ -81,7 +81,7 @@ internally chosen one.
.B CURLFORM_FILENAME .B CURLFORM_FILENAME
followed by a pointer to a string to a name, will make libcurl use the given followed by a pointer to a string to a name, will make libcurl use the given
name in the file upload part, intead of the actual file name given to name in the file upload part, instead of the actual file name given to
\fICURLFORM_FILE\fP. \fICURLFORM_FILE\fP.
.B BCURLFORM_BUFFER .B BCURLFORM_BUFFER

View File

@@ -36,7 +36,7 @@ This string specifies the time on a given day. Syntax supported includes:
.TP .TP
.B time zone items .B time zone items
Specifies international time zone. There are a few acronyms supported, but in Specifies international time zone. There are a few acronyms supported, but in
general you should instead use the specific realtive time compared to general you should instead use the specific relative time compared to
UTC. Supported formats include: -1200, MST, +0100. UTC. Supported formats include: -1200, MST, +0100.
.TP .TP
.B day of the week items .B day of the week items

View File

@@ -42,7 +42,7 @@ See this table for notable exceptions.
Normal printf() clone. Normal printf() clone.
.TP .TP
.B curl_mfprintf() .B curl_mfprintf()
Normal fprinf() clone. Normal fprintf() clone.
.TP .TP
.B curl_msprintf() .B curl_msprintf()
Normal sprintf() clone. Normal sprintf() clone.

View File

@@ -9,11 +9,22 @@ curl_multi_add_handle - add an easy handle to a multi session
CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle); CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
Adds a standard easy handle to the multi stack. This will make this multi Adds a standard easy handle to the multi stack. This function call will make
handle control the specified easy handle. this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
When an easy handle has been added to a multi stack, you can not and you must When an easy handle has been added to a multi stack, you can not and you must
not use curl_easy_perform() on that handle! not use \fIcurl_easy_perform(3)\fP on that handle!
The easy handle will remain added until you remove it again with
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
multi stack before you terminate first the easy handle and then the multi
handle:
1 - \fIcurl_multi_remove_handle(3)\fP
2 - \fIcurl_easy_cleanup(3)\fP
3 - \fIcurl_multi_cleanup(3)\fP
.SH RETURN VALUE .SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@@ -11,7 +11,16 @@ curl_multi_cleanup - close down a multi session
.SH DESCRIPTION .SH DESCRIPTION
Cleans up and removes a whole multi stack. It does not free or touch any Cleans up and removes a whole multi stack. It does not free or touch any
individual easy handles in any way - they still need to be closed individual easy handles in any way - they still need to be closed
individually, using the usual curl_easy_cleanup() way. individually, using the usual \fIcurl_easy_cleanup(3)\fP way. The order of
cleaning up should be:
1 - \fIcurl_multi_remove_handle(3)\fP before any easy handles are cleaned up
2 - \fIcurl_easy_cleanup(3)\fP can now be called independently since the easy
handle is no longer connected to the multi handle
3 - \fIcurl_multi_cleanup(3)\fP should be called when all easy handles are
removed
.SH RETURN VALUE .SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@@ -1,9 +1,10 @@
.\" $Id$ .\" $Id$
.\" .\"
.TH curl_multi_fdset 3 "3 May 2002" "libcurl 7.9.5" "libcurl Manual" .TH curl_multi_fdset 3 "15 Apr 2004" "libcurl 7.9.5" "libcurl Manual"
.SH NAME .SH NAME
curl_multi_fdset - extracts file descriptor information from a multi handle curl_multi_fdset - extracts file descriptor information from a multi handle
.SH SYNOPSIS .SH SYNOPSIS
.nf
#include <curl/curl.h> #include <curl/curl.h>
CURLMcode curl_multi_fdset(CURLM *multi_handle, CURLMcode curl_multi_fdset(CURLM *multi_handle,
@@ -14,14 +15,21 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
This function extracts file descriptor information from a given multi_handle. This function extracts file descriptor information from a given multi_handle.
libcurl returns its fd_set sets. The application can use these to select() or libcurl returns its fd_set sets. The application can use these to select()
poll() on. The curl_multi_perform() function should be called as soon as one on. The \fIcurl_multi_perform(3)\fI function should be called as soon as one
of them are ready to be read from or written to. of them are ready to be read from or written to.
NOTE that once this call is made, you must not remove the sets you point to, NOTE that once this call is made, you must not remove the sets you point to,
as libcurl will need to be able to read them. It needs them after select() as libcurl will need to be able to read them. It needs them after select()
calls, to know if certain sockets are readable or writable. calls, to know if certain sockets are readable or writable.
You should also be aware that when doing select(), you should consider using a
rather small (single-digit number of seconds) timeout and call
\fIcurl_multi_perform\fP regularly - even if no activity has been seen on the
fd_sets - as otherwise libcurl-internal retries and timeouts may not work as
you'd think.
.SH RETURN VALUE .SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code. See
\fIlibcurl-errors(3)\fP
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" .BR curl_multi_cleanup "(3)," curl_multi_init "(3)"

View File

@@ -21,13 +21,14 @@ 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.
The data the returned pointer points to will not survive calling The data the returned pointer points to will not survive calling
curl_multi_cleanup(). \fIcurl_multi_cleanup(3)\fP.
The 'CURLMsg' struct is very simple and only contain very basic informations. The 'CURLMsg' struct is very simple and only contain very basic information.
If more involved information is wanted, the particular "easy handle" in If more involved information is wanted, the particular "easy handle" in
present in that struct and can thus be used in subsequent regular present in that struct and can thus be used in subsequent regular
curl_easy_getinfo() calls (or similar): \fIcurl_easy_getinfo(3)\fP calls (or similar):
.NF
struct CURLMsg { struct CURLMsg {
CURLMSG msg; /* what this message means */ CURLMSG msg; /* what this message means */
CURL *easy_handle; /* the handle it concerns */ CURL *easy_handle; /* the handle it concerns */

View File

@@ -2,7 +2,7 @@
.\" .\"
.TH curl_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual" .TH curl_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
.SH NAME .SH NAME
curl_multi_init - Start a multi session curl_multi_init - create a multi handle
.SH SYNOPSIS .SH SYNOPSIS
.B #include <curl/curl.h> .B #include <curl/curl.h>
.sp .sp
@@ -10,13 +10,12 @@ curl_multi_init - Start a multi session
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
This function returns a CURLM handle to be used as input to all the other This function returns a CURLM handle to be used as input to all the other
multi-functions, sometimes refered to as a multi handle on some places in the multi-functions, sometimes referred to as a multi handle on some places in the
documentation. This init call MUST have a corresponding call to documentation. This init call MUST have a corresponding call to
\fIcurl_multi_cleanup\fP when the operation is complete. \fIcurl_multi_cleanup(3)\fP when the operation is complete.
.SH RETURN VALUE .SH RETURN VALUE
If this function returns NULL, something went wrong and you cannot use the If this function returns NULL, something went wrong and you cannot use the
other curl functions. other curl functions.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)" .BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)"
.SH BUGS
Surely there are some, you tell me!

View File

@@ -19,18 +19,19 @@ integer-pointer.
.SH "RETURN VALUE" .SH "RETURN VALUE"
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basicly means that you If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you
should call \fIcurl_multi_perform\fP again, before you select() on more 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".
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 invidual transfers even when this might still have occurred problems on individual transfers even when this
function returns OK. function returns OK.
.SH "TYPICAL USAGE" .SH "TYPICAL USAGE"
Most application will use \fIcurl_multi_fdset\fP to get the multi_handle's Most application will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
file descriptors, then it'll wait for action on them using select() and as file descriptors, then it'll wait for action on them using select() and as
soon as one or more of them are ready, \fIcurl_multi_perform\fP gets called. soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
called.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" .BR curl_multi_cleanup "(3)," curl_multi_init "(3)," curl_multi_fdset "(3)"

View File

@@ -10,7 +10,7 @@ curl_share_init - Create a shared object
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
This function returns a CURLSH handle to be used as input to all the other This function returns a CURLSH handle to be used as input to all the other
share-functions, sometimes refered to as a share handle on some places in the share-functions, sometimes referred to as a share handle on some places in the
documentation. This init call MUST have a corresponding call to documentation. This init call MUST have a corresponding call to
\fIcurl_share_cleanup\fP when all operations using the share are complete. \fIcurl_share_cleanup\fP when all operations using the share are complete.

View File

@@ -1 +1 @@
.so curl_strequal.3 .so man3/curl_strequal.3

View File

@@ -9,21 +9,21 @@ libcurl-easy \- easy interface overview
When using libcurl's "easy" interface you init your session and get a handle When using libcurl's "easy" interface you init your session and get a handle
(often referred to as an "easy handle" in various docs and sources), which you (often referred to as an "easy handle" in various docs and sources), which you
use as input to the easy interface functions you use. Use use as input to the easy interface functions you use. Use
\fIcurl_easy_init()\fP to get the handle. \fIcurl_easy_init(3)\fP to get the handle.
You continue by setting all the options you want in the upcoming transfer, the You continue by setting all the options you want in the upcoming transfer, the
most important among them is the URL itself (you can't transfer anything most important among them is the URL itself (you can't transfer anything
without a specified URL as you may have figured out yourself). You might want without a specified URL as you may have figured out yourself). You might want
to set some callbacks as well that will be called from the library when data to set some callbacks as well that will be called from the library when data
is available etc. \fIcurl_easy_setopt()\fP is used for all this. is available etc. \fIcurl_easy_setopt(3)\fP is used for all this.
When all is setup, you tell libcurl to perform the transfer using When all is setup, you tell libcurl to perform the transfer using
\fIcurl_easy_perform()\fP. It will then do the entire operation and won't \fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't
return until it is done (successfully or not). return until it is done (successfully or not).
After the transfer has been made, you can set new options and make another After the transfer has been made, you can set new options and make another
transfer, or if you're done, cleanup the session by calling transfer, or if you're done, cleanup the session by calling
\fIcurl_easy_cleanup()\fP. If you want persistant connections, you don't \fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't
cleanup immediately, but instead run ahead and perform other transfers using cleanup immediately, but instead run ahead and perform other transfers using
the same easy handle. the same easy handle.

View File

@@ -36,7 +36,7 @@ Couldn't resolve host. The given remote host was not resolved.
.IP "CURLE_COULDNT_CONNECT (7)" .IP "CURLE_COULDNT_CONNECT (7)"
Failed to connect() to host or proxy. Failed to connect() to host or proxy.
.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)" .IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
After connecting to a FTP server, libcurl expects to get a certain reply back. After connecting to an FTP server, libcurl expects to get a certain reply back.
This error code implies that it god a strange or bad reply. The given remote This error code implies that it god a strange or bad reply. The given remote
server is probably not an OK FTP server. server is probably not an OK FTP server.
.IP "CURLE_FTP_ACCESS_DENIED (9)" .IP "CURLE_FTP_ACCESS_DENIED (9)"
@@ -93,7 +93,7 @@ There was a problem reading a local file or an error returned by the read
callback. callback.
.IP "CURLE_OUT_OF_MEMORY (27)" .IP "CURLE_OUT_OF_MEMORY (27)"
Out of memory. A memory allocation request failed. This is serious badness and Out of memory. A memory allocation request failed. This is serious badness and
things are severly screwed up if this ever occur. things are severely screwed up if this ever occur.
.IP "CURLE_OPERATION_TIMEOUTED (28)" .IP "CURLE_OPERATION_TIMEOUTED (28)"
Operation timeout. The specified time-out period was reached according to the Operation timeout. The specified time-out period was reached according to the
conditions. conditions.
@@ -106,14 +106,14 @@ specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP.
The FTP REST command returned error. This should never happen if the server is The FTP REST command returned error. This should never happen if the server is
sane. sane.
.IP "CURLE_FTP_COULDNT_GET_SIZE (32)" .IP "CURLE_FTP_COULDNT_GET_SIZE (32)"
The FTP SIZE command returned errror. SIZE is not a kosher FTP command, it is The FTP SIZE command returned error. SIZE is not a kosher FTP command, it is
an extension and not all servers support it. This is not a surprising error. an extension and not all servers support it. This is not a surprising error.
.IP "CURLE_HTTP_RANGE_ERROR (33)" .IP "CURLE_HTTP_RANGE_ERROR (33)"
The HTTP server does not support or accept range requests. The HTTP server does not support or accept range requests.
.IP "CURLE_HTTP_POST_ERROR (34)" .IP "CURLE_HTTP_POST_ERROR (34)"
This is an odd error that mainly occurs due to internal confusion. This is an odd error that mainly occurs due to internal confusion.
.IP "CURLE_SSL_CONNECT_ERROR (35)" .IP "CURLE_SSL_CONNECT_ERROR (35)"
A problem occured somewhere in the SSL/TLS handshake. You really want the A problem occurred somewhere in the SSL/TLS handshake. You really want the
error buffer and read the message there as it pinpoints the problem slightly error buffer and read the message there as it pinpoints the problem slightly
more. Could be certificates (file formats, paths, permissions), passwords, and more. Could be certificates (file formats, paths, permissions), passwords, and
others. others.
@@ -187,8 +187,19 @@ Requested FTP SSL level failed
.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. interface.
.IP "CURLM_CALL_MULTI_PERFORM (-1)"
This is left to be documented. This is not really an error. It means you should call
\fIcurl_multi_perform(3)\fP again without doing select() or similar in between.
.IP "CURLM_OK (0)"
Things are fine.
.IP "CURLM_BAD_HANDLE (1)"
The passed-in handle is not a valid CURLM handle.
.IP "CURLM_BAD_EASY_HANDLE (2)"
An easy handle was not good/valid.
.IP "CURLM_OUT_OF_MEMORY (3)"
You are doomed.
.IP "CURLM_INTERNAL_ERROR (4)"
This can only be returned if libcurl bugs. Please report it to us!
.SH "CURLSHcode" .SH "CURLSHcode"
The "share" interface will return a CURLSHcode to indicate when an The "share" interface will return a CURLSHcode to indicate when an
error has occurred. error has occurred.

View File

@@ -32,7 +32,7 @@ complicated for the application.
file descriptors simultaneous easily. file descriptors simultaneous easily.
.SH "ONE MULTI HANDLE MANY EASY HANDLES" .SH "ONE MULTI HANDLE MANY EASY HANDLES"
To use the multi interface, you must first create a 'multi handle' with To use the multi interface, you must first create a 'multi handle' with
\fIcurl_multi_init\fP. This handle is then used as input to all further \fIcurl_multi_init(3)\fP. This handle is then used as input to all further
curl_multi_* functions. curl_multi_* functions.
Each single transfer is built up with an easy handle. You must create them, Each single transfer is built up with an easy handle. You must create them,
@@ -40,29 +40,29 @@ and setup the appropriate options for each easy handle, as outlined in the
\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP. \fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
When the easy handle is setup for a transfer, then instead of using When the easy handle is setup for a transfer, then instead of using
\fIcurl_easy_perform\fP (as when using the easy interface for transfers), you \fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers),
should instead add the easy handle to the multi handle using you should instead add the easy handle to the multi handle using
\fIcurl_easy_add_handl\fP. The multi handle is sometimes referred to as a \fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
\'multi stack\' because of the fact that it may hold a large amount of easy \'multi stack\' because of the fact that it may hold a large amount of easy
handles. handles.
Should you change your mind, the easy handle is again removed from the multi Should you change your mind, the easy handle is again removed from the multi
stack using \fIcurl_multi_remove_handle\fP. Once removed from the multi stack using \fIcurl_multi_remove_handle(3)\fP. Once removed from the multi
handle, you can again use other easy interface functions like handle, you can again use other easy interface functions like
\fIcurl_easy_perform\fP on the handle or whatever you think is necessary. \fIcurl_easy_perform(3)\fP on the handle or whatever you think is necessary.
Adding the easy handle to the multi handle does not start the transfer. Adding the easy handle to the multi handle does not start the transfer.
Remember that one of the main ideas with this interface is to let your Remember that one of the main ideas with this interface is to let your
application drive. You drive the transfers by invoking application drive. You drive the transfers by invoking
\fIcurl_multi_perform\fP. libcurl will then transfer data if there is anything \fIcurl_multi_perform(3)\fP. libcurl will then transfer data if there is
available to transfer. It'll use the callbacks and everything else you have anything available to transfer. It'll use the callbacks and everything else
setup in the individual easy handles. It'll transfer data on all current you have setup in the individual easy handles. It'll transfer data on all
transfers in the multi stack that are ready to transfer anything. It may be current transfers in the multi stack that are ready to transfer anything. It
all, it may be none. may be all, it may be none.
Your application can acquire knowledge from libcurl when it would like to get Your application can acquire knowledge from libcurl when it would like to get
invoked to transfer data, so that you don't have to busy-loop and call that invoked to transfer data, so that you don't have to busy-loop and call that
\fIcurl_multi_perform\fP like crazy. \fIcurl_multi_fdset\fP offers an \fIcurl_multi_perform(3)\fP like crazy. \fIcurl_multi_fdset(3)\fP offers an
interface using which you can extract fd_sets from libcurl to use in select() interface using which you can extract fd_sets from libcurl to use in select()
or poll() calls in order to get to know when the transfers in the multi stack or poll() calls in order to get to know when the transfers in the multi stack
might need attention. This also makes it very easy for your program to wait might need attention. This also makes it very easy for your program to wait
@@ -70,31 +70,31 @@ for input on your own private file descriptors at the same time or perhaps
timeout every now and then, should you want that. timeout every now and then, should you want that.
A little note here about the return codes from the multi functions, and A little note here about the return codes from the multi functions, and
especially the \fIcurl_multi_perform\fP: if you receive especially the \fIcurl_multi_perform(3)\fP: if you receive
\fICURLM_CALL_MULTI_PERFORM\fP, this basicly means that you should call \fICURLM_CALL_MULTI_PERFORM\fP, this basically means that you should call
\fIcurl_multi_perform\fP again, before you select() on more actions. You don't \fIcurl_multi_perform(3)\fP again, before you select() on more actions. You
have to do it immediately, but the return code means that libcurl may have don't have to do it immediately, but the return code means that libcurl may
more data available to return or that there may be more data to send off have more data available to return or that there may be more data to send off
before it is "satisfied". before it is "satisfied".
\fIcurl_multi_perform\fP stores the number of still running transfers in one \fIcurl_multi_perform(3)\fP stores the number of still running transfers in
of its input arguments, and by reading that you can figure out when all the one of its input arguments, and by reading that you can figure out when all
transfers in the multi handles are done. 'done' does not mean successful. One the transfers in the multi handles are done. 'done' does not mean
or more of the transfers may have failed. Tracking when this number changes, successful. One or more of the transfers may have failed. Tracking when this
you know when one or more transfers are done. number changes, you know when one or more transfers are done.
To get information about completed transfers, to figure out success or not and To get information about completed transfers, to figure out success or not and
similar, \fIcurl_multi_info_read\fP should be called. It can return a message similar, \fIcurl_multi_info_read(3)\fP should be called. It can return a
about a current or previous transfer. Repeated invokes of the function get message about a current or previous transfer. Repeated invokes of the function
more messages until the message queue is empty. The information you receive get more messages until the message queue is empty. The information you
there includes an easy handle pointer which you may use to identify which easy receive there includes an easy handle pointer which you may use to identify
handle the information regards. which easy handle the information regards.
When all transfers in the multi stack are done, cleanup the multi handle with When all transfers in the multi stack are done, cleanup the multi handle with
\fIcurl_multi_cleanup\fP. Be careful and please note that you \fBMUST\fP \fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP
invoke separate \fIcurl_easy_cleanup\fP calls on every single easy handle to invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle
clean them up properly. to clean them up properly.
If you want to re-use an easy handle that was added to the multi handle for If you want to re-use an easy handle that was added to the multi handle for
transfer, you must first remove it from the multi stack and then re-add it transfer, you must first remove it from the multi stack and then re-add it
again (possbily after having altered some options at your own choice). again (possibly after having altered some options at your own choice).

View File

@@ -20,27 +20,27 @@ You can have multiple easy handles share data between them. Have them update
and use the \fBsame\fP cookie database or DNS cache! This way, each single and use the \fBsame\fP cookie database or DNS cache! This way, each single
transfer will take advantage from data updates made by the other transfer(s). transfer will take advantage from data updates made by the other transfer(s).
.SH "SHARE OBJECT" .SH "SHARE OBJECT"
You create a shared object with \fIcurl_share_init()\fP. It returns a handle You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
for a newly created one. for a newly created one.
You tell the shared object what data you want it to share by using You tell the shared object what data you want it to share by using
\fIcurl_share_setopt()\fP. Currently you can only share DNS and/or COOKIE \fIcurl_share_setopt(3)\fP. Currently you can only share DNS and/or COOKIE
data. data.
Since you can use this share from multiple threads, and libcurl has no Since you can use this share from multiple threads, and libcurl has no
internal thread synchronization, you must provide mutex callbacks if you're internal thread synchronization, you must provide mutex callbacks if you're
using this multi-threaded. You set lock and unlock functions with using this multi-threaded. You set lock and unlock functions with
\fIcurl_share_setopt()\fP too. \fIcurl_share_setopt(3)\fP too.
Then, you make an easy handle to use this share, you set the CURLOPT_SHARE Then, you make an easy handle to use this share, you set the
option with \fIcurl_easy_setopt\fP, and pass in share handle. You can make any \fICURLOPT_SHARE\fP option with \fIcurl_easy_setopt(3)\fP, and pass in share
number of easy handles share the same share handle. handle. You can make any number of easy handles share the same share handle.
To make an easy handle stop using that particular share, you set CURLOPT_SHARE To make an easy handle stop using that particular share, you set
to NULL for that easy handle. To make a handle stop sharing a particular data, \fICURLOPT_SHARE\fP to NULL for that easy handle. To make a handle stop
you can CURLSHOPT_UNSHARE it. sharing a particular data, you can \fICURLSHOPT_UNSHARE\fP it.
When you're done using the share, make sure that no easy handle is still using When you're done using the share, make sure that no easy handle is still using
it, and call \fIcurl_share_cleanup()\fP on the handle. it, and call \fIcurl_share_cleanup(3)\fP on the handle.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_share_init "(3), " curl_share_setopt "(3), " curl_share_cleanup "(3)" .BR curl_share_init "(3), " curl_share_setopt "(3), " curl_share_cleanup "(3)"

View File

@@ -8,37 +8,36 @@ libcurl \- client-side URL transfers
.SH DESCRIPTION .SH DESCRIPTION
This is an overview on how to use libcurl in your C programs. There are This is an overview on how to use libcurl in your C programs. There are
specific man pages for each function mentioned in here. There are also the specific man pages for each function mentioned in here. There are also the
\fIlibcurl-easy\fP man page, the \fIlibcurl-multi\fP man page, the \fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
\fIlibcurl-share\fP man page and the \fIlibcurl-the-guide\fP document for \fIlibcurl-share(3)\fP man page and the \fIlibcurl-the-guide\fP document for
further reading on how to do programming with libcurl. further reading on how to do programming with libcurl.
There exist more than a dozen custom bindings that bring libcurl access to There exist more than a dozen custom bindings that bring libcurl access to
your favourite language. Look elsewhere for documentation on those. your favourite language. Look elsewhere for documentation on those.
All applications that use libcurl should call \fIcurl_global_init()\fP exactly All applications that use libcurl should call \fIcurl_global_init(3)\fP
once before any libcurl function can be used. After all usage of libcurl is exactly once before any libcurl function can be used. After all usage of
complete, it \fBmust\fP call \fIcurl_global_cleanup()\fP. In between those two libcurl is complete, it \fBmust\fP call \fIcurl_global_cleanup(3)\fP. In
calls, you can use libcurl as described below. between those two calls, you can use libcurl as described below.
To transfer files, you always set up an "easy handle" using To transfer files, you always set up an "easy handle" using
\fIcurl_easy_init()\fP, but when you want the file(s) transfered you have the \fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
option of using the "easy" interface, or the "multi" interface. the option of using the "easy" interface, or the "multi" interface.
The easy interface is a synchronous interface with which you call The easy interface is a synchronous interface with which you call
\fIcurl_easy_perform\fP and let it perform the transfer. When it is completed, \fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
the function return and you can continue. More details are found in the completed, the function return and you can continue. More details are found in
.BR "libcurl-easy (3)" the \fIlibcurl-easy(3)\fP man page.
man page.
The multi interface on the other hand is an asynchronous interface, that you The multi interface on the other hand is an asynchronous interface, that you
call and that performs only a little piece of the tranfer on each invoke. It call and that performs only a little piece of the transfer on each invoke. It
is perfect if you want to do things while the transfer is in progress, or is perfect if you want to do things while the transfer is in progress, or
similar. The multi interface allows you to select() on libcurl action, and similar. The multi interface allows you to select() on libcurl action, and
even to easily download multiple files simultaneously using a single thread. even to easily download multiple files simultaneously using a single thread.
You can have multiple easy handles share certain data, even if they are used You can have multiple easy handles share certain data, even if they are used
in different threads. This magic is setup using the share interface, as in different threads. This magic is setup using the share interface, as
described in the \fIlibcurl-share\fP man page. described in the \fIlibcurl-share(3)\fP man page.
There is also a series of other helpful functions to use. They are: There is also a series of other helpful functions to use. They are:
@@ -57,10 +56,10 @@ portable environment variable reader
get information about a performed transfer get information about a performed transfer
.TP .TP
.B curl_formadd() .B curl_formadd()
helps building a HTTP form POST helps building an HTTP form POST
.TP .TP
.B curl_formfree() .B curl_formfree()
free a list built with curl_formparse()/curl_formadd() free a list built with \fIcurl_formadd(3)\fP
.TP .TP
.B curl_slist_append() .B curl_slist_append()
builds a linked list builds a linked list
@@ -102,20 +101,20 @@ Never ever call curl-functions simultaneously using the same handle from
several threads. libcurl is thread-safe and can be used in any number of several threads. libcurl is thread-safe and can be used in any number of
threads, but you must use separate curl handles if you want to use libcurl in threads, but you must use separate curl handles if you want to use libcurl in
more than one thread simultaneously. more than one thread simultaneously.
.SH "PERSISTANT CONNECTIONS" .SH "PERSISTENT CONNECTIONS"
Persistent connections means that libcurl can re-use the same connection for Persistent connections means that libcurl can re-use the same connection for
several transfers, if the conditions are right. several transfers, if the conditions are right.
libcurl will *always* attempt to use persistent connections. Whenever you use libcurl will \fBalways\fP attempt to use persistent connections. Whenever you
\fIcurl_easy_perform()\fP or \fIcurl_multi_perform()\fP, libcurl will attempt use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP, libcurl will
to use an existing connection to do the transfer, and if none exists it'll attempt to use an existing connection to do the transfer, and if none exists
open a new one that will be subject for re-use on a possible following call to it'll open a new one that will be subject for re-use on a possible following
\fIcurl_easy_perform()\fP or \fIcurl_multi_perform()\fP. call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
To allow libcurl to take full advantage of persistent connections, you should To allow libcurl to take full advantage of persistent connections, you should
do as many of your file transfers as possible using the same curl handle. When do as many of your file transfers as possible using the same curl handle. When
you call \fIcurl_easy_cleanup()\fP, all the possibly open connections held by you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
libcurl will be closed and forgotten. libcurl will be closed and forgotten.
Note that the options set with \fIcurl_easy_setopt()\fP will be used in on Note that the options set with \fIcurl_easy_setopt(3)\fP will be used in on
every repeated \fIcurl_easy_perform()\fP call. every repeated \fIcurl_easy_perform(3)\fP call.

View File

@@ -1,8 +1,5 @@
pkginclude_HEADERS = \ pkginclude_HEADERS = \
curl.h \ curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h
easy.h \
mprintf.h \
stdcheaders.h \
types.h \
multi.h
pkgincludedir= $(includedir)/curl pkgincludedir= $(includedir)/curl
CLEANFILES = *dist

View File

@@ -27,31 +27,7 @@
http://curl.haxx.se/libcurl/ http://curl.haxx.se/libcurl/
*/ */
/* This is the version number of the libcurl package from which this header #include "curlver.h" /* the libcurl version defines */
file origins: */
#define LIBCURL_VERSION "7.11.0-CVS"
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal. All three numbers are always represented using two digits. 1.2
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
This 6-digit hexadecimal number does not show pre-release number, and it is
always a greater number in a more recent release. It makes comparisons with
greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x070b00
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 11
#define LIBCURL_VERSION_PATCH 0
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
@@ -783,6 +759,12 @@ typedef enum {
*/ */
CINIT(FTP_SSL, LONG, 119), CINIT(FTP_SSL, LONG, 119),
/* The _LARGE version of the standard POSTFIELDSIZE option */
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
/* Enable/disable the TCP Nagle algorithm */
CINIT(TCP_NODELAY, LONG, 121),
CURLOPT_LASTENTRY /* the last unused */ CURLOPT_LASTENTRY /* the last unused */
} CURLoption; } CURLoption;
@@ -801,12 +783,12 @@ 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 0 #define CURLOPT_HTTPREQUEST -1
#define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT #define CURLOPT_FTPASCII CURLOPT_TRANSFERTEXT
#define CURLOPT_MUTE 0 #define CURLOPT_MUTE -2
#define CURLOPT_PASSWDFUNCTION 0 #define CURLOPT_PASSWDFUNCTION -3
#define CURLOPT_PASSWDDATA 0 #define CURLOPT_PASSWDDATA -4
#define CURLOPT_CLOSEFUNCTION 0 #define CURLOPT_CLOSEFUNCTION -5
#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 */
@@ -1087,7 +1069,6 @@ void curl_slist_free_all(struct curl_slist *);
*/ */
time_t curl_getdate(const char *p, const time_t *now); time_t curl_getdate(const char *p, const time_t *now);
#define CURLINFO_STRING 0x100000 #define CURLINFO_STRING 0x100000
#define CURLINFO_LONG 0x200000 #define CURLINFO_LONG 0x200000
#define CURLINFO_DOUBLE 0x300000 #define CURLINFO_DOUBLE 0x300000
@@ -1263,6 +1244,28 @@ typedef struct {
*/ */
curl_version_info_data *curl_version_info(CURLversion); curl_version_info_data *curl_version_info(CURLversion);
/*
* NAME curl_easy_strerror()
*
* DESCRIPTION
*
* The curl_easy_strerror function may be used to turn a CURLcode value
* into the equivalent human readable error string. This is useful
* for printing meaningful error messages.
*/
const char *curl_easy_strerror(CURLcode);
/*
* NAME curl_share_strerror()
*
* DESCRIPTION
*
* The curl_share_strerror function may be used to turn a CURLSHcode value
* into the equivalent human readable error string. This is useful
* for printing meaningful error messages.
*/
const char *curl_share_strerror(CURLSHcode);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

55
include/curl/curlver.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef __CURL_CURLVER_H
#define __CURL_CURLVER_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/* This header file contains nothing but libcurl version info, generated by
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.11.2-CVS"
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal. All three numbers are always represented using two digits. 1.2
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
This 6-digit hexadecimal number does not show pre-release number, and it is
always a greater number in a more recent release. It makes comparisons with
greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x070b02
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 11
#define LIBCURL_VERSION_PATCH 2
#endif /* __CURL_CURLVER_H */

View File

@@ -55,10 +55,10 @@
#include <winsock2.h> #include <winsock2.h>
#else #else
#ifdef _AIX
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish /* 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 libc5-based Linux systems. Only include it on system that are known to
require it! */ require it! */
#if defined(_AIX) || defined(NETWARE)
#include <sys/select.h> #include <sys/select.h>
#endif #endif
@@ -203,6 +203,17 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle);
CURLMsg *curl_multi_info_read(CURLM *multi_handle, CURLMsg *curl_multi_info_read(CURLM *multi_handle,
int *msgs_in_queue); int *msgs_in_queue);
/*
* NAME curl_multi_strerror()
*
* DESCRIPTION
*
* The curl_multi_strerror function may be used to turn a CURLMcode value
* into the equivalent human readable error string. This is useful
* for printing meaningful error messages.
*/
const char *curl_multi_strerror(CURLMcode);
#ifdef __cplusplus #ifdef __cplusplus
} /* end of extern "C" */ } /* end of extern "C" */
#endif #endif

View File

@@ -1,16 +1,34 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
# #
# $Id$ # $Id$
# ###########################################################################
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \ EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \ Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp curllib.dsw \
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \ config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
config.h.in ca-bundle.crt README.encoding README.memoryleak \ ca-bundle.crt README.encoding README.memoryleak README.ares README.curlx \
README.ares makefile.dj config.dj \ makefile.dj config.dj libcurl.framework.make libcurl.plist libcurl.rc \
libcurl.framework.make libcurl.plist libcurl.rc \ config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
config-amigaos.h amigaos.c amigaos.h makefile.amiga Makefile.netware nwlib.c libcurl.imp
lib_LTLIBRARIES = libcurl.la lib_LTLIBRARIES = libcurl.la
@@ -37,16 +55,16 @@ VERSION=-version-info 2:2:0
# that the current interface number gets larger faster. # that the current interface number gets larger faster.
# #
# 3.If the library source code has changed at all since the last update, then # 3.If the library source code has changed at all since the last update, then
# increment revision (c:r:a becomes c:r+1:a). # increment revision (c:r+1:a)
# #
# 4.If any interfaces have been added, removed, or changed since the last # 4.If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0. # update, increment current, and set revision to 0. (c+1:r=0:a)
# #
# 5.If any interfaces have been added since the last public release, then # 5.If any interfaces have been added since the last public release, then
# increment age. # increment age. (c:r:a+1)
# #
# 6.If any interfaces have been removed since the last public release, then # 6.If any interfaces have been removed since the last public release, then
# set age to 0. # set age to 0. (c:r:a=0)
# #
if NO_UNDEFINED if NO_UNDEFINED
@@ -62,20 +80,20 @@ endif
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE) libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c \ libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c \ file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \ progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.h \
http.h sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \ sendf.h url.c dict.c ftp.h if2ip.c speedcheck.c url.h dict.h \
getdate.c if2ip.h speedcheck.h urldata.h getdate.h ldap.c ssluse.c \ getdate.c if2ip.h speedcheck.h urldata.h getdate.h ldap.c ssluse.c \
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c escape.h \ version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.c \
netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \ escape.h netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \
strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \ strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \ memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c \
connect.c connect.h llist.c llist.h hash.c hash.h multi.c \ strtok.h connect.c connect.h llist.c llist.h hash.c hash.h multi.c \
content_encoding.c content_encoding.h share.c share.h http_digest.c \ content_encoding.c content_encoding.h share.c share.h http_digest.c \
md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \ md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h \
http_ntlm.c http_ntlm.h ca-bundle.h inet_pton.c inet_pton.h \ http_ntlm.c http_ntlm.h ca-bundle.h inet_pton.c inet_pton.h \
strtoofft.c strtoofft.h strtoofft.c strtoofft.h strerror.c strerror.h
noinst_HEADERS = setup.h transfer.h noinst_HEADERS = setup.h transfer.h

View File

@@ -12,7 +12,7 @@ AR = ar
RM = rm -f RM = rm -f
RANLIB = ranlib RANLIB = ranlib
STRIP = strip -g STRIP = strip -g
OPENSSL_PATH = ../../openssl-0.9.7c OPENSSL_PATH = ../../openssl-0.9.7d
ZLIB_PATH = ../../zlib-1.2.1 ZLIB_PATH = ../../zlib-1.2.1
######################################################## ########################################################

277
lib/Makefile.netware Normal file
View File

@@ -0,0 +1,277 @@
#################################################################
#
## Makefile for building libcurl.nlm (NetWare version - gnu make)
## Use: make -f Makefile.netware
##
## Comments to: Guenter Knauf <eflash@gmx.net>
#
#################################################################
# Edit the path below to point to the base of your Novell NDK.
BASE = c:/novell
INSTDIR = s:/libcurl
# Edit the path below to point to the base of your Zlib sources.
ZLIB_PATH = ../../../cw/zlib-src-1.1.4
# Edit the vars below to change NLM target settings.
TARGET = libcurl
VERSION = $(LIBCURL_VERSION)
COPYR = Copyright (c) 1996 - 2004, Daniel Stenberg, <daniel@haxx.se>
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) - http://curl.haxx.se
MTSAFE = YES
STACK = 64000
SCREEN = none
#MODULES = libz.nlm
EXPORTS = @libcurl.imp
# Edit the var below to point to your lib architecture.
ifndef LIBARCH
LIBARCH = LIBC
endif
# must be equal to DEBUG or NDEBUG
DB = NDEBUG
# DB = DEBUG
# Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG)
OPT = -O2
OBJDIR = release
else
OPT = -g
OBJDIR = debug
endif
# Include the version info retrieved from jk_version.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
ifdef METROWERKS
CC = mwccnlm
else
CC = gcc
endif
# RM = rm -f
# CP = cp -fv
# if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.de/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
#CFLAGS += -DHAVE_LIBZ
ifeq ($(CC),mwccnlm)
LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJDIR)/*.o -o $(OBJDIR)/$(TARGET).nlm -commandfile
CFLAGS += -gccinc -inline off -opt nointrinsics
CFLAGS += -relax_pointers
#CFLAGS += -w on
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4 -inst mmx -proc 686
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
CFLAGS += -align 1 -proc 586
endif
else
LD = nlmconv
LDFLAGS = -T
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return
CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
CFLAGS += -include $(BASE)/nlmconv/genlm.h
endif
endif
LDLIBS =
NDK_ROOT = $(BASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
CURL_INC = ../include
INCLUDES = -I$(CURL_INC)
INCLUDES += -I$(ZLIB_PATH)
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
INCLUDES += -I$(SDK_LIBC)/include/winsock
INCLUDES += -I$(SDK_LDAP)/libc/inc
else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
INCLUDES += -I$(SDK_LDAP)/clib/inc
CFLAGS += -DNETDB_USE_INTERNET
endif
CFLAGS += $(INCLUDES)
ifeq ($(MTSAFE),YES)
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(OSTYPE),linux)
DL = '
-include $(BASE)/nlmconv/ncpfs.inc
endif
OBJS = \
$(OBJDIR)/file.o \
$(OBJDIR)/timeval.o \
$(OBJDIR)/base64.o \
$(OBJDIR)/hostip.o \
$(OBJDIR)/progress.o \
$(OBJDIR)/formdata.o \
$(OBJDIR)/cookie.o \
$(OBJDIR)/http.o \
$(OBJDIR)/sendf.o \
$(OBJDIR)/ftp.o \
$(OBJDIR)/url.o \
$(OBJDIR)/dict.o \
$(OBJDIR)/if2ip.o \
$(OBJDIR)/speedcheck.o \
$(OBJDIR)/getdate.o \
$(OBJDIR)/transfer.o \
$(OBJDIR)/ldap.o \
$(OBJDIR)/ssluse.o \
$(OBJDIR)/version.o \
$(OBJDIR)/getenv.o \
$(OBJDIR)/escape.o \
$(OBJDIR)/mprintf.o \
$(OBJDIR)/telnet.o \
$(OBJDIR)/netrc.o \
$(OBJDIR)/getinfo.o \
$(OBJDIR)/strequal.o \
$(OBJDIR)/easy.o \
$(OBJDIR)/security.o \
$(OBJDIR)/krb4.o \
$(OBJDIR)/memdebug.o \
$(OBJDIR)/http_chunks.o \
$(OBJDIR)/strtok.o \
$(OBJDIR)/connect.o \
$(OBJDIR)/hash.o \
$(OBJDIR)/llist.o \
$(OBJDIR)/multi.o \
$(OBJDIR)/share.o \
$(OBJDIR)/content_encoding.o \
$(OBJDIR)/http_digest.o \
$(OBJDIR)/http_negotiate.o \
$(OBJDIR)/http_ntlm.o \
$(OBJDIR)/md5.o \
$(OBJDIR)/strtoofft.o \
$(OBJDIR)/nwlib.o
all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm
$(OBJDIR)/%.o: %.c
@echo Compiling $<
@$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: $(CURL_INC)/curl/curl.h $(OBJDIR)
@echo Creating $@
@awk -f ../packages/netware/get_ver.awk $< > $@
dist: all
-$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv
-$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA)
# -$(CP) ../changes.txt $(OBJDIR)/
install: all
@[ -d $(INSTDIR) ] || mkdir $(INSTDIR)
@$(CP) $(TARGET).nlm $(INSTDIR)
clean:
-$(RM) -r $(OBJDIR)
$(OBJDIR):
@mkdir $(OBJDIR)
$(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA)
@echo Linking $@
@-$(RM) $@
@$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def
$(OBJDIR)/%.xdc: Makefile.netware
@echo Creating $@
@$(MPKXDC) $(XDCOPT) $@
$(OBJDIR)/%.def: Makefile.netware
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
@echo $(DL)#$(DL) >> $@
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
@echo $(DL)description "$(DESCR)"$(DL) >> $@
@echo $(DL)version $(VERSION)$(DL) >> $@
ifdef NLMTYPE
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
endif
ifdef STACK
@echo $(DL)stack $(STACK)$(DL) >> $@
endif
ifdef SCREEN
@echo $(DL)screenname "$(SCREEN)"$(DL) >> $@
else
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
endif
ifeq ($(DB),DEBUG)
@echo $(DL)debug$(DL) >> $@
endif
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@
ifdef XDCDATA
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
endif
ifeq ($(LIBARCH),CLIB)
@echo $(DL)start _Prelude$(DL) >> $@
@echo $(DL)exit _Stop$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@
else
ifeq ($(LD),nlmconv)
@echo $(DL)flag_on 64$(DL) >> $@
else
@echo $(DL)autounload$(DL) >> $@
endif
@echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
@echo $(DL)module libc$(DL) >> $@
endif
ifdef MODULES
@echo $(DL)module $(MODULES)$(DL) >> $@
endif
ifdef EXPORTS
@echo $(DL)export $(EXPORTS)$(DL) >> $@
endif
ifdef IMPORTS
@echo $(DL)import $(IMPORTS)$(DL) >> $@
endif
ifeq ($(LD),nlmconv)
@echo $(DL)input $(OBJS)$(DL) >> $@
@echo $(DL)input $(PRELUDE)$(DL) >> $@
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
endif

View File

@@ -19,6 +19,7 @@
# files in the "cfg" directory, but then the make file # files in the "cfg" directory, but then the make file
# in \src would need to be changed. # in \src would need to be changed.
# #
# $Id: Makefile.vc6,v 1.17 2004/01/13 08:57:01 bagder Exp $
############################################################## ##############################################################
# CHANGE LOG # CHANGE LOG
# ------------------------------------------------------------ # ------------------------------------------------------------
@@ -37,12 +38,17 @@ LIB_NAME_DEBUG = libcurld
OPENSSL_PATH = ../../openssl-0.9.7a OPENSSL_PATH = ../../openssl-0.9.7a
!ENDIF !ENDIF
!IFNDEF ZLIB_PATH
ZLIB_PATH = ../../zlib-1.1.4
!ENDIF
############################################################# #############################################################
## Nothing more to do below this line! ## Nothing more to do below this line!
CCNODBG = cl.exe /MD /O2 /D "NDEBUG" CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl" CFLAGSSSL = /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSZLIB = /D "HAVE_ZLIB_H" /D "HAVE_ZLIB" /D "HAVE_LIBZ" /I "$(ZLIB_PATH)"
CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS" CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
LNKDLL = link.exe /DLL /def:libcurl.def LNKDLL = link.exe /DLL /def:libcurl.def
@@ -100,6 +106,19 @@ CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res RESOURCE = $(DIROBJ)\libcurl.res
!ENDIF !ENDIF
######################
# release-ssl-zlib
!IF "$(CFG)" == "release-ssl-zlib"
TARGET =$(LIB_NAME).lib
DIROBJ =.\$(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32"
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(TARGET)
CC = $(CCNODBG) $(CFLAGSSSL) $(CFLAGSZLIB)
CFGSET = TRUE
!ENDIF
###################### ######################
# release-libcurl-ssl-dll # release-libcurl-ssl-dll
!IF "$(CFG)" == "release-libcurl-ssl-dll" !IF "$(CFG)" == "release-libcurl-ssl-dll"
@@ -169,6 +188,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
!MESSAGE release - release static library !MESSAGE release - release static library
!MESSAGE release-dll - release dll !MESSAGE release-dll - release dll
!MESSAGE release-ssl - release static library with ssl !MESSAGE release-ssl - release static library with ssl
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
!MESSAGE release-ssl-dll - release dll library with ssl !MESSAGE release-ssl-dll - release dll library with ssl
!MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl !MESSAGE release-libcurl-ssl-dll - static libcurl with shared ssl
!MESSAGE debug - debug static library !MESSAGE debug - debug static library
@@ -222,6 +242,8 @@ X_OBJS= \
$(DIROBJ)\http_negotiate.obj \ $(DIROBJ)\http_negotiate.obj \
$(DIROBJ)\http_ntlm.obj \ $(DIROBJ)\http_ntlm.obj \
$(DIROBJ)\md5.obj \ $(DIROBJ)\md5.obj \
$(DIROBJ)\strerror.obj \
$(DIROBJ)\content_encoding.obj \
$(RESOURCE) $(RESOURCE)
all : $(TARGET) all : $(TARGET)

View File

@@ -5,56 +5,53 @@ $Id$
| (__| |_| | _ <| |___ | (__| |_| | _ <| |___
\___|\___/|_| \_\_____| \___|\___/|_| \_\_____|
How To Build libcurl to Use ares For Asynch Name Resolves How To Build libcurl to Use c-ares For Asynch Name Resolves
========================================================= ===========================================================
ares: c-ares:
ftp://athena-dist.mit.edu/pub/ATHENA/ares/ares-1.1.1.tar.gz http://daniel.haxx.se/projects/c-ares/
http://curl.haxx.se/dev/ares-1.1.1.tar.gz
http://curl.sourceforge.net/dev/ares-1.1.1.tar.gz
http://curl.planetmirror.com/dev/ares-1.1.1.tar.gz
http://curl.tsuren.net/dev/ares-1.1.1.tar.gz
c-ares: (a patched and improved version of ares)
http://curl.haxx.se/beta/arescurl-1.0-pre1.tar.gz
NOTE NOTE
libcurl works with ares 1.1.1, but several patches and improvements have libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
been put into the c-ares package which has made it more portable and better 1.2.0 or alter.
working on several platforms.
Build ares Once upon the time libcurl built fine with the "original" ares. That is no
========== longer true. You need to use c-ares. c-ares is based on ares but improved.
1. unpack the ares archive Build c-ares
2. cd ares-dir ============
1. unpack the c-ares archive
2. cd c-ares-dir
3. ./configure 3. ./configure
4. make 4. make
Build libcurl to use ares in the curl source tree Build libcurl to use c-ares in the curl source tree
================================================= ===================================================
1. name the ares source directory 'ares' in the curl source directory 1. name the c-ares source directory 'ares' in the curl source directory
(if you have checked out the curl sources from CVS, you will already have
c-ares in a directory named ares).
2. ./configure --enable-ares 2. ./configure --enable-ares
3. make 3. make
Build libcurl to use an installed ares Build libcurl to use an installed c-ares
====================================== ========================================
1. ./configure --enable-ares=/path/to/ares/install 1. ./configure --enable-ares=/path/to/ares/install
2. make 2. make
Ares and ipv6 c-ares and ipv6
============= ===============
If the configure script enables IPv6 support you need to explicitly disable If the configure script enables IPv6 support you need to explicitly disable
that (--disable-ipv6) since ares isn't IPv6 compatible (yet). that (--disable-ipv6) since c-ares isn't IPv6 compatible (yet).
Ares on win32 c-ares on win32
============= ===============
(description brought by Dominick Meglio) (description brought by Dominick Meglio)
First I compiled curl-ares. I changed the default C runtime library to be the First I compiled c-ares. I changed the default C runtime library to be the
single-threaded rather than the multi-threaded (this seems to be required to single-threaded rather than the multi-threaded (this seems to be required to
prevent linking errors later on). Then I simply build the areslib project (the prevent linking errors later on). Then I simply build the areslib project (the
other projects adig/ahost seem to fail under MSVC). other projects adig/ahost seem to fail under MSVC).

43
lib/README.curlx Normal file
View File

@@ -0,0 +1,43 @@
$Id$
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Source Code Functions Apps Might Use
====================================
The libcurl source code offers a few functions by source only. They are not
part of the official libcurl API, but the source files might be useful for
others so apps can optionally compile/build with these sources to gain
additional functions.
strtoofft.[ch]
==============
curlx_strtoofft()
A macro that converts a string containing a number to a curl_off_t number.
This might use the curlx_strtoll() function which is provided as source
code in strtoofft.c. Note that the function is only provided if no
strtoll() (or equivalent) function exist on your platform. If curl_off_t
is only a 32 bit number on your platform, this macro uses strtol().
timeval.[ch]
============
Provides a 'struct timeval' for platforms that don't have one already, and
includes the proper include files for those that have one. Using this will
make the output require the 'winmm' lib on Windows (unless WITHOUT_MM_LIB
is defined at compile-time).
curlx_tvnow()
returns a struct timeval for the current time.
curlx_tvdiff()
returns the difference between two timeval structs, in number of
milliseconds.

485
lib/config-netware.h Normal file
View File

@@ -0,0 +1,485 @@
/* lib/config.h.in. Generated from configure.ac by autoheader. */
/* to disable DICT */
#undef CURL_DISABLE_DICT
/* to disable FILE */
#undef CURL_DISABLE_FILE
/* to disable FTP */
#undef CURL_DISABLE_FTP
/* to disable GOPHER */
#undef CURL_DISABLE_GOPHER
/* to disable HTTP */
#undef CURL_DISABLE_HTTP
/* to disable LDAP */
#undef CURL_DISABLE_LDAP
/* to disable TELNET */
#undef CURL_DISABLE_TELNET
/* Set to explicitly specify we don't want to use thread-safe functions */
#undef DISABLED_THREADSAFE
/* your Entropy Gathering Daemon socket pathname */
#undef EGD_SOCKET
/* Define if you want to enable IPv6 support */
#undef ENABLE_IPV6
/* Define to 1 if you have the <alloca.h> header file. */
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if you have the `closesocket' function. */
#undef HAVE_CLOSESOCKET
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
/* Define to 1 if you have the <crypto.h> header file. */
#undef HAVE_CRYPTO_H
/* Define to 1 if you have the <des.h> header file. */
#undef HAVE_DES_H
/* disabled non-blocking sockets */
#undef HAVE_DISABLED_NONBLOCKING
/* Define to 1 if you have the <dlfcn.h> header file. */
/* XXX: #undef HAVE_DLFCN_H */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `dlopen' function. */
#define HAVE_DLOPEN 1
/* Define to 1 if you have the <err.h> header file. */
#define HAVE_ERR_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* use FIONBIO for non-blocking sockets */
/* XXX: #undef HAVE_FIONBIO */
#define HAVE_FIONBIO 1
/* Define if getaddrinfo exists and works */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `geteuid' function. */
#undef HAVE_GETEUID
/* Define to 1 if you have the `gethostbyaddr' function. */
#define HAVE_GETHOSTBYADDR 1
/* Define to 1 if you have the `gethostbyaddr_r' function. */
#undef HAVE_GETHOSTBYADDR_R
/* gethostbyaddr_r() takes 5 args */
#undef HAVE_GETHOSTBYADDR_R_5
/* gethostbyaddr_r() takes 7 args */
#undef HAVE_GETHOSTBYADDR_R_7
/* gethostbyaddr_r() takes 8 args */
#undef HAVE_GETHOSTBYADDR_R_8
/* Define to 1 if you have the `gethostbyname_r' function. */
#undef HAVE_GETHOSTBYNAME_R
/* gethostbyname_r() takes 3 args */
#undef HAVE_GETHOSTBYNAME_R_3
/* gethostbyname_r() takes 5 args */
#undef HAVE_GETHOSTBYNAME_R_5
/* gethostbyname_r() takes 6 args */
#undef HAVE_GETHOSTBYNAME_R_6
/* Define to 1 if you have the `getpass_r' function. */
#undef HAVE_GETPASS_R
/* Define to 1 if you have the `getpwuid' function. */
#undef HAVE_GETPWUID
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
/* if you have the gssapi libraries */
#undef HAVE_GSSAPI
/* if you have the Heimdal gssapi libraries */
#undef HAVE_GSSHEIMDAL
/* if you have the MIT gssapi libraries */
#undef HAVE_GSSMIT
/* Define to 1 if you have the `inet_addr' function. */
#define HAVE_INET_ADDR 1
/* Define to 1 if you have the `inet_ntoa' function. */
#define HAVE_INET_NTOA 1
/* Define to 1 if you have the `inet_ntoa_r' function. */
#undef HAVE_INET_NTOA_R
/* inet_ntoa_r() is declared */
#undef HAVE_INET_NTOA_R_DECL
/* Define to 1 if you have the `inet_pton' function. */
#define HAVE_INET_PTON 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* use ioctlsocket() for non-blocking sockets */
#undef HAVE_IOCTLSOCKET
/* use Ioctlsocket() for non-blocking sockets */
#undef HAVE_IOCTLSOCKET_CASE
/* Define to 1 if you have the <io.h> header file. */
#undef HAVE_IO_H
/* if you have the Kerberos4 libraries (including -ldes) */
#undef HAVE_KRB4
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
/* Define to 1 if you have the <krb.h> header file. */
#undef HAVE_KRB_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the `resolve' library (-lresolve). */
#undef HAVE_LIBRESOLVE
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
/* If zlib is available */
#undef HAVE_LIBZ
//#define HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
/* if your compiler supports 'long long' */
#define HAVE_LONGLONG 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <openssl/crypto.h> header file. */
#undef HAVE_OPENSSL_CRYPTO_H
/* Define to 1 if you have the <openssl/engine.h> header file. */
#undef HAVE_OPENSSL_ENGINE_H
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/pem.h> header file. */
#undef HAVE_OPENSSL_PEM_H
/* Define to 1 if you have the <openssl/rsa.h> header file. */
#undef HAVE_OPENSSL_RSA_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define to 1 if you have the <openssl/x509.h> header file. */
#undef HAVE_OPENSSL_X509_H
/* use O_NONBLOCK for non-blocking sockets */
#undef HAVE_O_NONBLOCK
/* Define to 1 if you have the <pem.h> header file. */
#undef HAVE_PEM_H
/* Define to 1 if you have the `perror' function. */
#undef HAVE_PERROR
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the `RAND_egd' function. */
#undef HAVE_RAND_EGD
/* Define to 1 if you have the `RAND_screen' function. */
#undef HAVE_RAND_SCREEN
/* Define to 1 if you have the `RAND_status' function. */
#undef HAVE_RAND_STATUS
/* Define to 1 if you have the <rsa.h> header file. */
#undef HAVE_RSA_H
/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1
/* Define to 1 if you have the <setjmp.h> header file. */
#define HAVE_SETJMP_H 1
/* Define to 1 if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if you have the `siginterrupt' function. */
#undef HAVE_SIGINTERRUPT
/* Define to 1 if you have the `signal' function. */
#define HAVE_SIGNAL 1
/* If you have sigsetjmp */
#undef HAVE_SIGSETJMP
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* use SO_NONBLOCK for non-blocking sockets */
#undef HAVE_SO_NONBLOCK
/* Define this if you have the SPNEGO library fbopenssl */
#undef HAVE_SPNEGO
/* Define to 1 if you have the <ssl.h> header file. */
#undef HAVE_SSL_H
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strcmpi' function. */
#undef HAVE_STRCMPI
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the `stricmp' function. */
#undef HAVE_STRICMP
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
#define HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/poll.h> header file. */
#undef HAVE_SYS_POLL_H
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/sockio.h> header file. */
#define HAVE_SYS_SOCKIO_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/utime.h> header file. */
#undef HAVE_SYS_UTIME_H
/* Define to 1 if you have the `tcgetattr' function. */
#undef HAVE_TCGETATTR
/* Define to 1 if you have the `tcsetattr' function. */
#undef HAVE_TCSETATTR
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the `uname' function. */
#define HAVE_UNAME 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `utime' function. */
#undef HAVE_UTIME
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define to 1 if you have the <winsock.h> header file. */
#undef HAVE_WINSOCK_H
/* Define this symbol if your OS supports changing the contents of argv */
#undef HAVE_WRITABLE_ARGV
/* Define to 1 if you have the <x509.h> header file. */
#undef HAVE_X509_H
/* if you have the zlib.h header file */
#define HAVE_ZLIB_H 1
/* need REENTRANT defined */
#undef NEED_REENTRANT
/* cpu-machine-OS */
#define OS "i386-pc-NetWare"
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* a suitable file to read random data from */
#undef RANDOM_FILE
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to the type of arg 1 for `select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
#undef SELECT_TYPE_ARG5
/* The size of a `curl_off_t', as computed by sizeof. */
#define SIZEOF_CURL_OFF_T 4
/* Define to 1 if you have the ANSI C header files. */
/* XXX: #undef STDC_HEADERS */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define if you want to enable ares support */
#undef USE_ARES
/* Version number of package */
#undef VERSION
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* type to use in place of in_addr_t if not defined */
#undef in_addr_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* type to use in place of socklen_t if not defined */
#define socklen_t int
/* the signed version of size_t */
#undef ssize_t

View File

@@ -25,10 +25,12 @@
#define HAVE_IO_H 1 #define HAVE_IO_H 1
#define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET 1
#define HAVE_INET_PTON 1 #define HAVE_INET_PTON 1
#define HAVE_LONGLONG 1
#define HAVE_MALLOC_H 1 #define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1
#define HAVE_NETDB_H 1 #define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1 #define HAVE_NETINET_IN_H 1
#define HAVE_NETINET_TCP_H 1
#define HAVE_NET_IF_H 1 #define HAVE_NET_IF_H 1
#define HAVE_PERROR 1 #define HAVE_PERROR 1
#define HAVE_SELECT 1 #define HAVE_SELECT 1
@@ -38,12 +40,14 @@
#define HAVE_SIGACTION 1 #define HAVE_SIGACTION 1
#define HAVE_SIGSETJMP 1 #define HAVE_SIGSETJMP 1
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
#define HAVE_SPNEGO 1
#define HAVE_STRCASECMP 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_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
#define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_TYPES_H 1
@@ -53,9 +57,13 @@
#define HAVE_UNISTD_H 1 #define HAVE_UNISTD_H 1
#define HAVE_VPRINTF 1 #define HAVE_VPRINTF 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_LONG_LONG 8 #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

View File

@@ -32,7 +32,15 @@
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> /* for TCP_NODELAY */
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -52,6 +60,13 @@
#include <stdlib.h> /* required for free() prototype, without it, this crashes #include <stdlib.h> /* required for free() prototype, without it, this crashes
on macos 68K */ on macos 68K */
#endif #endif
#if (defined(HAVE_FIONBIO) && defined(__NOVELL_LIBC__))
#include <sys/filio.h>
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#ifdef VMS #ifdef VMS
#include <in.h> #include <in.h>
#include <inet.h> #include <inet.h>
@@ -79,6 +94,7 @@
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "if2ip.h" #include "if2ip.h"
#include "strerror.h"
#include "connect.h" #include "connect.h"
/* The last #include file should be: */ /* The last #include file should be: */
@@ -131,7 +147,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
#ifdef HAVE_IOCTLSOCKET #ifdef HAVE_IOCTLSOCKET
/* Windows? */ /* Windows? */
int flags; unsigned long flags;
flags = nonblock; flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags); return ioctlsocket(sockfd, FIONBIO, &flags);
#define SETBLOCK 3 #define SETBLOCK 3
@@ -288,10 +304,10 @@ static CURLcode bindlocal(struct connectdata *conn,
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
data->set.device, strlen(data->set.device)+1) != 0) { data->set.device, strlen(data->set.device)+1) != 0) {
/* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n", /* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
sockfd, data->set.device, strerror(errno)); */ sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */
infof(data, "SO_BINDTODEVICE %s failed\n", infof(data, "SO_BINDTODEVICE %s failed\n",
data->set.device); data->set.device);
/* This is typiclally "errno 1, error: Operation not permitted" if /* This is typically "errno 1, error: Operation not permitted" if
you're not running as root or another suitable privileged user */ you're not running as root or another suitable privileged user */
} }
} }
@@ -346,37 +362,9 @@ static CURLcode bindlocal(struct connectdata *conn,
} }
#endif #endif
if(!bindworked) { if(!bindworked) {
switch(errno) { failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
case EBADF:
failf(data, "Invalid descriptor: %d", errno);
break;
case EINVAL:
failf(data, "Invalid request: %d", errno);
break;
case EACCES:
failf(data, "Address is protected, user not superuser: %d", errno);
break;
case ENOTSOCK:
failf(data,
"Argument is a descriptor for a file, not a socket: %d",
errno);
break;
case EFAULT:
failf(data, "Inaccessable memory error: %d", errno);
break;
case ENAMETOOLONG:
failf(data, "Address too long: %d", errno);
break;
case ENOMEM:
failf(data, "Insufficient kernel memory was available: %d", errno);
break;
default:
failf(data, "errno %d", errno);
break;
} /* end of switch(errno) */
return CURLE_HTTP_PORT_FAILED; return CURLE_HTTP_PORT_FAILED;
} /* end of else */ }
} /* end of if h */ } /* end of if h */
else { else {
@@ -417,6 +405,7 @@ static bool verifyconnect(curl_socket_t sockfd)
/* This wasn't a successful connect */ /* This wasn't a successful connect */
return FALSE; return FALSE;
#else #else
(void)sockfd;
return TRUE; return TRUE;
#endif #endif
} }
@@ -480,8 +469,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
} }
else if(1 != rc) { else if(1 != rc) {
int error = Curl_ourerrno(); int error = Curl_ourerrno();
failf(data, "Failed connect to %s:%d, errno: %d", failf(data, "Failed connect to %s:%d; %s",
conn->hostname, conn->port, error); conn->hostname, conn->port, Curl_strerror(conn,error));
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }
/* /*
@@ -495,6 +484,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
static void Curl_setNoDelay(struct connectdata *conn,
curl_socket_t sockfd)
{
#ifdef TCP_NODELAY
struct SessionHandle *data= conn->data;
socklen_t onoff = (socklen_t) data->set.tcp_nodelay;
if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&onoff,
sizeof(onoff)) < 0)
infof(data, "Could not set TCP_NODELAY: %s\n",
Curl_strerror(conn, Curl_ourerrno()));
else
infof(data,"TCP_NODELAY set\n");
#else
(void)conn;
(void)sockfd;
#endif
}
/* /*
* TCP connect to the given host with timeout, proxy or remote doesn't matter. * TCP connect to the given host with timeout, proxy or remote doesn't matter.
@@ -571,8 +577,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
*/ */
for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) { for (ai = remotehost->addr; ai; ai = ai->ai_next, aliasindex++) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd < 0) if (sockfd == CURL_SOCKET_BAD)
continue; continue;
else if(data->set.tcp_nodelay)
Curl_setNoDelay(conn, sockfd);
#else #else
/* /*
* Connecting with old style IPv4-only support * Connecting with old style IPv4-only support
@@ -592,6 +601,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
return CURLE_COULDNT_CONNECT; /* big time error */ return CURLE_COULDNT_CONNECT; /* big time error */
} }
else if(data->set.tcp_nodelay)
Curl_setNoDelay(conn, sockfd);
/* nasty address work before connect can be made */ /* nasty address work before connect can be made */
memset((char *) &serv_addr, '\0', sizeof(serv_addr)); memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr), memcpy((char *)&(serv_addr.sin_addr),
@@ -643,8 +655,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
break; break;
default: default:
/* unknown error, fallthrough and try another address! */ /* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to %s IP number %d: %d", failf(data, "Failed to connect to %s IP number %d: %s",
hostname, aliasindex+1, error); hostname, aliasindex+1, Curl_strerror(conn,error));
break; break;
} }
} }
@@ -681,10 +693,10 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
} }
before = after; before = after;
} }
if (sockfd < 0) { if (sockfd == CURL_SOCKET_BAD) {
/* no good connect was made */ /* no good connect was made */
*sockconn = -1; *sockconn = -1;
failf(data, "Connect failed"); failf(data, "Connect failed; %s", Curl_strerror(conn,Curl_ourerrno()));
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /D "_WINDLL" /FR /FD /c
# SUBTRACT CPP /YX # SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /FR /FD /GZ /c
# SUBTRACT CPP /WX /YX # SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
@@ -387,6 +387,22 @@ SOURCE=.\http_digest.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\http_ntlm.c
# End Source File
# Begin Source File
SOURCE=.\http_ntlm.h
# End Source File
# Begin Source File
SOURCE=.\inet_pton.c
# End Source File
# Begin Source File
SOURCE=.\inet_pton.h
# End Source File
# Begin Source File
SOURCE=.\md5.c SOURCE=.\md5.c
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -198,8 +198,12 @@ CURL *curl_easy_init(void)
struct SessionHandle *data; struct SessionHandle *data;
/* Make sure we inited the global SSL stuff */ /* Make sure we inited the global SSL stuff */
if (!initialized) if (!initialized) {
curl_global_init(CURL_GLOBAL_DEFAULT); res = curl_global_init(CURL_GLOBAL_DEFAULT);
if(res)
/* something in the global init failed, return nothing */
return NULL;
}
/* We use curl_open() with undefined URL so far */ /* We use curl_open() with undefined URL so far */
res = Curl_open(&data); res = Curl_open(&data);
@@ -267,7 +271,7 @@ CURLcode curl_easy_perform(CURL *curl)
} }
if (!data->hostcache) { if (!data->hostcache) {
data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); data->hostcache = Curl_mk_dnscache();
if(!data->hostcache) if(!data->hostcache)
/* While we possibly could survive and do good without a host cache, /* While we possibly could survive and do good without a host cache,

View File

@@ -196,7 +196,7 @@ CURLcode Curl_file(struct connectdata *conn)
/* If we have selected NOBODY and HEADER, it means that we only want file /* If we have selected NOBODY and HEADER, it means that we only want file
information. Which for FILE can't be much more than the file size and information. Which for FILE can't be much more than the file size and
date. */ date. */
if(data->set.no_body && data->set.include_header && fstated) { if(conn->bits.no_body && data->set.include_header && fstated) {
CURLcode result; CURLcode result;
sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size); sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0); result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
@@ -242,7 +242,7 @@ CURLcode Curl_file(struct connectdata *conn)
it avoids problems with select() and recv() on file descriptors it avoids problems with select() and recv() on file descriptors
in Winsock */ in Winsock */
if(fstated) if(fstated)
Curl_pgrsSetDownloadSize(data, (double)expected_size); Curl_pgrsSetDownloadSize(data, expected_size);
if(conn->resume_from) if(conn->resume_from)
lseek(fd, conn->resume_from, SEEK_SET); lseek(fd, conn->resume_from, SEEK_SET);
@@ -268,7 +268,7 @@ CURLcode Curl_file(struct connectdata *conn)
if(res) if(res)
return res; return res;
Curl_pgrsSetDownloadCounter(data, (double)bytecount); Curl_pgrsSetDownloadCounter(data, bytecount);
if(Curl_pgrsUpdate(conn)) if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK; res = CURLE_ABORTED_BY_CALLBACK;

View File

@@ -176,7 +176,7 @@ int FormParse(char *input,
struct curl_httppost **httppost, struct curl_httppost **httppost,
struct curl_httppost **last_post) struct curl_httppost **last_post)
{ {
/* nextarg MUST be a string in the format 'name=contents' and we'll /* 'input' MUST be a string in the format 'name=contents' and we'll
build a linked list with the info */ build a linked list with the info */
char name[256]; char name[256];
char *contents; char *contents;
@@ -975,6 +975,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return return_value; return return_value;
} }
/*
* curl_formadd() is a public API to add a section to the multipart formpost.
*/
CURLFORMcode curl_formadd(struct curl_httppost **httppost, CURLFORMcode curl_formadd(struct curl_httppost **httppost,
struct curl_httppost **last_post, struct curl_httppost **last_post,
...) ...)
@@ -987,6 +991,9 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
return result; return result;
} }
/*
* AddFormData() adds a chunk of data to the FormData linked list.
*/
static size_t AddFormData(struct FormData **formp, static size_t AddFormData(struct FormData **formp,
const void *line, const void *line,
size_t length) size_t length)
@@ -1014,6 +1021,9 @@ static size_t AddFormData(struct FormData **formp,
return length; return length;
} }
/*
* AddFormDataf() adds printf()-style formatted data to the formdata chain.
*/
static size_t AddFormDataf(struct FormData **formp, static size_t AddFormDataf(struct FormData **formp,
const char *fmt, ...) const char *fmt, ...)
@@ -1027,7 +1037,10 @@ static size_t AddFormDataf(struct FormData **formp,
return AddFormData(formp, s, 0); return AddFormData(formp, s, 0);
} }
/*
* Curl_FormBoundary() creates a suitable boundary string and returns an
* allocated one.
*/
char *Curl_FormBoundary(void) char *Curl_FormBoundary(void)
{ {
char *retstring; char *retstring;
@@ -1056,7 +1069,10 @@ char *Curl_FormBoundary(void)
return retstring; return retstring;
} }
/* Used from http.c, this cleans a built FormData linked list */ /*
* Curl_formclean() is used from http.c, this cleans a built FormData linked
* list
*/
void Curl_formclean(struct FormData *form) void Curl_formclean(struct FormData *form)
{ {
struct FormData *next; struct FormData *next;
@@ -1069,7 +1085,10 @@ void Curl_formclean(struct FormData *form)
} while((form=next)); /* continue */ } while((form=next)); /* continue */
} }
/* external function to free up a whole form post chain */ /*
* curl_formfree() is an external function to free up a whole form post
* chain
*/
void curl_formfree(struct curl_httppost *form) void curl_formfree(struct curl_httppost *form)
{ {
struct curl_httppost *next; struct curl_httppost *next;
@@ -1098,9 +1117,16 @@ void curl_formfree(struct curl_httppost *form)
} while((form=next)); /* continue */ } while((form=next)); /* continue */
} }
/*
* Curl_getFormData() converts a linked list of "meta data" into a complete
* (possibly huge) multipart formdata. The input list is in 'post', while the
* output resulting linked lists gets stored in '*finalform'. *sizep will get
* the total size of the whole POST.
*/
CURLcode Curl_getFormData(struct FormData **finalform, CURLcode Curl_getFormData(struct FormData **finalform,
struct curl_httppost *post, struct curl_httppost *post,
size_t *sizep) curl_off_t *sizep)
{ {
struct FormData *form = NULL; struct FormData *form = NULL;
struct FormData *firstform; struct FormData *firstform;
@@ -1218,11 +1244,14 @@ CURLcode Curl_getFormData(struct FormData **finalform,
char buffer[1024]; char buffer[1024];
size_t nread; size_t nread;
fileread = strequal("-", file->contents)?stdin: fileread = strequal("-", file->contents)?
/* binary read for win32 crap */ stdin:fopen(file->contents, "rb"); /* binary read for win32 */
/*VMS??*/ fopen(file->contents, "rb"); /* ONLY ALLOWS FOR STREAM FILES ON VMS */ /*
/*VMS?? Stream files are OK, as are FIXED & VAR files WITHOUT implied CC */ * VMS: This only allows for stream files on VMS. Stream files are
/*VMS?? For implied CC, every record needs to have a \n appended & 1 added to SIZE */ * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
* every record needs to have a \n appended & 1 added to SIZE
*/
if(fileread) { if(fileread) {
while((nread = fread(buffer, 1, 1024, fileread))) while((nread = fread(buffer, 1, 1024, fileread)))
size += AddFormData(&form, buffer, nread); size += AddFormData(&form, buffer, nread);
@@ -1231,10 +1260,6 @@ CURLcode Curl_getFormData(struct FormData **finalform,
fclose(fileread); fclose(fileread);
} }
else { else {
#if 0
/* File wasn't found, add a nothing field! */
size += AddFormData(&form, "", 0);
#endif
Curl_formclean(firstform); Curl_formclean(firstform);
free(boundary); free(boundary);
*finalform = NULL; *finalform = NULL;
@@ -1278,6 +1303,10 @@ CURLcode Curl_getFormData(struct FormData **finalform,
return result; return result;
} }
/*
* Curl_FormInit() inits the struct 'form' points to with the 'formdata'
* and resets the 'sent' counter.
*/
int Curl_FormInit(struct Form *form, struct FormData *formdata ) int Curl_FormInit(struct Form *form, struct FormData *formdata )
{ {
if(!formdata) if(!formdata)
@@ -1289,7 +1318,10 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
return 0; return 0;
} }
/* fread() emulation */ /*
* Curl_FormReader() is the fread() emulation function that will be used to
* deliver the formdata to the transfer loop and then sent away to the peer.
*/
size_t Curl_FormReader(char *buffer, size_t Curl_FormReader(char *buffer,
size_t size, size_t size,
size_t nitems, size_t nitems,
@@ -1335,48 +1367,25 @@ size_t Curl_FormReader(char *buffer,
return gotsize; return gotsize;
} }
/* possible (old) fread() emulation that copies at most one line */ /*
size_t Curl_FormReadOneLine(char *buffer, * Curl_formpostheader() returns the first line of the formpost, the
size_t size, * request-header part (which is not part of the request-body like the rest of
size_t nitems, * the post).
FILE *mydata) */
char *Curl_formpostheader(void *formp, size_t *len)
{ {
struct Form *form; char *header;
size_t wantedsize; struct Form *form=(struct Form *)formp;
size_t gotsize;
form=(struct Form *)mydata;
wantedsize = size * nitems;
if(!form->data) if(!form->data)
return 0; /* nothing, error, empty */ return 0; /* nothing, ERROR! */
do { header = form->data->line;
*len = form->data->length;
if( (form->data->length - form->sent ) > wantedsize ) {
memcpy(buffer, form->data->line + form->sent, wantedsize);
form->sent += wantedsize;
return wantedsize;
}
memcpy(buffer,
form->data->line + form->sent,
gotsize = (form->data->length - form->sent) );
form->sent = 0;
form->data = form->data->next; /* advance */ form->data = form->data->next; /* advance */
} while(!gotsize && form->data); return header;
/* If we got an empty line and we have more data, we proceed to the next
line immediately to avoid returning zero before we've reached the end.
This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
return gotsize;
} }

View File

@@ -57,7 +57,7 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata );
CURLcode CURLcode
Curl_getFormData(struct FormData **, Curl_getFormData(struct FormData **,
struct curl_httppost *post, struct curl_httppost *post,
size_t *size); curl_off_t *size);
/* fread() emulation */ /* fread() emulation */
size_t Curl_FormReader(char *buffer, size_t Curl_FormReader(char *buffer,
@@ -65,11 +65,12 @@ size_t Curl_FormReader(char *buffer,
size_t nitems, size_t nitems,
FILE *mydata); FILE *mydata);
/* possible (old) fread() emulation that copies at most one line */ /*
size_t Curl_FormReadOneLine(char *buffer, * Curl_formpostheader() returns the first line of the formpost, the
size_t size, * request-header part (which is not part of the request-body like the rest of
size_t nitems, * the post).
FILE *mydata); */
char *Curl_formpostheader(void *formp, size_t *len);
char *Curl_FormBoundary(void); char *Curl_FormBoundary(void);

156
lib/ftp.c
View File

@@ -65,6 +65,11 @@
#include <errno.h> #include <errno.h>
#endif #endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include <curl/curl.h> #include <curl/curl.h>
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
@@ -86,6 +91,7 @@
#include "strequal.h" #include "strequal.h"
#include "ssluse.h" #include "ssluse.h"
#include "connect.h" #include "connect.h"
#include "strerror.h"
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h" #include "inet_ntoa_r.h"
@@ -99,12 +105,19 @@
#include "memdebug.h" #include "memdebug.h"
#endif #endif
#ifdef HAVE_NI_WITHSCOPEID
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
#else
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
#endif
/* Local API functions */ /* Local API functions */
static CURLcode ftp_sendquote(struct connectdata *conn, static CURLcode ftp_sendquote(struct connectdata *conn,
struct curl_slist *quote); struct curl_slist *quote);
static CURLcode ftp_cwd(struct connectdata *conn, char *path); static CURLcode ftp_cwd(struct connectdata *conn, char *path);
static CURLcode ftp_mkd(struct connectdata *conn, char *path); static CURLcode ftp_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path); static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
static CURLcode ftp_quit(struct connectdata *conn);
/* easy-to-use macro: */ /* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result #define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result
@@ -112,11 +125,21 @@ static CURLcode ftp_cwd_and_mkd(struct connectdata *conn, char *path);
static void freedirs(struct FTP *ftp) static void freedirs(struct FTP *ftp)
{ {
int i; int i;
for (i=0; ftp->dirs[i]; i++){ if(ftp->dirs) {
for (i=0; i < ftp->dirdepth; i++){
if(ftp->dirs[i]) {
free(ftp->dirs[i]); free(ftp->dirs[i]);
ftp->dirs[i]=NULL; ftp->dirs[i]=NULL;
} }
} }
free(ftp->dirs);
ftp->dirs = NULL;
}
if(ftp->file) {
free(ftp->file);
ftp->file = NULL;
}
}
/*********************************************************************** /***********************************************************************
* *
@@ -166,7 +189,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
default: default:
/* we have received data here */ /* we have received data here */
{ {
int s; curl_socket_t s;
size_t size = sizeof(struct sockaddr_in); size_t size = sizeof(struct sockaddr_in);
struct sockaddr_in add; struct sockaddr_in add;
@@ -175,7 +198,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
sclose(sock); /* close the first socket */ sclose(sock); /* close the first socket */
if (-1 == s) { if (CURL_SOCKET_BAD == s) {
/* DIE! */ /* DIE! */
failf(data, "Error accept()ing server connect"); failf(data, "Error accept()ing server connect");
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
@@ -334,6 +357,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line */ * line */
int i; int i;
conn->headerbytecount += gotbytes;
*nreadp += gotbytes; *nreadp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) { for(i = 0; i < gotbytes; ptr++, i++) {
perline++; perline++;
@@ -580,13 +605,13 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
infof(data, "We have successfully logged in\n"); infof(data, "We have successfully logged in\n");
if (conn->ssl[FIRSTSOCKET].use) { if (conn->ssl[FIRSTSOCKET].use) {
#ifdef HAVE_KRB4 #ifdef HAVE_KRB4
/* we are logged in (with Kerberos) /* We are logged in with Kerberos, now set the requested protection
* now set the requested protection level * level
*/ */
if(conn->sec_complete) if(conn->sec_complete)
Curl_sec_set_protection_level(conn); Curl_sec_set_protection_level(conn);
/* we may need to issue a KAUTH here to have access to the files /* We may need to issue a KAUTH here to have access to the files
* do it if user supplied a password * do it if user supplied a password
*/ */
if(conn->passwd && *conn->passwd) { if(conn->passwd && *conn->passwd) {
@@ -719,14 +744,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
bool was_ctl_valid = ftp->ctl_valid;
/* free the dir tree parts */ /* free the dir tree and file parts */
freedirs(ftp); freedirs(ftp);
if(ftp->file) { ftp->ctl_valid = FALSE;
free(ftp->file);
ftp->file = NULL;
}
if(data->set.upload) { if(data->set.upload) {
if((-1 != data->set.infilesize) && if((-1 != data->set.infilesize) &&
@@ -761,12 +784,14 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
} }
} }
ftp->ctl_valid = was_ctl_valid;
#ifdef HAVE_KRB4 #ifdef HAVE_KRB4
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]); Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
#endif #endif
/* shut down the socket to inform the server we're done */ /* shut down the socket to inform the server we're done */
sclose(conn->sock[SECONDARYSOCKET]); sclose(conn->sock[SECONDARYSOCKET]);
conn->sock[SECONDARYSOCKET] = -1; conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
if(!ftp->no_transfer) { if(!ftp->no_transfer) {
/* Let's see what the server says about the transfer we just performed, /* Let's see what the server says about the transfer we just performed,
@@ -949,7 +974,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
if(ftpcode == 213) { if(ftpcode == 213) {
/* get the size from the ascii string: */ /* get the size from the ascii string: */
*size = strtoofft(buf+4, NULL, 0); *size = curlx_strtoofft(buf+4, NULL, 0);
} }
else else
return CURLE_FTP_COULDNT_GET_SIZE; return CURLE_FTP_COULDNT_GET_SIZE;
@@ -1068,14 +1093,9 @@ ftp_pasv_verbose(struct connectdata *conn,
char hbuf[NI_MAXHOST]; /* ~1KB */ char hbuf[NI_MAXHOST]; /* ~1KB */
char nbuf[NI_MAXHOST]; /* ~1KB */ char nbuf[NI_MAXHOST]; /* ~1KB */
char sbuf[NI_MAXSERV]; /* around 32 */ char sbuf[NI_MAXSERV]; /* around 32 */
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif
(void)port; /* prevent compiler warning */ (void)port; /* prevent compiler warning */
if (getnameinfo(addr->ai_addr, addr->ai_addrlen, if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) { nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), NIFLAGS)) {
snprintf(nbuf, sizeof(nbuf), "?"); snprintf(nbuf, sizeof(nbuf), "?");
snprintf(sbuf, sizeof(sbuf), "?"); snprintf(sbuf, sizeof(sbuf), "?");
} }
@@ -1121,11 +1141,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
char hbuf[NI_MAXHOST]; char hbuf[NI_MAXHOST];
struct sockaddr *sa=(struct sockaddr *)&ss; struct sockaddr *sa=(struct sockaddr *)&ss;
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif
unsigned char *ap; unsigned char *ap;
unsigned char *pp; unsigned char *pp;
char portmsgbuf[4096], tmp[4096]; char portmsgbuf[4096], tmp[4096];
@@ -1133,6 +1148,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
char **modep; char **modep;
int rc; int rc;
int error;
/* /*
* we should use Curl_if2ip? given pickiness of recent ftpd, * we should use Curl_if2ip? given pickiness of recent ftpd,
@@ -1146,7 +1162,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0, rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
niflags); NIFLAGS);
if(rc) { if(rc) {
failf(data, "getnameinfo() returned %d\n", rc); failf(data, "getnameinfo() returned %d\n", rc);
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
@@ -1167,6 +1183,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
portsock = CURL_SOCKET_BAD; portsock = CURL_SOCKET_BAD;
error = 0;
for (ai = res; ai; ai = ai->ai_next) { for (ai = res; ai; ai = ai->ai_next) {
/* /*
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype): * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
@@ -1175,16 +1192,20 @@ CURLcode ftp_use_port(struct connectdata *conn)
ai->ai_socktype = hints.ai_socktype; ai->ai_socktype = hints.ai_socktype;
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (portsock == CURL_SOCKET_BAD) if (portsock == CURL_SOCKET_BAD) {
error = Curl_ourerrno();
continue; continue;
}
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) { if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
error = Curl_ourerrno();
sclose(portsock); sclose(portsock);
portsock = CURL_SOCKET_BAD; portsock = CURL_SOCKET_BAD;
continue; continue;
} }
if (listen(portsock, 1) < 0) { if (listen(portsock, 1) < 0) {
error = Curl_ourerrno();
sclose(portsock); sclose(portsock);
portsock = CURL_SOCKET_BAD; portsock = CURL_SOCKET_BAD;
continue; continue;
@@ -1194,13 +1215,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
freeaddrinfo(res); freeaddrinfo(res);
if (portsock == CURL_SOCKET_BAD) { if (portsock == CURL_SOCKET_BAD) {
failf(data, "%s", strerror(errno)); failf(data, "%s", Curl_strerror(conn,error));
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
sslen = sizeof(ss); sslen = sizeof(ss);
if (getsockname(portsock, sa, &sslen) < 0) { if (getsockname(portsock, sa, &sslen) < 0) {
failf(data, "%s", strerror(errno)); failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
@@ -1236,7 +1257,8 @@ CURLcode ftp_use_port(struct connectdata *conn)
if (eprtaf < 0) if (eprtaf < 0)
continue; continue;
if (getnameinfo((struct sockaddr *)&ss, sslen, if (getnameinfo((struct sockaddr *)&ss, sslen,
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags)) portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp),
NIFLAGS))
continue; continue;
/* do not transmit IPv6 scope identifier to the wire */ /* do not transmit IPv6 scope identifier to the wire */
@@ -1250,7 +1272,8 @@ CURLcode ftp_use_port(struct connectdata *conn)
portmsgbuf, tmp); portmsgbuf, tmp);
if(result) if(result)
return result; return result;
} else if (strcmp(*modep, "LPRT") == 0 || }
else if (strcmp(*modep, "LPRT") == 0 ||
strcmp(*modep, "PORT") == 0) { strcmp(*modep, "PORT") == 0) {
int i; int i;
@@ -1596,7 +1619,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
newport = num; newport = num;
/* we should use the same host we already are connected to */ /* we should use the same host we already are connected to */
newhostp = conn->name; newhostp = conn->hostname;
} }
} }
else else
@@ -1820,7 +1843,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
/* When we know we're uploading a specified file, we can get the file /* When we know we're uploading a specified file, we can get the file
size prior to the actual upload. */ size prior to the actual upload. */
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */ result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
SECONDARYSOCKET, bytecountp); SECONDARYSOCKET, bytecountp);
@@ -1828,7 +1851,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
return result; return result;
} }
else if(!data->set.no_body) { else if(!conn->bits.no_body) {
/* Retrieve file or directory */ /* Retrieve file or directory */
bool dirlist=FALSE; bool dirlist=FALSE;
curl_off_t downloadsize=-1; curl_off_t downloadsize=-1;
@@ -1839,10 +1862,10 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
char *ptr; char *ptr;
char *ptr2; char *ptr2;
from=strtoofft(conn->range, &ptr, 0); from=curlx_strtoofft(conn->range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-'))) while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++; ptr++;
to=strtoofft(ptr, &ptr2, 0); to=curlx_strtoofft(ptr, &ptr2, 0);
if(ptr == ptr2) { if(ptr == ptr2) {
/* we didn't get any digit */ /* we didn't get any digit */
to=-1; to=-1;
@@ -2061,7 +2084,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
/* only if we have nothing but digits: */ /* only if we have nothing but digits: */
if(bytes++) { if(bytes++) {
/* get the number! */ /* get the number! */
size = strtoofft(bytes, NULL, 0); size = curlx_strtoofft(bytes, NULL, 0);
} }
} }
@@ -2150,7 +2173,7 @@ CURLcode ftp_perform(struct connectdata *conn,
{ {
int i; /* counter for loop */ int i; /* counter for loop */
for (i=0; ftp->dirs[i]; i++) { for (i=0; i < ftp->dirdepth; i++) {
/* RFC 1738 says empty components should be respected too, but /* RFC 1738 says empty components should be respected too, but
that is plain stupid since CWD can't be used with an empty argument */ that is plain stupid since CWD can't be used with an empty argument */
if ((result = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK) if ((result = ftp_cwd_and_mkd(conn, ftp->dirs[i])) != CURLE_OK)
@@ -2199,7 +2222,7 @@ CURLcode ftp_perform(struct connectdata *conn,
/* If we have selected NOBODY and HEADER, it means that we only want file /* If we have selected NOBODY and HEADER, it means that we only want file
information. Which in FTP can't be much more than the file size and information. Which in FTP can't be much more than the file size and
date. */ date. */
if(data->set.no_body && data->set.include_header && ftp->file) { if(conn->bits.no_body && data->set.include_header && ftp->file) {
/* The SIZE command is _not_ RFC 959 specified, and therefor many servers /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
may not support it! It is however the only way we have to get a file's may not support it! It is however the only way we have to get a file's
size! */ size! */
@@ -2262,7 +2285,7 @@ CURLcode ftp_perform(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
if(data->set.no_body) if(conn->bits.no_body)
/* doesn't really transfer any data */ /* doesn't really transfer any data */
ftp->no_transfer = TRUE; ftp->no_transfer = TRUE;
/* Get us a second connection up and connected */ /* Get us a second connection up and connected */
@@ -2295,7 +2318,7 @@ CURLcode ftp_perform(struct connectdata *conn,
* The input argument is already checked for validity. * The input argument is already checked for validity.
* *
* ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
* end of the function. * Curl_ftp_done() function without finding any major problem.
*/ */
CURLcode Curl_ftp(struct connectdata *conn) CURLcode Curl_ftp(struct connectdata *conn)
{ {
@@ -2305,9 +2328,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
struct FTP *ftp; struct FTP *ftp;
char *slash_pos; /* position of the first '/' char in curpos */ char *slash_pos; /* position of the first '/' char in curpos */
char *cur_pos=conn->ppath; /* current position in ppath. point at the begin char *cur_pos=conn->path; /* current position in ppath. point at the begin
of next path component */ of next path component */
int path_part=0;/* current path component */
/* the ftp struct is already inited in ftp_connect() */ /* the ftp struct is already inited in ftp_connect() */
ftp = conn->proto.ftp; ftp = conn->proto.ftp;
@@ -2319,23 +2341,28 @@ CURLcode Curl_ftp(struct connectdata *conn)
Curl_pgrsSetUploadSize(data, 0); Curl_pgrsSetUploadSize(data, 0);
Curl_pgrsSetDownloadSize(data, 0); Curl_pgrsSetDownloadSize(data, 0);
/* fixed : initialize ftp->dirs[xxx] to NULL ! ftp->dirdepth = 0;
is done in Curl_ftp_connect() */ ftp->diralloc = 5; /* default dir depth to allocate */
ftp->dirs = (char **)malloc(ftp->diralloc * sizeof(ftp->dirs[0]));
if(!ftp->dirs)
return CURLE_OUT_OF_MEMORY;
ftp->dirs[0] = NULL; /* to start with */
/* parse the URL path into separate path components */ /* parse the URL path into separate path components */
while((slash_pos=strchr(cur_pos, '/'))) { while((slash_pos=strchr(cur_pos, '/'))) {
/* 1 or 0 to indicate absolute directory */ /* 1 or 0 to indicate absolute directory */
bool absolute_dir = (cur_pos - conn->ppath > 0) && (path_part == 0); bool absolute_dir = (cur_pos - conn->path > 0) && (ftp->dirdepth == 0);
/* seek out the next path component */ /* seek out the next path component */
if (slash_pos-cur_pos) { if (slash_pos-cur_pos) {
/* we skip empty path components, like "x//y" since the FTP command CWD /* we skip empty path components, like "x//y" since the FTP command CWD
requires a parameter and a non-existant parameter a) doesn't work on requires a parameter and a non-existant parameter a) doesn't work on
many servers and b) has no effect on the others. */ many servers and b) has no effect on the others. */
ftp->dirs[path_part] = curl_unescape(cur_pos - absolute_dir, ftp->dirs[ftp->dirdepth] = curl_unescape(cur_pos - absolute_dir,
slash_pos - cur_pos + absolute_dir); slash_pos - cur_pos +
absolute_dir);
if (!ftp->dirs[path_part]) { /* run out of memory ... */ if (!ftp->dirs[ftp->dirdepth]) { /* run out of memory ... */
failf(data, "no memory"); failf(data, "no memory");
freedirs(ftp); freedirs(ftp);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -2348,12 +2375,16 @@ CURLcode Curl_ftp(struct connectdata *conn)
if(!retcode) { if(!retcode) {
cur_pos = slash_pos + 1; /* jump to the rest of the string */ cur_pos = slash_pos + 1; /* jump to the rest of the string */
if(++path_part >= (CURL_MAX_FTP_DIRDEPTH-1)) { if(++ftp->dirdepth >= ftp->diralloc) {
/* too deep, we need the last entry to be kept NULL at all /* enlarge array */
times to signal end of list */ char *bigger;
failf(data, "too deep dir hierarchy"); ftp->diralloc *= 2; /* double the size each time */
bigger = realloc(ftp->dirs, ftp->diralloc * sizeof(ftp->dirs[0]));
if(!bigger) {
freedirs(ftp); freedirs(ftp);
return CURLE_URL_MALFORMAT; return CURLE_OUT_OF_MEMORY;
}
ftp->dirs = (char **)bigger;
} }
} }
} }
@@ -2378,10 +2409,10 @@ CURLcode Curl_ftp(struct connectdata *conn)
if(connected) if(connected)
retcode = Curl_ftp_nextconnect(conn); retcode = Curl_ftp_nextconnect(conn);
if(retcode && (conn->sock[SECONDARYSOCKET] >= 0)) { if(retcode && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
/* Failure detected, close the second socket if it was created already */ /* Failure detected, close the second socket if it was created already */
sclose(conn->sock[SECONDARYSOCKET]); sclose(conn->sock[SECONDARYSOCKET]);
conn->sock[SECONDARYSOCKET] = -1; conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
} }
if(ftp->no_transfer) if(ftp->no_transfer)
@@ -2394,7 +2425,8 @@ CURLcode Curl_ftp(struct connectdata *conn)
else else
freedirs(ftp); freedirs(ftp);
ftp->ctl_valid = TRUE; ftp->ctl_valid = TRUE; /* seems good */
return retcode; return retcode;
} }
@@ -2449,7 +2481,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
/*********************************************************************** /***********************************************************************
* *
* Curl_ftp_quit() * ftp_quit()
* *
* This should be called before calling sclose() on an ftp control connection * This should be called before calling sclose() on an ftp control connection
* (not data connections). We should then wait for the response from the * (not data connections). We should then wait for the response from the
@@ -2457,7 +2489,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
* connection. * connection.
* *
*/ */
CURLcode Curl_ftp_quit(struct connectdata *conn) static CURLcode ftp_quit(struct connectdata *conn)
{ {
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
@@ -2487,13 +2519,13 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
bad in any way, sending quit and waiting around here will make the bad in any way, sending quit and waiting around here will make the
disconnect wait in vain and cause more problems than we need to. disconnect wait in vain and cause more problems than we need to.
Curl_ftp_quit() will check the state of ftp->ctl_valid. If it's ok it ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
will try to send the QUIT command, otherwise it will just return. will try to send the QUIT command, otherwise it will just return.
*/ */
/* The FTP session may or may not have been allocated/setup at this point! */ /* The FTP session may or may not have been allocated/setup at this point! */
if(ftp) { if(ftp) {
(void)Curl_ftp_quit(conn); /* ignore errors on the QUIT */ (void)ftp_quit(conn); /* ignore errors on the QUIT */
if(ftp->entrypath) if(ftp->entrypath)
free(ftp->entrypath); free(ftp->entrypath);
@@ -2501,10 +2533,6 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
free(ftp->cache); free(ftp->cache);
ftp->cache = NULL; ftp->cache = NULL;
} }
if(ftp->file) {
free(ftp->file);
ftp->file = NULL; /* zero */
}
freedirs(ftp); freedirs(ftp);
} }
return CURLE_OK; return CURLE_OK;

View File

@@ -32,7 +32,6 @@ CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
int *ftpcode); int *ftpcode);
CURLcode Curl_ftp_nextconnect(struct connectdata *conn); CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
CURLcode Curl_ftp_quit(struct connectdata *conn);
#endif #endif
#endif #endif

View File

@@ -742,16 +742,16 @@ ToYear (int Year)
static int static int
LookupWord (YYSTYPE *yylval, char *buff) LookupWord (YYSTYPE *yylval, char *buff)
{ {
register char *p; char *p;
register char *q; char *q;
register const TABLE *tp; const TABLE *tp;
int i; size_t i;
int abbrev; int abbrev;
/* Make it lowercase. */ /* Make it lowercase. */
for (p = buff; *p; p++) for (p = buff; *p; p++)
if (ISUPPER ((unsigned char) *p)) if (ISUPPER ((unsigned char) *p))
*p = tolower (*p); *p = tolower ((int)*p);
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
{ {

View File

@@ -135,25 +135,25 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
*param_doublep = data->progress.t_starttransfer; *param_doublep = data->progress.t_starttransfer;
break; break;
case CURLINFO_SIZE_UPLOAD: case CURLINFO_SIZE_UPLOAD:
*param_doublep = data->progress.uploaded; *param_doublep = (double)data->progress.uploaded;
break; break;
case CURLINFO_SIZE_DOWNLOAD: case CURLINFO_SIZE_DOWNLOAD:
*param_doublep = data->progress.downloaded; *param_doublep = (double)data->progress.downloaded;
break; break;
case CURLINFO_SPEED_DOWNLOAD: case CURLINFO_SPEED_DOWNLOAD:
*param_doublep = data->progress.dlspeed; *param_doublep = (double)data->progress.dlspeed;
break; break;
case CURLINFO_SPEED_UPLOAD: case CURLINFO_SPEED_UPLOAD:
*param_doublep = data->progress.ulspeed; *param_doublep = (double)data->progress.ulspeed;
break; break;
case CURLINFO_SSL_VERIFYRESULT: case CURLINFO_SSL_VERIFYRESULT:
*param_longp = data->set.ssl.certverifyresult; *param_longp = data->set.ssl.certverifyresult;
break; break;
case CURLINFO_CONTENT_LENGTH_DOWNLOAD: case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
*param_doublep = data->progress.size_dl; *param_doublep = (double)data->progress.size_dl;
break; break;
case CURLINFO_CONTENT_LENGTH_UPLOAD: case CURLINFO_CONTENT_LENGTH_UPLOAD:
*param_doublep = data->progress.size_ul; *param_doublep = (double)data->progress.size_ul;
break; break;
case CURLINFO_REDIRECT_TIME: case CURLINFO_REDIRECT_TIME:
*param_doublep = data->progress.t_redirect; *param_doublep = data->progress.t_redirect;

View File

@@ -49,6 +49,9 @@
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
#include <stdlib.h> /* required for free() prototypes */ #include <stdlib.h> /* required for free() prototypes */
#endif #endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for the close() proto */
#endif
#ifdef VMS #ifdef VMS
#include <in.h> #include <in.h>
#include <inet.h> #include <inet.h>
@@ -60,11 +63,21 @@
#include <setjmp.h> #include <setjmp.h>
#endif #endif
#ifdef WIN32
#include <process.h>
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "hostip.h" #include "hostip.h"
#include "hash.h" #include "hash.h"
#include "share.h" #include "share.h"
#include "strerror.h"
#include "url.h" #include "url.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
@@ -83,19 +96,32 @@
#define ARES_SUCCESS CURLE_OK #define ARES_SUCCESS CURLE_OK
#endif #endif
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
many seconds for a name resolve */
/* These two symbols are for the global DNS cache */
static curl_hash hostname_cache; static curl_hash hostname_cache;
static int host_cache_initialized; static int host_cache_initialized;
static void freednsentry(void *freethis);
/*
* my_getaddrinfo() is the generic low-level name resolve API within this
* source file. There exist three versions of this function - for different
* name resolve layers (selected at build-time). They all take this same set
* of arguments
*/
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
char *hostname, char *hostname,
int port, int port,
int *waitp); int *waitp);
#ifndef ENABLE_IPV6
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \ #if (!defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
defined(USE_THREADING_GETHOSTBYNAME) defined(USE_THREADING_GETHOSTBYNAME)) && \
!defined(ENABLE_IPV6)
static struct hostent* pack_hostent(char** buf, struct hostent* orig); static struct hostent* pack_hostent(char** buf, struct hostent* orig);
#endif #endif
#endif
#ifdef USE_THREADING_GETHOSTBYNAME #ifdef USE_THREADING_GETHOSTBYNAME
#ifdef DEBUG_THREADING_GETHOSTBYNAME #ifdef DEBUG_THREADING_GETHOSTBYNAME
@@ -108,29 +134,40 @@ static void trace_it (const char *fmt, ...);
#define TRACE(x) #define TRACE(x)
#endif #endif
static struct hostent* pack_hostent (char** buf, struct hostent* orig);
static bool init_gethostbyname_thread (struct connectdata *conn, static bool init_gethostbyname_thread (struct connectdata *conn,
const char *hostname, int port); const char *hostname, int port);
struct thread_data { struct thread_data {
HANDLE thread_hnd; HANDLE thread_hnd;
DWORD thread_id; unsigned thread_id;
DWORD thread_status; DWORD thread_status;
curl_socket_t dummy_sock; /* dummy for Curl_multi_ares_fdset() */
}; };
#endif #endif
/*
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
* Global DNS cache is general badness. Do not use. This will be removed in
* a future version. Use the share interface instead!
*/
void Curl_global_host_cache_init(void) void Curl_global_host_cache_init(void)
{ {
if (!host_cache_initialized) { if (!host_cache_initialized) {
Curl_hash_init(&hostname_cache, 7, Curl_freednsinfo); Curl_hash_init(&hostname_cache, 7, freednsentry);
host_cache_initialized = 1; host_cache_initialized = 1;
} }
} }
/*
* Return a pointer to the global cache
*/
curl_hash *Curl_global_host_cache_get(void) curl_hash *Curl_global_host_cache_get(void)
{ {
return &hostname_cache; return &hostname_cache;
} }
/*
* Destroy and cleanup the global DNS cache
*/
void Curl_global_host_cache_dtor(void) void Curl_global_host_cache_dtor(void)
{ {
if (host_cache_initialized) { if (host_cache_initialized) {
@@ -139,7 +176,10 @@ void Curl_global_host_cache_dtor(void)
} }
} }
/* count the number of characters that an integer takes up */ /*
* Minor utility-function:
* Count the number of characters that an integer takes up.
*/
static int _num_chars(int i) static int _num_chars(int i)
{ {
int chars = 0; int chars = 0;
@@ -160,7 +200,10 @@ static int _num_chars(int i)
return chars; return chars;
} }
/* Create a hostcache id */ /*
* Minor utility-function:
* Create a hostcache id string for the DNS caching.
*/
static char * static char *
create_hostcache_id(char *server, int port, size_t *entry_len) create_hostcache_id(char *server, int port, size_t *entry_len)
{ {
@@ -187,6 +230,13 @@ struct hostcache_prune_data {
time_t now; time_t now;
}; };
/*
* This function is set as a callback to be called for every entry in the DNS
* cache when we want to prune old unused entries.
*
* Returning non-zero means remove the entry, return 0 to keep it in the
* cache.
*/
static int static int
hostcache_timestamp_remove(void *datap, void *hc) hostcache_timestamp_remove(void *datap, void *hc)
{ {
@@ -204,6 +254,9 @@ hostcache_timestamp_remove(void *datap, void *hc)
return 1; return 1;
} }
/*
* Prune the DNS cache. This assumes that a lock has already been taken.
*/
static void static void
hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now) hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
{ {
@@ -217,6 +270,10 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
hostcache_timestamp_remove); hostcache_timestamp_remove);
} }
/*
* Library-wide function for pruning the DNS cache. This function takes and
* returns the appropriate locks.
*/
void Curl_hostcache_prune(struct SessionHandle *data) void Curl_hostcache_prune(struct SessionHandle *data)
{ {
time_t now; time_t now;
@@ -240,15 +297,22 @@ void Curl_hostcache_prune(struct SessionHandle *data)
} }
#ifdef HAVE_SIGSETJMP #ifdef HAVE_SIGSETJMP
/* Beware this is a global and unique instance */ /* Beware this is a global and unique instance. This is used to store the
return address that we can jump back to from inside a signal handler. This
is not thread-safe stuff. */
sigjmp_buf curl_jmpenv; sigjmp_buf curl_jmpenv;
#endif #endif
/* When calling Curl_resolv() has resulted in a response with a returned /*
address, we call this function to store the information in the dns * cache_resolv_response() stores a 'Curl_addrinfo' struct in the DNS cache.
cache etc */ *
* When calling Curl_resolv() has resulted in a response with a returned
* address, we call this function to store the information in the dns
* cache etc
*
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
*/
static struct Curl_dns_entry * static struct Curl_dns_entry *
cache_resolv_response(struct SessionHandle *data, cache_resolv_response(struct SessionHandle *data,
Curl_addrinfo *addr, Curl_addrinfo *addr,
@@ -298,14 +362,21 @@ cache_resolv_response(struct SessionHandle *data,
return dns; return dns;
} }
/* Resolve a name and return a pointer in the 'entry' argument if one /*
is available. * Curl_resolv() is the main name resolve function within libcurl. It resolves
* a name and returns a pointer to the entry in the 'entry' argument (if one
Return codes: * is provided). This function might return immediately if we're using asynch
* resolves. See the return codes.
-1 = error, no pointer *
0 = OK, pointer provided * The cache entry we return will get its 'inuse' counter increased when this
1 = waiting for response, no pointer * function is used. You MUST call Curl_resolv_unlock() later (when you're
* done using this struct) to decrease the counter again.
*
* Return codes:
*
* -1 = error, no pointer
* 0 = OK, pointer provided
* 1 = waiting for response, no pointer
*/ */
int Curl_resolv(struct connectdata *conn, int Curl_resolv(struct connectdata *conn,
char *hostname, char *hostname,
@@ -400,6 +471,11 @@ int Curl_resolv(struct connectdata *conn,
return rc; return rc;
} }
/*
* Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
* made, the struct may be destroyed due to pruning. It is important that only
* one unlock is made for each Curl_resolv() call.
*/
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
{ {
if(data->share) if(data->share)
@@ -433,9 +509,9 @@ void Curl_freeaddrinfo(Curl_addrinfo *p)
} }
/* /*
* Free a cache dns entry. * File-internal: free a cache dns entry.
*/ */
void Curl_freednsinfo(void *freethis) static void freednsentry(void *freethis)
{ {
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis; struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
@@ -444,6 +520,14 @@ void Curl_freednsinfo(void *freethis)
free(p); free(p);
} }
/*
* Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
*/
curl_hash *Curl_mk_dnscache(void)
{
return Curl_hash_alloc(7, freednsentry);
}
/* --- resolve name or IP-number --- */ /* --- resolve name or IP-number --- */
/* Allocate enough memory to hold the full name information structs and /* Allocate enough memory to hold the full name information structs and
@@ -455,6 +539,15 @@ void Curl_freednsinfo(void *freethis)
#ifdef USE_ARES #ifdef USE_ARES
/*
* Curl_multi_ares_fdset() is called when someone from the outside world
* (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
* with ares. The caller must make sure that this function is only called when
* we have a working ares channel.
*
* Returns: CURLE_OK always!
*/
CURLcode Curl_multi_ares_fdset(struct connectdata *conn, CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
@@ -468,24 +561,32 @@ CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
/* called to check if the name is resolved now */ /*
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
* request has completed. It should also make sure to time-out if the
* operation seems to take too long.
*
* Returns normal CURLcode errors.
*/
CURLcode Curl_is_resolved(struct connectdata *conn, CURLcode Curl_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns) struct Curl_dns_entry **dns)
{ {
fd_set read_fds, write_fds; fd_set read_fds, write_fds;
static const struct timeval tv={0,0}; struct timeval tv={0,0};
int count; int count;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
int nfds; int nfds;
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
FD_ZERO(&write_fds); FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds); nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
count = select(nfds, &read_fds, &write_fds, NULL, count = select(nfds, &read_fds, &write_fds, NULL,
(struct timeval *)&tv); (struct timeval *)&tv);
if(count) /* Call ares_process() unconditonally here, even if we simply timed out
above, as otherwise the ares name resolve won't timeout! */
ares_process(data->state.areschannel, &read_fds, &write_fds); ares_process(data->state.areschannel, &read_fds, &write_fds);
*dns = NULL; *dns = NULL;
@@ -500,23 +601,21 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
/* This is a function that locks and waits until the name resolve operation /*
has completed. * Curl_wait_for_resolv() waits for a resolve to finish. This function should
* be avoided since using this risk getting the multi interface to "hang".
If 'entry' is non-NULL, make it point to the resolved dns entry *
* If 'entry' is non-NULL, make it point to the resolved dns entry
Return CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and *
CURLE_OPERATION_TIMEDOUT if a time-out occurred. * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
*/ */
CURLcode Curl_wait_for_resolv(struct connectdata *conn, CURLcode Curl_wait_for_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry) struct Curl_dns_entry **entry)
{ {
CURLcode rc=CURLE_OK; CURLcode rc=CURLE_OK;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct timeval now = Curl_tvnow(); long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
bool timedout = FALSE;
long timeout = 300; /* default name resolve timeout in seconds */
long elapsed = 0; /* time taken so far */
/* now, see if there's a connect timeout or a regular timeout to /* now, see if there's a connect timeout or a regular timeout to
use instead of the default one */ use instead of the default one */
@@ -525,34 +624,46 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
else if(conn->data->set.timeout) else if(conn->data->set.timeout)
timeout = conn->data->set.timeout; timeout = conn->data->set.timeout;
/* We convert the number of seconds into number of milliseconds here: */
if(timeout < 2147483)
/* maximum amount of seconds that can be multiplied with 1000 and
still fit within 31 bits */
timeout *= 1000;
else
timeout = 0x7fffffff; /* ridiculous amount of time anyway */
/* Wait for the name resolve query to complete. */ /* Wait for the name resolve query to complete. */
while (1) { while (1) {
int nfds=0; int nfds=0;
fd_set read_fds, write_fds; fd_set read_fds, write_fds;
struct timeval *tvp, tv, store; struct timeval *tvp, tv, store;
int count; int count;
struct timeval now = Curl_tvnow();
long timediff;
store.tv_sec = (int)(timeout - elapsed); store.tv_sec = (int)timeout/1000;
store.tv_usec = 0; store.tv_usec = (timeout%1000)*1000;
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
FD_ZERO(&write_fds); FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds); nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
if (nfds == 0) if (nfds == 0)
/* no file descriptors means we're done waiting */
break; break;
tvp = ares_timeout(data->state.areschannel, tvp = ares_timeout(data->state.areschannel, &store, &tv);
&store, &tv);
count = select(nfds, &read_fds, &write_fds, NULL, tvp); count = select(nfds, &read_fds, &write_fds, NULL, tvp);
if (count < 0 && errno != EINVAL) if (count < 0 && errno != EINVAL)
break; break;
else if(!count) {
/* timeout */
timedout = TRUE;
break;
}
ares_process(data->state.areschannel, &read_fds, &write_fds); ares_process(data->state.areschannel, &read_fds, &write_fds);
elapsed = Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */ timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
timeout -= timediff?timediff:1; /* always deduct at least 1 */
if (timeout < 0) {
/* our timeout, so we cancel the ares operation */
ares_cancel(data->state.areschannel);
break;
}
} }
/* Operation complete, if the lookup was successful we now have the entry /* Operation complete, if the lookup was successful we now have the entry
@@ -563,12 +674,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
if(!conn->async.dns) { if(!conn->async.dns) {
/* a name was not resolved */ /* a name was not resolved */
if(timedout || (conn->async.status == ARES_ETIMEOUT)) { if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
failf(data, "Resolving host timed out: %s", conn->name); failf(data, "Resolving host timed out: %s", conn->hostname);
rc = CURLE_OPERATION_TIMEDOUT; rc = CURLE_OPERATION_TIMEDOUT;
} }
else if(conn->async.done) { else if(conn->async.done) {
failf(data, "Could not resolve host: %s (%s)", conn->name, failf(data, "Could not resolve host: %s (%s)", conn->hostname,
ares_strerror(conn->async.status)); ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST; rc = CURLE_COULDNT_RESOLVE_HOST;
} }
@@ -586,8 +697,16 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
/* this function gets called by ares/gethostbyname_thread() when we got /*
the name resolved or not */ * host_callback() gets called by ares/gethostbyname_thread() when we got the
* name resolved (or not!).
*
* If the status argument is ARES_SUCCESS, we must copy the hostent field
* since ares will free it when this function returns. This operation stores
* the resolved data in the DNS cache.
*
* The storage operation locks and unlocks the DNS cache.
*/
static void host_callback(void *arg, /* "struct connectdata *" */ static void host_callback(void *arg, /* "struct connectdata *" */
int status, int status,
struct hostent *hostent) struct hostent *hostent)
@@ -628,9 +747,11 @@ static void host_callback(void *arg, /* "struct connectdata *" */
#ifdef USE_ARES #ifdef USE_ARES
/* /*
* Return name information about the given hostname and port number. If * my_getaddrinfo() when using ares for name resolves.
*
* Returns name information about the given hostname and port number. If
* successful, the 'hostent' is returned and the forth argument will point to * successful, the 'hostent' is returned and the forth argument will point to
* memory we need to free after use. That meory *MUST* be freed with * memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else. * Curl_freeaddrinfo(), nothing else.
*/ */
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
@@ -643,6 +764,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
*waitp = FALSE; *waitp = FALSE;
if(data->set.ip_version == CURL_IPRESOLVE_V6)
/* an ipv6 address was requested and we can't get/use one */
return NULL;
bufp = strdup(hostname); bufp = strdup(hostname);
if(bufp) { if(bufp) {
@@ -665,9 +790,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
#if !defined(USE_ARES) && !defined(USE_THREADING_GETHOSTBYNAME) #if !defined(USE_ARES) && !defined(USE_THREADING_GETHOSTBYNAME)
/* For builds without ARES and threaded gethostbyname, Curl_resolv() can never /*
return wait==TRUE, so this function will never be called. If it still gets * Curl_wait_for_resolv() for builds without ARES and threaded gethostbyname,
called, we return failure at once. */ * Curl_resolv() can never return wait==TRUE, so this function will never be
* called. If it still gets called, we return failure at once.
*
* We provide this function only to allow multi.c to remain unaware if we are
* doing asynch resolves or not.
*/
CURLcode Curl_wait_for_resolv(struct connectdata *conn, CURLcode Curl_wait_for_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry) struct Curl_dns_entry **entry)
{ {
@@ -676,6 +806,13 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
return CURLE_COULDNT_RESOLVE_HOST; return CURLE_COULDNT_RESOLVE_HOST;
} }
/*
* This function will never be called when built with ares or threaded
* resolves. If it still gets called, we return failure at once.
*
* We provide this function only to allow multi.c to remain unaware if we are
* doing asynch resolves or not.
*/
CURLcode Curl_is_resolved(struct connectdata *conn, CURLcode Curl_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns) struct Curl_dns_entry **dns)
{ {
@@ -687,18 +824,32 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
#endif #endif
#if !defined(USE_ARES) #if !defined(USE_ARES)
/*
* Non-ares build. If we are using threading gethostbyname, then this must
* set the fd_set for the threaded resolve socket. If not, we just return OK.
*/
CURLcode Curl_multi_ares_fdset(struct connectdata *conn, CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
int *max_fdp) int *max_fdp)
{ {
#ifdef USE_THREADING_GETHOSTBYNAME
const struct thread_data *td =
(const struct thread_data *) conn->async.os_specific;
if (td && td->dummy_sock != CURL_SOCKET_BAD) {
FD_SET(td->dummy_sock,write_fd_set);
*max_fdp = td->dummy_sock;
}
#else /* if not USE_THREADING_GETHOSTBYNAME */
(void)conn; (void)conn;
(void)read_fd_set; (void)read_fd_set;
(void)write_fd_set; (void)write_fd_set;
(void)max_fdp; (void)max_fdp;
#endif
return CURLE_OK; return CURLE_OK;
} }
#endif #endif /* !USE_ARES */
#if defined(ENABLE_IPV6) && !defined(USE_ARES) #if defined(ENABLE_IPV6) && !defined(USE_ARES)
@@ -740,9 +891,11 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
#endif #endif
/* /*
* Return name information about the given hostname and port number. If * my_getaddrinfo() when built ipv6-enabled.
*
* Returns name information about the given hostname and port number. If
* successful, the 'addrinfo' is returned and the forth argument will point to * successful, the 'addrinfo' is returned and the forth argument will point to
* memory we need to free after use. That meory *MUST* be freed with * memory we need to free after use. That memory *MUST* be freed with
* Curl_freeaddrinfo(), nothing else. * Curl_freeaddrinfo(), nothing else.
*/ */
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
@@ -760,11 +913,17 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
/* see if we have an IPv6 stack */ /* see if we have an IPv6 stack */
s = socket(PF_INET6, SOCK_DGRAM, 0); s = socket(PF_INET6, SOCK_DGRAM, 0);
if (s < 0) if (s < 0) {
/* Some non-IPv6 stacks have been found to make very slow name resolves /* Some non-IPv6 stacks have been found to make very slow name resolves
* when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
* the stack seems to be a non-ipv6 one. */ * the stack seems to be a non-ipv6 one. */
if(data->set.ip_version == CURL_IPRESOLVE_V6)
/* an ipv6 address was requested and we can't get/use one */
return NULL;
pf = PF_INET; pf = PF_INET;
}
else { else {
/* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
* possible checks. And close the socket again. * possible checks. And close the socket again.
@@ -802,11 +961,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
} }
#else /* following code is IPv4-only */ #else /* following code is IPv4-only */
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) #if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
defined(USE_THREADING_GETHOSTBYNAME)
static void hostcache_fixoffset(struct hostent *h, long offset); static void hostcache_fixoffset(struct hostent *h, long offset);
/* /*
* Performs a "deep" copy of a hostent into a buffer (returns a pointer to the * pack_hostent() is a file-local function that performs a "deep" copy of a
* copy). Make absolutely sure the destination buffer is big enough! * hostent into a buffer (returns a pointer to the copy). Make absolutely sure
* the destination buffer is big enough!
*/ */
static struct hostent* pack_hostent(char** buf, struct hostent* orig) static struct hostent* pack_hostent(char** buf, struct hostent* orig)
{ {
@@ -882,11 +1044,11 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
/* now, shrink the allocated buffer to the size we actually need, which /* now, shrink the allocated buffer to the size we actually need, which
most often is only a fraction of the original alloc */ most often is only a fraction of the original alloc */
newbuf=(char *)realloc(*buf, (long)bufptr-(long)(*buf)); newbuf=(char *)realloc(*buf, (long)(bufptr-*buf));
/* if the alloc moved, we need to adjust things again */ /* if the alloc moved, we need to adjust things again */
if(newbuf != *buf) if(newbuf != *buf)
hostcache_fixoffset((struct hostent*)newbuf, (long)newbuf-(long)*buf); hostcache_fixoffset((struct hostent*)newbuf, (long)(newbuf-*buf));
/* setup the return */ /* setup the return */
*buf = newbuf; *buf = newbuf;
@@ -896,6 +1058,12 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
} }
#endif #endif
/*
* hostcache_fixoffset() is a utility-function that corrects all pointers in
* the given hostent struct according to the offset. This is typically used
* when a hostent has been reallocated and needs to be setup properly on the
* new address.
*/
static void hostcache_fixoffset(struct hostent *h, long offset) static void hostcache_fixoffset(struct hostent *h, long offset)
{ {
int i=0; int i=0;
@@ -920,6 +1088,11 @@ static void hostcache_fixoffset(struct hostent *h, long offset)
#ifndef USE_ARES #ifndef USE_ARES
/*
* MakeIP() converts the input binary ipv4-address to an ascii string in the
* dotted numerical format. 'addr' is a pointer to a buffer that is 'addr_len'
* bytes big. 'num' is the 32 bit IP number.
*/
static char *MakeIP(unsigned long num, char *addr, int addr_len) static char *MakeIP(unsigned long num, char *addr, int addr_len)
{ {
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R) #if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
@@ -941,9 +1114,13 @@ static char *MakeIP(unsigned long num, char *addr, int addr_len)
return (addr); return (addr);
} }
/* The original code to this function was once stolen from the Dancer source /*
code, written by Bjorn Reese, it has since been patched and modified * my_getaddrinfo() - the ipv4 "traditional" version.
considerably. */ *
* The original code to this function was once stolen from the Dancer source
* code, written by Bjorn Reese, it has since been patched and modified
* considerably.
*/
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn, static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
char *hostname, char *hostname,
int port, int port,
@@ -956,6 +1133,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
*waitp = 0; /* don't wait, we act synchronously */ *waitp = 0; /* don't wait, we act synchronously */
if(data->set.ip_version == CURL_IPRESOLVE_V6)
/* an ipv6 address was requested and we can't get/use one */
return NULL;
in=inet_addr(hostname); in=inet_addr(hostname);
if (in != CURL_INADDR_NONE) { if (in != CURL_INADDR_NONE) {
struct in_addr *addrentry; struct in_addr *addrentry;
@@ -1143,6 +1324,7 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
else { else {
#ifdef USE_THREADING_GETHOSTBYNAME #ifdef USE_THREADING_GETHOSTBYNAME
/* fire up a new resolver thread! */
if (init_gethostbyname_thread(conn,hostname,port)) { if (init_gethostbyname_thread(conn,hostname,port)) {
*waitp = TRUE; /* please wait for the response */ *waitp = TRUE; /* please wait for the response */
return NULL; return NULL;
@@ -1178,20 +1360,26 @@ static void trace_it (const char *fmt, ...)
static int do_trace = -1; static int do_trace = -1;
va_list args; va_list args;
if (do_trace == -1) if (do_trace == -1) {
do_trace = getenv("CURL_TRACE") ? 1 : 0; const char *env = getenv("CURL_TRACE");
do_trace = (env && atoi(env) > 0);
}
if (!do_trace) if (!do_trace)
return; return;
va_start (args, fmt); va_start (args, fmt);
vfprintf (stderr, fmt, args); vfprintf (stderr, fmt, args);
fflush (stderr); /*fflush (stderr); */ /* seems a bad idea in a multi-threaded app */
va_end (args); va_end (args);
} }
#endif #endif
/* For builds without ARES/USE_IPV6, create a resolver thread and wait on it. /*
* gethostbyname_thread() resolves a name, calls the host_callback and then
* exits.
*
* For builds without ARES/USE_IPV6, create a resolver thread and wait on it.
*/ */
static DWORD WINAPI gethostbyname_thread (void *arg) static unsigned __stdcall gethostbyname_thread (void *arg)
{ {
struct connectdata *conn = (struct connectdata*) arg; struct connectdata *conn = (struct connectdata*) arg;
struct hostent *he; struct hostent *he;
@@ -1210,32 +1398,43 @@ static DWORD WINAPI gethostbyname_thread (void *arg)
TRACE(("Winsock-error %d, addr %s\n", conn->async.status, TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
return (rc); return (rc);
/* An implicit ExitThread() here */ /* An implicit _endthreadex() here */
} }
/* complementary of ares_destroy /*
* destroy_thread_data() cleans up async resolver data.
* Complementary of ares_destroy.
*/ */
static void destroy_thread_data (struct connectdata *conn) static void destroy_thread_data (struct Curl_async *async)
{ {
if (conn->async.hostname) if (async->hostname)
free(conn->async.hostname); free(async->hostname);
if (conn->async.os_specific)
free(conn->async.os_specific); if (async->os_specific) {
conn->async.hostname = NULL; curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock;
conn->async.os_specific = NULL;
if (sock != CURL_SOCKET_BAD)
sclose(sock);
free(async->os_specific);
}
async->hostname = NULL;
async->os_specific = NULL;
} }
/*
* init_gethostbyname_thread() starts a new thread that performs
* the actual resolve. This function returns before the resolve is done.
*/
static bool init_gethostbyname_thread (struct connectdata *conn, static bool init_gethostbyname_thread (struct connectdata *conn,
const char *hostname, int port) const char *hostname, int port)
{ {
struct thread_data *td = malloc(sizeof(*td)); struct thread_data *td = calloc(sizeof(*td), 1);
if (!td) { if (!td) {
SetLastError(ENOMEM); SetLastError(ENOMEM);
return (0); return (0);
} }
memset (td, 0, sizeof(*td));
Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.hostname);
conn->async.hostname = strdup(hostname); conn->async.hostname = strdup(hostname);
if (!conn->async.hostname) { if (!conn->async.hostname) {
@@ -1250,17 +1449,31 @@ static bool init_gethostbyname_thread (struct connectdata *conn,
conn->async.dns = NULL; conn->async.dns = NULL;
conn->async.os_specific = (void*) td; conn->async.os_specific = (void*) td;
td->thread_hnd = CreateThread(NULL, 0, gethostbyname_thread, td->dummy_sock = CURL_SOCKET_BAD;
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, gethostbyname_thread,
conn, 0, &td->thread_id); conn, 0, &td->thread_id);
if (!td->thread_hnd) { if (!td->thread_hnd) {
TRACE(("CreateThread() failed; %lu\n", GetLastError())); SetLastError(errno);
destroy_thread_data(conn); TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
destroy_thread_data(&conn->async);
return (0); return (0);
} }
/* This socket is only to keep Curl_multi_ares_fdset() and select() happy;
* should never become signalled for read/write since it's unbound but
* Windows needs atleast 1 socket in select().
*/
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
return (1); return (1);
} }
/* called to check if the name is resolved now */ /*
* Curl_wait_for_resolv() waits for a resolve to finish. This function should
* be avoided since using this risk getting the multi interface to "hang".
*
* If 'entry' is non-NULL, make it point to the resolved dns entry
*
* This is the version for resolves-in-a-thread.
*/
CURLcode Curl_wait_for_resolv(struct connectdata *conn, CURLcode Curl_wait_for_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry) struct Curl_dns_entry **entry)
{ {
@@ -1274,26 +1487,31 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
/* now, see if there's a connect timeout or a regular timeout to /* now, see if there's a connect timeout or a regular timeout to
use instead of the default one */ use instead of the default one */
timeout = conn->data->set.connecttimeout ? conn->data->set.connecttimeout : timeout =
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
conn->data->set.timeout ? conn->data->set.timeout : conn->data->set.timeout ? conn->data->set.timeout :
300; /* default name resolve timeout in seconds */ CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
ticks = GetTickCount(); ticks = GetTickCount();
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout); status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) { if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
/* Thread finished before timeout; propagate Winsock error to this thread */ /* Thread finished before timeout; propagate Winsock error to this thread.
* 'conn->async.done = TRUE' is set in host_callback().
*/
WSASetLastError(conn->async.status); WSASetLastError(conn->async.status);
GetExitCodeThread(td->thread_hnd, &td->thread_status); GetExitCodeThread(td->thread_hnd, &td->thread_status);
TRACE(("status %lu, thread-status %08lX\n", status, td->thread_status)); TRACE(("gethostbyname_thread() status %lu, thread retval %lu, ",
status, td->thread_status));
} }
else { else {
conn->async.done = TRUE; conn->async.done = TRUE;
TerminateThread(td->thread_hnd, (DWORD)-1);
td->thread_status = (DWORD)-1; td->thread_status = (DWORD)-1;
TRACE(("gethostbyname_thread() timeout, "));
} }
TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n", TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
td->thread_status, GetTickCount()-ticks));
CloseHandle(td->thread_hnd);
if(entry) if(entry)
*entry = conn->async.dns; *entry = conn->async.dns;
@@ -1303,24 +1521,33 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
if (!conn->async.dns) { if (!conn->async.dns) {
/* a name was not resolved */ /* a name was not resolved */
if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) { if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
failf(data, "Resolving host timed out: %s", conn->name); failf(data, "Resolving host timed out: %s", conn->hostname);
rc = CURLE_OPERATION_TIMEDOUT; rc = CURLE_OPERATION_TIMEDOUT;
} }
else if(conn->async.done) { else if(conn->async.done) {
failf(data, "Could not resolve host: %s (code %lu)", conn->name, conn->async.status); failf(data, "Could not resolve host: %s; %s",
conn->hostname, Curl_strerror(conn,conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST; rc = CURLE_COULDNT_RESOLVE_HOST;
} }
else else
rc = CURLE_OPERATION_TIMEDOUT; rc = CURLE_OPERATION_TIMEDOUT;
}
destroy_thread_data(conn); destroy_thread_data(&conn->async);
if (CURLE_OK != rc)
/* close the connection, since we can't return failure here without /* close the connection, since we can't return failure here without
cleaning up this connection properly */ cleaning up this connection properly */
Curl_disconnect(conn); Curl_disconnect(conn);
}
return (rc); return (rc);
} }
/*
* Curl_is_resolved() is called repeatedly to check if a previous name resolve
* request has completed. It should also make sure to time-out if the
* operation seems to take too long.
*/
CURLcode Curl_is_resolved(struct connectdata *conn, CURLcode Curl_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **entry) struct Curl_dns_entry **entry)
{ {
@@ -1328,7 +1555,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
if (conn->async.done) { if (conn->async.done) {
/* we're done */ /* we're done */
destroy_thread_data(conn); destroy_thread_data(&conn->async);
if (!conn->async.dns) { if (!conn->async.dns) {
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n")); TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
return CURLE_COULDNT_RESOLVE_HOST; return CURLE_COULDNT_RESOLVE_HOST;

View File

@@ -74,8 +74,8 @@ void Curl_scan_cache_used(void *user, void *ptr);
/* free name info */ /* free name info */
void Curl_freeaddrinfo(Curl_addrinfo *freeaddr); void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
/* free cached name info */ /* make a new dns cache and return the handle */
void Curl_freednsinfo(void *freethis); curl_hash *Curl_mk_dnscache(void);
/* prune old entries from the DNS cache */ /* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct SessionHandle *data); void Curl_hostcache_prune(struct SessionHandle *data);

View File

@@ -105,8 +105,10 @@
static CURLcode Curl_output_basic_proxy(struct connectdata *conn); static CURLcode Curl_output_basic_proxy(struct connectdata *conn);
/* /*
* This function checks the linked list of custom HTTP headers for a particular * checkheaders() checks the linked list of custom HTTP headers for a
* header (prefix). * particular header (prefix).
*
* Returns a pointer to the first matching header or NULL if none matched.
*/ */
static char *checkheaders(struct SessionHandle *data, const char *thisheader) static char *checkheaders(struct SessionHandle *data, const char *thisheader)
{ {
@@ -120,6 +122,12 @@ static char *checkheaders(struct SessionHandle *data, const char *thisheader)
return NULL; return NULL;
} }
/*
* Curl_output_basic() sets up an Authorization: header for HTTP Basic
* authentication. It uses the conn->user, conn->passwd fields for it.
*
* Returns CURLcode.
*/
static CURLcode Curl_output_basic(struct connectdata *conn) static CURLcode Curl_output_basic(struct connectdata *conn)
{ {
char *authorization; char *authorization;
@@ -139,6 +147,13 @@ static CURLcode Curl_output_basic(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
/*
* Curl_output_basic_proxy() sets up a proxy-Authorization: header for HTTP
* Basic proxy authentication. It uses the conn->proxyuser and
* conn->proxypasswd fields for it.
*
* Returns CURLcode.
*/
static CURLcode Curl_output_basic_proxy(struct connectdata *conn) static CURLcode Curl_output_basic_proxy(struct connectdata *conn)
{ {
char *authorization; char *authorization;
@@ -186,33 +201,49 @@ void Curl_http_auth_act(struct connectdata *conn)
conn->newurl = strdup(data->change.url); /* clone URL */ conn->newurl = strdup(data->change.url); /* clone URL */
data->state.authavail = CURLAUTH_NONE; /* clear it here */ data->state.authavail = CURLAUTH_NONE; /* clear it here */
} }
else if(!data->state.authdone && (data->info.httpcode < 400)) {
/* no (known) authentication available,
authentication is not "done" yet and
no authentication seems to be required and
we didn't try HEAD or GET */
if((data->set.httpreq != HTTPREQ_GET) &&
(data->set.httpreq != HTTPREQ_HEAD)) {
conn->newurl = strdup(data->change.url); /* clone URL */
data->state.authdone = TRUE;
}
}
} }
/* /**
* Setup the authentication headers for the host/proxy and the correct * http_auth_headers() setups the authentication headers for the host/proxy
* authentication method. * and the correct authentication method. conn->data->state.authdone is set to
* TRUE when authentication is done.
*
* @param conn all information about the current connection
*
* Returns CURLcode
*/ */
static CURLcode http_auth_headers(struct connectdata *conn, static CURLcode http_auth_headers(struct connectdata *conn,
char *request, char *request,
char *path, char *path)
bool *ready) /* set TRUE when the auth phase
is done and ready to do the *actual*
request */
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
char *auth=NULL; char *auth=NULL;
*ready = FALSE; /* default is no */ curlassert(data);
if(!data->state.authstage) { if(!data->state.authstage) {
if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) if(conn->bits.httpproxy && conn->bits.proxy_user_passwd) {
data->state.authdone = FALSE;
Curl_http_auth_stage(data, 407); Curl_http_auth_stage(data, 407);
else if(conn->bits.user_passwd) }
else if(conn->bits.user_passwd) {
data->state.authdone = FALSE;
Curl_http_auth_stage(data, 401); Curl_http_auth_stage(data, 401);
}
else { else {
*ready = TRUE; data->state.authdone = TRUE;
return CURLE_OK; /* no authentication with no user or password */ return CURLE_OK; /* no authentication with no user or password */
} }
} }
@@ -229,7 +260,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
if(data->state.authwant == CURLAUTH_NTLM) { if(data->state.authwant == CURLAUTH_NTLM) {
auth=(char *)"NTLM"; auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, TRUE, ready); result = Curl_output_ntlm(conn, TRUE);
if(result) if(result)
return result; return result;
} }
@@ -244,7 +275,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
if(result) if(result)
return result; return result;
} }
*ready = TRUE; data->state.authdone = TRUE;
/* Switch to web authentication after proxy authentication is done */ /* Switch to web authentication after proxy authentication is done */
Curl_http_auth_stage(data, 401); Curl_http_auth_stage(data, 401);
} }
@@ -262,14 +293,14 @@ static CURLcode http_auth_headers(struct connectdata *conn,
result = Curl_output_negotiate(conn); result = Curl_output_negotiate(conn);
if (result) if (result)
return result; return result;
*ready = TRUE; data->state.authdone = TRUE;
} }
else else
#endif #endif
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
if(data->state.authwant == CURLAUTH_NTLM) { if(data->state.authwant == CURLAUTH_NTLM) {
auth=(char *)"NTLM"; auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, FALSE, ready); result = Curl_output_ntlm(conn, FALSE);
if(result) if(result)
return result; return result;
} }
@@ -284,7 +315,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
(unsigned char *)path); (unsigned char *)path);
if(result) if(result)
return result; return result;
*ready = TRUE; data->state.authdone = TRUE;
} }
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */ else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
if(conn->bits.user_passwd && if(conn->bits.user_passwd &&
@@ -295,7 +326,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
return result; return result;
} }
/* basic is always ready */ /* basic is always ready */
*ready = TRUE; data->state.authdone = TRUE;
} }
} }
if(auth) if(auth)
@@ -304,7 +335,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
} }
} }
else else
*ready = TRUE; data->state.authdone = TRUE;
return result; return result;
} }
@@ -365,8 +396,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) { if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
/* 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); conn->newurl = strdup(data->change.url);
data->state.authproblem = (conn->newurl == NULL);
}
else {
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
} }
else else
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE) if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
@@ -383,10 +420,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
CURLntlm ntlm = CURLntlm ntlm =
Curl_input_ntlm(conn, (bool)(httpcode == 407), start); Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
if(CURLNTLM_BAD != ntlm) if(CURLNTLM_BAD != ntlm) {
conn->newurl = strdup(data->change.url); /* clone string */ conn->newurl = strdup(data->change.url); /* clone string */
else data->state.authproblem = (conn->newurl == NULL);
}
else {
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
} }
else else
if(data->state.authwant & CURLAUTH_NTLM) if(data->state.authwant & CURLAUTH_NTLM)
@@ -398,17 +439,18 @@ CURLcode Curl_http_auth(struct connectdata *conn,
*availp |= CURLAUTH_DIGEST; *availp |= CURLAUTH_DIGEST;
if(data->state.authwant == CURLAUTH_DIGEST) { if(data->state.authwant == CURLAUTH_DIGEST) {
/* Digest authentication is activated */ /* Digest authentication is activated */
CURLdigest dig = CURLDIGEST_BAD; CURLdigest dig = Curl_input_digest(conn, start);
if(data->state.digest.nonce) if(CURLDIGEST_FINE == dig) {
infof(data, "Authentication problem. Ignoring this.\n");
else
dig = Curl_input_digest(conn, start);
if(CURLDIGEST_FINE == dig)
/* We act on it. Store our new url, which happens to be /* We act on it. Store our new url, which happens to be
the same one we already use! */ the same one we already use! */
conn->newurl = strdup(data->change.url); /* clone string */ conn->newurl = strdup(data->change.url); /* clone string */
data->state.authproblem = (conn->newurl == NULL);
}
else {
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
} }
else else
if(data->state.authwant & CURLAUTH_DIGEST) { if(data->state.authwant & CURLAUTH_DIGEST) {
@@ -430,16 +472,114 @@ CURLcode Curl_http_auth(struct connectdata *conn,
valid. */ valid. */
data->state.authavail = CURLAUTH_NONE; data->state.authavail = CURLAUTH_NONE;
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
} }
else if(data->state.authwant & CURLAUTH_BASIC) { else if(data->state.authwant & CURLAUTH_BASIC) {
data->state.authavail |= CURLAUTH_BASIC; data->state.authavail |= CURLAUTH_BASIC;
} else {
/*
** We asked for something besides basic but got
** Basic anyway. This is no good.
*/
infof(data, "Server expects Basic auth, but we're doing something else.\n");
data->state.authproblem = TRUE;
} }
} }
return CURLE_OK; return CURLE_OK;
} }
/**
* Curl_http_should_fail() determines whether an HTTP response has gotten us
* into an error state or not.
*
* @param conn all information about the current connection
*
* @retval 0 communications should continue
*
* @retval 1 communications should not continue
*/
int Curl_http_should_fail(struct connectdata *conn)
{
struct SessionHandle *data;
struct Curl_transfer_keeper *k;
/* fread() emulation to provide POST and/or request data */ curlassert(conn);
data = conn->data;
curlassert(data);
/*
** For readability
*/
k = &conn->keep;
/*
** If we haven't been asked to fail on error,
** don't fail.
*/
if (!data->set.http_fail_on_error)
return 0;
/*
** Any code < 400 is never terminal.
*/
if (k->httpcode < 400)
return 0;
/*
** Any code >= 400 that's not 401 or 407 is always
** a terminal error
*/
if ((k->httpcode != 401) &&
(k->httpcode != 407))
return 1;
/*
** All we have left to deal with is 401 and 407
*/
curlassert((k->httpcode == 401) || (k->httpcode == 407));
/*
** Examine the current authentication state to see if this
** is an error. The idea is for this function to get
** called after processing all the headers in a response
** message. So, if we've been to asked to authenticate a
** particular stage, and we've done it, we're OK. But, if
** we're already completely authenticated, it's not OK to
** get another 401 or 407.
**
** It is possible for authentication to go stale such that
** the client needs to reauthenticate. Once that info is
** available, use it here.
*/
#if 0 /* set to 1 when debugging this functionality */
infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage);
infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant);
infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail);
infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode);
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
infof(data,"%s: newurl = %s\n",__FUNCTION__,conn->newurl ? conn->newurl : "(null)");
infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
#endif
if (data->state.authstage &&
(data->state.authstage == k->httpcode))
return (data->state.authdone || data->state.authproblem);
/*
** Either we're not authenticating, or we're supposed to
** be authenticating something else. This is an error.
*/
return 1;
}
/*
* readmoredata() is a "fread() emulation" to provide POST and/or request
* data. It is used when a huge POST is to be made and the entire chunk wasn't
* sent in the first send(). This function will then be called from the
* transfer.c loop when more data is to be sent to the peer.
*
* Returns the amount of bytes it filled the buffer with.
*/
static size_t readmoredata(char *buffer, static size_t readmoredata(char *buffer,
size_t size, size_t size,
size_t nitems, size_t nitems,
@@ -456,9 +596,9 @@ static size_t readmoredata(char *buffer,
/* 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= (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
if(http->postsize <= fullsize) { if(http->postsize <= (curl_off_t)fullsize) {
memcpy(buffer, http->postdata, http->postsize); memcpy(buffer, http->postdata, (size_t)http->postsize);
fullsize = http->postsize; fullsize = (size_t)http->postsize;
if(http->backup.postsize) { if(http->backup.postsize) {
/* move backup data into focus and continue on that */ /* move backup data into focus and continue on that */
@@ -502,7 +642,7 @@ static CURLcode
add_buffer(send_buffer *in, const void *inptr, size_t size); add_buffer(send_buffer *in, const void *inptr, size_t size);
/* /*
* add_buffer_init() returns a fine buffer struct * add_buffer_init() sets up and returns a fine buffer struct
*/ */
static static
send_buffer *add_buffer_init(void) send_buffer *add_buffer_init(void)
@@ -518,6 +658,8 @@ send_buffer *add_buffer_init(void)
/* /*
* add_buffer_send() sends a buffer and frees all associated memory. * add_buffer_send() sends a buffer and frees all associated memory.
*
* Returns CURLcode
*/ */
static static
CURLcode add_buffer_send(send_buffer *in, CURLcode add_buffer_send(send_buffer *in,
@@ -608,7 +750,7 @@ CURLcode add_buffer_send(send_buffer *in,
/* /*
* add_bufferf() builds a buffer from the formatted input * add_bufferf() add the formatted input to the buffer.
*/ */
static static
CURLcode add_bufferf(send_buffer *in, const char *fmt, ...) CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
@@ -633,7 +775,7 @@ CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
} }
/* /*
* add_buffer() appends a memory chunk to the existing one * add_buffer() appends a memory chunk to the existing buffer
*/ */
static static
CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size) CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
@@ -750,7 +892,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
fd_set readfd; fd_set readfd;
char *line_start; char *line_start;
char *host_port; char *host_port;
int tunnelsocket = conn->sock[sockindex]; curl_socket_t tunnelsocket = conn->sock[sockindex];
#define SELECT_OK 0 #define SELECT_OK 0
#define SELECT_ERROR 1 #define SELECT_ERROR 1
@@ -760,9 +902,6 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port); infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
do { do {
bool auth; /* we don't really have to know when the auth phase is done,
but this variable will be set to true then */
if(conn->newurl) { if(conn->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()
@@ -776,7 +915,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
/* Setup the proxy-authorization header, if any */ /* Setup the proxy-authorization header, if any */
result = http_auth_headers(conn, (char *)"CONNECT", host_port, &auth); result = http_auth_headers(conn, (char *)"CONNECT", host_port);
if(CURLE_OK == result) { if(CURLE_OK == result) {
/* OK, now send the connect request to the proxy */ /* OK, now send the connect request to the proxy */
@@ -877,7 +1016,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
/* send the header to the callback */ /* send the header to the callback */
writetype = CLIENTWRITE_HEADER; writetype = CLIENTWRITE_HEADER;
if(data->set.http_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(data, writetype, line_start, perline);
@@ -951,7 +1090,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
} }
/* /*
* HTTP stuff to do at connect-time. * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
* the generic Curl_connect().
*/ */
CURLcode Curl_http_connect(struct connectdata *conn) CURLcode Curl_http_connect(struct connectdata *conn)
{ {
@@ -997,6 +1137,11 @@ CURLcode Curl_http_connect(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
/*
* Curl_http_done() gets called from Curl_done() after a single HTTP request
* has been performed.
*/
CURLcode Curl_http_done(struct connectdata *conn) CURLcode Curl_http_done(struct connectdata *conn)
{ {
struct SessionHandle *data; struct SessionHandle *data;
@@ -1029,10 +1174,12 @@ CURLcode Curl_http_done(struct connectdata *conn)
conn->bytecount = http->readbytecount + http->writebytecount; conn->bytecount = http->readbytecount + http->writebytecount;
if(!conn->bits.retry && if(!conn->bits.retry &&
!(http->readbytecount + conn->headerbytecount)) { ((http->readbytecount +
conn->headerbytecount -
conn->deductheadercount)) <= 0) {
/* If this connection isn't simply closed to be retried, AND nothing was /* If this connection isn't simply closed to be retried, AND nothing was
read from the HTTP server, this can't be right so we return an error read from the HTTP server (that counts), this can't be right so we
here */ return an error here */
failf(data, "Empty reply from server"); failf(data, "Empty reply from server");
return CURLE_GOT_NOTHING; return CURLE_GOT_NOTHING;
} }
@@ -1040,6 +1187,10 @@ CURLcode Curl_http_done(struct connectdata *conn)
return CURLE_OK; return CURLE_OK;
} }
/*
* Curl_http_auth_stage() sets the "authentication stage" - which is 407 for
* proxy authentication or 401 for host authentication.
*/
void Curl_http_auth_stage(struct SessionHandle *data, void Curl_http_auth_stage(struct SessionHandle *data,
int stage) int stage)
{ {
@@ -1054,6 +1205,11 @@ void Curl_http_auth_stage(struct SessionHandle *data,
data->state.authavail = CURLAUTH_NONE; /* no type available yet */ data->state.authavail = CURLAUTH_NONE; /* no type available yet */
} }
/*
* Curl_http() gets called from the generic Curl_do() function when a HTTP
* request is to be performed. This creates and sends a propperly constructed
* HTTP request.
*/
CURLcode Curl_http(struct connectdata *conn) CURLcode Curl_http(struct connectdata *conn)
{ {
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
@@ -1061,12 +1217,12 @@ CURLcode Curl_http(struct connectdata *conn)
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
struct HTTP *http; struct HTTP *http;
struct Cookie *co=NULL; /* no cookies from start */ struct Cookie *co=NULL; /* no cookies from start */
char *ppath = conn->ppath; /* three previous function arguments */ char *ppath = conn->path;
char *host = conn->name; char *host = conn->hostname;
const char *te = ""; /* tranfer-encoding */ const char *te = ""; /* tranfer-encoding */
char *ptr; char *ptr;
char *request; char *request;
bool authdone=TRUE; /* if the authentication phase is done */ Curl_HttpReq httpreq = data->set.httpreq;
if(!conn->proto.http) { if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */ /* Only allocate this struct if we don't already have it! */
@@ -1085,19 +1241,40 @@ CURLcode Curl_http(struct connectdata *conn)
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) && if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
data->set.upload) { data->set.upload) {
data->set.httpreq = HTTPREQ_PUT; httpreq = HTTPREQ_PUT;
} }
request = data->set.customrequest? /* Now set the 'request' pointer to the proper request string */
data->set.customrequest: if(data->set.customrequest)
(data->set.no_body?(char *)"HEAD": request = data->set.customrequest;
((HTTPREQ_POST == data->set.httpreq) || else {
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST": if(conn->bits.no_body)
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET"); request = (char *)"HEAD";
else {
curlassert((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
switch(httpreq) {
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
request = (char *)"POST";
break;
case HTTPREQ_PUT:
request = (char *)"PUT";
break;
case HTTPREQ_GET:
request = (char *)"GET";
break;
case HTTPREQ_HEAD:
request = (char *)"HEAD";
break;
default: /* this should never happen */
break;
}
}
}
/* The User-Agent string has been built in url.c already, because it might /* The User-Agent string might have been allocated in url.c already, because
have been used in the proxy connect, but if we have got a header with it might have been used in the proxy connect, but if we have got a header
the user-agent string specified, we erase the previously made string with the user-agent string specified, we erase the previously made string
here. */ here. */
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) { if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
free(conn->allocptr.uagent); free(conn->allocptr.uagent);
@@ -1105,10 +1282,20 @@ CURLcode Curl_http(struct connectdata *conn)
} }
/* setup the authentication headers */ /* setup the authentication headers */
result = http_auth_headers(conn, request, ppath, &authdone); result = http_auth_headers(conn, request, ppath);
if(result) if(result)
return result; return result;
if(!data->state.authdone && (httpreq != HTTPREQ_GET)) {
/* Until we are authenticated, we switch over to HEAD. Unless its a GET
we want to do. The explanation for this is rather long and boring, but
the point is that it can't be done otherwise without risking having to
send the POST or PUT data multiple times. */
httpreq = HTTPREQ_HEAD;
request = (char *)"HEAD";
conn->bits.no_body = TRUE;
}
Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.ref);
if(data->change.referer && !checkheaders(data, "Referer:")) if(data->change.referer && !checkheaders(data, "Referer:"))
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer); conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
@@ -1121,7 +1308,7 @@ CURLcode Curl_http(struct connectdata *conn)
else else
conn->allocptr.cookie = NULL; conn->allocptr.cookie = NULL;
if(!conn->bits.upload_chunky && (data->set.httpreq != HTTPREQ_GET)) { if(!conn->bits.upload_chunky && (httpreq != HTTPREQ_GET)) {
/* not a chunky transfer yet, but data is to be sent */ /* not a chunky transfer yet, but data is to be sent */
ptr = checkheaders(data, "Transfer-Encoding:"); ptr = checkheaders(data, "Transfer-Encoding:");
if(ptr) { if(ptr) {
@@ -1212,7 +1399,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* The path sent to the proxy is in fact the entire URL */ /* The path sent to the proxy is in fact the entire URL */
ppath = data->change.url; ppath = data->change.url;
} }
if(HTTPREQ_POST_FORM == data->set.httpreq) { if(HTTPREQ_POST_FORM == httpreq) {
/* we must build the whole darned post sequence first, so that we have /* we must build the whole darned post sequence first, so that we have
a size of the whole shebang before we start to send it */ a size of the whole shebang before we start to send it */
result = Curl_getFormData(&http->sendit, data->set.httppost, result = Curl_getFormData(&http->sendit, data->set.httppost,
@@ -1231,9 +1418,9 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Accept:")) if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: */*\r\n"; http->p_accept = "Accept: */*\r\n";
if(( (HTTPREQ_POST == data->set.httpreq) || if(( (HTTPREQ_POST == httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq) || (HTTPREQ_POST_FORM == httpreq) ||
(HTTPREQ_PUT == data->set.httpreq) ) && (HTTPREQ_PUT == httpreq) ) &&
conn->resume_from) { conn->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
@@ -1296,14 +1483,14 @@ CURLcode Curl_http(struct connectdata *conn)
* or uploading and we always let customized headers override our internal * or uploading and we always let customized headers override our internal
* ones if any such are specified. * ones if any such are specified.
*/ */
if((data->set.httpreq == HTTPREQ_GET) && if((httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) { !checkheaders(data, "Range:")) {
/* 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", conn->range);
} }
else if((data->set.httpreq != HTTPREQ_GET) && else if((httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) { !checkheaders(data, "Content-Range:")) {
if(conn->resume_from) { if(conn->resume_from) {
@@ -1333,7 +1520,7 @@ CURLcode Curl_http(struct connectdata *conn)
send_buffer *req_buffer; send_buffer *req_buffer;
struct curl_slist *headers=data->set.headers; struct curl_slist *headers=data->set.headers;
size_t postsize; curl_off_t postsize; /* off_t type to be able to hold a large file size */
/* initialize a dynamic send-buffer */ /* initialize a dynamic send-buffer */
req_buffer = add_buffer_init(); req_buffer = add_buffer_init();
@@ -1466,11 +1653,11 @@ CURLcode Curl_http(struct connectdata *conn)
http->postdata = NULL; /* nothing to post at this point */ http->postdata = NULL; /* nothing to post at this point */
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */ Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
/* If 'authdone' is still FALSE, we must not set the write socket index to /* If 'authdone' is FALSE, we must not set the write socket index to the
the Curl_transfer() call below, as we're not ready to actually upload Curl_transfer() call below, as we're not ready to actually upload any
any data yet. */ data yet. */
switch(data->set.httpreq) { switch(httpreq) {
case HTTPREQ_POST_FORM: case HTTPREQ_POST_FORM:
if(Curl_FormInit(&http->form, http->sendit)) { if(Curl_FormInit(&http->form, http->sendit)) {
@@ -1487,7 +1674,7 @@ CURLcode Curl_http(struct connectdata *conn)
if(!conn->bits.upload_chunky) if(!conn->bits.upload_chunky)
/* only add Content-Length if not uploading chunked */ /* only add Content-Length if not uploading chunked */
add_bufferf(req_buffer, add_bufferf(req_buffer,
"Content-Length: %d\r\n", http->postsize); "Content-Length: %" FORMAT_OFF_T "\r\n", http->postsize);
if(!checkheaders(data, "Expect:")) { if(!checkheaders(data, "Expect:")) {
/* if not disabled explicitly we add a Expect: 100-continue /* if not disabled explicitly we add a Expect: 100-continue
@@ -1499,7 +1686,7 @@ CURLcode Curl_http(struct connectdata *conn)
} }
if(!checkheaders(data, "Content-Type:")) { if(!checkheaders(data, "Content-Type:")) {
/* Get Content-Type: line from Curl_FormReadOneLine, which happens /* Get Content-Type: line from Curl_formpostheader, which happens
to always be the first line. We can know this for sure since to always be the first line. We can know this for sure since
we always build the formpost linked list the same way! we always build the formpost linked list the same way!
@@ -1507,13 +1694,11 @@ CURLcode Curl_http(struct connectdata *conn)
string etc why disabling this header is likely to not make things string etc why disabling this header is likely to not make things
work, but we support it anyway. work, but we support it anyway.
*/ */
char contentType[256]; char *contentType;
size_t linelength=0; size_t linelength=0;
linelength = Curl_FormReadOneLine(contentType, contentType = Curl_formpostheader((void *)&http->form,
sizeof(contentType), &linelength);
1, if(!contentType) {
(FILE *)&http->form);
if(!linelength) {
failf(data, "Could not get Content-Type header line!"); failf(data, "Could not get Content-Type header line!");
return CURLE_HTTP_POST_ERROR; return CURLE_HTTP_POST_ERROR;
} }
@@ -1535,8 +1720,8 @@ CURLcode Curl_http(struct connectdata *conn)
/* setup variables for the upcoming transfer */ /* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
authdone?FIRSTSOCKET:-1, data->state.authdone?FIRSTSOCKET:-1,
authdone?&http->writebytecount:NULL); data->state.authdone?&http->writebytecount:NULL);
if(result) { if(result) {
Curl_formclean(http->sendit); /* free that whole lot */ Curl_formclean(http->sendit); /* free that whole lot */
return result; return result;
@@ -1563,7 +1748,7 @@ CURLcode Curl_http(struct connectdata *conn)
add_buffer(req_buffer, "\r\n", 2); /* end of headers */ add_buffer(req_buffer, "\r\n", 2); /* end of headers */
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* this sends the buffer and frees all the buffer resources */ /* this sends the buffer and frees all the buffer resources */
result = add_buffer_send(req_buffer, conn, result = add_buffer_send(req_buffer, conn,
@@ -1574,8 +1759,8 @@ CURLcode Curl_http(struct connectdata *conn)
/* prepare for transfer */ /* prepare for transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE, result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, &http->readbytecount,
authdone?FIRSTSOCKET:-1, data->state.authdone?FIRSTSOCKET:-1,
authdone?&http->writebytecount:NULL); data->state.authdone?&http->writebytecount:NULL);
if(result) if(result)
return result; return result;
break; break;
@@ -1586,7 +1771,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* store the size of the postfields */ /* store the size of the postfields */
postsize = data->set.postfieldsize? postsize = data->set.postfieldsize?
data->set.postfieldsize: data->set.postfieldsize:
(data->set.postfields?strlen(data->set.postfields):0); (data->set.postfields?(curl_off_t)strlen(data->set.postfields):0);
if(!conn->bits.upload_chunky) { if(!conn->bits.upload_chunky) {
/* We only set Content-Length and allow a custom Content-Length if /* We only set Content-Length and allow a custom Content-Length if
@@ -1596,7 +1781,8 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Content-Length:")) if(!checkheaders(data, "Content-Length:"))
/* we allow replacing this header, although it isn't very wise to /* we allow replacing this header, although it isn't very wise to
actually set your own */ actually set your own */
add_bufferf(req_buffer, "Content-Length: %d\r\n", postsize); add_bufferf(req_buffer, "Content-Length: %" FORMAT_OFF_T"\r\n",
postsize);
} }
if(!checkheaders(data, "Content-Type:")) if(!checkheaders(data, "Content-Type:"))
@@ -1605,7 +1791,7 @@ CURLcode Curl_http(struct connectdata *conn)
if(data->set.postfields) { if(data->set.postfields) {
if(authdone && (postsize < (100*1024))) { if(data->state.authdone && (postsize < (100*1024))) {
/* If we're not done with the authentication phase, we don't expect /* If we're not done with the authentication phase, we don't expect
to actually send off any data yet. Hence, we delay the sending of to actually send off any data yet. Hence, we delay the sending of
the body until we receive that friendly 100-continue response */ the body until we receive that friendly 100-continue response */
@@ -1619,11 +1805,11 @@ CURLcode Curl_http(struct connectdata *conn)
if(!conn->bits.upload_chunky) if(!conn->bits.upload_chunky)
/* We're not sending it 'chunked', append it to the request /* We're not sending it 'chunked', append it to the request
already now to reduce the number if send() calls */ already now to reduce the number if send() calls */
add_buffer(req_buffer, data->set.postfields, postsize); add_buffer(req_buffer, data->set.postfields, (size_t)postsize);
else { else {
/* Append the POST data chunky-style */ /* Append the POST data chunky-style */
add_bufferf(req_buffer, "%x\r\n", postsize); add_bufferf(req_buffer, "%x\r\n", (int)postsize);
add_buffer(req_buffer, data->set.postfields, postsize); add_buffer(req_buffer, data->set.postfields, (size_t)postsize);
add_buffer(req_buffer, "\r\n0\r\n\r\n", 7); /* end of a chunked add_buffer(req_buffer, "\r\n0\r\n\r\n", 7); /* end of a chunked
transfer stream */ transfer stream */
} }
@@ -1641,7 +1827,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize); Curl_pgrsSetUploadSize(data, http->postsize);
if(!authdone && !checkheaders(data, "Expect:")) { if(!data->state.authdone && !checkheaders(data, "Expect:")) {
/* if not disabled explicitly we add a Expect: 100-continue to the /* if not disabled explicitly we add a Expect: 100-continue to the
headers which actually speeds up post operations (as there is headers which actually speeds up post operations (as there is
one packet coming back from the web server) */ one packet coming back from the web server) */
@@ -1657,7 +1843,7 @@ CURLcode Curl_http(struct connectdata *conn)
add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, (double)data->set.infilesize); Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* set the pointer to mark that we will send the post body using /* set the pointer to mark that we will send the post body using
the read callback */ the read callback */

View File

@@ -42,9 +42,13 @@ CURLcode Curl_http_connect(struct connectdata *conn);
void Curl_httpchunk_init(struct connectdata *conn); void Curl_httpchunk_init(struct connectdata *conn);
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
ssize_t length, ssize_t *wrote); ssize_t length, ssize_t *wrote);
/* These functions are in http.c */
void Curl_http_auth_stage(struct SessionHandle *data, int stage); void Curl_http_auth_stage(struct SessionHandle *data, int stage);
CURLcode Curl_http_auth(struct connectdata *conn, CURLcode Curl_http_auth(struct connectdata *conn,
int httpcode, char *header); int httpcode, char *header);
void Curl_http_auth_act(struct connectdata *conn); void Curl_http_auth_act(struct connectdata *conn);
int Curl_http_should_fail(struct connectdata *conn);
#endif #endif
#endif #endif

View File

@@ -36,6 +36,7 @@
#include "md5.h" #include "md5.h"
#include "http_digest.h" #include "http_digest.h"
#include "url.h" /* for Curl_safefree() */
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -57,6 +58,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
{ {
bool more = TRUE; bool more = TRUE;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
bool before = FALSE; /* got a nonce before */
struct digestdata *d = &data->state.digest;
/* skip initial whitespaces */ /* skip initial whitespaces */
while(*header && isspace((int)*header)) while(*header && isspace((int)*header))
@@ -65,6 +68,10 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
if(checkprefix("Digest", header)) { if(checkprefix("Digest", header)) {
header += strlen("Digest"); header += strlen("Digest");
/* If we already have received a nonce, keep that in mind */
if(d->nonce)
before = TRUE;
/* clear off any former leftovers and init to defaults */ /* clear off any former leftovers and init to defaults */
Curl_digest_cleanup(data); Curl_digest_cleanup(data);
@@ -77,21 +84,32 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
header++; header++;
/* how big can these strings be? */ /* how big can these strings be? */
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"", if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
value, content)) { value, content)) ||
/* try the same scan but without quotes around the content but don't
include the possibly trailing comma */
(2 == sscanf(header, "%31[^=]=%127[^,]",
value, content)) ) {
if(strequal(value, "nonce")) { if(strequal(value, "nonce")) {
data->state.digest.nonce = strdup(content); d->nonce = strdup(content);
}
else if(strequal(value, "stale")) {
if(strequal(content, "true"))
d->stale = TRUE;
} }
else if(strequal(value, "cnonce")) { else if(strequal(value, "cnonce")) {
data->state.digest.cnonce = strdup(content); d->cnonce = strdup(content);
} }
else if(strequal(value, "realm")) { else if(strequal(value, "realm")) {
data->state.digest.realm = strdup(content); d->realm = strdup(content);
} }
else if(strequal(value, "algorithm")) { else if(strequal(value, "algorithm")) {
if(strequal(content, "MD5-sess")) if(strequal(content, "MD5-sess"))
data->state.digest.algo = CURLDIGESTALGO_MD5SESS; d->algo = CURLDIGESTALGO_MD5SESS;
/* else, remain using the default md5 */ else if(strequal(content, "MD5"))
d->algo = CURLDIGESTALGO_MD5;
else
return CURLDIGEST_BADALGO;
} }
else { else {
/* unknown specifier, ignore it! */ /* unknown specifier, ignore it! */
@@ -106,8 +124,15 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
/* allow the list to be comma-separated */ /* allow the list to be comma-separated */
header++; header++;
} }
/* We had a nonce since before, and we got another one now without
'stale=true'. This means we provided bad credentials in the previous
request */
if(!data->state.digest.nonce) if(before && !d->stale)
return CURLDIGEST_BAD;
/* We got this header without a nonce, that's a bad Digest line! */
if(!d->nonce)
return CURLDIGEST_BAD; return CURLDIGEST_BAD;
} }
else else
@@ -140,6 +165,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char *md5this; unsigned char *md5this;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct digestdata *d = &data->state.digest;
/* /*
if the algorithm is "MD5" or unspecified (which then defaults to MD5): if the algorithm is "MD5" or unspecified (which then defaults to MD5):
@@ -151,20 +177,20 @@ CURLcode Curl_output_digest(struct connectdata *conn,
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd ) A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
":" unq(nonce-value) ":" unq(cnonce-value) ":" unq(nonce-value) ":" unq(cnonce-value)
*/ */
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) { if(d->algo == CURLDIGESTALGO_MD5SESS) {
md5this = (unsigned char *) md5this = (unsigned char *)
aprintf("%s:%s:%s:%s:%s", aprintf("%s:%s:%s:%s:%s",
conn->user, conn->user,
data->state.digest.realm, d->realm,
conn->passwd, conn->passwd,
data->state.digest.nonce, d->nonce,
data->state.digest.cnonce); d->cnonce);
} }
else { else {
md5this = (unsigned char *) md5this = (unsigned char *)
aprintf("%s:%s:%s", aprintf("%s:%s:%s",
conn->user, conn->user,
data->state.digest.realm, d->realm,
conn->passwd); conn->passwd);
} }
Curl_md5it(md5buf, md5this); Curl_md5it(md5buf, md5this);
@@ -183,7 +209,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
free(md5this); /* free this again */ free(md5this); /* free this again */
md5_to_ascii(md5buf, ha2); md5_to_ascii(md5buf, ha2);
md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, data->state.digest.nonce, md5this = (unsigned char *)aprintf("%s:%s:%s", ha1, d->nonce,
ha2); ha2);
Curl_md5it(md5buf, md5this); Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */ free(md5this); /* free this again */
@@ -195,6 +221,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
*/ */
Curl_safefree(conn->allocptr.userpwd);
conn->allocptr.userpwd = conn->allocptr.userpwd =
aprintf( "Authorization: Digest " aprintf( "Authorization: Digest "
"username=\"%s\", " "username=\"%s\", "
@@ -203,8 +230,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"uri=\"%s\", " "uri=\"%s\", "
"response=\"%s\"\r\n", "response=\"%s\"\r\n",
conn->user, conn->user,
data->state.digest.realm, d->realm,
data->state.digest.nonce, d->nonce,
uripath, /* this is the PATH part of the URL */ uripath, /* this is the PATH part of the URL */
request_digest ); request_digest );
@@ -213,19 +240,23 @@ CURLcode Curl_output_digest(struct connectdata *conn,
void Curl_digest_cleanup(struct SessionHandle *data) void Curl_digest_cleanup(struct SessionHandle *data)
{ {
if(data->state.digest.nonce) struct digestdata *d = &data->state.digest;
free(data->state.digest.nonce);
data->state.digest.nonce = NULL;
if(data->state.digest.cnonce) if(d->nonce)
free(data->state.digest.cnonce); free(d->nonce);
data->state.digest.cnonce = NULL; d->nonce = NULL;
if(data->state.digest.realm) if(d->cnonce)
free(data->state.digest.realm); free(d->cnonce);
data->state.digest.realm = NULL; d->cnonce = NULL;
data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */ if(d->realm)
free(d->realm);
d->realm = NULL;
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
d->stale = FALSE; /* default means normal, not stale */
} }
#endif #endif

View File

@@ -26,6 +26,7 @@
typedef enum { typedef enum {
CURLDIGEST_NONE, /* not a digest */ CURLDIGEST_NONE, /* not a digest */
CURLDIGEST_BAD, /* a digest, but one we don't like */ CURLDIGEST_BAD, /* a digest, but one we don't like */
CURLDIGEST_BADALGO, /* unsupported algorithm requested */
CURLDIGEST_FINE, /* a digest we act on */ CURLDIGEST_FINE, /* a digest we act on */
CURLDIGEST_LAST /* last entry in this enum, don't use */ CURLDIGEST_LAST /* last entry in this enum, don't use */

View File

@@ -77,7 +77,7 @@
#endif #endif
/* Define this to make the type-3 message include the NT response message */ /* Define this to make the type-3 message include the NT response message */
#undef USE_NTRESPONSES #define USE_NTRESPONSES 1
/* /*
(*) = A "security buffer" is a triplet consisting of two shorts and one (*) = A "security buffer" is a triplet consisting of two shorts and one
@@ -277,8 +277,7 @@ static void mkhash(char *password,
/* this is for creating ntlm header output */ /* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, CURLcode Curl_output_ntlm(struct connectdata *conn,
bool proxy, bool proxy)
bool *ready)
{ {
const char *domain=""; /* empty */ const char *domain=""; /* empty */
const char *host=""; /* empty */ const char *host=""; /* empty */
@@ -300,7 +299,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
/* point to the correct struct with this */ /* point to the correct struct with this */
struct ntlmdata *ntlm; struct ntlmdata *ntlm;
*ready = FALSE; curlassert(conn);
curlassert(conn->data);
conn->data->state.authdone = FALSE;
if(proxy) { if(proxy) {
allocuserpwd = &conn->allocptr.proxyuserpwd; allocuserpwd = &conn->allocptr.proxyuserpwd;
@@ -562,7 +563,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY; /* FIX TODO */ return CURLE_OUT_OF_MEMORY; /* FIX TODO */
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
*ready = TRUE; conn->data->state.authdone = TRUE;
/* Switch to web authentication after proxy authentication is done */ /* Switch to web authentication after proxy authentication is done */
if (proxy) if (proxy)
@@ -577,7 +578,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
free(*allocuserpwd); free(*allocuserpwd);
*allocuserpwd=NULL; *allocuserpwd=NULL;
} }
*ready = TRUE; conn->data->state.authdone = TRUE;
break; break;
} }

View File

@@ -36,7 +36,7 @@ typedef enum {
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header); CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
/* this is for creating ntlm header output */ /* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy, bool *ready); CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
void Curl_ntlm_cleanup(struct SessionHandle *data); void Curl_ntlm_cleanup(struct SessionHandle *data);

View File

@@ -32,7 +32,7 @@
#endif #endif
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \ #if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
!defined(__riscos__) && !defined(__INTERIX) !defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE)
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
@@ -125,5 +125,8 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
/* -- end of if2ip() -- */ /* -- end of if2ip() -- */
#else #else
#define if2ip(x) NULL char *Curl_if2ip(char *interface, char *buf, int buf_size)
{
return NULL;
}
#endif #endif

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