Compare commits

..

179 Commits

Author SHA1 Message Date
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
162 changed files with 4269 additions and 1210 deletions

215
CHANGES
View File

@@ -6,6 +6,221 @@
Changelog
Daniel (7 April 2004)
- A request that sends "Expect: 100-continue" and gets nothing but a single
100 response back will now return a CURLE_GOT_NOTHING. Test 158 verifies.
- The strtoofft() macro is now named curlx_strtoofft() to use the curlx_*
approach fully.
Daniel (6 April 2004)
- Gisle Vanem's fixed bug #927979 reported by Nathan O'Sullivan. The problem
made libcurl on Windows leak a small amount of memory in each name resolve
when not used as a DLL.
- 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. Previously libcurl
sent POST immediately and expected the server to reply a final status code
with an error and then libcurl would not send the request-body but instead
send then next request in the sequence.
The reason for this change is due to IIS6 barfing on libcurl when we attempt
to POST with NTLM authentication. The reason for the problems is found in
RFC2616 section 8.2.3 regarding how servers should deal with the 100
continue request-header:
If it responds with a final status code, it MAY close the transport
connection or it MAY continue to read and discard the rest of the
request.
Previous versions of IIS clearly did close the connection in this case,
while this newer version decided it should "read and discard". That would've
forced us to send the whole POST (or PUT) data only to have it discarded and
then be forced to send it again. To avoid that huge penality, we switch to
using HEAD until we are authenticated and then send the POST.
The only actual drawback I can think of (except for the odd sites that might
treat HEAD differently than they would treat POST/PUT when given the same
URL) is that if you do POST with CURLAUTH_ANY set and the site requires NO
authentication, libcurl will still use a HEAD in a first round and then do a
POST.
If you do a HEAD or a GET on a site using CURLAUTH_ANY, libcurl will send
an un-authenticated request at once, which then is the only request if the
site requires no auth.
Alan Pinstein helped me work out the protocol details by figuring out why
libcurl failed and what IIS6 expects.
- The --limit-rate logic was corrected and now it works a lot better for
higher speeds, such as '10m' or similar. Reported in bug report #930249.
- Introducing curlx_tvnow() and curlx_tvdiff() using the new curlx_* fashion.
#include "timeval.h" from the lib dir to get the protos etc. Note that
these are NOT part of the libcurl API. The curl app simply uses the same
source files as the library does and therefore the file needs to be compiled
and linked with curl too, not just when creating libcurl.
- lib/strerror.c no longer uses sys_nerr on non-windows platforms since it
isn't portable enough
Daniel (2 April 2004)
- In the curl_strnqual.3 man page, we now prepend the man3 dir to the file
name to work better. As pointed out by Robin Kay.
- Andr<64>s Garc<72>a updated the mingw makefiles.
- Dirk Manske fixed a problem I recently added in the progress meter code that
broke subsecond resolution for CURLINFO_TOTAL_TIME. He also pointed out a
mistake in the code that produces the final update of the progress meter
that would often prevent it from actually being updated that final time.
Daniel (1 April 2004)
- Dirk Manske fixed a memory leak that happened when we use ares for name
resolves and decides to time-out before ares does it. This fix uses the
brand new ares_cancel() function which is not present in c-ares 1.1.0.
When told to enable ares, the configure script now checks for presence of
the ares_cancel function to alert users if they attempt to use a too old
c-ares library.
Daniel (31 March 2004)
- Roy Shan fixed a flaw that prevented ares name resolve timeouts to occur!
- Dirk Manske found out that libcurl timed out waiting for resolves far too
easy when libcurl was built to use (c-)ares for name resolving.
- Further Digest fixing and a successful test case 153 now makes me believe
Mitz Wark's problems are fixed.
- Andres Garcia figured out that test case 63, while working, only proved a
flaw in libcurl's 'http_proxy' parser when a user name and password is
provided. The user name was not extracted properly (and 'http' was always
used as user name).
- Andr<64>s Garc<72>a fixed compiler warnings in our ioctlsocket() usage.
Daniel (30 March 2004)
- Joe Halpin faced problems with the getnameinfo() argument ai_flags and the
particular bit named 'NI_WITHSCOPEID' on Solaris 9 for Intel. I've now
written a configure test that checks for a working NI_WITHSCOPEID
implemenation. No code uses the result from this test yet, it is still
experimental. James Carlson wrote in comp.unix.solaris: "It's a bug
(5006623) -- it's not supported and shouldn't be in the header file."
- I provided Mitz Wark with a first patch in order to fix libcurl's problems
to re-negotiate Digest authentication (when 'stale=true' is included in the
response header).
- Roy Shan discovered that the multi interface didn't properly timeout name
lookups which could make handles get stuck in that state and thus never get
completed. I've produced a first test patch that attempts to correct this.
- 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.
Daniel (29 March 2004)
- Gisle Vanem updated files for the djgpp/MS-DOS build.
- Andr<64>s Garc<72>a helped me work out a fix for the runtests.pl script to make
the file:// tests run fine when tested with the mingw-built version of curl.
- Fixed an include issue with netinet/tcp.h on AIX, based on input by Tor.
This also required a minor fix of the configure script.
- The postit2.c source example used the wrong struct name for the post data.
Daniel (26 March 2004)
- Gisle Vanem improved ipv6 support on windows by making the curl build to use
the correct getaddrinfo() function.
Daniel (25 March 2004)
- It turned out that AIX, despite having a "thread-safe libc", doesn't offer
all traditional functions thread-safe. This URL is informative on this
subject:
http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
genprogc/thread_quick_ref.htm
As a result of this, we now check for three *_r() functions on recent AIX
versions as well that the URL mentions aren't thread-safe in AIX 5.1.
- renamed curl_strerror.[ch] to strerror.[ch]
- Joe Halpin added CURLOPT_TCP_NODELAY and --tcp-nodelay to make it possible
for users to disable the Nagle algorthim-usage.
- Tor Arntsen provided some interesting strerror_r() knowledge. glibc has its
own API which differs from the POSIX one. Daniel adjusted the configure
script to detect the version in use, and the code now uses the new defines
accordingly.
- Fixed some build flaws with the new lib/curl_strerror.c source file.
Daniel (24 March 2004)
- 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!
- Tor Arntsen spell-fixed lots of libcurl man pages.
- Tor Arntsen made testcurl.pl work with older perl 5 versions, and Daniel
made it not use chdir .. to go back, as that isn't very good when you've
setup a testdir containing symlinks.
- Added a check for strerror_r() in the configure script.
Daniel (23 March 2004)
- Added Greg Hewgill's testcurl.pl script to CVS. We have not moved over to
use this script for the real distributed testing just yet, but it is only
a matter of time.
- Gisle Vanem provided code that makes curl report a better error message
if --interface fails on windows.
- The regular progress meter is now fixed to never wrap due to long lines. All
fields are now static sized. If the time in the time fields get a time value
that would represent a time that is 100 hours or more (if not, it remains
using a HH:MM:SS display), it switches first to a "NNNd NNh" display (for
days and hours) and if that isn't enough it switches to a "NNNd" display if
it is more than 999 days.
Several of the calculations were also moved to fixed-point math instead of
using doubles.
Daniel (22 March 2004)
- Glen Nakamura noticed CURLINFO_CONTENT_LENGTH_DOWNLOAD didn't work as it
used to do if CURLOPT_NOBODY is set TRUE.
- Kevin Roth patched the cygwin package makefile and README to adjust to
new cygwin packaging guidelines.
- Enabled "NT responses" in the NTLM authentication. Doing this simply means
that we provide an extra chunk of data in each "type-3 message". The only
reason for doing this is that it seems that using only the "Lanmanager hash"
(as we've been doing until now) doesn't support passwords longer than 14
characters and it turns out there are users out there who want to use
libcurl and NTLM with such passwords! ;-) Seven NTLM-related test cases were
updated accordingly. Mentioned as issue 29 in TODO-RELEASE, bug report
#915609
- Moved the generated libcurl version info to a new header file, named
curl/curlver.h. Now interested parties can include ONLY version info, should
anyone want that (and it seems at least some windows resource files would).
Mentioned as issue 27 in TODO-RELEASE.
Daniel (21 March 2004)
- Fixed the root Makefile to use tabs for the netware target. G<>nter Knauf
pointed this out.
- Marty Kuhrt's VMS cleanup
- Thomas Schwinge made buildconf recognize ACLOCAL_FLAGS to invoke aclocal
with particular pre-determined options.
Version 7.11.1 (19 March 2004)
Daniel (18 March 2004)
- Tor Arntsen brought some info about SGI IRIX:

View File

@@ -82,8 +82,8 @@ amiga:
cd ./src && make -f makefile.amiga
netware:
cd lib && make -f Makefile.netware
cd src && make -f Makefile.netware
cd lib && make -f Makefile.netware
cd src && make -f Makefile.netware
unix: all

13
README
View File

@@ -34,6 +34,7 @@ WEB SITE
Australia -- http://curl.planetmirror.com/
Estonia -- http://curl.dope-brothers.com/
Germany -- http://curl.mirror.at.stealer.net/
Germany -- http://curl.netmirror.org/
Russia -- http://curl.tsuren.net/
Thailand -- http://curl.siamu.ac.th/
US (CA) -- http://curl.mirror.redwire.net/
@@ -42,15 +43,17 @@ DOWNLOAD
The official download mirror sites are:
Australia -- http://curl.planetmirror.com/download/
Estonia -- http://curl.dope-brothers.com/download/
Australia -- http://curl.planetmirror.com/download.html
Estonia -- http://curl.dope-brothers.com/download.html
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/
Russia -- http://curl.tsuren.net/download/
Russia -- http://curl.tsuren.net/download.html
Sweden -- ftp://ftp.sunet.se/pub/www/utilities/curl/
Sweden -- http://cool.haxx.se/curl/
Thailand -- http://curl.siamu.ac.th/download/
US (CA) -- http://curl.mirror.redwire.net/download/
Thailand -- http://curl.siamu.ac.th/download.html
US (CA) -- http://curl.mirror.redwire.net/download.html
CVS

View File

@@ -1,89 +1,54 @@
Curl and libcurl 7.11.1. A bugfix release.
Curl and libcurl 7.11.2. A bugfix release.
Public curl release number: 79
Releases counted from the very beginning: 106
Public curl release number: 80
Releases counted from the very beginning: 107
Available command line options: 94
Available curl_easy_setopt() options: 112
Available curl_easy_setopt() options: 113
This release includes the following changes:
o CURLOPT_POSTFIELDSIZE_LARGE added to offer POSTs larger than 2GB
o CURL_VERSION_LARGEFILE is a feature bit returned by libcurls that feature
large file support
o libcurl only requires winsock 1.1 on windows now
o when doing FTP, curl now sends QUIT before disconnecting
o name resolves can now timeout on windows too
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
o the ares build now requires c-ares 1.2.0 or later
o --tcp-nodelay and CURLOPT_TCP_NODELAY were added
o curl/curlver.h contains the libcurl version info now
This release includes the following bugfixes:
o builds and runs on Novell NetWare
o Windows builds now report OS as "i386-pc-win32"
o received signals during SSL connect is handled better
o improved PUT/POST with NTLM/Digest authentication
o following redirects and doing NTLM/Digest (where the first connection gets
closed) with the multi interface work better now
o file: progress meter and getinfo variables work now
o CURLOPT_FRESH_CONNECT and CURLAUTH_NTLM now work when set together
o share interface usage without (un)lock functions segfaulted
o --limit-rate no longer cripples the --speed-limit feature
o fixed verbose output problem with ipv6-enabled re-used connections
o fixed the socks5 code to check version in the socks response properly
o dns cache bug - fixed the 'inuse' counter
o large file fix for Content-Length
o better docs for the share interface
o several configure fixes for mingw/msys
o setting a Host: header is no longer affecting the Host: header used when
libcurl follows a Location:
o fixed numerous compiler warnings on several operating systems and compilers
o PUTing from stdin couldn't disable chunked transfer-encoding
o corrected the mingw makefiles
o improved the configure libz detection
o fixed EPRT/PORT use when doing FTP on ipv6-enabled AIX hosts
o *nroff commands that only support -mandoc and not -man are now supported
(for the built-in manual text in the command line tool)
o fixed the unconditional #include of config.h in hugehelp.c
o builds fine on MPE/iX
o upload using chunked transfer-encoding now sends the last chunk properly
teriminated with an extra CRLF
o Fixed the progress meter display for files >2GB
o persistant connections over a proxy messed up the proxy name/password
o the socks5 code segfaulted if no username/password was set
o the *_LARGE options now take curl_off_t types as parameters and this will
make it possible to handle large files on windows too
o builds with large file support even on systems without strtoll()
o getting only a 100 Continue response and nothing else, when talking HTTP,
is now treated as an error by libcurl
o fixed minor memory leak in libcurl for Windows when staticly linked
o POST/PUT using Digest/NTLM/Negotiate (including anyauth) now work better
o --limit-rate with high speed rates is a lot more accurate now, and supports
limiting to speeds >2GB/sec on systems with Large File support.
o curl_strnqual.3 "refer-to" man page fix
o fixed a minor very old progress meter final update bug
o added checks for a working NI_WITHSCOPEID before that is used
o fixed a flaw that prevented ares name resolve timeouts to occur
o getting user name from http_proxy env variable works now
o fixed too early name resolve timeouts with ares
o HTTP Digest "re-negotiation" works now
o CURLOPT_FAILONERROR (-f/--fail) works with all kinds of authentication
o better thread-safety thanks to the internal strerror() replacement
o better thread-safety on AIX thanks to better function detection
o minor ipv6 build fix for windows
o the test suite runs fine with mingw-built curl
o the postit2.c example works now
o better error message when --interface fails on windows
o the progress meter now displays very long times better
o CURLINFO_CONTENT_LENGTH_DOWNLOAD with CURLOPT_NOBODY set TRUE now works
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:
o Many platforms are being used to autobuild and autotest curl on a daily
basis. Please join in and test curl on your systems:
http://curl.haxx.se/auto/
o the curl mailing lists moved, (re-)subscribe to the new ones from here:
http://curl.haxx.se/mail/
o c-ares 1.1.0 was relased: http://daniel.haxx.se/projects/c-ares/
o TclCurl 0.11.0 was released:
http://personal1.iddeo.es/andresgarci/tclcurl/english/
o PycURL 7.11.0 was released: http://pycurl.sourceforge.net/
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/
o PycURL 7.11.1 was released: http://pycurl.sf.net/
o New German web mirror: http://curl.netmirror.org/
This release would not have looked like this without help, code, reports and
advice from friends like these:
Gisle Vanem, Vincent Bronner, Richard Bramante, Dirk Manske, Dan Fandrich,
Ken Hirsch, Stadler Stephan, Domenico Andreoli, Patrick Smith, Tor Arntsen,
Andr<64>s Garc<72>a, Tim Baker, Len Krause, Gilad, Ken Rastatter, P R Schaffner,
Greg Hewgill, Ben Greear, Jeff Lawson, Grigory Entin, Doug Porter, David
Byron, Andy Serpa, Joe Halpin, Christopher R. Palmer, G<>nter Knauf
Thomas Schwinge, Marty Kuhrt, G<>nter Knauf, Kevin Roth, Glen Nakamura, Gisle
Vanem, Greg Hewgill, Joe Halpin, Tor Arntsen, Dirk Manske, Roy Shan, Mitz
Wark, Andr<64>s Garc<72>a, Robin Kay, Alan Pinstein, David Byron, Nathan O'Sullivan
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -3,51 +3,26 @@ Issues not sorted in any particular order.
UNASSIGNED means that no person has publicly stated to work on the issue.
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 May/June 2004)
======================
6. 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.
UNASSIGNED
10. Anton Fedorov's "dumpcert" patch UNASSIGNED
http://curl.haxx.se/mail/lib-2004-03/0088.html
14. Evaluate/apply Gertjan van Wingerde's SSL patches, UNASSIGNED
http://curl.haxx.se/mail/lib-2004-03/0087.html
23. Peter Sylvester's "Most Significant Common Name" change. Feedback welcome.
At least the UTF8 conversion and comparison should be done. Patch?
UNASSIGNED
24. Make the progress meter use one digit more for the hour time fields.
Accomplish this by removing one of the times displayed.
27. Put the version defines in their own header file, so that lib/libcurl.rc
can include only that to reduce problems with MSVC.
28. Optimize the way libcurl uses CWD on each new request over a persistent
connection (on FTP) even if it doesn't have to.
29. Define USE_NTRESPONSES in the NTLM code to work properly with >14 letter
passwords against IIS servers. Requires test cases to be updated
accordingly. #915609
30. Digest re-negotiation is not supported, we wrongly assume a new 401
response to signify an authenticaion error. We need to detect the
difference between a 401 due to a bad Digest authorization header and a
401 because the server wants to re-negotiate.
Mitz Wark provided details and traces here:
http://curl.haxx.se/mail/lib-2004-03/0299.html
31. Fix multi interface for windows with ares. curl_multi_fdset() returns
blank fdsets during name lookup which causes a following select() to fail!
High prio.
To get fixed in 7.12.0
======================
25. curl_easy_strerror() curl_multi_strerror() curl_share_strerror()
Code already in CVS. Messages need overview/improvements.
Medium prio.
26. i18n of error messages
26. i18n of error messages?
Low prio. Nobody has volunteered. Subject for removal.
33. Add a function to replace the malloc-calls within libcurl.
Low prio. Seshubabu Pasam works on this.
35. Rearrange lib/hostip.c to reduce the amount of #ifdefs and make it easier
to follow "the flow". Daniel's task.
Medium prio.

View File

@@ -64,7 +64,7 @@ dnl the code was bad, try a different program now, test 3
],[
/* ioctlsocket source code */
int socket;
int flags = ioctlsocket(socket, FIONBIO, &flags);
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
],[
dnl ioctlsocket test was good
nonblock="ioctlsocket"
@@ -245,7 +245,8 @@ AC_DEFUN([CURL_CHECK_WORKING_GETADDRINFO],[
#include <sys/types.h>
#include <sys/socket.h>
void main(void) {
int main(void)
{
struct addrinfo hints, *ai;
int error;
@@ -254,11 +255,9 @@ void main(void) {
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
if (error) {
exit(1);
}
else {
exit(0);
return 1;
}
return 0;
}
],[
ac_cv_working_getaddrinfo="yes"
@@ -276,10 +275,72 @@ if test "$ac_cv_working_getaddrinfo" = "yes"; then
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],
[
dnl check for a few thread-safe functions
dnl check for localtime_r
AC_CHECK_FUNCS(localtime_r,[
AC_MSG_CHECKING(whether localtime_r is declared)
AC_EGREP_CPP(localtime_r,[
@@ -295,6 +356,92 @@ AC_DEFUN([CURL_CHECK_LOCALTIME_R],
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],
[
dnl determine if function definition for inet_ntoa_r exists.

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
- Gisle Vanem improved build on Windows.
@@ -74,3 +98,5 @@ Version 1.0-pre1 (8 October 2003)
- Daniel Stenberg adjusted the 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.plg
vc/vc.dsw
vc/vc.ncb
vc/vc.opt
vc/ahost/ahost.dep
vc/ahost/ahost.dsp
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_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_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}
ar cru $@ ${OBJS}
@@ -60,31 +68,9 @@ install:
chmod u-w ${DESTDIR}${libdir}/$(LIB)
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
${INSTALL} -m 444 ${srcdir}/ares_version.h ${DESTDIR}${includedir}
${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3
${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
(for man in $(MANPAGES); do \
${INSTALL} -m 444 ${srcdir}/$${man} ${DESTDIR}${mandir}/man3; \
done)
clean:
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
put together and release my own ares archives since the ares maintainer
doesn't want these improvements.
This package is based on ares 1.1.1 (written by Greg Hudson). I decided to
fork and release a separate project since the ares author didn't want the
improvements that were vital for our use of it.
The package is thus dubbed 'c-ares' since I (Daniel Stenberg) want this for
use within the curl project (hence the letter C) and it makes a nice
pun. Also, c-ares will not remain API compatible with the original ares, so
picking a new name makes it more obvious to the public.
This package is dubbed 'c-ares' since I (Daniel Stenberg) wanted this for use
within the curl project (hence the letter C) and it makes a nice pun. Also,
c-ares is not API compatible with ares: a new name makes that more obvious to
the public.
The full source code is available in the 'c-ares' release archives, and in the
'ares' subdir of the curl CVS source repostitory.
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
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
original ares.

View File

@@ -55,6 +55,7 @@
#define ARES_EFILE 14
#define ARES_ENOMEM 15
#define ARES_EDESTRUCTION 16
#define ARES_EBADSTR 17
/* Flag values */
#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 optmask);
void ares_destroy(ares_channel channel);
void ares_cancel(ares_channel channel);
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
ares_callback callback, void *arg);
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 ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
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,
struct hostent **host);
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
might have been stored in their arguments.
.SH SEE ALSO
.BR ares_init (3)
.BR ares_init (3),
.BR ares_cancel (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.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
function frees a
.B struct hostent
allocated by one of the functions
.I ares_parse_a_reply
or
.IR ares_parse_ptr_reply .
allocated by one of the functions \fIares_parse_a_reply(3)\fP or
\fIares_parse_ptr_reply(3)\fP.
.SH NOTES
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
.BR ares_parse_a_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
Greg Hudson, MIT Information Systems
.br

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,11 +21,9 @@ ares_mkquery \- Compose a single-question DNS query buffer
.nf
.B #include <ares.h>
.PP
.B
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
.B
unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP,
int *\fIbuflen\fP)
.B 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 int *\fIbuflen\fP)
.fi
.SH DESCRIPTION
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
.IR buflen .
It is the caller's responsibility to free this buffer using
.B ares_free_string
when it is no longer needed.
\fIares_free_string(3)\fP when it is no longer needed.
.SH RETURN VALUES
.B ares_mkquery
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
.B #include <ares.h>
.PP
.B
int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB,
.B struct hostent **\fIhost\fB);
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
.B struct hostent **\fIhost\fP);
.fi
.SH DESCRIPTION
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
.B #include <ares.h>
.PP
.B
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 struct hostent **\fIhost\fB);
.B int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
.B const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
.B struct hostent **\fIhost\fP);
.fi
.SH DESCRIPTION
The

View File

@@ -35,13 +35,10 @@ The file descriptor sets pointed to by
and
.I write_fds
should have file descriptors set in them according to whether the file
descriptors specified by
.BR ares_fds (3)
are ready for reading and writing. (The easiest way to determine this
information is to invoke
descriptors specified by \fIares_fds(3)\fP are ready for reading and writing.
(The easiest way to determine this information is to invoke
.B select
with a timeout no greater than the timeout given by
.BR ares_timeout (3)).
with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ).
.PP
The
.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 unsigned char *\fIabuf\fP, int \fIalen\fP)
.PP
.B
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
.fi
.SH DESCRIPTION

View File

@@ -35,7 +35,9 @@ const char *ares_strerror(int code)
"Timeout while contacting DNS servers",
"End of 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)));

View File

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

View File

@@ -4,12 +4,12 @@
#define ARES__VERSION_H
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 0
#define ARES_VERSION_MINOR 2
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.0.0"
#define ARES_VERSION_STR "1.2.0"
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`;
# remove the dir
`rm -rf $name-$version`;
print "NOTE: now cvs tag this release!\n";

Binary file not shown.

Binary file not shown.

View File

@@ -67,7 +67,7 @@ echo "buildconf: autoheader version $ah_version (ok)"
# automake 1.7 or newer
#
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
echo "buildconf: automake not found."
echo " You need automake version $need_automake or newer installed."
@@ -159,7 +159,7 @@ fi
echo "buildconf: running libtoolize"
${LIBTOOLIZE:-libtoolize} --copy --automake --force || die "The command '${LIBTOOLIZE:-libtoolize} --copy --automake --force' failed"
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"
perl -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
echo "buildconf: running autoheader"
@@ -170,7 +170,7 @@ ${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
if test -d ares; then
cd ares
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"
${AUTOCONF:-autoconf} || die "The command '${AUTOCONF:-autoconf}' failed"
cd ..

View File

@@ -24,14 +24,14 @@ AC_PATH_PROG( AR, ar, , $PATH:/usr/bin:/usr/local/bin:/usr/ccs/bin)
AC_SUBST(AR)
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)
AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($VERSION)
dnl
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)
dnl Solaris pkgadd support definitions
@@ -384,6 +384,8 @@ main()
if test "$ipv6" = "yes"; then
CURL_CHECK_WORKING_GETADDRINFO
CURL_CHECK_NI_WITHSCOPEID
fi
dnl **********************************************************************
@@ -915,6 +917,7 @@ printf("just fine");
#endif
],
[ AC_MSG_RESULT([yes])
RECENTAIX=yes
OPT_THREAD=off ],
[ AC_MSG_RESULT([no]) ]
)
@@ -952,10 +955,31 @@ else
dnl is there a 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
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 Back to "normal" configuring
dnl **********************************************************************
@@ -979,6 +1003,7 @@ AC_CHECK_HEADERS(
arpa/inet.h \
net/if.h \
netinet/in.h \
netinet/tcp.h \
netdb.h \
sys/sockio.h \
sys/stat.h \
@@ -1015,6 +1040,9 @@ dnl default includes
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#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.
if test "x$enableval" = "xyes" ; then
if test -d "$srcdir/ares"; then
aresembedded="yes"
AC_CONFIG_SUBDIRS(ares)
aresinc=`cd $srcdir/ares && pwd`
CPPFLAGS="$CPPFLAGS -I$aresinc"
@@ -1240,6 +1269,31 @@ AC_HELP_STRING([--disable-ares],[Disable ares for name lookups]),
CPPFLAGS="$CPPFLAGS -I$enableval/include"
LDFLAGS="$LDFLAGS -L$enableval/lib"
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 ],
AC_MSG_RESULT(no)

View File

@@ -2,17 +2,8 @@
;;;; $Id$
;;; The curl hacker's C conventions.
;;; After loading this file and added the mode-hook you can in C
;;; files, put something like this to use the curl style
;;; automatically:
;;
;; /* -----------------------------------------------------------------
;; * local variables:
;; * eval: (set c-file-style "curl")
;; * end:
;; */
;;
;;; See the sample.emacs file on how this file can be made to take
;;; effect automatically when editing curl source files.
(defconst curl-c-style
'((c-basic-offset . 2)
@@ -37,7 +28,7 @@
(setq tab-width 8
indent-tabs-mode nil ; Use spaces. Not tabs.
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
;; c-mode-base-map because of inheritance ...

View File

@@ -3,8 +3,9 @@ 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
may have been fixed since this was written!
* NTLM authentication with passwords longer than 14 letters fail. There is
a known fix for this, planned to come in curl 7.11.2
* --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
doesn't do a HEAD first to get the initial size. This needs to be done
@@ -22,13 +23,6 @@ may have been fixed since this was written!
indicate that the user wants to reach the root dir (this exception SHALL
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
it seems HTTP servers send the *uncompressed* length in that header and
libcurl thinks of it as the *compressed* lenght. Some explanations are here:
@@ -38,9 +32,6 @@ may have been fixed since this was written!
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
* 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
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
FTPS
It is just like for FTP, but you may also want to specify and use
SSL-specific options for certificates etc.
HTTP
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
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
style when using Curl via a proxy. You _must_ use the -u style fetch
during such circumstances.

View File

@@ -28,6 +28,12 @@ server, do one of the following:
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
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")
@@ -40,7 +46,3 @@ connections that previously weren't really secure. It turned out many people
were using previous versions of curl/libcurl without realizing the need for
the CA cert options to get truly secure SSL connections.
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.

View File

@@ -57,6 +57,13 @@ TODO
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
allegedly from ncftp:
http://curl.haxx.se/mail/archive-2003-04/0126.html
@@ -91,6 +98,15 @@ TODO
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
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

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" 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
curl \- transfer a URL
.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.
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>"
Pass options to the telnet protocol. Supported options are:

View File

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

View File

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

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,
all results from this function are undefined until the transfer is completed.
.SH AVAILABLE INFORMATION
These are informations that can be extracted:
The following information can be extracted:
.IP CURLINFO_EFFECTIVE_URL
Pass a pointer to a 'char *' to receive the last used effective URL.
.IP CURLINFO_RESPONSE_CODE
@@ -51,7 +51,7 @@ pre-transfer commands and negotiations that are specific to the particular
protocol(s) involved.
.IP CURLINFO_STARTTRANSFER_TIME
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
the result.
.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)
.IP CURLINFO_PROXYAUTH_AVAIL
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
If the operation was successful, CURLE_OK is returned. Otherwise an
appropriate error code will be returned.

View File

@@ -13,7 +13,7 @@ curl_easy_init - Start a libcurl easy session
.SH DESCRIPTION
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
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.
.SH RETURN VALUE

View File

@@ -85,7 +85,7 @@ lookups. It enables nice timeouts for name resolves without signals.
.IP CURLOPT_WRITEFUNCTION
Function pointer that should match the following prototype: \fBsize_t
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
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
@@ -165,7 +165,7 @@ Function pointer that should match the following prototype: \fIint
curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
\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
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
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
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
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
@@ -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
\fICURLOPT_PROXYPORT\fP.
\fBNOTE:\fP when you tell the library to use a HTTP proxy, libcurl will
transparently convert operations to HTTP even if you specify a FTP URL
\fBNOTE:\fP when you tell the library to use an HTTP proxy, libcurl will
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
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
@@ -282,19 +282,35 @@ libcurl caches this info for 60 seconds.
.IP CURLOPT_DNS_USE_GLOBAL_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
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
to using the share interface instead! See \fICURLOPT_SHARE\fP and
\fIcurl_share_init(3)\fP.
.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
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)
.IP CURLOPT_PORT
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.
.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)
.IP CURLOPT_NETRC
This parameter controls the preference of libcurl between using user names and
@@ -370,7 +386,7 @@ regular old-fashioned Basic method.
.IP CURLAUTH_GSSNEGOTIATE
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
"Negotiate") method was designed by Microsoft and is used in their web
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
information see IETF draft draft-brezak-spnego-http-04.txt.
@@ -379,17 +395,17 @@ this to work.
.IP CURLAUTH_NTLM
HTTP NTLM authentication. A proprietary protocol invented and used by
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
work.
.IP CURLAUTH_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.
.IP CURLAUTH_ANYSAFE
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.
.RE
.IP CURLOPT_PROXYAUTH
@@ -405,7 +421,7 @@ this writing, only Basic and NTLM work. (Added in 7.10.7)
.SH HTTP OPTIONS
.IP CURLOPT_AUTOREFERER
Pass a non-zero parameter to enable this. When enabled, libcurl will
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.
.IP CURLOPT_ENCODING
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.
.IP CURLOPT_FOLLOWLOCATION
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
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
size. Using the \fICURLOPT_POSTFIELDS\fP option implies this option.
.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
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.
@@ -529,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
should contain.
If you need to set mulitple 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
cookies in one string like this: "name1=content1; name2=content2;" etc.
If you need to set multiple cookies, you need to set them all using a single
option and thus you need to concatenate them all in one single string. Set
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
previously ones.
@@ -622,7 +639,7 @@ only files in their response to NLST; they might not include subdirectories
and symbolic links.
.IP CURLOPT_FTPAPPEND
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
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
@@ -684,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)
.IP CURLOPT_CUSTOMREQUEST
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
more or less obscure HTTP requests. Don't do this at will, make sure your
server supports the command first.
@@ -863,7 +880,7 @@ key.
\fBNOTE:\fPIf the crypto device cannot be loaded,
\fICURLE_SSL_ENGINE_NOTFOUND\fP is returned.
.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.
\fBNOTE:\fPIf the crypto device cannot be set,
@@ -904,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)
.IP CURLOPT_SSL_CIPHER_LIST
Pass a char *, pointing to a zero terminated string holding the list of
ciphers to use for the SSL connection. The list must be syntactly correct, it
consists of one or more cipher strings separated by colons. Commas or spaces
ciphers to use for the SSL connection. The list must be syntactically correct,
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
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

View File

@@ -13,7 +13,7 @@ curl_formadd - add a section to a multipart/formdata HTTP POST
.ad
.SH DESCRIPTION
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
the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
\fIlastitem\fP is set after each call and on repeated invokes it should be
@@ -81,7 +81,7 @@ internally chosen one.
.B CURLFORM_FILENAME
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.
.B BCURLFORM_BUFFER

View File

@@ -36,7 +36,7 @@ This string specifies the time on a given day. Syntax supported includes:
.TP
.B time zone items
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.
.TP
.B day of the week items

View File

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

View File

@@ -23,7 +23,7 @@ remaining messages after this function was called.
The data the returned pointer points to will not survive calling
\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
present in that struct and can thus be used in subsequent regular
\fIcurl_easy_getinfo(3)\fP calls (or similar):

View File

@@ -10,7 +10,7 @@ curl_multi_init - create a multi handle
.ad
.SH DESCRIPTION
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
\fIcurl_multi_cleanup(3)\fP when the operation is complete.
.SH RETURN VALUE

View File

@@ -19,14 +19,14 @@ integer-pointer.
.SH "RETURN VALUE"
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
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
to send off before it is "satisfied".
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.
.SH "TYPICAL USAGE"
Most application will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's

View File

@@ -10,7 +10,7 @@ curl_share_init - Create a shared object
.ad
.SH DESCRIPTION
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
\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

@@ -23,7 +23,7 @@ return until it is done (successfully or not).
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
\fIcurl_easy_cleanup(3)\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
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)"
Failed to connect() to host or proxy.
.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
server is probably not an OK FTP server.
.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.
.IP "CURLE_OUT_OF_MEMORY (27)"
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)"
Operation timeout. The specified time-out period was reached according to the
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
sane.
.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.
.IP "CURLE_HTTP_RANGE_ERROR (33)"
The HTTP server does not support or accept range requests.
.IP "CURLE_HTTP_POST_ERROR (34)"
This is an odd error that mainly occurs due to internal confusion.
.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
more. Could be certificates (file formats, paths, permissions), passwords, and
others.

View File

@@ -71,7 +71,7 @@ timeout every now and then, should you want that.
A little note here about the return codes from the multi functions, and
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(3)\fP again, before you select() on more 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 to send off
@@ -97,4 +97,4 @@ to clean them up properly.
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
again (possbily after having altered some options at your own choice).
again (possibly after having altered some options at your own choice).

View File

@@ -21,8 +21,8 @@ libcurl is complete, it \fBmust\fP call \fIcurl_global_cleanup(3)\fP. In
between those two calls, you can use libcurl as described below.
To transfer files, you always set up an "easy handle" using
\fIcurl_easy_init(3)\fP, but when you want the file(s) transfered you have the
option of using the "easy" interface, or the "multi" interface.
\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
the option of using the "easy" interface, or the "multi" interface.
The easy interface is a synchronous interface with which you call
\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
@@ -30,7 +30,7 @@ completed, the function return and you can continue. More details are found in
the \fIlibcurl-easy(3)\fP man page.
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
similar. The multi interface allows you to select() on libcurl action, and
even to easily download multiple files simultaneously using a single thread.
@@ -56,7 +56,7 @@ portable environment variable reader
get information about a performed transfer
.TP
.B curl_formadd()
helps building a HTTP form POST
helps building an HTTP form POST
.TP
.B curl_formfree()
free a list built with \fIcurl_formadd(3)\fP

View File

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

View File

@@ -27,31 +27,7 @@
http://curl.haxx.se/libcurl/
*/
/* This is the version number of the libcurl package from which this header
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 "curlver.h" /* the libcurl version defines */
#include <stdio.h>
#include <limits.h>
@@ -786,6 +762,9 @@ typedef enum {
/* 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 */
} CURLoption;
@@ -1090,7 +1069,6 @@ void curl_slist_free_all(struct curl_slist *);
*/
time_t curl_getdate(const char *p, const time_t *now);
#define CURLINFO_STRING 0x100000
#define CURLINFO_LONG 0x200000
#define CURLINFO_DOUBLE 0x300000
@@ -1266,6 +1244,28 @@ typedef struct {
*/
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
}
#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

@@ -203,6 +203,17 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle);
CURLMsg *curl_multi_info_read(CURLM *multi_handle,
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
} /* end of extern "C" */
#endif

View File

@@ -1,17 +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$
#
###########################################################################
AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp \
curllib.dsw config-vms.h config-win32.h config-riscos.h config-mac.h \
config.h.in ca-bundle.crt README.encoding README.memoryleak \
README.ares makefile.dj config.dj \
libcurl.framework.make libcurl.plist libcurl.rc \
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
Makefile.netware nwlib.c libcurl.imp
EXTRA_DIST = getdate.y Makefile.b32 Makefile.b32.resp Makefile.m32 \
Makefile.vc6 Makefile.riscos libcurl.def curllib.dsp curllib.dsw \
config-vms.h config-win32.h config-riscos.h config-mac.h config.h.in \
ca-bundle.crt README.encoding README.memoryleak README.ares README.curlx \
makefile.dj config.dj libcurl.framework.make libcurl.plist libcurl.rc \
config-amigaos.h amigaos.c amigaos.h makefile.amiga config-netware.h \
Makefile.netware nwlib.c libcurl.imp
lib_LTLIBRARIES = libcurl.la
@@ -38,16 +55,16 @@ VERSION=-version-info 2:2:0
# that the current interface number gets larger faster.
#
# 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
# 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
# increment age.
# increment age. (c:r:a+1)
#
# 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
@@ -63,20 +80,20 @@ endif
libcurl_la_LDFLAGS = $(UNDEF) $(VERSION) $(MIMPURE)
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c \
base64.c file.h hostip.c progress.c timeval.h base64.h formdata.c \
hostip.h progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c \
http.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 \
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.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 \
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.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 \
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 \
strtoofft.c strtoofft.h
libcurl_la_SOURCES = arpa_telnet.h file.c netrc.h timeval.c base64.c \
file.h hostip.c progress.c timeval.h base64.h formdata.c hostip.h \
progress.h cookie.c formdata.h http.c sendf.c cookie.h ftp.c http.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 \
version.c getenv.c ldap.h ssluse.h escape.c mprintf.c telnet.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 \
memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.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 \
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 \
strtoofft.c strtoofft.h strerror.c strerror.h
noinst_HEADERS = setup.h transfer.h

View File

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

View File

@@ -19,6 +19,7 @@
# files in the "cfg" directory, but then the make file
# in \src would need to be changed.
#
# $Id: Makefile.vc6,v 1.17 2004/01/13 08:57:01 bagder Exp $
##############################################################
# CHANGE LOG
# ------------------------------------------------------------
@@ -37,12 +38,17 @@ LIB_NAME_DEBUG = libcurld
OPENSSL_PATH = ../../openssl-0.9.7a
!ENDIF
!IFNDEF ZLIB_PATH
ZLIB_PATH = ../../zlib-1.1.4
!ENDIF
#############################################################
## Nothing more to do below this line!
CCNODBG = cl.exe /MD /O2 /D "NDEBUG"
CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D "_DEBUG" /GZ
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"
LNKDLL = link.exe /DLL /def:libcurl.def
@@ -100,6 +106,19 @@ CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
!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
!IF "$(CFG)" == "release-libcurl-ssl-dll"
@@ -169,6 +188,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
!MESSAGE release - release static library
!MESSAGE release-dll - release dll
!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-libcurl-ssl-dll - static libcurl with shared ssl
!MESSAGE debug - debug static library
@@ -222,6 +242,8 @@ X_OBJS= \
$(DIROBJ)\http_negotiate.obj \
$(DIROBJ)\http_ntlm.obj \
$(DIROBJ)\md5.obj \
$(DIROBJ)\strerror.obj \
$(DIROBJ)\content_encoding.obj \
$(RESOURCE)
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:
ftp://athena-dist.mit.edu/pub/ATHENA/ares/ares-1.1.1.tar.gz
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
c-ares:
http://daniel.haxx.se/projects/c-ares/
NOTE
libcurl works with ares 1.1.1, but several patches and improvements have
been put into the c-ares package which has made it more portable and better
working on several platforms.
libcurl 7.11.1 builds with c-ares 1.1.0, but 7.11.2 and later require c-ares
1.2.0 or alter.
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
2. cd ares-dir
Build c-ares
============
1. unpack the c-ares archive
2. cd c-ares-dir
3. ./configure
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
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
2. make
Ares and ipv6
=============
c-ares and ipv6
===============
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)
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
prevent linking errors later on). Then I simply build the areslib project (the
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.

View File

@@ -25,10 +25,12 @@
#define HAVE_IO_H 1
#define HAVE_IOCTLSOCKET 1
#define HAVE_INET_PTON 1
#define HAVE_LONGLONG 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
#define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1
#define HAVE_NETINET_TCP_H 1
#define HAVE_NET_IF_H 1
#define HAVE_PERROR 1
#define HAVE_SELECT 1
@@ -38,12 +40,14 @@
#define HAVE_SIGACTION 1
#define HAVE_SIGSETJMP 1
#define HAVE_SOCKET 1
#define HAVE_SPNEGO 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1
#define HAVE_STRFTIME 1
#define HAVE_STRICMP 1
#define HAVE_STRSTR 1
#define HAVE_STRTOLL 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
@@ -53,9 +57,13 @@
#define HAVE_UNISTD_H 1
#define HAVE_VPRINTF 1
#if (DJGPP_MINOR >= 4)
#define HAVE_STRLCAT 1
#endif
#define RETSIGTYPE void
#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 TIME_WITH_SYS_TIME 1

View File

@@ -32,7 +32,15 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#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>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -86,6 +94,7 @@
#include "urldata.h"
#include "sendf.h"
#include "if2ip.h"
#include "strerror.h"
#include "connect.h"
/* The last #include file should be: */
@@ -138,7 +147,7 @@ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
#ifdef HAVE_IOCTLSOCKET
/* Windows? */
int flags;
unsigned long flags;
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#define SETBLOCK 3
@@ -295,10 +304,10 @@ static CURLcode bindlocal(struct connectdata *conn,
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
data->set.device, strlen(data->set.device)+1) != 0) {
/* 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",
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 */
}
}
@@ -353,37 +362,9 @@ static CURLcode bindlocal(struct connectdata *conn,
}
#endif
if(!bindworked) {
switch(errno) {
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) */
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
return CURLE_HTTP_PORT_FAILED;
} /* end of else */
}
} /* end of if h */
else {
@@ -488,8 +469,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
}
else if(1 != rc) {
int error = Curl_ourerrno();
failf(data, "Failed connect to %s:%d, errno: %d",
conn->hostname, conn->port, error);
failf(data, "Failed connect to %s:%d; %s",
conn->hostname, conn->port, Curl_strerror(conn,error));
return CURLE_COULDNT_CONNECT;
}
/*
@@ -503,6 +484,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
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.
@@ -581,6 +579,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd == CURL_SOCKET_BAD)
continue;
else if(data->set.tcp_nodelay)
Curl_setNoDelay(conn, sockfd);
#else
/*
* Connecting with old style IPv4-only support
@@ -600,6 +601,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
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 */
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr),
@@ -651,8 +655,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
break;
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to %s IP number %d: %d",
hostname, aliasindex+1, error);
failf(data, "Failed to connect to %s IP number %d: %s",
hostname, aliasindex+1, Curl_strerror(conn,error));
break;
}
}

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# 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 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
# ADD BASE 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 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 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
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

View File

@@ -271,7 +271,7 @@ CURLcode curl_easy_perform(CURL *curl)
}
if (!data->hostcache) {
data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
data->hostcache = Curl_mk_dnscache();
if(!data->hostcache)
/* 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
information. Which for FILE can't be much more than the file size and
date. */
if(data->set.no_body && data->set.include_header && fstated) {
if(conn->bits.no_body && data->set.include_header && fstated) {
CURLcode result;
sprintf(buf, "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);

View File

@@ -91,6 +91,7 @@
#include "strequal.h"
#include "ssluse.h"
#include "connect.h"
#include "strerror.h"
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
@@ -104,6 +105,12 @@
#include "memdebug.h"
#endif
#ifdef HAVE_NI_WITHSCOPEID
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
#else
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
#endif
/* Local API functions */
static CURLcode ftp_sendquote(struct connectdata *conn,
struct curl_slist *quote);
@@ -954,7 +961,7 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
if(ftpcode == 213) {
/* get the size from the ascii string: */
*size = strtoofft(buf+4, NULL, 0);
*size = curlx_strtoofft(buf+4, NULL, 0);
}
else
return CURLE_FTP_COULDNT_GET_SIZE;
@@ -1073,14 +1080,9 @@ ftp_pasv_verbose(struct connectdata *conn,
char hbuf[NI_MAXHOST]; /* ~1KB */
char nbuf[NI_MAXHOST]; /* ~1KB */
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 */
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(sbuf, sizeof(sbuf), "?");
}
@@ -1126,11 +1128,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
char hbuf[NI_MAXHOST];
struct sockaddr *sa=(struct sockaddr *)&ss;
#ifdef NI_WITHSCOPEID
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
#else
#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
#endif
unsigned char *ap;
unsigned char *pp;
char portmsgbuf[4096], tmp[4096];
@@ -1138,6 +1135,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
char **modep;
int rc;
int error;
/*
* we should use Curl_if2ip? given pickiness of recent ftpd,
@@ -1172,6 +1170,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
}
portsock = CURL_SOCKET_BAD;
error = 0;
for (ai = res; ai; ai = ai->ai_next) {
/*
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
@@ -1180,16 +1179,20 @@ CURLcode ftp_use_port(struct connectdata *conn)
ai->ai_socktype = hints.ai_socktype;
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;
}
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
error = Curl_ourerrno();
sclose(portsock);
portsock = CURL_SOCKET_BAD;
continue;
}
if (listen(portsock, 1) < 0) {
error = Curl_ourerrno();
sclose(portsock);
portsock = CURL_SOCKET_BAD;
continue;
@@ -1199,13 +1202,13 @@ CURLcode ftp_use_port(struct connectdata *conn)
}
freeaddrinfo(res);
if (portsock == CURL_SOCKET_BAD) {
failf(data, "%s", strerror(errno));
failf(data, "%s", Curl_strerror(conn,error));
return CURLE_FTP_PORT_FAILED;
}
sslen = sizeof(ss);
if (getsockname(portsock, sa, &sslen) < 0) {
failf(data, "%s", strerror(errno));
failf(data, "%s", Curl_strerror(conn,Curl_ourerrno()));
return CURLE_FTP_PORT_FAILED;
}
@@ -1248,18 +1251,19 @@ CURLcode ftp_use_port(struct connectdata *conn)
/* do not transmit IPv6 scope identifier to the wire */
if (sa->sa_family == AF_INET6) {
char *q = strchr(portmsgbuf, '%');
if (q)
*q = '\0';
if (q)
*q = '\0';
}
result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,
portmsgbuf, tmp);
if(result)
return result;
} else if (strcmp(*modep, "LPRT") == 0 ||
strcmp(*modep, "PORT") == 0) {
}
else if (strcmp(*modep, "LPRT") == 0 ||
strcmp(*modep, "PORT") == 0) {
int i;
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
continue;
if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET)
@@ -1834,7 +1838,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
return result;
}
else if(!data->set.no_body) {
else if(!conn->bits.no_body) {
/* Retrieve file or directory */
bool dirlist=FALSE;
curl_off_t downloadsize=-1;
@@ -1845,10 +1849,10 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
char *ptr;
char *ptr2;
from=strtoofft(conn->range, &ptr, 0);
from=curlx_strtoofft(conn->range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++;
to=strtoofft(ptr, &ptr2, 0);
to=curlx_strtoofft(ptr, &ptr2, 0);
if(ptr == ptr2) {
/* we didn't get any digit */
to=-1;
@@ -2067,7 +2071,7 @@ CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
/* only if we have nothing but digits: */
if(bytes++) {
/* get the number! */
size = strtoofft(bytes, NULL, 0);
size = curlx_strtoofft(bytes, NULL, 0);
}
}
@@ -2205,7 +2209,7 @@ CURLcode ftp_perform(struct connectdata *conn,
/* 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
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
may not support it! It is however the only way we have to get a file's
size! */
@@ -2268,7 +2272,7 @@ CURLcode ftp_perform(struct connectdata *conn,
return CURLE_OK;
}
if(data->set.no_body)
if(conn->bits.no_body)
/* doesn't really transfer any data */
ftp->no_transfer = TRUE;
/* Get us a second connection up and connected */

View File

@@ -742,10 +742,10 @@ ToYear (int Year)
static int
LookupWord (YYSTYPE *yylval, char *buff)
{
register char *p;
register char *q;
register const TABLE *tp;
int i;
char *p;
char *q;
const TABLE *tp;
size_t i;
int abbrev;
/* Make it lowercase. */

View File

@@ -60,6 +60,10 @@
#include <setjmp.h>
#endif
#ifdef WIN32
#include <process.h>
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
@@ -70,6 +74,7 @@
#include "hostip.h"
#include "hash.h"
#include "share.h"
#include "strerror.h"
#include "url.h"
#define _MPRINTF_REPLACE /* use our functions only */
@@ -88,19 +93,32 @@
#define ARES_SUCCESS CURLE_OK
#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 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,
char *hostname,
int port,
int *waitp);
#ifndef ENABLE_IPV6
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
defined(USE_THREADING_GETHOSTBYNAME)
#if (!defined(HAVE_GETHOSTBYNAME_R) || defined(USE_ARES) || \
defined(USE_THREADING_GETHOSTBYNAME)) && \
!defined(ENABLE_IPV6)
static struct hostent* pack_hostent(char** buf, struct hostent* orig);
#endif
#endif
#ifdef USE_THREADING_GETHOSTBYNAME
#ifdef DEBUG_THREADING_GETHOSTBYNAME
@@ -113,29 +131,39 @@ static void trace_it (const char *fmt, ...);
#define TRACE(x)
#endif
static struct hostent* pack_hostent (char** buf, struct hostent* orig);
static bool init_gethostbyname_thread (struct connectdata *conn,
const char *hostname, int port);
struct thread_data {
HANDLE thread_hnd;
DWORD thread_id;
unsigned thread_id;
DWORD thread_status;
};
#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)
{
if (!host_cache_initialized) {
Curl_hash_init(&hostname_cache, 7, Curl_freednsinfo);
Curl_hash_init(&hostname_cache, 7, freednsentry);
host_cache_initialized = 1;
}
}
/*
* Return a pointer to the global cache
*/
curl_hash *Curl_global_host_cache_get(void)
{
return &hostname_cache;
}
/*
* Destroy and cleanup the global DNS cache
*/
void Curl_global_host_cache_dtor(void)
{
if (host_cache_initialized) {
@@ -144,7 +172,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)
{
int chars = 0;
@@ -165,7 +196,10 @@ static int _num_chars(int i)
return chars;
}
/* Create a hostcache id */
/*
* Minor utility-function:
* Create a hostcache id string for the DNS caching.
*/
static char *
create_hostcache_id(char *server, int port, size_t *entry_len)
{
@@ -192,6 +226,13 @@ struct hostcache_prune_data {
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
hostcache_timestamp_remove(void *datap, void *hc)
{
@@ -209,6 +250,9 @@ hostcache_timestamp_remove(void *datap, void *hc)
return 1;
}
/*
* Prune the DNS cache. This assumes that a lock has already been taken.
*/
static void
hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
{
@@ -222,6 +266,10 @@ hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
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)
{
time_t now;
@@ -245,15 +293,22 @@ void Curl_hostcache_prune(struct SessionHandle *data)
}
#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;
#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 etc */
/*
* cache_resolv_response() stores a 'Curl_addrinfo' struct in the DNS cache.
*
* 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 *
cache_resolv_response(struct SessionHandle *data,
Curl_addrinfo *addr,
@@ -303,15 +358,22 @@ cache_resolv_response(struct SessionHandle *data,
return dns;
}
/* Resolve a name and return a pointer in the 'entry' argument if one
is available.
Return codes:
-1 = error, no pointer
0 = OK, pointer provided
1 = waiting for response, no pointer
*/
/*
* 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
* is provided). This function might return immediately if we're using asynch
* resolves. See the return codes.
*
* The cache entry we return will get its 'inuse' counter increased when this
* 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,
char *hostname,
int port,
@@ -405,6 +467,11 @@ int Curl_resolv(struct connectdata *conn,
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)
{
if(data->share)
@@ -438,9 +505,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;
@@ -449,6 +516,14 @@ void Curl_freednsinfo(void *freethis)
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 --- */
/* Allocate enough memory to hold the full name information structs and
@@ -460,6 +535,15 @@ void Curl_freednsinfo(void *freethis)
#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,
fd_set *read_fd_set,
fd_set *write_fd_set,
@@ -473,25 +557,33 @@ CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
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,
struct Curl_dns_entry **dns)
{
fd_set read_fds, write_fds;
static const struct timeval tv={0,0};
struct timeval tv={0,0};
int count;
struct SessionHandle *data = conn->data;
int nfds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
count = select(nfds, &read_fds, &write_fds, NULL,
(struct timeval *)&tv);
if(count)
ares_process(data->state.areschannel, &read_fds, &write_fds);
/* 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);
*dns = NULL;
@@ -505,23 +597,21 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
return CURLE_OK;
}
/* This is a function that locks and waits until the name resolve operation
has completed.
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.
*/
/*
* 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
*
* 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,
struct Curl_dns_entry **entry)
{
CURLcode rc=CURLE_OK;
struct SessionHandle *data = conn->data;
struct timeval now = Curl_tvnow();
bool timedout = FALSE;
long timeout = 300; /* default name resolve timeout in seconds */
long elapsed = 0; /* time taken so far */
long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
/* now, see if there's a connect timeout or a regular timeout to
use instead of the default one */
@@ -536,28 +626,30 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
fd_set read_fds, write_fds;
struct timeval *tvp, tv, store;
int count;
struct timeval now = Curl_tvnow();
store.tv_sec = (int)(timeout - elapsed);
store.tv_sec = (int)timeout;
store.tv_usec = 0;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
if (nfds == 0)
/* no file descriptors means we're done waiting */
break;
tvp = ares_timeout(data->state.areschannel,
&store, &tv);
tvp = ares_timeout(data->state.areschannel, &store, &tv);
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
if (count < 0 && errno != EINVAL)
break;
else if(!count) {
/* timeout */
timedout = TRUE;
break;
}
ares_process(data->state.areschannel, &read_fds, &write_fds);
elapsed = Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
timeout -= Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
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
@@ -568,7 +660,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
if(!conn->async.dns) {
/* 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);
rc = CURLE_OPERATION_TIMEDOUT;
}
@@ -591,8 +683,16 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
#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 *" */
int status,
struct hostent *hostent)
@@ -633,9 +733,11 @@ static void host_callback(void *arg, /* "struct connectdata *" */
#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
* 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.
*/
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
@@ -670,9 +772,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
#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
called, we return failure at once. */
/*
* Curl_wait_for_resolv() 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 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,
struct Curl_dns_entry **entry)
{
@@ -681,6 +788,13 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
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,
struct Curl_dns_entry **dns)
{
@@ -692,6 +806,12 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
#endif
#if !defined(USE_ARES)
/*
* Non-ares build.
*
* We provide this function only to allow multi.c to remain unaware if we are
* doing asynch resolves or not.
*/
CURLcode Curl_multi_ares_fdset(struct connectdata *conn,
fd_set *read_fd_set,
fd_set *write_fd_set,
@@ -745,9 +865,11 @@ void curl_freeaddrinfo(struct addrinfo *freethis,
#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
* 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.
*/
static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
@@ -807,11 +929,14 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
}
#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);
/*
* Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
* copy). Make absolutely sure the destination buffer is big enough!
* pack_hostent() is a file-local function that performs a "deep" copy of a
* 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)
{
@@ -887,11 +1012,11 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
/* now, shrink the allocated buffer to the size we actually need, which
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(newbuf != *buf)
hostcache_fixoffset((struct hostent*)newbuf, (long)newbuf-(long)*buf);
hostcache_fixoffset((struct hostent*)newbuf, (long)(newbuf-*buf));
/* setup the return */
*buf = newbuf;
@@ -901,6 +1026,12 @@ static struct hostent* pack_hostent(char** buf, struct hostent* orig)
}
#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)
{
int i=0;
@@ -925,6 +1056,11 @@ static void hostcache_fixoffset(struct hostent *h, long offset)
#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)
{
#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
@@ -946,9 +1082,13 @@ static char *MakeIP(unsigned long num, char *addr, int addr_len)
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
considerably. */
/*
* my_getaddrinfo() - the ipv4 "traditional" version.
*
* 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,
char *hostname,
int port,
@@ -1148,9 +1288,10 @@ static Curl_addrinfo *my_getaddrinfo(struct connectdata *conn,
else {
#ifdef USE_THREADING_GETHOSTBYNAME
/* fire up a new resolver thread! */
if (init_gethostbyname_thread(conn,hostname,port)) {
*waitp = TRUE; /* please wait for the response */
return NULL;
*waitp = TRUE; /* please wait for the response */
return NULL;
}
infof(data, "init_gethostbyname_thread() failed for %s; code %lu\n",
hostname, GetLastError());
@@ -1183,8 +1324,10 @@ static void trace_it (const char *fmt, ...)
static int do_trace = -1;
va_list args;
if (do_trace == -1)
do_trace = getenv("CURL_TRACE") ? 1 : 0;
if (do_trace == -1) {
const char *env = getenv("CURL_TRACE");
do_trace = (env && atoi(env) > 0);
}
if (!do_trace)
return;
va_start (args, fmt);
@@ -1194,9 +1337,13 @@ static void trace_it (const char *fmt, ...)
}
#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 hostent *he;
@@ -1215,32 +1362,37 @@ static DWORD WINAPI gethostbyname_thread (void *arg)
TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
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)
free(conn->async.hostname);
if (conn->async.os_specific)
free(conn->async.os_specific);
conn->async.hostname = NULL;
conn->async.os_specific = NULL;
if (async->hostname)
free(async->hostname);
if (async->os_specific)
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,
const char *hostname, int port)
{
struct thread_data *td = malloc(sizeof(*td));
struct thread_data *td = calloc(sizeof(*td), 1);
if (!td) {
SetLastError(ENOMEM);
return (0);
}
memset (td, 0, sizeof(*td));
Curl_safefree(conn->async.hostname);
conn->async.hostname = strdup(hostname);
if (!conn->async.hostname) {
@@ -1255,17 +1407,25 @@ static bool init_gethostbyname_thread (struct connectdata *conn,
conn->async.dns = NULL;
conn->async.os_specific = (void*) td;
td->thread_hnd = CreateThread(NULL, 0, gethostbyname_thread,
td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, gethostbyname_thread,
conn, 0, &td->thread_id);
if (!td->thread_hnd) {
TRACE(("CreateThread() failed; %lu\n", GetLastError()));
destroy_thread_data(conn);
SetLastError(errno);
TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
destroy_thread_data(&conn->async);
return (0);
}
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,
struct Curl_dns_entry **entry)
{
@@ -1279,26 +1439,31 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
/* now, see if there's a connect timeout or a regular timeout to
use instead of the default one */
timeout = conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
conn->data->set.timeout ? conn->data->set.timeout :
300; /* default name resolve timeout in seconds */
timeout =
conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
conn->data->set.timeout ? conn->data->set.timeout :
CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
ticks = GetTickCount();
status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
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);
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 {
conn->async.done = TRUE;
TerminateThread(td->thread_hnd, (DWORD)-1);
td->thread_status = (DWORD)-1;
TRACE(("gethostbyname_thread() timeout, "));
}
TRACE(("gethostbyname_thread() retval %08lX, elapsed %lu ms\n",
td->thread_status, GetTickCount()-ticks));
TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
CloseHandle(td->thread_hnd);
if(entry)
*entry = conn->async.dns;
@@ -1312,13 +1477,14 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
rc = CURLE_OPERATION_TIMEDOUT;
}
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->name, Curl_strerror(conn,conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST;
}
else
rc = CURLE_OPERATION_TIMEDOUT;
destroy_thread_data(conn);
destroy_thread_data(&conn->async);
/* close the connection, since we can't return failure here without
cleaning up this connection properly */
Curl_disconnect(conn);
@@ -1326,6 +1492,11 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
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,
struct Curl_dns_entry **entry)
{
@@ -1333,7 +1504,7 @@ CURLcode Curl_is_resolved(struct connectdata *conn,
if (conn->async.done) {
/* we're done */
destroy_thread_data(conn);
destroy_thread_data(&conn->async);
if (!conn->async.dns) {
TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
return CURLE_COULDNT_RESOLVE_HOST;

View File

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

View File

@@ -186,33 +186,47 @@ void Curl_http_auth_act(struct connectdata *conn)
conn->newurl = strdup(data->change.url); /* clone URL */
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
* authentication method.
* authentication method. @p conn->data->state.authdone set to TRUE
* when authentication is done.
*
* @param conn all information about the current connection
*/
static CURLcode http_auth_headers(struct connectdata *conn,
char *request,
char *path,
bool *ready) /* set TRUE when the auth phase
is done and ready to do the *actual*
request */
char *path)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *auth=NULL;
*ready = FALSE; /* default is no */
curlassert(data);
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);
else if(conn->bits.user_passwd)
}
else if(conn->bits.user_passwd) {
data->state.authdone = FALSE;
Curl_http_auth_stage(data, 401);
}
else {
*ready = TRUE;
data->state.authdone = TRUE;
return CURLE_OK; /* no authentication with no user or password */
}
}
@@ -229,7 +243,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
#ifdef USE_SSLEAY
if(data->state.authwant == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, TRUE, ready);
result = Curl_output_ntlm(conn, TRUE);
if(result)
return result;
}
@@ -244,7 +258,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
if(result)
return result;
}
*ready = TRUE;
data->state.authdone = TRUE;
/* Switch to web authentication after proxy authentication is done */
Curl_http_auth_stage(data, 401);
}
@@ -262,14 +276,14 @@ static CURLcode http_auth_headers(struct connectdata *conn,
result = Curl_output_negotiate(conn);
if (result)
return result;
*ready = TRUE;
data->state.authdone = TRUE;
}
else
#endif
#ifdef USE_SSLEAY
if(data->state.authwant == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, FALSE, ready);
result = Curl_output_ntlm(conn, FALSE);
if(result)
return result;
}
@@ -284,7 +298,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
(unsigned char *)path);
if(result)
return result;
*ready = TRUE;
data->state.authdone = TRUE;
}
else if(data->state.authwant == CURLAUTH_BASIC) {/* Basic */
if(conn->bits.user_passwd &&
@@ -295,7 +309,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
return result;
}
/* basic is always ready */
*ready = TRUE;
data->state.authdone = TRUE;
}
}
if(auth)
@@ -304,7 +318,7 @@ static CURLcode http_auth_headers(struct connectdata *conn,
}
}
else
*ready = TRUE;
data->state.authdone = TRUE;
return result;
}
@@ -398,17 +412,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
*availp |= CURLAUTH_DIGEST;
if(data->state.authwant == CURLAUTH_DIGEST) {
/* Digest authentication is activated */
CURLdigest dig = CURLDIGEST_BAD;
if(data->state.digest.nonce)
infof(data, "Authentication problem. Ignoring this.\n");
else
dig = Curl_input_digest(conn, start);
CURLdigest dig = Curl_input_digest(conn, start);
if(CURLDIGEST_FINE == dig)
/* We act on it. Store our new url, which happens to be
the same one we already use! */
conn->newurl = strdup(data->change.url); /* clone string */
else
infof(data, "Authentication problem. Ignoring this.\n");
}
else
if(data->state.authwant & CURLAUTH_DIGEST) {
@@ -438,6 +449,85 @@ CURLcode Curl_http_auth(struct connectdata *conn,
return CURLE_OK;
}
/**
* determine 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;
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: httpcode = %d\n",__FUNCTION__,k->httpcode);
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
#endif
if (data->state.authstage &&
(data->state.authstage == k->httpcode))
return data->state.authdone;
/*
** Either we're not authenticating, or we're supposed to
** be authenticating something else. This is an error.
*/
return 1;
}
/* fread() emulation to provide POST and/or request data */
static size_t readmoredata(char *buffer,
@@ -760,9 +850,6 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
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) {
/* 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()
@@ -776,7 +863,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
/* 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) {
/* OK, now send the connect request to the proxy */
@@ -877,7 +964,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
/* send the header to the callback */
writetype = CLIENTWRITE_HEADER;
if(data->set.http_include_header)
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
result = Curl_client_write(data, writetype, line_start, perline);
@@ -1029,10 +1116,12 @@ CURLcode Curl_http_done(struct connectdata *conn)
conn->bytecount = http->readbytecount + http->writebytecount;
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
read from the HTTP server, this can't be right so we return an error
here */
read from the HTTP server (that counts), this can't be right so we
return an error here */
failf(data, "Empty reply from server");
return CURLE_GOT_NOTHING;
}
@@ -1066,7 +1155,7 @@ CURLcode Curl_http(struct connectdata *conn)
const char *te = ""; /* tranfer-encoding */
char *ptr;
char *request;
bool authdone=TRUE; /* if the authentication phase is done */
Curl_HttpReq httpreq = data->set.httpreq;
if(!conn->proto.http) {
/* Only allocate this struct if we don't already have it! */
@@ -1085,19 +1174,40 @@ CURLcode Curl_http(struct connectdata *conn)
if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
data->set.upload) {
data->set.httpreq = HTTPREQ_PUT;
httpreq = HTTPREQ_PUT;
}
request = data->set.customrequest?
data->set.customrequest:
(data->set.no_body?(char *)"HEAD":
((HTTPREQ_POST == data->set.httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq))?(char *)"POST":
(HTTPREQ_PUT == data->set.httpreq)?(char *)"PUT":(char *)"GET");
/* Now set the 'request' pointer to the proper request string */
if(data->set.customrequest)
request = data->set.customrequest;
else {
if(conn->bits.no_body)
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
have been used in the proxy connect, but if we have got a header with
the user-agent string specified, we erase the previously made string
/* The User-Agent string might have been allocated in url.c already, because
it might have been used in the proxy connect, but if we have got a header
with the user-agent string specified, we erase the previously made string
here. */
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
free(conn->allocptr.uagent);
@@ -1105,10 +1215,20 @@ CURLcode Curl_http(struct connectdata *conn)
}
/* setup the authentication headers */
result = http_auth_headers(conn, request, ppath, &authdone);
result = http_auth_headers(conn, request, ppath);
if(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);
if(data->change.referer && !checkheaders(data, "Referer:"))
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->change.referer);
@@ -1121,7 +1241,7 @@ CURLcode Curl_http(struct connectdata *conn)
else
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 */
ptr = checkheaders(data, "Transfer-Encoding:");
if(ptr) {
@@ -1212,7 +1332,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* The path sent to the proxy is in fact the entire 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
a size of the whole shebang before we start to send it */
result = Curl_getFormData(&http->sendit, data->set.httppost,
@@ -1231,9 +1351,9 @@ CURLcode Curl_http(struct connectdata *conn)
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: */*\r\n";
if(( (HTTPREQ_POST == data->set.httpreq) ||
(HTTPREQ_POST_FORM == data->set.httpreq) ||
(HTTPREQ_PUT == data->set.httpreq) ) &&
if(( (HTTPREQ_POST == httpreq) ||
(HTTPREQ_POST_FORM == httpreq) ||
(HTTPREQ_PUT == httpreq) ) &&
conn->resume_from) {
/**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have
@@ -1296,14 +1416,14 @@ CURLcode Curl_http(struct connectdata *conn)
* or uploading and we always let customized headers override our internal
* ones if any such are specified.
*/
if((data->set.httpreq == HTTPREQ_GET) &&
if((httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) {
/* if a line like this was already allocated, free the previous one */
if(conn->allocptr.rangeline)
free(conn->allocptr.rangeline);
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:")) {
if(conn->resume_from) {
@@ -1466,11 +1586,11 @@ CURLcode Curl_http(struct connectdata *conn)
http->postdata = NULL; /* nothing to post at this point */
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
/* If 'authdone' is still FALSE, we must not set the write socket index to
the Curl_transfer() call below, as we're not ready to actually upload
any data yet. */
/* If 'authdone' is FALSE, we must not set the write socket index to the
Curl_transfer() call below, as we're not ready to actually upload any
data yet. */
switch(data->set.httpreq) {
switch(httpreq) {
case HTTPREQ_POST_FORM:
if(Curl_FormInit(&http->form, http->sendit)) {
@@ -1535,8 +1655,8 @@ CURLcode Curl_http(struct connectdata *conn)
/* setup variables for the upcoming transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
authdone?FIRSTSOCKET:-1,
authdone?&http->writebytecount:NULL);
data->state.authdone?FIRSTSOCKET:-1,
data->state.authdone?&http->writebytecount:NULL);
if(result) {
Curl_formclean(http->sendit); /* free that whole lot */
return result;
@@ -1574,8 +1694,8 @@ CURLcode Curl_http(struct connectdata *conn)
/* prepare for transfer */
result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
authdone?FIRSTSOCKET:-1,
authdone?&http->writebytecount:NULL);
data->state.authdone?FIRSTSOCKET:-1,
data->state.authdone?&http->writebytecount:NULL);
if(result)
return result;
break;
@@ -1606,7 +1726,7 @@ CURLcode Curl_http(struct connectdata *conn)
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
to actually send off any data yet. Hence, we delay the sending of
the body until we receive that friendly 100-continue response */
@@ -1642,7 +1762,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* set the upload size to the progress meter */
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
headers which actually speeds up post operations (as there is
one packet coming back from the web server) */

View File

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

View File

@@ -36,6 +36,7 @@
#include "md5.h"
#include "http_digest.h"
#include "url.h" /* for Curl_safefree() */
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -57,6 +58,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
{
bool more = TRUE;
struct SessionHandle *data=conn->data;
bool before = FALSE; /* got a nonce before */
struct digestdata *d = &data->state.digest;
/* skip initial whitespaces */
while(*header && isspace((int)*header))
@@ -65,6 +68,10 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
if(checkprefix("Digest", header)) {
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 */
Curl_digest_cleanup(data);
@@ -77,21 +84,32 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
header++;
/* how big can these strings be? */
if(2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
value, content)) {
if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
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")) {
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")) {
data->state.digest.cnonce = strdup(content);
d->cnonce = strdup(content);
}
else if(strequal(value, "realm")) {
data->state.digest.realm = strdup(content);
d->realm = strdup(content);
}
else if(strequal(value, "algorithm")) {
if(strequal(content, "MD5-sess"))
data->state.digest.algo = CURLDIGESTALGO_MD5SESS;
/* else, remain using the default md5 */
d->algo = CURLDIGESTALGO_MD5SESS;
else if(strequal(content, "MD5"))
d->algo = CURLDIGESTALGO_MD5;
else
return CURLDIGEST_BADALGO;
}
else {
/* unknown specifier, ignore it! */
@@ -106,8 +124,15 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
/* allow the list to be comma-separated */
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;
}
else
@@ -140,6 +165,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char *md5this;
struct SessionHandle *data = conn->data;
struct digestdata *d = &data->state.digest;
/*
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 )
":" unq(nonce-value) ":" unq(cnonce-value)
*/
if(data->state.digest.algo == CURLDIGESTALGO_MD5SESS) {
if(d->algo == CURLDIGESTALGO_MD5SESS) {
md5this = (unsigned char *)
aprintf("%s:%s:%s:%s:%s",
conn->user,
data->state.digest.realm,
d->realm,
conn->passwd,
data->state.digest.nonce,
data->state.digest.cnonce);
d->nonce,
d->cnonce);
}
else {
md5this = (unsigned char *)
aprintf("%s:%s:%s",
conn->user,
data->state.digest.realm,
d->realm,
conn->passwd);
}
Curl_md5it(md5buf, md5this);
@@ -183,7 +209,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
free(md5this); /* free this again */
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);
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
@@ -195,6 +221,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
*/
Curl_safefree(conn->allocptr.userpwd);
conn->allocptr.userpwd =
aprintf( "Authorization: Digest "
"username=\"%s\", "
@@ -203,8 +230,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"uri=\"%s\", "
"response=\"%s\"\r\n",
conn->user,
data->state.digest.realm,
data->state.digest.nonce,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
request_digest );
@@ -213,19 +240,23 @@ CURLcode Curl_output_digest(struct connectdata *conn,
void Curl_digest_cleanup(struct SessionHandle *data)
{
if(data->state.digest.nonce)
free(data->state.digest.nonce);
data->state.digest.nonce = NULL;
struct digestdata *d = &data->state.digest;
if(data->state.digest.cnonce)
free(data->state.digest.cnonce);
data->state.digest.cnonce = NULL;
if(d->nonce)
free(d->nonce);
d->nonce = NULL;
if(data->state.digest.realm)
free(data->state.digest.realm);
data->state.digest.realm = NULL;
if(d->cnonce)
free(d->cnonce);
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

View File

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

View File

@@ -77,7 +77,7 @@
#endif
/* 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
@@ -277,8 +277,7 @@ static void mkhash(char *password,
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn,
bool proxy,
bool *ready)
bool proxy)
{
const char *domain=""; /* empty */
const char *host=""; /* empty */
@@ -300,7 +299,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
/* point to the correct struct with this */
struct ntlmdata *ntlm;
*ready = FALSE;
curlassert(conn);
curlassert(conn->data);
conn->data->state.authdone = FALSE;
if(proxy) {
allocuserpwd = &conn->allocptr.proxyuserpwd;
@@ -562,7 +563,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
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 */
if (proxy)
@@ -577,7 +578,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
free(*allocuserpwd);
*allocuserpwd=NULL;
}
*ready = TRUE;
conn->data->state.authdone = TRUE;
break;
}

View File

@@ -36,7 +36,7 @@ typedef enum {
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
/* 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);

View File

@@ -1,5 +1,5 @@
#include <winver.h>
#include "../include/curl/curl.h"
#include "../include/curl/curlver.h"
LANGUAGE 0x09,0x01

View File

@@ -14,13 +14,14 @@ endif
SOURCES = base64.c connect.c content_.c cookie.c dict.c \
easy.c escape.c file.c formdata.c ftp.c \
getdate.c getenv.c getinfo.c hash.c hostip.c \
http.c http_chu.c http_dig.c http_neg.c http_ntl.c \
if2ip.c krb4.c md5.c ldap.c llist.c \
memdebug.c mprintf.c multi.c netrc.c progress.c \
security.c sendf.c share.c speedche.c ssluse.c \
strequal.c strtok.c telnet.c timeval.c transfer.c \
url.c version.c
strerror.c strtoofft.c url.c version.c http.c \
http_chunks.c http_digest.c http_negotiate.c http_ntlm.c
SOURCES := $(strip $(SOURCES))
OBJECTS = $(SOURCES:.c=.o)
CURL_LIB = libcurl.a
@@ -46,130 +47,155 @@ realclean vclean: clean
base64.o: base64.c setup.h config.h config.dj ../include/curl/mprintf.h \
base64.h
connect.o: connect.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h if2ip.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
if2ip.h strerror.h connect.h
content_.o: content_.c setup.h config.h config.dj
cookie.o: cookie.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h getdate.h strequal.h strtok.h sendf.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h getdate.h \
strequal.h strtok.h sendf.h
dict.o: dict.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h progress.h strequal.h \
../include/curl/mprintf.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
sendf.h progress.h strequal.h dict.h ../include/curl/mprintf.h
easy.o: easy.c setup.h config.h config.dj strequal.h urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h ssluse.h url.h getinfo.h share.h \
../include/curl/mprintf.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
ssluse.h url.h getinfo.h share.h ../include/curl/mprintf.h
escape.o: escape.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h
file.o: file.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h progress.h sendf.h escape.h ../include/curl/mprintf.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h progress.h \
sendf.h escape.h file.h speedcheck.h getinfo.h transfer.h \
../include/curl/mprintf.h
formdata.o: formdata.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h strequal.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h formdata.h strequal.h
ftp.o: ftp.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h if2ip.h progress.h transfer.h escape.h http.h ftp.h \
strequal.h ssluse.h connect.h ../include/curl/mprintf.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
if2ip.h progress.h transfer.h escape.h http.h ftp.h strtoofft.h \
strequal.h ssluse.h connect.h strerror.h ../include/curl/mprintf.h
getdate.o: getdate.c setup.h config.h config.dj getdate.h
getenv.o: getenv.c setup.h config.h config.dj
getenv.o: getenv.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h
getinfo.o: getinfo.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h getinfo.h
hash.o: hash.c setup.h config.h config.dj hash.h llist.h
hostip.o: hostip.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h share.h url.h ../include/curl/mprintf.h
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h progress.h base64.h strequal.h \
ssluse.h http_digest.h http_ntlm.h http_negotiate.h url.h share.h \
http.h ../include/curl/mprintf.h
http_chu.o: http_chu.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h content_encoding.h ../include/curl/mprintf.h
http_dig.o: http_dig.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h strequal.h md5.h http_digest.h \
../include/curl/mprintf.h
http_neg.o: http_neg.c setup.h config.h config.dj
http_ntl.o: http_ntl.c setup.h config.h config.dj
if2ip.o: if2ip.c setup.h config.h config.dj
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
share.h url.h ../include/curl/mprintf.h
if2ip.o: if2ip.c setup.h config.h config.dj if2ip.h
krb4.o: krb4.c setup.h config.h config.dj
md5.o: md5.c setup.h config.h config.dj
md5.o: md5.c setup.h config.h config.dj md5.h
ldap.o: ldap.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h escape.h transfer.h ../include/curl/mprintf.h
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
escape.h transfer.h ldap.h ../include/curl/mprintf.h
llist.o: llist.c setup.h config.h config.dj llist.h
memdebug.o: memdebug.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
../include/curl/mprintf.h urldata.h cookie.h formdata.h timeval.h \
http_chunks.h hostip.h hash.h llist.h
mprintf.o: mprintf.c setup.h config.h config.dj
memdebug.o: memdebug.c
mprintf.o: mprintf.c setup.h config.h config.dj ../include/curl/mprintf.h
multi.o: multi.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h transfer.h url.h connect.h progress.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
url.h connect.h progress.h
netrc.o: netrc.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
strequal.h strtok.h ../include/curl/mprintf.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h netrc.h strequal.h \
strtok.h ../include/curl/mprintf.h
progress.o: progress.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h progress.h ../include/curl/mprintf.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
progress.h ../include/curl/mprintf.h
security.o: security.c setup.h config.h config.dj
sendf.o: sendf.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h connect.h ../include/curl/mprintf.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
connect.h ../include/curl/mprintf.h
share.o: share.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h share.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h share.h
speedche.o: speedche.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h sendf.h speedcheck.h
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
speedcheck.h
ssluse.o: ssluse.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h sendf.h url.h inet_pton.h
strequal.o: strequal.c setup.h config.h config.dj
strtok.o: strtok.c setup.h config.h config.dj
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h transfer.h sendf.h ../include/curl/mprintf.h \
arpa_telnet.h
timeval.o: timeval.c timeval.h setup.h config.h config.dj
transfer.o: transfer.c setup.h config.h config.dj strequal.h urldata.h \
cookie.h ../include/curl/curl.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h formdata.h timeval.h \
http_chunks.h hostip.h hash.h llist.h netrc.h content_encoding.h \
transfer.h sendf.h speedcheck.h progress.h getdate.h http.h url.h \
getinfo.h ssluse.h http_digest.h http_ntlm.h http_negotiate.h share.h \
../include/curl/mprintf.h
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/types.h ../include/curl/easy.h \
../include/curl/multi.h formdata.h timeval.h http_chunks.h hostip.h \
hash.h llist.h netrc.h base64.h ssluse.h if2ip.h transfer.h sendf.h \
progress.h strequal.h escape.h strtok.h share.h content_encoding.h \
http_digest.h http_negotiate.h ftp.h dict.h telnet.h http.h file.h \
ldap.h url.h connect.h ca-bundle.h ../include/curl/mprintf.h
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h \
llist.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
url.h inet_pton.h ssluse.h connect.h
strequal.o: strequal.c setup.h config.h config.dj strequal.h
strtok.o: strtok.c setup.h config.h config.dj strtok.h
telnet.o: telnet.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
sendf.h telnet.h ../include/curl/mprintf.h arpa_telnet.h
timeval.o: timeval.c timeval.h setup.h config.h config.dj
transfer.o: transfer.c setup.h config.h config.dj strtoofft.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
strequal.h urldata.h cookie.h formdata.h timeval.h http_chunks.h \
hostip.h hash.h llist.h netrc.h content_encoding.h transfer.h sendf.h \
speedcheck.h progress.h getdate.h http.h url.h getinfo.h ssluse.h \
http_digest.h http_ntlm.h http_negotiate.h share.h \
../include/curl/mprintf.h
strerror.o: strerror.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h strerror.h urldata.h \
cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h \
../include/curl/mprintf.h
strtoofft.o: strtoofft.c setup.h config.h config.dj strtoofft.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h
url.o: url.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h netrc.h \
base64.h ssluse.h if2ip.h transfer.h sendf.h progress.h strequal.h \
escape.h strtok.h share.h content_encoding.h http_digest.h \
http_negotiate.h ftp.h dict.h telnet.h http.h file.h ldap.h url.h \
connect.h ca-bundle.h ../include/curl/mprintf.h
version.o: version.c setup.h config.h config.dj ../include/curl/curl.h \
../include/curl/curlver.h ../include/curl/types.h \
../include/curl/easy.h ../include/curl/multi.h urldata.h cookie.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h
http.o: http.c setup.h config.h config.dj urldata.h cookie.h \
../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h transfer.h \
sendf.h progress.h base64.h strequal.h ssluse.h http_digest.h \
http_ntlm.h http_negotiate.h url.h share.h http.h \
../include/curl/mprintf.h
http_chunks.o: http_chunks.c setup.h config.h config.dj urldata.h \
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
content_encoding.h http.h ../include/curl/mprintf.h
http_digest.o: http_digest.c setup.h config.h config.dj urldata.h \
cookie.h ../include/curl/curl.h ../include/curl/curlver.h \
../include/curl/types.h ../include/curl/easy.h ../include/curl/multi.h \
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h sendf.h \
strequal.h md5.h http_digest.h ../include/curl/mprintf.h
http_negotiate.o: http_negotiate.c setup.h config.h config.dj
http_ntlm.o: http_ntlm.c setup.h config.h config.dj

View File

@@ -122,8 +122,8 @@ enum {
typedef struct {
FormatType type;
int flags;
int width; /* width OR width parameter number */
int precision; /* precision OR precision parameter number */
long width; /* width OR width parameter number */
long precision; /* precision OR precision parameter number */
union {
char *str;
void *ptr;
@@ -281,7 +281,8 @@ int dprintf_Pass1Report(va_stack_t *vto, int max)
*
******************************************************************/
static int dprintf_Pass1(char *format, va_stack_t *vto, char **endpos, va_list arglist)
static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
va_list arglist)
{
char *fmt = format;
int param_num = 0;
@@ -681,7 +682,7 @@ static int dprintf_formatf(
else
prec = -1;
alt = p->flags & FLAGS_ALT;
alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
switch (p->type) {
case FORMAT_INT:
@@ -1042,7 +1043,7 @@ static int alloc_addbyter(int output, FILE *data)
infop->alloc *= 2;
}
infop->buffer[ infop->len ] = output;
infop->buffer[ infop->len ] = (char)output;
infop->len++;

View File

@@ -122,7 +122,7 @@ CURLM *curl_multi_init(void)
multi->type = CURL_MULTI_HANDLE;
}
multi->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
multi->hostcache = Curl_mk_dnscache();
if(!multi->hostcache) {
/* failure, free mem and bail out */
free(multi);
@@ -380,7 +380,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
case CURLM_STATE_WAITRESOLVE:
/* awaiting an asynch name resolve to complete */
{
struct Curl_dns_entry *dns;
struct Curl_dns_entry *dns = NULL;
/* check if we have the name resolved by now */
easy->result = Curl_is_resolved(easy->easy_conn, &dns);

View File

@@ -91,7 +91,7 @@ int Curl_parsenetrc(char *host,
char state_login=0; /* Found a login keyword */
char state_password=0; /* Found a password keyword */
char state_our_login=0; /* With specific_login, found *our* login name */
int state_our_login=FALSE; /* With specific_login, found *our* login name */
#define NETRC DOT_CHAR "netrc"
@@ -210,7 +210,7 @@ int Curl_parsenetrc(char *host,
else if(strequal("machine", tok)) {
/* ok, there's machine here go => */
state = HOSTFOUND;
state_our_login = 0;
state_our_login = FALSE;
}
break;
} /* switch (state) */

View File

@@ -26,9 +26,6 @@
#include <string.h>
#include <time.h>
/* 20000318 mgs
* later we use _scrsize to determine the screen width, this emx library
* function needs stdlib.h to be included */
#if defined(__EMX__)
#include <stdlib.h>
#endif
@@ -36,19 +33,34 @@
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "progress.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
static void time2str(char *r, int t)
/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
byte) */
static void time2str(char *r, long t)
{
int h = (t/3600);
int m = (t-(h*3600))/60;
int s = (t-(h*3600)-(m*60));
sprintf(r,"%2d:%02d:%02d",h,m,s);
long h;
if(!t) {
strcpy(r, "--:--:--");
return;
}
h = (t/3600);
if(h <= 99) {
long m = (t-(h*3600))/60;
long s = (t-(h*3600)-(m*60));
sprintf(r, "%2ld:%02ld:%02ld",h,m,s);
}
else {
/* this equals to more than 99 hours, switch to a more suitable output
format to fit within the limits. */
if(h/24 <= 999)
sprintf(r, "%3ldd %02ldh", h/24, h-(h/24)*24);
else
sprintf(r, "%7ldd", h/24);
}
}
/* The point of this function would be to return a string of the input data,
@@ -105,13 +117,12 @@ static char *max5data(curl_off_t bytes, char *max5)
void Curl_pgrsDone(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
if(!(data->progress.flags & PGRS_HIDE)) {
data->progress.lastshow=0;
Curl_pgrsUpdate(conn); /* the final (forced) update */
if(!data->progress.callback)
/* only output if we don't use progress callback */
fprintf(data->set.err, "\n");
}
data->progress.lastshow=0;
Curl_pgrsUpdate(conn); /* the final (forced) update */
if(!(data->progress.flags & PGRS_HIDE) &&
!data->progress.callback)
/* only output if we don't use a progress callback and we're not hidden */
fprintf(data->set.err, "\n");
}
/* reset all times except redirect */
@@ -137,26 +148,26 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
case TIMER_NAMELOOKUP:
data->progress.t_nslookup =
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
break;
case TIMER_CONNECT:
data->progress.t_connect =
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
break;
case TIMER_PRETRANSFER:
data->progress.t_pretransfer =
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
break;
case TIMER_STARTTRANSFER:
data->progress.t_starttransfer =
(double)Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle)/1000.0;
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
break;
case TIMER_POSTRANSFER:
/* this is the normal end-of-transfer thing */
break;
case TIMER_REDIRECT:
data->progress.t_redirect =
(double)Curl_tvdiff(Curl_tvnow(), data->progress.start)/1000.0;
Curl_tvdiff_secs(Curl_tvnow(), data->progress.start);
break;
}
}
@@ -195,44 +206,27 @@ void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
}
/* EXAMPLE OUTPUT to follow:
% Total % Received % Xferd Average Speed Time Curr.
Dload Upload Total Current Left Speed
100 12345 100 12345 100 12345 12345 12345 12:12:12 12:12:12 12:12:12 12345
*/
int Curl_pgrsUpdate(struct connectdata *conn)
{
struct timeval now;
int result;
char max5[6][10];
double dlpercen=0;
double ulpercen=0;
double total_percen=0;
int dlpercen=0;
int ulpercen=0;
int total_percen=0;
curl_off_t total_transfer;
curl_off_t total_expected_transfer;
double timespent;
long timespent;
struct SessionHandle *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
int countindex; /* amount of seconds stored in the speeder array */
char time_left[10];
char time_total[10];
char time_current[10];
double ulestimate=0;
double dlestimate=0;
double total_estimate;
char time_spent[10];
long ulestimate=0;
long dlestimate=0;
long total_estimate;
if(data->progress.flags & PGRS_HIDE)
; /* We do enter this function even if we don't wanna see anything, since
@@ -246,26 +240,25 @@ int Curl_pgrsUpdate(struct connectdata *conn)
"\n",
conn->resume_from);
fprintf(data->set.err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n");
" %% Total %% Received %% Xferd Average Speed Time Time Time Current\n"
" Dload Upload Total Spent Left Speed\n");
}
data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
}
now = Curl_tvnow(); /* what time is it */
/* The exact time spent so far (from the start) */
timespent = (double)Curl_tvdiff (now, data->progress.start)/1000;
data->progress.timespent = timespent;
/* The time spent so far (from the start) */
data->progress.timespent = Curl_tvdiff_secs(now, data->progress.start);
timespent = (long)data->progress.timespent*1000.0;
/* The average download speed this far */
data->progress.dlspeed =
data->progress.downloaded/(timespent>0.01?timespent:1);
data->progress.downloaded/(timespent?timespent:1);
/* The average upload speed this far */
data->progress.ulspeed =
data->progress.uploaded/(timespent>0.01?timespent:1);
data->progress.uploaded/(timespent?timespent:1);
if(data->progress.lastshow == Curl_tvlong(now))
return 0; /* never update this more than once a second if the end isn't
@@ -309,7 +302,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
span_ms=1; /* at least one millisecond MUST have passed */
/* Calculate the average speed the last 'countindex' seconds */
data->progress.current_speed =
data->progress.current_speed = (curl_off_t)
(data->progress.speeder[nowindex]-
data->progress.speeder[checkindex])/((double)span_ms/1000);
}
@@ -338,35 +331,25 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Figure out the estimated time of arrival for the upload */
if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
(data->progress.ulspeed > 0)) {
ulestimate = (double)data->progress.size_ul / data->progress.ulspeed;
ulpercen = ((double)data->progress.uploaded / data->progress.size_ul)*100;
ulestimate = (long)(data->progress.size_ul / data->progress.ulspeed);
ulpercen = (long)(data->progress.uploaded / data->progress.size_ul)*100;
}
/* ... and the download */
if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
(data->progress.dlspeed > 0)) {
dlestimate = (double)data->progress.size_dl / data->progress.dlspeed;
dlpercen = ((double)data->progress.downloaded / data->progress.size_dl)*100;
dlestimate = (long)(data->progress.size_dl / data->progress.dlspeed);
dlpercen = (long)(data->progress.downloaded / data->progress.size_dl)*100;
}
/* Now figure out which of them that is slower and use for the for
total estimate! */
total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
/* If we have a total estimate, we can display that and the expected
time left */
if(total_estimate > 0) {
time2str(time_left, (int)(total_estimate - data->progress.timespent));
time2str(time_total, (int)total_estimate);
}
else {
/* otherwise we blank those times */
strcpy(time_left, "--:--:--");
strcpy(time_total, "--:--:--");
}
/* The time spent so far is always known */
time2str(time_current, (int)data->progress.timespent);
/* create the three time strings */
time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
time2str(time_total, total_estimate);
time2str(time_spent, timespent);
/* Get the total amount of data expected to get transfered */
total_expected_transfer =
@@ -380,22 +363,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Get the percentage of data transfered so far */
if(total_expected_transfer > 0)
total_percen=((double)total_transfer/total_expected_transfer)*100;
total_percen=(int)(total_transfer/total_expected_transfer)*100;
fprintf(data->set.err,
"\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
(int)total_percen, /* total % */
total_percen, /* 3 letters */ /* total % */
max5data(total_expected_transfer, max5[2]), /* total size */
(int)dlpercen, /* rcvd % */
dlpercen, /* 3 letters */ /* rcvd % */
max5data(data->progress.downloaded, max5[0]), /* rcvd size */
(int)ulpercen, /* xfer % */
ulpercen, /* 3 letters */ /* xfer % */
max5data(data->progress.uploaded, max5[1]), /* xfer size */
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
time_total, /* total time */
time_current, /* current time */
time_left, /* time left */
max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
time_total, /* 8 letters */ /* total time */
time_spent, /* 8 letters */ /* time spent */
time_left, /* 8 letters */ /* time left */
max5data(data->progress.current_speed, max5[5]) /* current speed */
);

View File

@@ -46,10 +46,6 @@
#endif
#endif
#ifdef VMS
/* hand-modified VMS config.h! */
#include "config-vms.h"
#endif
#ifdef NETWARE
/* hand-modified NetWare config.h! */
#include "config-netware.h"
@@ -134,12 +130,8 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#endif
#ifndef STDC_HEADERS /* no standard C headers! */
#ifdef VMS
#include "../include/curl/stdcheaders.h"
#else
#include <curl/stdcheaders.h>
#endif
#endif
#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
#define NDEBUG
@@ -174,6 +166,17 @@ defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
#define WIN32_LEAN_AND_MEAN /* Prevent including <winsock*.h> in <windows.h> */
#endif
#if (defined(ENABLE_IPV6) || defined(CURLDEBUG)) && defined(_MSC_VER) && \
(!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500)
/*
* Needed to pull in the real getaddrinfo() and not the inline version
* in <wspiAPI.H> which doesn't support IPv6 (IPv4 only). <wspiAPI.H> is
* included from <ws2tcpip.h> for <= 0x0500 SDKs.
*/
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <winsock2.h> /* required by telnet.c */
#if defined(ENABLE_IPV6) || defined(USE_SSLEAY)
@@ -276,10 +279,6 @@ typedef struct hostent Curl_addrinfo;
typedef struct in_addr Curl_ipconnect;
#endif
#ifdef VMS
#define IOCTL_3_ARGS
#endif
#ifdef mpeix
#define IOCTL_3_ARGS
#endif

View File

@@ -73,7 +73,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
{
case CURL_LOCK_DATA_DNS:
if (!share->hostcache) {
share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
share->hostcache = Curl_mk_dnscache();
}
break;

View File

@@ -94,7 +94,7 @@ static int passwd_callback(char *buf, int num, int verify
else {
if(num > (int)strlen((char *)global_passwd)) {
strcpy(buf, global_passwd);
return strlen(buf);
return (int)strlen(buf);
}
}
return 0;
@@ -185,7 +185,7 @@ int random_the_seed(struct SessionHandle *data)
if(!area)
return 3; /* out of memory */
len = strlen(area);
len = (int)strlen(area);
RAND_add(area, len, (len >> 1));
free(area); /* now remove the random junk */
@@ -818,10 +818,10 @@ static CURLcode verifyhost(struct connectdata *conn,
int i;
if(GEN_DNS == target) {
hostlen = strlen(conn->hostname);
hostlen = (int)strlen(conn->hostname);
domain = strchr(conn->hostname, '.');
if(domain)
domainlen = strlen(domain);
domainlen = (int)strlen(domain);
}
/* get amount of alternatives, RFC2459 claims there MUST be at least
@@ -1070,7 +1070,7 @@ Curl_SSLConnect(struct connectdata *conn,
and then how much time that has elapsed to know how much time we
allow for the connect call */
if(data->set.timeout || data->set.connecttimeout) {
double has_passed;
long has_passed;
/* Evaluate in milliseconds how much time that has passed */
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
@@ -1087,7 +1087,7 @@ Curl_SSLConnect(struct connectdata *conn,
timeout_ms = data->set.connecttimeout*1000;
/* subtract the passed time */
timeout_ms -= (long)has_passed;
timeout_ms -= has_passed;
if(timeout_ms < 0) {
/* a precaution, no need to continue if time already is up */
@@ -1117,14 +1117,15 @@ Curl_SSLConnect(struct connectdata *conn,
FD_SET(sockfd, &writefd);
else {
/* untreated error */
unsigned long errdetail;
char error_buffer[120]; /* OpenSSL documents that this must be at least
120 bytes long. */
detail = ERR_get_error(); /* Gets the earliest error code from the
thread's error queue and removes the
entry. */
errdetail = ERR_get_error(); /* Gets the earliest error code from the
thread's error queue and removes the
entry. */
switch(detail) {
switch(errdetail) {
case 0x1407E086:
/* 1407E086:
SSL routines:
@@ -1140,7 +1141,7 @@ Curl_SSLConnect(struct connectdata *conn,
return CURLE_SSL_CACERT;
default:
/* detail is already set to the SSL error above */
failf(data, "SSL: %s", ERR_error_string(detail, error_buffer));
failf(data, "SSL: %s", ERR_error_string(errdetail, error_buffer));
/* OpenSSL 0.9.6 and later has a function named
ERRO_error_string_n() that takes the size of the buffer as a third
argument, and we should possibly switch to using that one in the

View File

@@ -20,7 +20,17 @@
*
***************************************************************************/
#include "setup.h"
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "strerror.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
const char *
curl_easy_strerror(CURLcode error)
@@ -244,14 +254,13 @@ curl_easy_strerror(CURLcode error)
const char *
curl_multi_strerror(CURLMcode error)
{
switch (error)
{
switch (error) {
case CURLM_CALL_MULTI_PERFORM:
return "please call curl_multi_perform() soon";
case CURLM_OK:
return "no error";
case CURLM_BAD_HANDLE:
return "CURLM not valid multi handle";
@@ -274,8 +283,7 @@ curl_multi_strerror(CURLMcode error)
const char *
curl_share_strerror(CURLSHcode error)
{
switch (error)
{
switch (error) {
case CURLSHE_OK:
return "no error";
@@ -294,3 +302,252 @@ curl_share_strerror(CURLSHcode error)
return "CURLSH unknown";
}
#if defined(WIN32) && !defined(__CYGWIN__)
/* This function handles most / all (?) Winsock errors cURL is able to produce.
*/
static const char *
get_winsock_error (int err, char *buf, size_t len)
{
char *p;
switch (err) {
case WSAEINTR:
p = "Call interrupted.";
break;
case WSAEBADF:
p = "Bad file";
break;
case WSAEACCES:
p = "Bad access";
break;
case WSAEFAULT:
p = "Bad argument";
break;
case WSAEINVAL:
p = "Invalid arguments";
break;
case WSAEMFILE:
p = "Out of file descriptors";
break;
case WSAEWOULDBLOCK:
p = "Call would block";
break;
case WSAEINPROGRESS:
case WSAEALREADY:
p = "Blocking call in progress";
break;
case WSAENOTSOCK:
p = "Descriptor is not a socket.";
break;
case WSAEDESTADDRREQ:
p = "Need destination address";
break;
case WSAEMSGSIZE:
p = "Bad message size";
break;
case WSAEPROTOTYPE:
p = "Bad protocol";
break;
case WSAENOPROTOOPT:
p = "Protocol option is unsupported";
break;
case WSAEPROTONOSUPPORT:
p = "Protocol is unsupported";
break;
case WSAESOCKTNOSUPPORT:
p = "Socket is unsupported";
break;
case WSAEOPNOTSUPP:
p = "Operation not supported";
break;
case WSAEAFNOSUPPORT:
p = "Address family not supported";
break;
case WSAEPFNOSUPPORT:
p = "Protocol family not supported";
break;
case WSAEADDRINUSE:
p = "Address already in use";
break;
case WSAEADDRNOTAVAIL:
p = "Address not available";
break;
case WSAENETDOWN:
p = "Network down";
break;
case WSAENETUNREACH:
p = "Network unreachable";
break;
case WSAENETRESET:
p = "Network has been reset";
break;
case WSAECONNABORTED:
p = "Connection was aborted";
break;
case WSAECONNRESET:
p = "Connection was reset";
break;
case WSAENOBUFS:
p = "No buffer space";
break;
case WSAEISCONN:
p = "Socket is already connected";
break;
case WSAENOTCONN:
p = "Socket is not connected";
break;
case WSAESHUTDOWN:
p = "Socket has been shut down";
break;
case WSAETOOMANYREFS:
p = "Too many references";
break;
case WSAETIMEDOUT:
p = "Timed out";
break;
case WSAECONNREFUSED:
p = "Connection refused";
break;
case WSAELOOP:
p = "Loop??";
break;
case WSAENAMETOOLONG:
p = "Name too long";
break;
case WSAEHOSTDOWN:
p = "Host down";
break;
case WSAEHOSTUNREACH:
p = "Host unreachable";
break;
case WSAENOTEMPTY:
p = "Not empty";
break;
case WSAEPROCLIM:
p = "Process limit reached";
break;
case WSAEUSERS:
p = "Too many users";
break;
case WSAEDQUOT:
p = "Bad quota";
break;
case WSAESTALE:
p = "Something is stale";
break;
case WSAEREMOTE:
p = "Remote error";
break;
case WSAEDISCON:
p = "Disconnected";
break;
/* Extended Winsock errors */
case WSASYSNOTREADY:
p = "Winsock library is not ready";
break;
case WSANOTINITIALISED:
p = "Winsock library not initalised";
break;
case WSAVERNOTSUPPORTED:
p = "Winsock version not supported.";
break;
/* getXbyY() errors (already handled in herrmsg):
* Authoritative Answer: Host not found */
case WSAHOST_NOT_FOUND:
p = "Host not found";
break;
/* Non-Authoritative: Host not found, or SERVERFAIL */
case WSATRY_AGAIN:
p = "Host not found, try again";
break;
/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
case WSANO_RECOVERY:
p = "Unrecoverable error in call to nameserver";
break;
/* Valid name, no data record of requested type */
case WSANO_DATA:
p = "No data record of requested type";
break;
default:
return NULL;
}
strncpy (buf, p, len);
buf [len-1] = '\0';
return buf;
}
#endif /* WIN32 && !__CYGWIN__ */
/*
* Our thread-safe and smart strerror() replacement.
*
* The 'err' argument passed in to this function MUST be a true errno number
* as reported on this system. We do no range checking on the number before
* we pass it to the "number-to-message" convertion function and there might
* be systems that don't do proper range checking in there themselves.
*
* We don't do range checking (on systems other than Windows) since there is
* no good reliable and portable way to do it.
*/
const char *Curl_strerror(struct connectdata *conn, int err)
{
char *buf, *p;
size_t max;
curlassert(conn);
curlassert(err >= 0);
buf = conn->syserr_buf;
max = sizeof(conn->syserr_buf)-1;
*buf = '\0';
#if defined(WIN32) && !defined(__CYGWIN__)
/* 'sys_nerr' is the maximum errno number, it is not widely portable */
if (err >= 0 && err < sys_nerr)
strncpy(buf, strerror(err), max);
else {
if (!get_winsock_error (err, buf, max) &&
!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
LANG_NEUTRAL, buf, max, NULL))
snprintf(buf, max, "Unknown error %d (%#x)", err, err);
}
#else /* not native Windows coming up */
/* These should be atomic and hopefully thread-safe */
#ifdef HAVE_STRERROR_R
/* There are two different APIs for strerror_r(). The POSIX and the GLIBC
versions. */
#ifdef HAVE_POSIX_STRERROR_R
strerror_r(err, buf, max);
/* this may set errno to ERANGE if insufficient storage was supplied via
'strerrbuf' and 'buflen' to contain the generated message string, or
EINVAL if the value of 'errnum' is not a valid error number.*/
#else
{
/* HAVE_GLIBC_STRERROR_R */
char buffer[256];
char *msg = strerror_r(err, buffer, sizeof(buffer));
strncpy(buf, msg, max);
}
#endif /* end of HAVE_GLIBC_STRERROR_R */
#else /* HAVE_STRERROR_R */
strncpy(buf, strerror(err), max);
#endif /* end of HAVE_STRERROR_R */
#endif /* end of ! Windows */
buf[max] = '\0'; /* make sure the string is zero terminated */
/* strip trailing '\r\n' or '\n'. */
if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
*p = '\0';
if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
*p = '\0';
return buf;
}

30
lib/strerror.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef __CURL_STRERROR_H
#define __CURL_STRERROR_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$
***************************************************************************/
#include "urldata.h"
const char *Curl_strerror (struct connectdata *conn, int err);
#endif

View File

@@ -40,22 +40,22 @@
*/
#if SIZEOF_CURL_OFF_T > 4
#if HAVE_STRTOLL
#define strtoofft strtoll
#define curlx_strtoofft strtoll
#else /* HAVE_STRTOLL */
/* For MSVC7 we can use _strtoi64() which seems to be a strtoll() clone */
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
#define strtoofft _strtoi64
#define curlx_strtoofft _strtoi64
#else /* MSVC7 or later */
curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
#define strtoofft curlx_strtoll
#define curlx_strtoofft curlx_strtoll
#define NEED_CURL_STRTOLL
#endif /* MSVC7 or later */
#endif /* HAVE_STRTOLL */
#else /* SIZEOF_CURL_OFF_T > 4 */
/* simply use strtol() to get 32bit numbers */
#define strtoofft strtol
#define curlx_strtoofft strtol
#endif
#endif

View File

@@ -856,8 +856,8 @@ static void suboption(struct connectdata *conn)
{
struct curl_slist *v;
unsigned char temp[2048];
int len;
int tmplen;
size_t len;
size_t tmplen;
char varname[128];
char varval[128];
struct SessionHandle *data = conn->data;

View File

@@ -78,7 +78,8 @@ static int gettimeofday(struct timeval *tp, void *nothing)
#endif /* WIN32 */
#endif /* HAVE_GETTIMEOFDAY */
struct timeval Curl_tvnow (void)
/* Return the current time in a timeval struct */
struct timeval curlx_tvnow(void)
{
struct timeval now;
(void)gettimeofday(&now, NULL);
@@ -88,14 +89,28 @@ struct timeval Curl_tvnow (void)
/*
* Make sure that the first argument is the more recent time, as otherwise
* we'll get a weird negative time-diff back...
*
* Returns: the time difference in number of milliseconds.
*/
long Curl_tvdiff (struct timeval newer, struct timeval older)
long curlx_tvdiff(struct timeval newer, struct timeval older)
{
return (newer.tv_sec-older.tv_sec)*1000+
(499+newer.tv_usec-older.tv_usec)/1000;
(newer.tv_usec-older.tv_usec)/1000;
}
long Curl_tvlong (struct timeval t1)
/*
* Same as curlx_tvdiff but with full usec resolution.
*
* Returns: the time difference in seconds with subsecond resolution.
*/
double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
{
return (double)(newer.tv_sec-older.tv_sec)+
(double)(newer.tv_usec-older.tv_usec)/1000000.0;
}
/* return the number of seconds in the given input timeval struct */
long Curl_tvlong(struct timeval t1)
{
return t1.tv_sec;
}

View File

@@ -23,6 +23,11 @@
* $Id$
***************************************************************************/
/*
* CAUTION: this header is designed to work when included by the app-side
* as well as the library. Do not mix with library internals!
*/
#include "setup.h"
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
@@ -40,10 +45,29 @@ struct timeval {
#endif
#endif
struct timeval Curl_tvnow(void);
struct timeval curlx_tvnow(void);
/*
* Make sure that the first argument (t1) is the more recent time and t2 is
* the older time, as otherwise you get a weird negative time-diff back...
*
* Returns: the time difference in number of milliseconds.
*/
long curlx_tvdiff(struct timeval t1, struct timeval t2);
/*
* Same as curlx_tvdiff but with full usec resolution.
*
* Returns: the time difference in seconds with subsecond resolution.
*/
double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
/* the diff is from now on returned in number of milliseconds! */
long Curl_tvdiff(struct timeval t1, struct timeval t2);
long Curl_tvlong(struct timeval t1);
/* These two defines below exist to provide the older API for library
internals only. */
#define Curl_tvnow() curlx_tvnow()
#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y)
#endif

View File

@@ -441,10 +441,20 @@ CURLcode Curl_readwrite(struct connectdata *conn,
FD_ZERO(&k->wkeepfd);
}
/*
** Now that all of the headers have been parsed, see
** if we should give up and return an error.
*/
if (Curl_http_should_fail(conn)) {
failf (data, "The requested URL returned error: %d",
k->httpcode);
return CURLE_HTTP_RETURNED_ERROR;
}
/* now, only output this if the header AND body are requested:
*/
writetype = CLIENTWRITE_HEADER;
if (data->set.http_include_header)
if (data->set.include_header)
writetype |= CLIENTWRITE_BODY;
headerlen = k->p - data->state.headerbuff;
@@ -458,6 +468,9 @@ CURLcode Curl_readwrite(struct connectdata *conn,
data->info.header_size += headerlen;
conn->headerbytecount += headerlen;
conn->deductheadercount =
(100 == k->httpcode)?conn->headerbytecount:0;
if (conn->resume_from &&
!k->content_range &&
(data->set.httpreq==HTTPREQ_GET)) {
@@ -488,7 +501,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
* If we requested a "no body", this is a good time to get
* out and return home.
*/
if(data->set.no_body)
if(conn->bits.no_body)
stop_reading = TRUE;
else {
/* If we know the expected size of this document, we set the
@@ -507,10 +520,14 @@ CURLcode Curl_readwrite(struct connectdata *conn,
if(conn->bits.chunk)
conn->size=-1;
if(-1 != conn->size) {
Curl_pgrsSetDownloadSize(data, conn->size);
conn->maxdownload = conn->size;
}
}
if(-1 != conn->size) {
/* We do this operation even if no_body is true, since this
data might be retrieved later with curl_easy_getinfo()
and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
Curl_pgrsSetDownloadSize(data, conn->size);
conn->maxdownload = conn->size;
}
/* If max download size is *zero* (nothing) we already
have nothing and can safely return ok now! */
@@ -541,10 +558,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* This is the first header, it MUST be the error code line
or else we consiser this to be the body right away! */
int httpversion_major;
int nc=sscanf (k->p, " HTTP/%d.%d %3d",
&httpversion_major,
&k->httpversion,
&k->httpcode);
int nc=sscanf(k->p, " HTTP/%d.%d %3d",
&httpversion_major,
&k->httpversion,
&k->httpcode);
if (nc==3) {
k->httpversion += 10 * httpversion_major;
}
@@ -552,7 +569,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* this is the real world, not a Nirvana
NCSA 1.5.x returns this crap when asked for HTTP/1.1
*/
nc=sscanf (k->p, " HTTP %3d", &k->httpcode);
nc=sscanf(k->p, " HTTP %3d", &k->httpcode);
k->httpversion = 10;
/* If user has set option HTTP200ALIASES,
@@ -572,9 +589,21 @@ CURLcode Curl_readwrite(struct connectdata *conn,
data->info.httpcode = k->httpcode;
data->info.httpversion = k->httpversion;
/* 404 -> URL not found! */
/*
** This code executes as part of processing
** the header. As a result, it's not
** totally clear how to interpret the
** response code yet as that depends on what
** other headers may be present. 401 and
** 407 may be errors, but may be OK
** depending on how authentication is
** working. Other codes are definitely
** errors, so give up here.
*/
if (data->set.http_fail_on_error &&
(k->httpcode >= 400)) {
(k->httpcode >= 400) &&
(k->httpcode != 401) &&
(k->httpcode != 407)) {
/* If we have been told to fail hard on HTTP-errors,
here is the check for that: */
/* serious error, go home! */
@@ -625,7 +654,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
info about the true size of the document we didn't get now. */
if ((k->httpcode != 416) &&
checkprefix("Content-Length:", k->p)) {
contentlength = strtoofft(k->p+15, NULL, 10);
contentlength = curlx_strtoofft(k->p+15, NULL, 10);
if (data->set.max_filesize && contentlength >
data->set.max_filesize) {
failf(data, "Maximum file size exceeded");
@@ -758,7 +787,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* stupid colon skip */
ptr++;
k->offset = strtoofft(ptr, NULL, 10);
k->offset = curlx_strtoofft(ptr, NULL, 10);
if (conn->resume_from == k->offset)
/* we asked for a resume and we got it */
@@ -839,7 +868,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*/
writetype = CLIENTWRITE_HEADER;
if (data->set.http_include_header)
if (data->set.include_header)
writetype |= CLIENTWRITE_BODY;
if(data->set.verbose)
@@ -1248,7 +1277,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
* returning.
*/
if(!(data->set.no_body) && (conn->size != -1) &&
if(!(conn->bits.no_body) && (conn->size != -1) &&
(k->bytecount != conn->size) &&
!conn->newurl) {
failf(data, "transfer closed with %" FORMAT_OFF_T
@@ -1305,7 +1334,7 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
Curl_pgrsSetDownloadSize(data, conn->size);
}
/* we want header and/or body, if neither then don't do this! */
if(conn->bits.getheader || !data->set.no_body) {
if(conn->bits.getheader || !conn->bits.no_body) {
FD_ZERO (&k->readfd); /* clear it */
if(conn->sockfd != CURL_SOCKET_BAD) {
@@ -1394,7 +1423,6 @@ void Curl_single_fdset(struct connectdata *conn,
static CURLcode
Transfer(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
CURLcode result;
struct Curl_transfer_keeper *k = &conn->keep;
bool done=FALSE;
@@ -1409,7 +1437,7 @@ Transfer(struct connectdata *conn)
return CURLE_OK;
/* we want header and/or body, if neither then don't do this! */
if(!conn->bits.getheader && data->set.no_body)
if(!conn->bits.getheader && conn->bits.no_body)
return CURLE_OK;
k->writefdp = &k->writefd; /* store the address of the set */
@@ -1833,7 +1861,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
if(data->set.httpreq != HTTPREQ_GET) {
data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
infof(data, "Disables POST, goes with %s\n",
data->set.no_body?"HEAD":"GET");
data->set.opt_no_body?"HEAD":"GET");
}
break;
case 304: /* Not Modified */

View File

@@ -246,6 +246,14 @@ CURLcode Curl_close(struct SessionHandle *data)
return CURLE_OK;
}
/**
* Curl_open()
*
* @param curl is a pointer to a sessionhandle pointer that gets set by this
* function.
* @return CURLcode
*/
CURLcode Curl_open(struct SessionHandle **curl)
{
/* We don't yet support specifying the URL at this point */
@@ -447,7 +455,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
/*
* Set to include the header in the general data output stream.
*/
data->set.http_include_header = va_arg(param, long)?TRUE:FALSE;
data->set.include_header = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_NOPROGRESS:
/*
@@ -463,7 +471,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
/*
* Do not include the body part in the output data stream.
*/
data->set.no_body = va_arg(param, long)?TRUE:FALSE;
data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_FAILONERROR:
/*
@@ -1303,6 +1311,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.max_filesize = va_arg(param, curl_off_t);
break;
case CURLOPT_TCP_NODELAY:
/*
* Enable or disable TCP_NODELAY, which will disable/enable the Nagle
* algorithm
*/
data->set.tcp_nodelay = va_arg(param, long);
break;
default:
/* unknown tag and its companion, just ignore: */
return CURLE_FAILED_INIT; /* correct this */
@@ -1869,7 +1885,7 @@ static void verboseconnect(struct connectdata *conn,
#ifdef ENABLE_IPV6
{
char hbuf[NI_MAXHOST];
#ifdef NI_WITHSCOPEID
#ifdef HAVE_NI_WITHSCOPEID
#define NIFLAGS NI_NUMERICHOST | NI_WITHSCOPEID
#else
#define NIFLAGS NI_NUMERICHOST
@@ -1960,13 +1976,20 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
return result; /* pass back status */
}
/*
/**
* CreateConnection() sets up a new connectdata struct, or re-uses an already
* existing one, and resolves host name.
*
* if this function returns CURLE_OK and *async is set to TRUE, the resolve
* response will be coming asynchronously. If *async is FALSE, the name is
* already resolved.
*
* @param data The sessionhandle pointer
* @param in_connect is set to the next connection data pointer
* @param addr is set to the new dns entry for this connection
* @param async is set TRUE/FALSE depending on the nature of this lookup
* @return CURLcode
* @see SetupConnection()
*/
static CURLcode CreateConnection(struct SessionHandle *data,
@@ -2058,6 +2081,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->bits.user_passwd = data->set.userpwd?1:0;
conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
conn->bits.no_body = data->set.opt_no_body;
/* This initing continues below, see the comment "Continue connectdata
* initialization here" */
@@ -2343,6 +2367,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char proxyuser[MAX_CURL_USER_LENGTH];
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
char *fineptr;
/* skip the possible protocol piece */
ptr=strstr(proxy, "://");
if(ptr)
@@ -2350,9 +2376,12 @@ static CURLcode CreateConnection(struct SessionHandle *data,
else
ptr = proxy;
fineptr = ptr;
/* check for an @-letter */
ptr = strchr(ptr, '@');
if(ptr && (2 == sscanf(proxy, "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
if(ptr && (2 == sscanf(fineptr,
"%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
proxyuser, proxypasswd))) {
/* found user and password, rip them out */
@@ -2370,7 +2399,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->bits.proxy_user_passwd = TRUE; /* enable it */
ptr = strdup(ptr+1);
ptr = strdup(ptr+1); /* the right side of the @-letter */
free(proxy); /* free the former data */
proxy = ptr; /* now use this instead */
}
@@ -2911,6 +2940,9 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->bits.user_passwd = old_conn->bits.user_passwd;
conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
/* get the newly set value, not the old one */
conn->bits.no_body = old_conn->bits.no_body;
/* If we speak over a proxy, we need to copy the host name too, as it
might be another remote host even when re-using a connection */
strcpy(conn->gname, old_conn->gname); /* safe strcpy() */

View File

@@ -173,6 +173,7 @@ struct digestdata {
char *cnonce;
char *realm;
int algo;
bool stale; /* set true for re-negotiation */
};
typedef enum {
@@ -301,6 +302,7 @@ struct ConnectBits {
call */
bool retry; /* this connection is about to get closed and then
re-attempted at another connection. */
bool no_body; /* CURLOPT_NO_BODY (or similar) was set */
};
/*
@@ -436,6 +438,11 @@ struct connectdata {
char *ppath;
curl_off_t bytecount;
long headerbytecount; /* only count received headers */
long deductheadercount; /* this amount of bytes doesn't count when we check
if anything has been transfered at the end of
a connection. We use this counter to make only
a 100 reply (without a following second response
code) result in a CURLE_GOT_NOTHING error code */
char *range; /* range, if used. See README for detailed specification on
this syntax. */
@@ -572,6 +579,8 @@ struct connectdata {
int sockerror; /* errno stored by Curl_read() if the underlying layer returns
error */
char syserr_buf [256]; /* buffer for Curl_strerror() */
#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME)
/* data used for the asynch name resolve callback */
struct Curl_async async;
@@ -641,6 +650,7 @@ typedef enum {
HTTPREQ_POST,
HTTPREQ_POST_FORM, /* we make a difference internally */
HTTPREQ_PUT,
HTTPREQ_HEAD,
HTTPREQ_CUSTOM,
HTTPREQ_LAST /* last in list */
} Curl_HttpReq;
@@ -678,8 +688,8 @@ struct UrlState {
char buffer[BUFSIZE+1]; /* download buffer */
char uploadbuffer[BUFSIZE+1]; /* upload buffer */
double current_speed; /* the ProgressShow() funcion sets this */
curl_off_t current_speed; /* the ProgressShow() funcion sets this,
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
char *auth_host; /* if set, this should be the host name that we will
@@ -717,6 +727,8 @@ struct UrlState {
depending on authstage) */
long authavail; /* what the server reports */
bool authdone; /* TRUE when the auth phase is done and ready
to do the *actual* request */
#ifdef USE_ARES
ares_channel areschannel; /* for name resolves */
#endif
@@ -856,12 +868,10 @@ struct UserDefined {
bool http_fail_on_error;
bool http_follow_location;
bool http_disable_hostname_check_before_authentication;
bool include_header;
#define http_include_header include_header /* former name */
bool include_header; /* include received protocol headers in data output */
bool http_set_referer;
bool http_auto_referer; /* set "correct" referer when following location: */
bool no_body;
bool opt_no_body; /* as set with CURLOPT_NO_BODY */
bool set_port;
bool upload;
enum CURL_NETRC_OPTION
@@ -877,8 +887,9 @@ struct UserDefined {
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
curl_ftpssl ftp_ssl; /* if AUTH TLS is to be attempted etc */
bool no_signal; /* do not use any signal/alarm handler */
bool global_dns_cache; /* subject for future removal */
bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */
bool global_dns_cache;
};
/*

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