Compare commits

..

228 Commits

Author SHA1 Message Date
Daniel Stenberg
1dc54324f4 time to release 2009-01-19 09:59:20 +00:00
Gisle Vanem
89ecf4ac01 fopen() returns error in 'errno' even on Windows.
So don't use ERRNO (GetLastError()). Trimmed trailing
blanks.
2009-01-18 17:03:31 +00:00
Gisle Vanem
d42eac4287 Constified some arguments in local functions. 2009-01-18 16:33:10 +00:00
Gunter Knauf
3fa6c51bb1 fixed global copyright. 2009-01-17 14:56:33 +00:00
Daniel Stenberg
37c5250e03 - Andrew de los Reyes fixed curlbuild.h for "generic" gcc builds on PPC, both
32 bit and 64 bit.
2009-01-16 08:36:40 +00:00
Dan Fandrich
0d3bb93ce8 Add steps needed for zlib support under Minix 2009-01-15 08:49:22 +00:00
Daniel Stenberg
5e74c58b73 - Tim Ansell fixed a compiler warning in lib/cookie.c 2009-01-15 08:32:58 +00:00
Daniel Stenberg
7ac16811cc a bunch of minor updates 2009-01-14 22:52:18 +00:00
Daniel Stenberg
29b6a732f3 - ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it
now declares the private struct ares_in6_addr for all systems instead of
  relying on one possibly not present in the system.
2009-01-14 13:08:50 +00:00
Daniel Stenberg
3dcd6bc597 213 - bug #2501457 "Timeouts not working with curl_multi_socket_action()" -
now put in KNOWN_BUGS as entry #62
2009-01-13 23:45:24 +00:00
Daniel Stenberg
1342f5d592 62. CURLOPT_TIMEOUT does not work properly with the regular multi and
multi_socket interfaces. The work-around for apps is to simply remove the
  easy handle once the time is up. See also:
  http://curl.haxx.se/bug/view.cgi?id=2501457
2009-01-13 23:43:23 +00:00
Daniel Stenberg
8fbfd5916d Karl Moerder removed wsock32.lib from the vc9 makefiles 2009-01-13 23:29:56 +00:00
Daniel Stenberg
1225d36188 Grant Erickson fixed timeouts for TFTP 2009-01-13 23:24:06 +00:00
Daniel Stenberg
a19e02be5e - Michael Wallner fixed a NULL pointer deref when calling
curl_easy_setup(curl, CURLOPT_COOKIELIST, "SESS") on a CURL handle with no
  cookies data.
2009-01-13 22:21:14 +00:00
Daniel Stenberg
0761e60a4a Stefan Teleman's curlbuild.h fix for SunPro compilers 2009-01-13 22:05:48 +00:00
Daniel Stenberg
af96c8304f oops, the previous wasn't meant to get committed but since I did it I thought
I'd just as well enumerate the remainder and commit a "proper" looking one
2009-01-13 22:04:43 +00:00
Daniel Stenberg
0de0e95020 - Stefan Teleman brought a patch to fix the default curlbuild.h file for the
SunPro compilers.
2009-01-13 22:01:39 +00:00
Phil Blundell
35d8fb0501 - ares__send_query() now varies the retry timeout pseudo-randomly to avoid
packet storms when several queries were started at the same time.
2009-01-13 11:51:04 +00:00
Daniel Stenberg
87c71953be spell-checked a bunch of comments 2009-01-13 06:44:03 +00:00
Daniel Stenberg
79a91b8168 make this example not only replace an internal header but also add a totally
new and non-standard one
2009-01-12 21:29:23 +00:00
Daniel Stenberg
2f9038bf62 Mohun Biswas clarified 2009-01-12 21:22:51 +00:00
Daniel Stenberg
4d50ca4e21 bump year 2009-01-11 23:48:20 +00:00
Daniel Stenberg
a1077d0970 changed the wording to possibly make some sense 2009-01-11 23:47:01 +00:00
Daniel Stenberg
b9fdc0c251 - Based on bug report #2498665 (http://curl.haxx.se/bug/view.cgi?id=2498665)
by Daniel Black, I've now added magic to the configure script that makes it
  use pkg-config to detect gnutls details as well if the existing method
  (using libgnutls-config) fails. While doing this, I cleaned up and unified
  the pkg-config usage when detecting openssl and nss as well.
2009-01-11 23:41:50 +00:00
Daniel Stenberg
f471b4836f credit Karl Moerder properly 2009-01-11 22:05:38 +00:00
Daniel Stenberg
32b75d1b69 - Phil Blundell added the internal function ares__expand_name_for_response()
that is now used by the ares_parse_*_reply() functions instead of the
  ares_expand_name() simply to easier return ARES_EBADRESP for the cases where
  the name expansion fails as in responses that really isn't expected.
2009-01-11 13:49:13 +00:00
Daniel Stenberg
f7e3bd28b4 - Karl M brought the patch that creates vc9 Makefiles, and I made 'maketgz'
now use the actual makefile targets to do the VC8 and VC9 makefiles.
2009-01-11 13:34:05 +00:00
Daniel Stenberg
452e52f958 - Emil Romanus fixed:
When using the multi interface over HTTP and the server returns a Location
  header, the running easy handle will get stuck in the CURLM_STATE_PERFORM
  state, leaving the external event loop stuck waiting for data from the
  ingoing socket (when using the curl_multi_socket_action stuff). While this
  bug was pretty hard to find, it seems to require only a one-line fix. The
  break statement on line 1374 in multi.c caused the function to skip the call
  to multistate().

  How to reproduce this bug? Well, that's another question.  evhiperfifo.c in
  the examples directory chokes on this bug only _sometimes_, probably
  depending on how fast the URLs are added. One way of testing the bug out is
  writing to hiper.fifo from more than one source at the same time.
2009-01-10 22:10:57 +00:00
Daniel Stenberg
0090099565 Only care about the first line of libtool --version as otherwise this script
get fooled by libtool 2, and at least libtool 1.5.2x do output the interesting
version string in the first line.
2009-01-08 22:53:37 +00:00
Daniel Stenberg
2ed23cb50d "204 - Rob C's NSS fix" is done and since we enter feature freeze now I moved
the remaining three issues to next release since they are about new things and
not just fixing bugs
2009-01-08 10:32:54 +00:00
Dan Fandrich
a97ab4f933 Added a few more issues 2009-01-08 01:09:29 +00:00
Dan Fandrich
bc93011554 Unified much of the SessionHandle initialization done in Curl_open() and
curl_easy_reset() by creating Curl_init_userdefined(). This had the side effect
of fixing curl_easy_reset() so it now also resets CURLOPT_FTP_FILEMETHOD and
CURLOPT_SSL_SESSIONID_CACHE
2009-01-08 00:31:49 +00:00
Dan Fandrich
14b6cc4e22 Always use nocheck="yes" for consistency 2009-01-07 21:57:26 +00:00
Dan Fandrich
80ffd3581f Created a CURLMIN macro to match CURLMAX 2009-01-07 19:39:35 +00:00
Daniel Stenberg
dd058b8de6 fix compiler warnings 2009-01-07 14:12:01 +00:00
Daniel Stenberg
3c2ad4022c - Rob Crittenden did once again provide an NSS update:
I have to jump through a few hoops now with the NSS library initialization
  since another part of an application may have already initialized NSS by the
  time Curl gets invoked. This patch is more careful to only shutdown the NSS
  library if Curl did the initialization.

  It also adds in a bit of code to set the default ciphers if the app that
  call NSS_Init* did not call NSS_SetDomesticPolicy() or set specific
  ciphers. One might argue that this lets other application developers get
  lazy and/or they aren't using the NSS API correctly, and you'd be right.
  But still, this will avoid terribly difficult-to-trace crashes and is
  generally helpful.
2009-01-07 14:10:35 +00:00
Daniel Stenberg
1f4b8da60a four fresh items to deal with! 2009-01-06 22:30:40 +00:00
Daniel Stenberg
9af4cf219e - 'reconf' is removed since we rather have users use 'buildconf' 2009-01-01 20:50:59 +00:00
Daniel Stenberg
cf4b88fcc4 credit Bas 2008-12-31 20:36:08 +00:00
Daniel Stenberg
2215a9a181 - Bas Mevissen reported http://curl.haxx.se/bug/view.cgi?id=2479030 pointing
out that 'reconf' didn't properly point out the m4 subdirectory when running
  aclocal.
2008-12-31 20:35:46 +00:00
Gunter Knauf
aa32f61ce7 sync'd address with other tests. 2008-12-30 15:33:09 +00:00
Gunter Knauf
8266727062 trial with an address which has a valid domain part but invalid host to avoid dns redirections. 2008-12-30 09:16:38 +00:00
Gunter Knauf
d839230402 added HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID to ares Makefile.netware and sync'd with other Makefile.netware. 2008-12-30 08:16:24 +00:00
Gunter Knauf
1cc50d31f9 changed HAVE_SIN6_SCOPE_ID define to HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID since just found that ares already uses this define. 2008-12-30 08:05:38 +00:00
Gunter Knauf
104377d718 added HAVE_SIN6_SCOPE_ID define to all non-configure platforms which seem to be IPv6-aware. 2008-12-30 07:31:04 +00:00
Daniel Stenberg
83640b2ee5 - Phil Lisiecki filed bug report #2413067
(http://curl.haxx.se/bug/view.cgi?id=2413067) that identified a problem that
  would cause libcurl to mark a DNS cache entry "in use" eternally if the
  subsequence TCP connect failed. It would thus never get pruned and refreshed
  as it should've been.
2008-12-29 22:25:50 +00:00
Daniel Stenberg
9aea3e265d further clarifcation based on input from Anthony Bryan 2008-12-29 21:26:11 +00:00
Daniel Stenberg
59227bf075 - Peter Korsgaard fixed building libcurl with "configure --with-ssl
--disable-verbose".
2008-12-28 22:00:36 +00:00
Daniel Stenberg
f61cfc5931 Anthony Bryan's man page cleanup in language and spelling 2008-12-28 21:56:56 +00:00
Daniel Stenberg
27b8a5fd84 Anthony Bryan reported quirks, I updated 2008-12-28 21:43:34 +00:00
Daniel Stenberg
60ff74140e Anthony Bryan reported and I corrected two typos. 2008-12-28 21:35:53 +00:00
Daniel Stenberg
4f0a7170af The CURLOPT_KRBLEVEL description wasn't properly formatted and thus was
corrupted in ouputs. Another report from Anthony Bryan.
2008-12-28 21:31:55 +00:00
Daniel Stenberg
6d2ff9d2a7 Anthony Bryan reported this outputs wrong in the PDF and I've now tried to
escape these letters what I think is the correct way.
2008-12-28 21:29:13 +00:00
Gunter Knauf
122b0bfe82 silent 'unused' warnings. 2008-12-28 05:49:39 +00:00
Daniel Stenberg
3eae7695fc libssh2 0.19 became 1.0 instead 2008-12-27 23:25:31 +00:00
Gunter Knauf
6efde61227 added check for sin6_scope_id member in struct sockaddr_in6. 2008-12-27 04:30:36 +00:00
Daniel Stenberg
1c48124db4 193 removed, no work has been started on this and I personally don't care that
much about it
2008-12-25 15:09:18 +00:00
Gisle Vanem
e9895ea2e7 Remove trailing #undef value. Typo? 2008-12-22 18:46:12 +00:00
Daniel Stenberg
eab8c0d754 libssh2_sftp_seek2 was just renamed to libssh2_sftp_seek64 ... 2008-12-22 13:21:23 +00:00
Daniel Stenberg
7ffe62d901 - Given a recent enough libssh2, libcurl can now seek/resume with SFTP even
on file indexes beyond 2 or 4GB.
2008-12-22 13:12:36 +00:00
Daniel Stenberg
d5bfec70af - Anthony Bryan provided a set of patches that cleaned up manual language,
corrected spellings and more.
2008-12-22 13:07:13 +00:00
Daniel Stenberg
2a86817349 malloc+memset => calloc 2008-12-20 22:51:57 +00:00
Daniel Stenberg
5be7d88b34 same procedure, simpler code 2008-12-20 22:47:49 +00:00
Daniel Stenberg
8a335ee7fd 197 - IIS-bug in Digest
The curl tool parts are postponed to a later time

201 - "bug: header data output to the body callback function after set header"
 Was probably not a bug, I asked about it but I didn't get any response.

202 - "hangs up of application above libcurl" - problems with the multi_socket
 Fixes from Igor have been committed and there's currently no pending ones.
2008-12-20 22:10:42 +00:00
Daniel Stenberg
216ad2680b - Igor Novoseltsev fixed a bad situation for the multi_socket() API when doing
pipelining, as libcurl could then easily get confused and A) work on the
  handle that was not "first in queue" on a pipeline, or even B) tell the app
  to REMOVE a socket while it was in use by a second handle in a pipeline. Both
  errors caused hanging or stalling applications.
2008-12-20 22:03:22 +00:00
Daniel Stenberg
e16509d5cf make the debug/helper function output to stderr as that makes it play nicer
in combination with infof() calls
2008-12-20 21:48:34 +00:00
Daniel Stenberg
19c9b7c803 remove outdated stuff 2008-12-20 17:16:45 +00:00
Daniel Stenberg
ffd08df863 - curl_multi_timeout() could return a timeout value of 0 even though nothing
was actually ready to get done, as the internal time resolution is higher
  than the returned millisecond timer. Therefore it could cause applications
  running on fast processors to do short bursts of busy-loops.
  curl_multi_timeout() will now only return 0 if the timeout is actually
  alreay triggered.
2008-12-19 22:58:22 +00:00
Daniel Stenberg
460459e8db oops, removing debug output that wasn't supposed to be there 2008-12-19 22:27:11 +00:00
Daniel Stenberg
07416b61e3 - Using the libssh2 0.19 function libssh2_session_block_directions(), libcurl
now has an improved ability to do right when the multi interface (both
  "regular" and multi_socket) is used for SCP and SFTP transfers. This should
  result in (much) less busy-loop situations and thus less CPU usage with no
  speed loss.
2008-12-19 21:14:52 +00:00
Daniel Stenberg
000a13e21a expand the CURLOPT_POSTREDIR explanation 2008-12-19 19:03:55 +00:00
Daniel Stenberg
03ca98b0df - SCP and SFTP with the multi interface had the same flaw: the 'DONE'
operation didn't complete properly if the EAGAIN equivalent was returned but
  libcurl would simply continue with a half-completed close operation
  performed. This ruined persistent connection re-use and cause some
  SSH-protocol errors in general. The correction is unfortunately adding a
  blocking function - doing it entirely non-blocking should be considered for
  a better fix.
2008-12-17 12:32:41 +00:00
Gisle Vanem
abb74a1203 Updated dependencies based on "gcc -MM". 2008-12-16 09:12:46 +00:00
Gisle Vanem
77c1d556bb Added the use of Watt-32 tcp/ip stack for Win32 target.
If USE_WATT32=1 one needs to use stack-based calls (-3s).
So to keep the makefile nice and clean, specify -3s for
Winsock target too (there's hardly any speed-gain using -3r).
2008-12-16 09:03:58 +00:00
Gisle Vanem
bd55ab05bd Added the use of Watt-32 tcp/ip stack for Win32 targets. 2008-12-16 08:59:45 +00:00
Gisle Vanem
2025193b7a Added the use of Watt-32 tcp/ip stack for Win32 targets.
Added USE_WATT32 unconditionally for MSDOS targets since
it's the only option. Adjusted the text for '--wdebug'.
2008-12-16 08:48:44 +00:00
Gisle Vanem
418683f537 Added the use of Watt-32 tcp/ip stack for Win32 targets. 2008-12-16 08:25:55 +00:00
Daniel Stenberg
008b848dcc - libssh2_sftp_last_error() was wrongly used at some places in libcurl which
made libcurl sometimes not properly abort problematic SFTP transfers.
2008-12-15 23:04:51 +00:00
Daniel Stenberg
79b7575fd8 196 is gone 2008-12-12 12:38:47 +00:00
Daniel Stenberg
792279581b - More work with Igor Novoseltsev to first fix the remaining stuff for
removing easy handles from multi handles when the easy handle is/was within
  a HTTP pipeline. His bug report #2351653
  (http://curl.haxx.se/bug/view.cgi?id=2351653) was also related and was
  eventually fixed by a patch by Igor himself.
2008-12-12 12:21:11 +00:00
Daniel Stenberg
3ca360391a Make the getoff all pipelines function only set _inuse to FALSE if the
specified data pointer was head.
2008-12-12 12:04:10 +00:00
Daniel Stenberg
5f0a3797c9 credit Mark Karpeles for his report and work 2008-12-12 08:36:56 +00:00
Yang Tse
2d2c53d20e Patrick Monnerat fixed a build regression, introduced in 7.19.2, affecting
OS/400 compilations with IPv6 enabled.
2008-12-12 03:24:59 +00:00
Daniel Stenberg
02ca14fd0e Removed 200 as it wasn't a bug after all
Added 203 "dns cache memory leak and TTL failure after failed conn"
2008-12-11 23:55:20 +00:00
Daniel Stenberg
0f5895faee - Bug report #2416182 titled "crash in ConnectionExists when using
duphandle+curl_mutli" (http://curl.haxx.se/bug/view.cgi?id=2416182) showed
  that curl_easy_duphandle() wrongly also copied the pointer to the connection
  cache, which was plain wrong and caused a segfault if the handle would be
  used in a different multi handle than the handle it was duplicated from.
2008-12-11 23:52:56 +00:00
Daniel Stenberg
c0dfe6e51d Dan F pointed out that we don't need to scan IPv6 addresses for '%'-letters
in the parse_remote_port() function as the scope id has already been stripped
from the string.
2008-12-11 23:27:22 +00:00
Daniel Stenberg
1b4af1f8d8 - Keshav Krity found out that libcurl failed to deal with dotted IPv6
addresses if they were very long (>39 letters) due to a too strict address
  validity parser. It now accepts addresses up to 45 bytes long.
2008-12-11 22:22:46 +00:00
Patrick Monnerat
8e255534a1 _ Use getaddrinfo/getnameinfo ascii wrappers on OS400.
_ Adjust OS400 make script for non-CVS distributions.
_ Upgrade ILE/RPG binding.
_ Define CURL_HIDDEN_SYMBOLS on OS400, since only CURL_EXTERN-marked symbols are exported.
2008-12-11 19:20:03 +00:00
Dan Fandrich
4607dfe257 Mention what makes this test special 2008-12-11 03:01:38 +00:00
Daniel Stenberg
6e376532b0 - Internet Explorer had a broken HTTP digest authentication before v7 and
there are servers "out there" that relies on the client doing this broken
  Digest authentication. Apache even comes with an option to work with such
  broken clients.

  The difference is only for URLs that contain a query-part (a '?'-letter and
  text to the right of it).

  libcurl now supports this quirk, and you enable it by setting the
  CURLAUTH_DIGEST_IE bit in the bitmask you pass to the CURLOPT_HTTPAUTH or
  CURLOPT_PROXYAUTH options. They are thus individually controlled to server
  and proxy.
2008-12-10 23:13:31 +00:00
Daniel Stenberg
4ed64fd5ee use the new URL 2008-12-09 22:49:51 +00:00
Daniel Stenberg
21700ae515 start over on the 1.6.1 release... 2008-12-09 22:41:36 +00:00
Daniel Stenberg
b962ef3154 add space 2008-12-09 22:30:59 +00:00
Dan Fandrich
32f78136b2 Documented CURLOPT_CONNECT_ONLY as being useful only on HTTP URLs. 2008-12-09 22:00:18 +00:00
Dan Fandrich
01d6133bd7 Added test cases 1089 and 1090 to test --write-out after a redirect to
test a report that the size didn't work, but these test cases pass.
2008-12-09 21:59:57 +00:00
Daniel Stenberg
4b62cd3616 - Ken Hirsch simplified how libcurl does FTPS: now it doesn't assume any
particular state for the control connection like it did before for implicit
  FTPS (libcurl assumed such control connections to be encrypted while some
  FTPS servers such as FileZilla assumes such connections to be clear
  mode). Use the CURLOPT_USE_SSL option to set your desired level.
2008-12-09 15:02:37 +00:00
Gisle Vanem
df7b1d8e64 Fix for Win32 targets using Watt-32. 2008-12-09 14:39:08 +00:00
Dan Fandrich
2449e1f5a5 C89 compilers (like Minix' ACK) only need to handle 31 functions arguments
so split a long sprintf into two calls to get below that number.
2008-12-09 01:02:28 +00:00
Daniel Stenberg
66c0e4ad5f 195 - SIZE returning 550 must not abort the transfer
Fixed!
2008-12-08 20:21:36 +00:00
Daniel Stenberg
18371aaff9 - Fred Machado posted about a weird FTP problem on the curl-users list and when
researching it, it turned out he got a 550 response back from a SIZE command
  and then I fell over the text in RFC3659 that says:

   The presence of the 550 error response to a SIZE command MUST NOT be taken
   by the client as an indication that the file cannot be transferred in the
   current MODE and TYPE.

  In other words: the change I did on September 30th 2008 and that has been
  included in the last two releases were a regression and a bad idea. We MUST
  NOT take a 550 response from SIZE as a hint that the file doesn't exist.
2008-12-08 20:20:51 +00:00
Gisle Vanem
f36eab2608 Added needed defines for Watt-32 on Windows. 2008-12-08 16:12:11 +00:00
Gisle Vanem
66d38261f7 Undefine 'optarg', 'optind' and 'opterr' when using Watt-32
(to get correct linkage on Windows).
2008-12-08 16:11:16 +00:00
Gisle Vanem
553b4cfd0b ares_writev() shall not be exported when using Watt-32 (has writev).
Added _USE_32BIT_TIME_T to avoid runtime warning. Applies to
VC-2008+ only.
2008-12-08 16:09:21 +00:00
Gisle Vanem
edd63a7920 Removed unneeded defines HAVE_SIGNAL_H, HAVE_SIG_ATOMIC_T,
RETSIGTYPE and HAVE_PROCESS_H.
2008-12-08 14:58:56 +00:00
Daniel Stenberg
5ce03efc3e one more 2008-12-08 14:26:28 +00:00
Daniel Stenberg
4645e8b6b1 192 - "infinite loop during GSS authentication" bug #2221237
Fixed!
2008-12-08 14:24:12 +00:00
Daniel Stenberg
42365aa7ef - Christian Krause filed bug #2221237
(http://curl.haxx.se/bug/view.cgi?id=2221237) that identified an infinite
  loop during GSS authentication given some specific conditions. With his
  patience and great feedback I managed to narrow down the problem and
  eventually fix it although I can't test any of this myself!
2008-12-08 13:52:20 +00:00
Daniel Stenberg
dff4ce92ad the initial version of the ares_set_socket_callback man page 2008-12-04 12:54:43 +00:00
Daniel Stenberg
e5b0533dab Gregor Jasny provided the patch that introduces ares_set_socket_callback(),
and I edited it to also get duped by ares_dup().
2008-12-04 12:53:03 +00:00
Dan Fandrich
a2a315a6e8 Bring the sys/include.h include test in line with curl's. 2008-12-04 07:18:13 +00:00
Dan Fandrich
7abdc4b218 Fixed the getifaddrs version of Curl_if2ip to work on systems without IPv6
support (e.g. Minix)
2008-12-04 06:24:00 +00:00
Daniel Stenberg
479ddb1fee - Igor Novoseltsev filed bug #2351645
(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with
  the multi interface that occured if you removed an easy handle while in
  progress and the handle was used in a HTTP pipeline.
2008-12-03 15:20:27 +00:00
Daniel Stenberg
4ee27b4594 filled in SONAME number bump info, after some CVS digging 2008-12-03 15:20:06 +00:00
Daniel Stenberg
58ebde9502 - Pawel Kierski pointed out a mistake in the cookie code that could lead to a
bad fclose() after a fatal error had occured.
  (http://curl.haxx.se/bug/view.cgi?id=2382219)
2008-12-03 15:08:09 +00:00
Daniel Stenberg
04ee89493e Let's not call ares_save_options() deprecated just yet 2008-12-03 10:03:07 +00:00
Daniel Stenberg
dd3594c6b3 Introduce ares_dup(3) and new thoughts about API/ABI and how to move forwards.
Also discussed on the ml.
2008-12-03 09:59:50 +00:00
Daniel Stenberg
f7ea431516 explain the two *channel_inuse fields somewhat better 2008-12-02 23:00:10 +00:00
Dan Fandrich
16a153468d Make sure sys/socket.h is included before netinet/in.h (required by
OpenWatcom C, and condoned by SUS)
2008-12-02 02:58:04 +00:00
Daniel Stenberg
b062212e55 minor indent fix 2008-12-01 22:36:39 +00:00
Daniel Stenberg
39eb96e9ff Convert the public config struct to the same binary size/construct as in the
latest releases to remain ABI compatible.
2008-12-01 19:06:24 +00:00
Daniel Stenberg
4c84f6b423 added some more entries for stuff done the last ~2 years 2008-12-01 18:46:31 +00:00
Daniel Stenberg
0b2ae71f8b People have successfully ran libcurl on iphone 2008-11-30 22:51:54 +00:00
Yang Tse
39d0b57ebf Further adjust a libssh2 preprocessor function-symbol definition check 2008-11-29 17:45:16 +00:00
Yang Tse
c036f6ae2d Adjust some libssh2 preprocessor symbol definition checks 2008-11-29 16:39:56 +00:00
Gisle Vanem
e35e2ea6ec Added '-DHAVE_GETHOSTNAME'. 2008-11-29 15:19:46 +00:00
Dan Fandrich
f33f8eee26 Make sure sys/socket.h is included before netinet/in.h (required by
OpenWatcom C)
2008-11-29 00:26:07 +00:00
Dan Fandrich
31a3f064c0 Netware has gethostname() 2008-11-28 23:34:39 +00:00
Dan Fandrich
232518a219 Fixed a couple of typos 2008-11-28 23:24:06 +00:00
Dan Fandrich
bc165078a2 Don't tweak the HAVE_* macros when using autoconf 2008-11-28 23:12:11 +00:00
Dan Fandrich
e4dabef0c7 Make use of gethostname() conditional on it being available 2008-11-28 22:41:14 +00:00
Dan Fandrich
00142d8443 Only set TCP_NODELAY when it exists 2008-11-28 22:07:40 +00:00
Daniel Stenberg
1b0b7fa0e1 updated with changes, preparing for a release soon 2008-11-28 15:44:01 +00:00
Yang Tse
67fb731ec4 Gerald Combs fixed a bug in ares_parse_ptr_reply() which would cause a
buffer to shrink instead of expand if a reply contained 8 or more records.
2008-11-26 17:04:35 +00:00
Yang Tse
a30a6f2f20 Brad Spencer provided changes to allow buildconf to work on OS X. 2008-11-26 16:51:51 +00:00
Daniel Stenberg
baeebb2b57 narrow the comment to < 80 columns 2008-11-26 12:35:24 +00:00
Dan Fandrich
ecc6f550eb Added tests 1087 and 1088 to test Basic authentication on a redirect
with and without --location-trusted
2008-11-25 23:30:53 +00:00
Dan Fandrich
640974fb28 If a HTTP request is Basic and num is already >=1000, the HTTP test server
adds 1 to num to get the data section to return. This allows testing
authentication negotiations using the Basic authentication method.
2008-11-25 23:23:47 +00:00
Yang Tse
3b0c5ae467 In preparation for the upcomming IPv6 nameservers patch, the internal
ares_addr union is now changed into an internal struct which also holds
the address family.
2008-11-25 16:26:58 +00:00
Dan Fandrich
0fa14c8662 Fully clean up after test 608 so that it can be run twice in succession. 2008-11-24 22:06:43 +00:00
Daniel Stenberg
d17be0df52 191 - "proposed patch for curl/libssh2 bugfix"
http://curl.haxx.se/mail/archive-2008-10/0000.html
Done!
2008-11-24 14:05:05 +00:00
Daniel Stenberg
53a8a6e5a6 - Based on a patch by Vlad Grachov, libcurl now uses a new libssh2 0.19
function when built to support SCP and SFTP that helps the library to know
  in which direction a particular libssh2 operation would return EAGAIN so
  that libcurl knows what socket conditions to wait for before trying the
  function call again. Previously (and still when using libssh2 0.18 or
  earlier), libcurl will busy-loop in this situation when the easy interface
  is used!
2008-11-24 13:59:51 +00:00
Daniel Stenberg
dd2fc45c27 Markus Koetter's adaptation of hiperfifo.c to instead use libev 2008-11-21 10:10:33 +00:00
Daniel Stenberg
ba9f8c674c restored from my messy previous commit mistake 2008-11-21 07:47:31 +00:00
Dan Fandrich
c4f4fa4089 Automatically detect OpenBSD's CA cert bundle. 2008-11-21 06:36:21 +00:00
Dan Fandrich
32634b0771 Make checking for struct ifreq a prerequisite for setting
HAVE_IOCTL_SIOCGIFADDR since it's needed to use SIOCGIFADDR and Watcom C
doesn't currently define it.
2008-11-20 07:59:26 +00:00
Daniel Stenberg
c97b66287c use unsigned short better intead of mixing with ints to prevent compiler
warnings
2008-11-20 07:50:48 +00:00
Daniel Stenberg
cd6fc8a8ef please the picky compilers by staying with short as the data we get is short
only
2008-11-20 07:41:26 +00:00
Daniel Stenberg
3308781376 194 - remove "Pragma: no-cache" from default HTTP requests
done!
2008-11-19 22:02:38 +00:00
Daniel Stenberg
40e8b4e527 - I removed the default use of "Pragma: no-cache" from libcurl when a proxy is
used. It has been used since forever but it was never a good idea to use
  unless explicitly asked for.
2008-11-19 22:00:14 +00:00
Daniel Stenberg
4741e64c89 Josef Wolf's extension that allows a $TESTDIR/gdbinit$testnum file that when
you use runtests.pl -g, will be sourced by gdb to allow additional fancy
or whatever you see fit
2008-11-19 21:56:11 +00:00
Daniel Stenberg
0b489c7e61 and now it compiles too! 2008-11-19 15:31:55 +00:00
Daniel Stenberg
22d4db1cf2 I updated this example to use the modern paradigms of the socket API where
*_socket_all() and *_socket() aren't used at all but only *_socket_action()
is.
2008-11-19 15:30:41 +00:00
Daniel Stenberg
7383225271 - Brad Spencer brought the new function ares_gethostbyname_file() which simply
resolves a host name from the given file, using the regular hosts syntax.
2008-11-19 15:16:16 +00:00
Daniel Stenberg
4b3ae5e157 - Christian Krause reported and fixed a memory leak that would occur with HTTP
GSS/kerberos authentication (http://curl.haxx.se/bug/view.cgi?id=2284386)
2008-11-19 14:22:01 +00:00
Daniel Stenberg
797bc8504c - Andreas Wurf and Markus Koetter helped me analyze a problem that Andreas got
when uploading files to a single FTP server using multiple easy handle
  handles with the multi interface. Occasionally a handle would stall in
  mysterious ways.

  The problem turned out to be a side-effect of the ConnectionExists()
  function's eagerness to re-use a handle for HTTP pipelining so it would
  select it even if already being in use, due to an inadequate check for its
  chances of being used for pipelnining.
2008-11-19 10:15:19 +00:00
Yang Tse
305f4d92ef user provided PATH_SEPARATOR always overrides auto-detected one 2008-11-19 01:57:27 +00:00
Yang Tse
c36f0e71b6 attempting to keep lines below 80 chars 2008-11-18 20:13:55 +00:00
Dan Fandrich
a028c69f48 Avoid creating garbage on an OOM error 2008-11-18 19:58:44 +00:00
Yang Tse
4e4b6de5ce provide a common PATH_SEPARATOR check method which is required by
upcomming work to support the broadest range of Autoconf versions
2008-11-18 19:29:31 +00:00
Dan Fandrich
9aac2328c6 Made an array static const 2008-11-18 09:11:34 +00:00
Dan Fandrich
e5084c1eca Added #include "rawstr.h" 2008-11-18 08:53:51 +00:00
Yang Tse
9b12f09600 check for gethostbyaddr and gethostbyname as it is done for other functions 2008-11-18 01:57:28 +00:00
Daniel Stenberg
a71762e405 curl also builds fine for microblaze uclinux 2008-11-17 21:43:39 +00:00
Daniel Stenberg
b8f3e5675a libcurl has been built and ran on Cell OS on the Cell processor (playstation 3) 2008-11-17 21:41:03 +00:00
Dan Fandrich
820011dedc Added more compiler warning options for gcc 4.3 2008-11-17 21:11:10 +00:00
Dan Fandrich
cdd6054e08 Display the time in verbose mode during the torture tests to help determine
when the tests stall.
2008-11-17 20:24:13 +00:00
Yang Tse
a15b6a6f86 the IP address we want/request/use from the interface is the 'local'
address, the one on the box libcurl is running, not the 'remote' one.
2008-11-17 19:08:35 +00:00
Yang Tse
20d3e2b967 fix comment 2008-11-17 14:26:22 +00:00
Yang Tse
608fdce0a0 if2ip.c related preprocessor cleanup 2008-11-17 14:24:15 +00:00
Yang Tse
ecd3251542 Make configure script check if ioctl with the SIOCGIFADDR command can be
used, and define HAVE_IOCTL_SIOCGIFADDR if appropriate.
2008-11-17 13:13:15 +00:00
Yang Tse
999c7126b3 fix leftover from previous commit 2008-11-17 10:05:35 +00:00
Daniel Stenberg
3c50ea961f pipelining for PUT is a good idea 2008-11-17 09:35:10 +00:00
Dan Fandrich
acc29ff1d9 Fixed an outdated mention of having keep strings around in curl_easy_setopt
calls. Added a paragraph explaining that libcurl takes care of low-level
protocol details. Made a few minor edits.
2008-11-17 08:16:25 +00:00
Yang Tse
886bba55ac update with my last changes 2008-11-17 04:11:29 +00:00
Yang Tse
cd440215a5 fix inet_pton() runtime configure check 2008-11-17 03:54:05 +00:00
Yang Tse
73060b4523 backport fix for failures to reject certain malformed literals 2008-11-17 02:40:41 +00:00
Daniel Stenberg
c76d939563 Christian Krause fixed a build failure when building with gss support
enabled and FTP disabled.
2008-11-16 12:42:53 +00:00
Daniel Stenberg
3c4b69f95d fix OOM problem reported by Jim Meyering 2008-11-16 12:26:50 +00:00
Yang Tse
3f01d9a043 trim down configure script size 2008-11-16 02:23:18 +00:00
Daniel Stenberg
dbc6fe3e84 my recent changes 2008-11-15 23:47:01 +00:00
Daniel Stenberg
da6c15163b based on a report by Jim Meyering, I went over and added checks for return
codes for all calls to malloc and strdup that were missing. I also changed
a few malloc(13) to use arrays on the stack and a few malloc(PATH_MAX) to
instead use aprintf() to lower memory use.
I also fixed a memory leak in Curl_nss_connect() when CURLOPT_ISSUERCERT is
in use.
2008-11-15 23:43:10 +00:00
Daniel Stenberg
9818bf7026 Fixed an OOM condition reported by Jim Meyering 2008-11-15 23:07:35 +00:00
Dan Fandrich
73c7acb159 Added some more examples of options to reduce binary size. Added x86_64 Linux
as a known-working environment.
2008-11-14 23:19:18 +00:00
Dan Fandrich
ea8fbb5233 Added some #ifdefs around header files and change the EAGAIN test to
fix compilation on Cell (reported by Jeff Curley).
2008-11-14 23:17:32 +00:00
Dan Fandrich
9b033e1b8a Added .xml as one of the few common file extensions known by the multipart
form generator.  Made the extensions part of the MIME type struct to reduce
the size and run-time relocations necessary to build the table.
2008-11-14 19:22:40 +00:00
Daniel Stenberg
a65ce7b107 check for NULL returns from strdup() - reported by Jim Meyering
also prevent buffer overflow on MSDOS when you do for example -O on a url
with a file name part longer than PATH_MAX letters
2008-11-14 16:42:05 +00:00
Daniel Stenberg
2249c12a3c fix an OOM problem detected by Jim Meyering 2008-11-14 16:26:39 +00:00
Daniel Stenberg
b4ac9cd02c Remove a chunk of unused code that was #ifdef'de on defines we never set.
We do testing of code functions using the test suite instead!
2008-11-14 16:22:18 +00:00
Yang Tse
3517eba632 fix typo affecting inclusion of <arpa/inet.h> in configure
checks for inet_ntoa_r() inet_ntop() and inet_pton()
2008-11-14 15:26:27 +00:00
Yang Tse
2cd44abafc #include <string.h> in the getaddrinfo() runtime check for the memset() prototype 2008-11-14 14:47:53 +00:00
Yang Tse
4b486ebbc1 fix symbol definition check for fcntl.h inclusion 2008-11-14 05:18:08 +00:00
Yang Tse
f9f211d2c6 #include <stdlib.h> in the getifaddrs() runtime check for the exit() prototype 2008-11-14 02:51:41 +00:00
Daniel Stenberg
77b30f69e4 curl runs fine on Linux on Cell (PS3) 2008-11-13 23:19:01 +00:00
Yang Tse
17d2a464ad Refactor configure script detection of functions used to set sockets into
non-blocking mode, and decouple function detection from function capability.
2008-11-13 18:56:55 +00:00
Daniel Stenberg
ae6530ee82 and we are now on the 7.19.3 road 2008-11-13 13:24:00 +00:00
Daniel Stenberg
a6ba9e5ccd 7.19.2 coming up 2008-11-13 12:42:20 +00:00
Daniel Stenberg
c4cdab969b two more things for 7.19.3 2008-11-13 10:46:10 +00:00
Michal Marek
c331c73ec6 - Fixed a potential data loss in Curl_client_write() when the transfer is
paused.
2008-11-13 08:20:23 +00:00
Dan Fandrich
d1f063c62d Shortened some FTP responses to allow the timeout to be reduced by a second
while still causing a timeout during the data phase.
2008-11-13 01:45:59 +00:00
Gunter Knauf
b686dc4911 changed to latest libidn version. 2008-11-13 01:39:10 +00:00
Gunter Knauf
78936b2f2a changed defines to make autobuild logs display libidn usage. 2008-11-13 01:36:04 +00:00
Dan Fandrich
b2ed1e2607 Fixed an OOM problem with test 560 2008-11-12 22:26:06 +00:00
Dan Fandrich
fb8870297d Give the test an extra second to run so it passes on slow machines 2008-11-12 01:04:27 +00:00
Daniel Stenberg
4cbc0f6c2e - Rainer Canavan filed bug #2255627
(http://curl.haxx.se/bug/view.cgi?id=2255627) which pointed out that a
  program using libcurl's multi interface to download a HTTPS page with a
  libcurl built powered by OpenSSL, would easily get silly and instead hand
  over SSL details as data instead of the actual HTTP headers and body. This
  happened because libcurl would consider the connection handshake done too
  early. This problem was introduced at September 22nd 2008 with my fix of the
  bug #2107377

  The correct fix is now instead done within the GnuTLS-handling code, as both
  the OpenSSL and the NSS code already deal with this situation in similar
  fashion. I added test case 560 in an attempt to verify this fix, but
  unfortunately it didn't trigger it even before this fix!
2008-11-11 22:19:27 +00:00
Daniel Stenberg
1b9eff64fa bump them all to 7.19.3 and remove some of the pending ones until they are
either sorted out or more/new details come up
2008-11-11 22:01:15 +00:00
Daniel Stenberg
d07d1a6ef8 Added test case 560:
This test was added after the HTTPS-using-multi-interface with OpenSSL
regression of 7.19.1 to hopefully prevent this embarassing mistake from
appearing again... Unfortunately the bug wasn't triggered by this test, which
presumably is because the connect to a local server is too fast/different
compared to the real/distant servers we saw the bug happen with.
2008-11-11 21:59:25 +00:00
Daniel Stenberg
8bdd60fa71 Added missing <keywords> 2008-11-11 21:58:41 +00:00
Gunter Knauf
b872086c74 updated OpenSSL version. 2008-11-11 19:43:35 +00:00
Gunter Knauf
e0af4a15d0 added libidn build. 2008-11-11 19:42:35 +00:00
Gunter Knauf
d31802ed98 updated coment, updated OpenSSL version. 2008-11-11 17:46:31 +00:00
Gunter Knauf
87c4136bd4 added libidn build. 2008-11-11 17:43:02 +00:00
Daniel Stenberg
09e027bc9d cleaned up entries that have been implemented already or are deemed not really
wanted anyway
2008-11-11 13:33:01 +00:00
Yang Tse
707828b71a Related with bug #2230535 (http://curl.haxx.se/bug/view.cgi?id=2230535)
Daniel Fandrich noticed that curl_addrinfo was also missing in the build
process of other four non-configure platforms. Added now.
2008-11-11 01:12:17 +00:00
Daniel Stenberg
8f44037133 11 new contributors from the 7.19.1 release 2008-11-09 12:38:54 +00:00
Yang Tse
9717ccb786 check for getifaddrs and freeifaddrs as it is done for other functions 2008-11-08 03:27:15 +00:00
Dan Fandrich
6354cbf9d6 The getifaddrs() version of Curl_if2ip() crashed when used on a Linux
system with a TEQL load-balancing device configured, which doesn't
have an address.  Thanks to Adam Sampson for spotting this (bug #2234923).
2008-11-07 18:33:20 +00:00
Yang Tse
95a849efc2 terminate with appropriate exit code 2008-11-07 12:22:43 +00:00
Yang Tse
fe083a94b9 give credit where credit is due 2008-11-07 01:42:34 +00:00
Yang Tse
6fdcdfa5ea Bug #2230535 (http://curl.haxx.se/bug/view.cgi?id=2230535) pointed out a
problem with MSVC 6 makefile that caused a build failure. It was noted that
the curl_addrinfo.obj reference was missing. I took the opportunity to sort
the list in which this was missing.
2008-11-06 19:11:46 +00:00
Yang Tse
4a4885eead Add missing curl_addrinfo, and sort the list. 2008-11-06 18:50:32 +00:00
Yang Tse
a0ef686c54 Merged existing IPv4 and IPv6 Curl_ip2addr functions into a single one
which now also takes a protocol address family argument.
2008-11-06 17:19:56 +00:00
Dan Fandrich
2903a5c050 Added test 1086 to test a timeout the occurs during an FTP data transfer. 2008-11-06 00:13:18 +00:00
Dan Fandrich
4d50b9f1f1 Make the SLOWDOWN option slow the FTP data connection, not just the
control connection.
2008-11-06 00:10:58 +00:00
Dan Fandrich
5e3c2af236 Factored out some common code into a new function output_auth_headers 2008-11-06 00:01:13 +00:00
Daniel Stenberg
5d791838d2 mention the speed unit for the _SPEED_LARGE options from bug #2226722 2008-11-05 21:48:00 +00:00
Daniel Stenberg
b80c5cff49 corrected and clarified the *_SPEED_LARGE comments 2008-11-05 21:46:40 +00:00
Daniel Stenberg
47b5740bdf 7.19.1 is now history 2008-11-05 21:28:04 +00:00
Daniel Stenberg
b8092857d9 and we're back on square one working on the next release... 2008-11-05 12:17:30 +00:00
273 changed files with 7479 additions and 4460 deletions

404
CHANGES
View File

@@ -6,6 +6,392 @@
Changelog
Version 7.19.3 (19 January 2009)
Daniel Stenberg (16 Jan 2009)
- Andrew de los Reyes fixed curlbuild.h for "generic" gcc builds on PPC, both
32 bit and 64 bit.
Daniel Stenberg (15 Jan 2009)
- Tim Ansell fixed a compiler warning in lib/cookie.c
Daniel Stenberg (14 Jan 2009)
- Grant Erickson fixed timeouts for TFTP such that specifying a
connect-timeout, a max-time or both options work correctly and as expected
by passing the correct boolean value to Curl_timeleft via the
'duringconnect' parameter.
With this small change, curl TFTP now behaves as expected (and likely as
originally-designed):
1) For non-existent or unreachable dotted IP addresses:
a) With no options, follows the default curl 300s timeout...
b) With --connect-timeout only, follows that value...
c) With --max-time only, follows that value...
d) With both --connect-timeout and --max-time, follows the smaller value...
and times out with a "curl: (7) Couldn't connect to server" error.
2) For transfers to/from a valid host:
a) With no options, follows default curl 300s timeout for the
first XRQ/DATA/ACK transaction and the default TFTP 3600s
timeout for the remainder of the transfer...
b) With --connect-time only, follows that value for the
first XRQ/DATA/ACK transaction and the default TFTP 3600s
timeout for the remainder of the transfer...
c) With --max-time only, follows that value for the first
XRQ/DATA/ACK transaction and for the remainder of the
transfer...
d) With both --connect-timeout and --max-time, follows the former
for the first XRQ/DATA/ACK transaction and the latter for the
remainder of the transfer...
and times out with a "curl: (28) Timeout was reached" error as
appropriate.
Daniel Stenberg (13 Jan 2009)
- Michael Wallner fixed a NULL pointer deref when calling
curl_easy_setup(curl, CURLOPT_COOKIELIST, "SESS") on a CURL handle with no
cookies data.
- Stefan Teleman brought a patch to fix the default curlbuild.h file for the
SunPro compilers.
Daniel Stenberg (12 Jan 2009)
- Based on bug report #2498665 (http://curl.haxx.se/bug/view.cgi?id=2498665)
by Daniel Black, I've now added magic to the configure script that makes it
use pkg-config to detect gnutls details as well if the existing method
(using libgnutls-config) fails. While doing this, I cleaned up and unified
the pkg-config usage when detecting openssl and nss as well.
Daniel Stenberg (11 Jan 2009)
- Karl Moerder brought the patch that creates vc9 Makefiles, and I made
'maketgz' now use the actual makefile targets to do the VC8 and VC9
makefiles.
Daniel Stenberg (10 Jan 2009)
- Emil Romanus fixed:
When using the multi interface over HTTP and the server returns a Location
header, the running easy handle will get stuck in the CURLM_STATE_PERFORM
state, leaving the external event loop stuck waiting for data from the
ingoing socket (when using the curl_multi_socket_action stuff). While this
bug was pretty hard to find, it seems to require only a one-line fix. The
break statement on line 1374 in multi.c caused the function to skip the call
to multistate().
How to reproduce this bug? Well, that's another question. evhiperfifo.c in
the examples directory chokes on this bug only _sometimes_, probably
depending on how fast the URLs are added. One way of testing the bug out is
writing to hiper.fifo from more than one source at the same time.
Daniel Fandrich (7 Jan 2009)
- Unified much of the SessionHandle initialization done in Curl_open() and
curl_easy_reset() by creating Curl_init_userdefined(). This had the side
effect of fixing curl_easy_reset() so it now also resets
CURLOPT_FTP_FILEMETHOD and CURLOPT_SSL_SESSIONID_CACHE
Daniel Stenberg (7 Jan 2009)
- Rob Crittenden did once again provide an NSS update:
I have to jump through a few hoops now with the NSS library initialization
since another part of an application may have already initialized NSS by the
time Curl gets invoked. This patch is more careful to only shutdown the NSS
library if Curl did the initialization.
It also adds in a bit of code to set the default ciphers if the app that
call NSS_Init* did not call NSS_SetDomesticPolicy() or set specific
ciphers. One might argue that this lets other application developers get
lazy and/or they aren't using the NSS API correctly, and you'd be right.
But still, this will avoid terribly difficult-to-trace crashes and is
generally helpful.
Daniel Stenberg (1 Jan 2009)
- 'reconf' is removed since we rather have users use 'buildconf'
Daniel Stenberg (31 Dec 2008)
- Bas Mevissen reported http://curl.haxx.se/bug/view.cgi?id=2479030 pointing
out that 'reconf' didn't properly point out the m4 subdirectory when running
aclocal.
Daniel Stenberg (29 Dec 2008)
- Phil Lisiecki filed bug report #2413067
(http://curl.haxx.se/bug/view.cgi?id=2413067) that identified a problem that
would cause libcurl to mark a DNS cache entry "in use" eternally if the
subsequence TCP connect failed. It would thus never get pruned and refreshed
as it should've been.
Phil provided his own patch to this problem that while it seemed to work
wasn't complete and thus I wrote my own fix to the problem.
Daniel Stenberg (28 Dec 2008)
- Peter Korsgaard fixed building libcurl with "configure --with-ssl
--disable-verbose".
- Anthony Bryan fixed more language and spelling flaws in man pages.
Daniel Stenberg (22 Dec 2008)
- Given a recent enough libssh2, libcurl can now seek/resume with SFTP even
on file indexes beyond 2 or 4GB.
- Anthony Bryan provided a set of patches that cleaned up manual language,
corrected spellings and more.
Daniel Stenberg (20 Dec 2008)
- Igor Novoseltsev fixed a bad situation for the multi_socket() API when doing
pipelining, as libcurl could then easily get confused and A) work on the
handle that was not "first in queue" on a pipeline, or even B) tell the app
to REMOVE a socket while it was in use by a second handle in a pipeline. Both
errors caused hanging or stalling applications.
Daniel Stenberg (19 Dec 2008)
- curl_multi_timeout() could return a timeout value of 0 even though nothing
was actually ready to get done, as the internal time resolution is higher
than the returned millisecond timer. Therefore it could cause applications
running on fast processors to do short bursts of busy-loops.
curl_multi_timeout() will now only return 0 if the timeout is actually
alreay triggered.
- Using the libssh2 0.19 function libssh2_session_block_directions(), libcurl
now has an improved ability to do right when the multi interface (both
"regular" and multi_socket) is used for SCP and SFTP transfers. This should
result in (much) less busy-loop situations and thus less CPU usage with no
speed loss.
Daniel Stenberg (17 Dec 2008)
- SCP and SFTP with the multi interface had the same flaw: the 'DONE'
operation didn't complete properly if the EAGAIN equivalent was returned but
libcurl would simply continue with a half-completed close operation
performed. This ruined persistent connection re-use and cause some
SSH-protocol errors in general. The correction is unfortunately adding a
blocking function - doing it entirely non-blocking should be considered for
a better fix.
Gisle Vanem (16 Dec 2008)
- Added the possibility to use the Watt-32 tcp/ip stack under Windows.
The change simply involved adding a USE_WATT32 section in the
config-win32.h files (under ./lib and ./src). This section disables
the use of any Winsock headers.
Daniel Stenberg (16 Dec 2008)
- libssh2_sftp_last_error() was wrongly used at some places in libcurl which
made libcurl sometimes not properly abort problematic SFTP transfers.
Daniel Stenberg (12 Dec 2008)
- More work with Igor Novoseltsev to first fix the remaining stuff for
removing easy handles from multi handles when the easy handle is/was within
a HTTP pipeline. His bug report #2351653
(http://curl.haxx.se/bug/view.cgi?id=2351653) was also related and was
eventually fixed by a patch by Igor himself.
Yang Tse (12 Dec 2008)
- Patrick Monnerat fixed a build regression, introduced in 7.19.2, affecting
OS/400 compilations with IPv6 enabled.
Daniel Stenberg (12 Dec 2008)
- Mark Karpeles filed bug report #2416182 titled "crash in ConnectionExists
when using duphandle+curl_mutli"
(http://curl.haxx.se/bug/view.cgi?id=2416182) which showed that
curl_easy_duphandle() wrongly also copied the pointer to the connection
cache, which was plain wrong and caused a segfault if the handle would be
used in a different multi handle than the handle it was duplicated from.
Daniel Stenberg (11 Dec 2008)
- Keshav Krity found out that libcurl failed to deal with dotted IPv6
addresses if they were very long (>39 letters) due to a too strict address
validity parser. It now accepts addresses up to 45 bytes long.
Daniel Stenberg (11 Dec 2008)
- Internet Explorer had a broken HTTP digest authentication before v7 and
there are servers "out there" that relies on the client doing this broken
Digest authentication. Apache even comes with an option to work with such
broken clients.
The difference is only for URLs that contain a query-part (a '?'-letter and
text to the right of it).
libcurl now supports this quirk, and you enable it by setting the
CURLAUTH_DIGEST_IE bit in the bitmask you pass to the CURLOPT_HTTPAUTH or
CURLOPT_PROXYAUTH options. They are thus individually controlled to server
and proxy.
(note that there's no way to activate this with the curl tool yet)
Daniel Fandrich (9 Dec 2008)
- Added test cases 1089 and 1090 to test --write-out after a redirect to
test a report that the size didn't work, but these test cases pass.
- Documented CURLOPT_CONNECT_ONLY as being useful only on HTTP URLs.
Daniel Stenberg (9 Dec 2008)
- Ken Hirsch simplified how libcurl does FTPS: now it doesn't assume any
particular state for the control connection like it did before for implicit
FTPS (libcurl assumed such control connections to be encrypted while some
FTPS servers such as FileZilla assumes such connections to be clear
mode). Use the CURLOPT_USE_SSL option to set your desired level.
Daniel Stenberg (8 Dec 2008)
- Fred Machado posted about a weird FTP problem on the curl-users list and when
researching it, it turned out he got a 550 response back from a SIZE command
and then I fell over the text in RFC3659 that says:
The presence of the 550 error response to a SIZE command MUST NOT be taken
by the client as an indication that the file cannot be transferred in the
current MODE and TYPE.
In other words: the change I did on September 30th 2008 and that has been
included in the last two releases were a regression and a bad idea. We MUST
NOT take a 550 response from SIZE as a hint that the file doesn't exist.
- Christian Krause filed bug #2221237
(http://curl.haxx.se/bug/view.cgi?id=2221237) that identified an infinite
loop during GSS authentication given some specific conditions. With his
patience and great feedback I managed to narrow down the problem and
eventually fix it although I can't test any of this myself!
Daniel Fandrich (3 Dec 2008)
- Fixed the getifaddrs version of Curl_if2ip to work on systems without IPv6
support (e.g. Minix)
Daniel Stenberg (3 Dec 2008)
- Igor Novoseltsev filed bug #2351645
(http://curl.haxx.se/bug/view.cgi?id=2351645) that identified a problem with
the multi interface that occured if you removed an easy handle while in
progress and the handle was used in a HTTP pipeline.
- Pawel Kierski pointed out a mistake in the cookie code that could lead to a
bad fclose() after a fatal error had occured.
(http://curl.haxx.se/bug/view.cgi?id=2382219)
Daniel Fandrich (25 Nov 2008)
- If a HTTP request is Basic and num is already >=1000, the HTTP test
server adds 1 to num to get the data section to return. This allows
testing authentication negotiations using the Basic authentication
method.
- Added tests 1087 and 1088 to test Basic authentication on a redirect
with and without --location-trusted
Daniel Stenberg (24 Nov 2008)
- Based on a patch by Vlad Grachov, libcurl now uses a new libssh2 0.19
function when built to support SCP and SFTP that helps the library to know
in which direction a particular libssh2 operation would return EAGAIN so
that libcurl knows what socket conditions to wait for before trying the
function call again. Previously (and still when using libssh2 0.18 or
earlier), libcurl will busy-loop in this situation when the easy interface
is used!
Daniel Fandrich (20 Nov 2008)
- Automatically detect OpenBSD's CA cert bundle.
Daniel Stenberg (19 Nov 2008)
- I removed the default use of "Pragma: no-cache" from libcurl when a proxy is
used. It has been used since forever but it was never a good idea to use
unless explicitly asked for.
- Josef Wolf's extension that allows a $TESTDIR/gdbinit$testnum file that when
you use runtests.pl -g, will be sourced by gdb to allow additional fancy or
whatever you see fit
- Christian Krause reported and fixed a memory leak that would occur with HTTP
GSS/kerberos authentication (http://curl.haxx.se/bug/view.cgi?id=2284386)
- Andreas Wurf and Markus Koetter helped me analyze a problem that Andreas got
when uploading files to a single FTP server using multiple easy handle
handles with the multi interface. Occasionally a handle would stall in
mysterious ways.
The problem turned out to be a side-effect of the ConnectionExists()
function's eagerness to re-use a handle for HTTP pipelining so it would
select it even if already being in use, due to an inadequate check for its
chances of being used for pipelnining.
Daniel Fandrich (17 Nov 2008)
- Added more compiler warning options for gcc 4.3
Yang Tse (17 Nov 2008)
- Fix a remaining problem in the inet_pton() runtime configure check. And
fix internal Curl_inet_pton() failures to reject certain malformed literals.
- Make configure script check if ioctl with the SIOCGIFADDR command can be
used, and define HAVE_IOCTL_SIOCGIFADDR if appropriate.
Daniel Stenberg (16 Nov 2008)
- Christian Krause fixed a build failure when building with gss support
enabled and FTP disabled.
- Added check for NULL returns from strdup() in src/main.c and lib/formdata.c
- reported by Jim Meyering also prevent buffer overflow on MSDOS when you do
for example -O on a url with a file name part longer than PATH_MAX letters
- lib/nss.c fixes based on the report by Jim Meyering: I went over and added
checks for return codes for all calls to malloc and strdup that were
missing. I also changed a few malloc(13) to use arrays on the stack and a
few malloc(PATH_MAX) to instead use aprintf() to lower memory use.
- I fixed a memory leak in Curl_nss_connect() when CURLOPT_ISSUERCERT is
in use.
Daniel Fandrich (14 Nov 2008)
- Added .xml as one of the few common file extensions known by the multipart
form generator.
- Added some #ifdefs around header files and change the EAGAIN test to
fix compilation on Cell (reported by Jeff Curley).
Yang Tse (14 Nov 2008)
- Fixed several configure script issues affecting checks for inet_ntoa_r(),
inet_ntop(), inet_pton(), getifaddrs(), fcntl() and getaddrinfo().
Yang Tse (13 Nov 2008)
- Refactored configure script detection of functions used to set sockets into
non-blocking mode, and decouple function detection from function capability.
Version 7.19.2 (13 November 2008)
Michal Marek (13 Nov 2008)
- Fixed a potential data loss in Curl_client_write() when the transfer is
paused.
Daniel Stenberg (11 Nov 2008)
- Rainer Canavan filed bug #2255627
(http://curl.haxx.se/bug/view.cgi?id=2255627) which pointed out that a
program using libcurl's multi interface to download a HTTPS page with a
libcurl built powered by OpenSSL, would easily get silly and instead hand
over SSL details as data instead of the actual HTTP headers and body. This
happened because libcurl would consider the connection handshake done too
early. This problem was introduced at September 22nd 2008 with my fix of the
bug #2107377
The correct fix is now instead done within the GnuTLS-handling code, as both
the OpenSSL and the NSS code already deal with this situation in similar
fashion. I added test case 560 in an attempt to verify this fix, but
unfortunately it didn't trigger it even before this fix!
Yang Tse (11 Nov 2008)
- Related with bug #2230535 (http://curl.haxx.se/bug/view.cgi?id=2230535)
Daniel Fandrich noticed that curl_addrinfo was also missing in the build
process of other four non-configure platforms. Added now.
Daniel Fandrich (7 Nov 2008)
- The getifaddrs() version of Curl_if2ip() crashed when used on a Linux
system with a TEQL load-balancing device configured, which doesn't
have an address. Thanks to Adam Sampson for spotting this (bug #2234923).
Yang Tse (6 Nov 2008)
- Merged existing IPv4 and IPv6 Curl_ip2addr functions into a single one
which now also takes a protocol address family argument.
- Bug #2230535 (http://curl.haxx.se/bug/view.cgi?id=2230535) pointed out a
problem with MSVC 6 makefile that caused a build failure. It was noted that
the curl_addrinfo.obj reference was missing. I took the opportunity to sort
the list in which this was missing. Issue submitted by John Wilkinson.
Version 7.19.1 (5 November 2008)
Daniel Stenberg (4 Nov 2008)
@@ -176,7 +562,7 @@ Yang Tse (2 Oct 2008)
runtests.pl will now run with picky compiler warnings enabled unless
explicitly disabled.
Daniel Fandrich (1 Oct 2008)
- "make clean" now cleans out the docs and tests directories, too.
@@ -192,7 +578,7 @@ Daniel Stenberg (29 Sep 2008)
- Daniel Egger provided a patch that allows you to disable proxy support in
libcurl to somewhat reduce the size of the binary. Run configure
--disable-proxy.
Daniel Fandrich (29 Sep 2008)
- Moved all signal-based name resolution timeout handling into a single new
Curl_resolv_timeout function to reduce coupling.
@@ -204,7 +590,7 @@ Daniel Stenberg (29 Sep 2008)
- Maxim Ivanov filed bug report #2107803
(http://curl.haxx.se/bug/view.cgi?id=2107803) "no CURLINFO_REDIRECT_URL in
multi mode" together with a patch that fixed the problem.
Daniel Stenberg (25 Sep 2008)
- Emanuele Bovisio submitted bug report #2126435. We fixed the HTTP Digest
auth code to not behave badly when getting a blank realm with
@@ -876,7 +1262,7 @@ Daniel Stenberg (22 Jun 2008)
libcurl used Content-Range: instead of Range when doing a range request with
--head (CURLOPT_NOBODY). This is now fixed and test case 1032 was added to
verify.
Daniel Fandrich (21 Jun 2008)
- Stopped using ranges in scanf character sequences (e.g. %[a-z]) since that
is not ANSI C, just a common extension. This caused problems on
@@ -1017,7 +1403,7 @@ Daniel Stenberg (26 May 2008)
the new url was but a query string such as "Location: ?moo=foo". Test case
1031 was added to verify this fix.
- Andreas Faerber and Scott McCreary made (lib)curl build for the Haiku OS.
- Andreas Faerber and Scott McCreary made (lib)curl build for the Haiku OS.
Yang Tse (26 May 2008)
- David Rosenstrauch reported that header files spnegohelp.h and
@@ -1130,7 +1516,7 @@ Daniel Stenberg (26 Apr 2008)
bug #1944825 (http://curl.haxx.se/bug/view.cgi?id=1944825). I have not
personally approached the automake team about either one of these but I
figure we need a Solaris 10 guy to do it!
Yang Tse (25 Apr 2008)
- Added 'timeout' and 'delay' attributes support for the test harness
<command> subsection.
@@ -1181,7 +1567,7 @@ Michal Marek (7 Apr 2008)
- Fix the MIT / Heimdal check for good:
Define HAVE_GSSMIT if <gssapi/{gssapi.h,gssapi_generic.h,gssapi_krb5.h}> are
available, otherwise define HAVE_GSSHEIMDAL if <gssapi.h> is available.
Only define GSS_C_NT_HOSTBASED_SERVICE to gss_nt_service_name if
GSS_C_NT_HOSTBASED_SERVICE isn't declared by the gssapi headers. This should
avoid breakage in case we wrongly recognize Heimdal as MIT again.
@@ -1386,7 +1772,7 @@ Daniel S (20 Feb 2008)
Guenter Knauf (19 Feb 2008)
- We do no longer support SSLv2 by default since it has known flaws.
Kaspar Brand provided a patch for all supported SSL toolkits.
Daniel Fandrich (19 Feb 2008)
- Added test309 to test HTTP redirect to HTTPS URL
@@ -1409,7 +1795,7 @@ Daniel S (17 Feb 2008)
- Based on the same debugging logic, I've also made Curl_http_done() not
return CURLE_GOT_NOTHING if called "prematurely". This should have no real
effect to anything but the code makes more sense like this.
Daniel S (15 Feb 2008)
- Made the gnutls code path not even try to get the server cert if no peer
verification is requested. Previously it would even return failure if gnutls

View File

@@ -1,6 +1,6 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2008, Daniel Stenberg, <daniel@haxx.se>.
Copyright (c) 1996 - 2009, Daniel Stenberg, <daniel@haxx.se>.
All rights reserved.

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -25,7 +25,7 @@ AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = CHANGES COPYING maketgz reconf Makefile.dist curl-config.in \
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
curl-style.el sample.emacs RELEASE-NOTES buildconf buildconf.bat \
libcurl.pc.in vc6curl.dsw

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2009, 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
@@ -256,11 +256,18 @@ linux: all
linux-ssl: ssl
vc8:
@echo "generate VC8 makefiles"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/wsock32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8
# VC9 makefiles are for use with VS2008
vc9:
@echo "generate VC9 makefiles"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" lib/Makefile.vc6 > lib/Makefile.vc9
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/wsock32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" src/Makefile.vc6 > src/Makefile.vc9
ca-bundle: lib/mk-ca-bundle.pl
@echo "generate a fresh ca-bundle.crt"
@perl $< -b -l -u lib/ca-bundle.crt

View File

@@ -1,67 +1,67 @@
Curl and libcurl 7.19.1
Curl and libcurl 7.19.3
Public curl releases: 107
Public curl releases: 109
Command line options: 128
curl_easy_setopt() options: 158
Public functions in libcurl: 58
Known libcurl bindings: 37
Contributors: 672
Contributors: 683
This release includes the following changes:
o pkg-config can now show supported_protocols and supported_features
o Added CURLOPT_CERTINFO and CURLINFO_CERTINFO
o Added CURLOPT_POSTREDIR
o Better detect HTTP 1.0 servers and don't do HTTP 1.1 requests on them
o configure --disable-proxy disables proxy support
o Added CURLOPT_USERNAME and CURLOPT_PASSWORD
o --interface now works with IPv6 connections on glibc systems
o Added CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD
o CURLAUTH_DIGEST_IE bit added for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH
o VC9 Makefiles were added to the release package
This release includes the following bugfixes:
o MingW32 non-configure builds are now largefile feature enabled by default
o NetWare LIBC builds are now largefile feature enabled by default
o curl_easy_pause() could behave wrongly on unpause
o cookies with invalid expire dates are now considered expired
o HTTP pipelining over proxy
o fix regression in configure script which affected OpenSSL builds on MSYS
o GnuTLS-based multi interface doing HTTPS over proxy failed
o recv() failures cause CURLE_RECV_ERROR
o SFTP over SOCKS crash fixed
o thread-safety issues addressed for NSS-powered libcurls
o removed the use of mktime() and gmtime(_r)() in date parsing and conversions
o HTTP Digest with a blank realm did wrong
o CURLINFO_REDIRECT_URL didn't work with the multi interface
o CURLOPT_RANGE now works for SFTP downloads
o FTP SIZE response 550 now causes CURLE_REMOTE_FILE_NOT_FOUND
o CURLINFO_PRIMARY_IP fixed for persistent connection re-use cases
o remove_handle/add_handle multi interface timer callback flaw
o CURLINFO_REDIRECT_URL memory leak and wrong-doing
o case insensitive string matching works in Turkish too
o Solaris builds get _REENTRANT defined properly and work again
o Garbage sent on chunky upload after curl_easy_pause()
o ipv4 name resolves when libcurl is built with ipv6-enabled c-ares
o undersized IPv6 address internal buffer truncated long IPv6 addresses
o CURLINFO_FILETIME works for file:// transfers as well
o build failure when disabling FTP but enabling GSS
o fixed several calls to memory functions that didn't check return codes
o memory leak for SSL connects with libcurl/NSS when CURLOPT_ISSUERCERT was
used
o re-use of connections with the multi interface when multiple handles used
the same server
o memory leak with HTTP GSS/kerberos authentication
o removed the default use of "Pragma: no-cache"
o fix SCP/SFTP busyloop by using a new libssh2 1.0 function
o bad fclose() after a fatal error in cookie code
o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
o GSS authentication infinite loop problem
o 550 response from SIZE no longer treated as missing file
o ftps:// control connections now use explicit protection level
o dotted IPv6 addresses longer than 39 bytes failed
o curl_easy_duphandle() doesn't try to duplicate the connection cache pointer
o build failure on OS/400 when enabling IPv6
o better detection of SFTP failures
o improved connection re-use for subsequent SCP and SFTP transfers
o multi interface does less busy-loops for SCP and SFTP transfers with libssh2
1.0 or later
o curl_multi_timeout() no longer returns timeout 0 when there's still more
than 0 but less than 999 microseconds left
o the multi_socket API and HTTP pipelining now work a lot better when combined
o SFTP seek/resume beyond 32bit file sizes
o fixed breakage with --with-ssl --disable-verbose
o TTL "leak" in the DNS cache
o improved NSS initing
o curl_easy_reset now resets more options
o rare Location: follow bug with the multi interface
o the configure script can now detect gnutls with pkg-config
o curlbuild.h was adjusted for SunPro compilers
o CURLOPT_COOKIELIST set to "SESS" on an easy handle with no cookies data
o fixed timeouts for TFTP
o fixed PPC builds
This release includes the following known bugs:
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html)
Other curl-related news:
o
This release would not have looked like this without help, code, reports and
advice from friends like these:
Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev,
Linus Nielsen Feltzing, Martin Drasar, Stefan Krause, Dmitry Kurochkin,
Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden,
Jamie Lokier, Emanuele Bovisio, Maxim Ivanov, Ian Lynagh, Daniel Egger,
Igor Novoseltsev, John Wilkinson, Pascal Terjan, Steve Roskowski,
Daniel Johnson
Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski, Igor Novoseltsev,
Fred Machado, Ken Hirsch, Keshav Krity, Patrick Monnerat, Mark Karpeles,
Anthony Bryan, Peter Korsgaard, Phil Lisiecki, Bas Mevissen, Rob Crittenden,
Emil Romanus, Karl Moerder, Daniel Black, Stefan Teleman, Michael Wallner,
Grant Erickson, Tim Ansell, Andrew de los Reyes
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,18 +1,19 @@
To be addressed before 7.19.1 (planned release: November 2008)
=============================
To be addressed in 7.19.2 (planned release: January 2009)
To be addressed in 7.19.3 (planned release: January 2009)
=========================
188 - "Curl keep special character in filename when saving" bug #2192220
189 - "NTLM authentication and POST wrong behavior" bug #2203193
To be addressed in 7.19.4 (planned release: March 2009)
=========================
190 - "Using NTLM proxy will lose form-data. Makes NTLM unusable." bug #2210686
205 - A. Craig West's CURLOPT_NOPROXY option
191 - "proposed patch for curl/libssh2 bugfix"
http://curl.haxx.se/mail/archive-2008-10/0000.html
206 - A. Craig West's CURLOPT_HTTP_VERSION change for CONNECT
208 - Patch to allow GSSAPI authentication to a socks5 server
192 -
214 - progress bar prefix, second try (for the curl tool)
215 - Patch for Metalink Support (for the curl tool)
216 -

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2009, 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
@@ -1965,154 +1965,6 @@ AC_DEFUN([TYPE_SIG_ATOMIC_T], [
])
dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist
dnl four known different ways, with the one used almost everywhere being POSIX
dnl and XPG3, while the other different ways for different systems (old BSD,
dnl Windows and Amiga).
dnl
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
dnl O_NONBLOCK define is found but does not work. This condition is attempted
dnl to get caught in this script by using an excessive number of #ifdefs...
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
AC_MSG_CHECKING([non-blocking sockets style])
nonblock="unknown"
#
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for O_NONBLOCK test */
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
/* */
#if defined(sun) || defined(__sun__) || \
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# if defined(__SVR4) || defined(__srv4__)
# define PLATFORM_SOLARIS
# else
# define PLATFORM_SUNOS4
# endif
#endif
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# define PLATFORM_AIX_V3
#endif
/* */
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
#error "O_NONBLOCK does not work on this platform"
#endif
]],[[
/* O_NONBLOCK source test */
int socket;
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
]])
],[
dnl the O_NONBLOCK test was fine
nonblock="O_NONBLOCK"
AC_DEFINE(HAVE_O_NONBLOCK, 1,
[use O_NONBLOCK for non-blocking sockets])
])
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for FIONBIO test */
#include <unistd.h>
#include <stropts.h>
]],[[
/* FIONBIO source test (old-style unix) */
int socket;
int flags = ioctl(socket, FIONBIO, &flags);
]])
],[
dnl FIONBIO test was good
nonblock="FIONBIO"
AC_DEFINE(HAVE_FIONBIO, 1,
[use FIONBIO for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for ioctlsocket test (Windows) */
#undef inline
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#endif
#endif
]],[[
/* ioctlsocket source code (Windows) */
SOCKET sd;
unsigned long flags = 0;
sd = socket(0, 0, 0);
ioctlsocket(sd, FIONBIO, &flags);
]])
],[
dnl ioctlsocket test was good
nonblock="ioctlsocket"
AC_DEFINE(HAVE_IOCTLSOCKET, 1,
[use ioctlsocket() for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
/* headers for IoctlSocket test (Amiga?) */
#include <sys/ioctl.h>
]],[[
/* IoctlSocket source code (Amiga?) */
int socket;
int flags = IoctlSocket(socket, FIONBIO, (long)1);
]])
],[
dnl Ioctlsocket test was good
nonblock="IoctlSocket"
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1,
[use Ioctlsocket() for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for SO_NONBLOCK test (BeOS) */
#include <socket.h>
]],[[
/* SO_NONBLOCK source code (BeOS) */
long b = 1;
int socket;
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
]])
],[
dnl the SO_NONBLOCK test was good
nonblock="SO_NONBLOCK"
AC_DEFINE(HAVE_SO_NONBLOCK, 1,
[use SO_NONBLOCK for non-blocking sockets])
])
fi
#
AC_MSG_RESULT($nonblock)
#
if test "$nonblock" = "unknown"; then
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
[disabled non-blocking sockets])
AC_MSG_WARN([non-block sockets disabled])
fi
])
dnl TYPE_IN_ADDR_T
dnl -------------------------------------------------
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
@@ -2689,6 +2541,7 @@ dnl /etc/ssl/certs/ca-certificates.crt Debian systems
dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva
dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat
dnl /usr/local/share/certs/ca-root.crt FreeBSD
dnl /etc/ssl/cert.pem OpenBSD
dnl /etc/ssl/certs/ (ca path) SUSE
AC_DEFUN([CURL_CHECK_CA_BUNDLE], [
@@ -2751,6 +2604,7 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
/etc/pki/tls/certs/ca-bundle.crt \
/usr/share/ssl/certs/ca-bundle.crt \
/usr/local/share/certs/ca-root.crt \
/etc/ssl/cert.pem \
"$cac"; do
if test -f "$a"; then
ca="$a"
@@ -3203,3 +3057,36 @@ AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [
;;
esac
])
dnl CURL_CHECK_PKGCONFIG ($module)
dnl ------------------------
dnl search for the pkg-config tool (if not cross-compiling). Set the PKGCONFIG
dnl variable to hold the path to it, or 'no' if not found/present.
dnl
dnl If pkg-config is present, check that it has info about the $module or return
dnl "no" anyway!
dnl
AC_DEFUN([CURL_CHECK_PKGCONFIG], [
if test x$cross_compiling != xyes; then
dnl only do pkg-config magic when not cross-compiling
AC_PATH_PROG( PKGCONFIG, pkg-config, no, $PATH:/usr/bin:/usr/local/bin)
if test x$PKGCONFIG != xno; then
AC_MSG_CHECKING([for $1 options with pkg-config])
dnl ask pkg-config about $1
$PKGCONFIG --exists $1
if test "$?" -ne "0"; then
dnl pkg-config does not have info about the given module! set the
dnl variable to 'no'
PKGCONFIG="no"
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([found])
fi
fi
else
PKGCONFIG="no"
fi
])

View File

@@ -1,8 +1,83 @@
Changelog for the c-ares project
* January 14 2009 (Daniel Stenberg)
- ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it
now declares the private struct ares_in6_addr for all systems instead of
relying on one possibly not present in the system.
* January 13 2009 (Phil Blundell)
- ares__send_query() now varies the retry timeout pseudo-randomly to avoid
packet storms when several queries were started at the same time.
* January 11 2009 (Daniel Stenberg)
- Phil Blundell added the internal function ares__expand_name_for_response()
that is now used by the ares_parse_*_reply() functions instead of the
ares_expand_name() simply to easier return ARES_EBADRESP for the cases where
the name expansion fails as in responses that really isn't expected.
Version 1.6.0 (Dec 9, 2008)
* December 9 2008 (Gisle Vanem)
Fixes for Win32 targets using the Watt-32 tcp/ip stack.
* Dec 4 2008 (Daniel Stenberg)
Gregor Jasny provided the patch that introduces ares_set_socket_callback(),
and I edited it to also get duped by ares_dup().
* Dec 3 2008 (Daniel Stenberg)
API changes:
I made sure the public ares_config struct looks like before and yet it
supports the ROTATE option thanks to c-ares now storing the "optmask"
internally. Thus we should be ABI compatible with the past release(s)
now. My efforts mentioned below should not break backwards ABI compliance.
Here's how I suggest we proceed with the API:
ares_init() will be primary "channel creator" function.
ares_init_options() will continue to work exactly like now and before. For
starters, it will be the (only) way to set the existing options.
ares_save_options() will continue to work like today, but will ONLY save
options that you can set today (including ARES_OPT_ROTATE actually) but new
options that we add may not be saved with this.
Instead we introduce:
ares_dup() that instead can make a new channel and clone the config used
from an existing channel. It will then clone all config options, including
future new things we add.
ares_set_*() style functions that set (new) config options. As a start we
simply add these for new functionality, but over time we can also introduce
them for existing "struct ares_options" so that we can eventually deprecate
the two ares_*_options() functions.
ares_get_*() style functions for extracting info from a channel handle that
should be used instead of ares_save_options().
* Nov 26 2008 (Yang Tse)
- Brad Spencer provided changes to allow buildconf to work on OS X.
- Gerald Combs fixed a bug in ares_parse_ptr_reply() which would cause a
buffer to shrink instead of expand if a reply contained 8 or more records.
* Nov 25 2008 (Yang Tse)
- In preparation for the upcomming IPv6 nameservers patch, the internal
ares_addr union is now changed into an internal struct which also holds
the address family.
* Nov 19 2008 (Daniel Stenberg)
- Brad Spencer brought the new function ares_gethostbyname_file() which simply
resolves a host name from the given file, using the regular hosts syntax.
* Nov 1 2008 (Daniel Stenberg)
- Carlo Contavalli added support for the glibc "rotate" option, as documented
in man resolv.conf:
in man resolv.conf:
causes round robin selection of nameservers from among those listed. This
has the effect of spreading the query load among all listed servers, rather

View File

@@ -11,10 +11,10 @@ include ../packages/DOS/common.dj
include Makefile.inc
CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \
-DHAVE_PROCESS_H -DHAVE_ARPA_NAMESER_H -DHAVE_SYS_SOCKET_H \
-DHAVE_IOCTLSOCKET_FIONBIO -DHAVE_STRUCT_IN6_ADDR \
-DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -DHAVE_SYS_TIME_H \
-DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_ARPA_NAMESER_H -DHAVE_ARPA_INET_H -DHAVE_SYS_SOCKET_H \
-DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H -DHAVE_NETINET_TCP_H \
-DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND -DHAVE_GETTIMEOFDAY \
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
@@ -29,7 +29,7 @@ CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \
-DRECVFROM_TYPE_ARG6='int' -DRECVFROM_TYPE_RETV='int' \
-DRECVFROM_TYPE_ARG5='struct sockaddr' -DHAVE_RECVFROM \
-DRECVFROM_TYPE_ARG2_IS_VOID -DHAVE_STRDUP -DHAVE_NETDB_H \
-DHAVE_ARPA_INET_H -DHAVE_STRCASECMP -DHAVE_STRNCASECMP
-DHAVE_STRCASECMP -DHAVE_STRNCASECMP -DHAVE_GETHOSTNAME
LDFLAGS = -s

View File

@@ -18,5 +18,6 @@ MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \
ares_getsock.3 ares_parse_ns_reply.3 \
ares_destroy_options.3 ares_save_options.3
ares_getsock.3 ares_parse_ns_reply.3 ares_dup.3 \
ares_destroy_options.3 ares_save_options.3 ares_gethostbyname_file.3 \
ares_set_socket_callback.3

View File

@@ -323,6 +323,9 @@ else
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_FREEADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@
@@ -350,12 +353,14 @@ endif
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@
@echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@

View File

@@ -26,7 +26,7 @@ OBJ_DIR = VC6_obj
DEF_FILE = cares.def
!if "$(USE_WATT32)" == "1"
CFLAGS = $(CFLAGS) -UWIN32 -DWATT32 -I$(WATT_ROOT)\inc
CFLAGS = $(CFLAGS) -UWIN32 -DWATT32 -D_USE_32BIT_TIME_T -I$(WATT_ROOT)\inc
EX_LIBS = $(WATT_ROOT)\lib\wattcpvc_imp.lib
!else
@@ -124,9 +124,11 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
@echo ares_inet_net_pton >> $@
@echo ares_inet_ntop >> $@
@echo ares_inet_pton >> $@
@echo ares_writev >> $@
@echo ares_getnameinfo >> $@
@echo ares_parse_aaaa_reply >> $@
!if "$(USE_WATT32)" == "0"
@echo ares_writev >> $@
!endif
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)

View File

@@ -11,7 +11,7 @@ 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.
'ares' subdir of the curl CVS source repository.
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
@@ -22,4 +22,4 @@ original ares.
You'll find all c-ares details and news here:
http://daniel.haxx.se/projects/c-ares
http://c-ares.haxx.se/

View File

@@ -1,11 +1,17 @@
This is what's new and changed in the c-ares 1.5.4 release:
This is what's new and changed in the c-ares 1.6.1 release:
o improved configure detection of several functions
o improved source code portability
Changed:
o in6_addr is not used in ares.h anymore, but a private ares_in6_addr is instead
declared and used
Fixed:
o ares_parse_*_reply() functions now return ARES_EBADRESP instead of
ARES_EBADNAME if the name in the response failed to decode
Thanks go to these friendly people for their efforts and contributions:
and obviously Daniel Stenberg
Phil Blundell
Have fun!

View File

@@ -1433,154 +1433,6 @@ AC_DEFUN([TYPE_SIG_ATOMIC_T], [
])
dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist
dnl four known different ways, with the one used almost everywhere being POSIX
dnl and XPG3, while the other different ways for different systems (old BSD,
dnl Windows and Amiga).
dnl
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
dnl O_NONBLOCK define is found but does not work. This condition is attempted
dnl to get caught in this script by using an excessive number of #ifdefs...
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
AC_MSG_CHECKING([non-blocking sockets style])
nonblock="unknown"
#
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for O_NONBLOCK test */
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
/* */
#if defined(sun) || defined(__sun__) || \
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# if defined(__SVR4) || defined(__srv4__)
# define PLATFORM_SOLARIS
# else
# define PLATFORM_SUNOS4
# endif
#endif
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# define PLATFORM_AIX_V3
#endif
/* */
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
#error "O_NONBLOCK does not work on this platform"
#endif
]],[[
/* O_NONBLOCK source test */
int socket;
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
]])
],[
dnl the O_NONBLOCK test was fine
nonblock="O_NONBLOCK"
AC_DEFINE(HAVE_O_NONBLOCK, 1,
[use O_NONBLOCK for non-blocking sockets])
])
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for FIONBIO test */
#include <unistd.h>
#include <stropts.h>
]],[[
/* FIONBIO source test (old-style unix) */
int socket;
int flags = ioctl(socket, FIONBIO, &flags);
]])
],[
dnl FIONBIO test was good
nonblock="FIONBIO"
AC_DEFINE(HAVE_FIONBIO, 1,
[use FIONBIO for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for ioctlsocket test (Windows) */
#undef inline
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#endif
#endif
]],[[
/* ioctlsocket source code (Windows) */
SOCKET sd;
unsigned long flags = 0;
sd = socket(0, 0, 0);
ioctlsocket(sd, FIONBIO, &flags);
]])
],[
dnl ioctlsocket test was good
nonblock="ioctlsocket"
AC_DEFINE(HAVE_IOCTLSOCKET, 1,
[use ioctlsocket() for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
/* headers for IoctlSocket test (Amiga?) */
#include <sys/ioctl.h>
]],[[
/* IoctlSocket source code (Amiga?) */
int socket;
int flags = IoctlSocket(socket, FIONBIO, (long)1);
]])
],[
dnl Ioctlsocket test was good
nonblock="IoctlSocket"
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1,
[use Ioctlsocket() for non-blocking sockets])
])
fi
#
if test "$nonblock" = "unknown"; then
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
/* headers for SO_NONBLOCK test (BeOS) */
#include <socket.h>
]],[[
/* SO_NONBLOCK source code (BeOS) */
long b = 1;
int socket;
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
]])
],[
dnl the SO_NONBLOCK test was good
nonblock="SO_NONBLOCK"
AC_DEFINE(HAVE_SO_NONBLOCK, 1,
[use SO_NONBLOCK for non-blocking sockets])
])
fi
#
AC_MSG_RESULT($nonblock)
#
if test "$nonblock" = "unknown"; then
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
[disabled non-blocking sockets])
AC_MSG_WARN([non-block sockets disabled])
fi
])
dnl TYPE_IN_ADDR_T
dnl -------------------------------------------------
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()

View File

@@ -50,6 +50,7 @@
#if defined(WIN32) && !defined(WATT32)
#include <winsock.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>

View File

@@ -1,7 +1,7 @@
/* $Id$ */
/* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2007 by Daniel Stenberg
* Copyright (C) 2007-2009 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
@@ -29,10 +29,11 @@
#include <sys/types.h>
#if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
libc5-based Linux systems. Only include it on system that are known to
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
#include <sys/select.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
@@ -51,8 +52,8 @@
# include <winsock2.h>
# include <ws2tcpip.h>
#else
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#ifdef __cplusplus
@@ -180,12 +181,28 @@ typedef void (*ares_sock_state_cb)(void *data,
struct apattern;
/* NOTE about the ares_options struct to users and developers.
This struct will remain looking like this. It will not be extended nor
shrunk in future releases, but all new options will be set by ares_set_*()
options instead of with the ares_init_options() function.
Eventually (in a galaxy far far away), all options will be settable by
ares_set_*() options and the ares_init_options() function will become
deprecated.
When new options are added to c-ares, they are not added to this
struct. And they are not "saved" with the ares_save_options() function but
instead we encourage the use of the ares_dup() function. Needless to say,
if you add config options to c-ares you need to make sure ares_dup()
duplicates this new option.
*/
struct ares_options {
int flags;
int timeout; /* in seconds or milliseconds, depending on options */
int tries;
int ndots;
int rotate;
unsigned short udp_port;
unsigned short tcp_port;
int socket_send_buffer_size;
@@ -212,14 +229,21 @@ typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
struct hostent *hostent);
typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
char *node, char *service);
typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
int type, void *data);
int ares_init(ares_channel *channelptr);
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int optmask);
int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask);
int ares_save_options(ares_channel channel, struct ares_options *options,
int *optmask);
void ares_destroy_options(struct ares_options *options);
int ares_dup(ares_channel *dest, ares_channel src);
void ares_destroy(ares_channel channel);
void ares_cancel(ares_channel channel);
void ares_set_socket_callback(ares_channel channel,
ares_sock_create_callback callback,
void *user_data);
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,
@@ -228,6 +252,8 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
int type, ares_callback callback, void *arg);
void ares_gethostbyname(ares_channel channel, const char *name, int family,
ares_host_callback callback, void *arg);
int ares_gethostbyname_file(ares_channel channel, const char *name,
int family, struct hostent **host);
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
int family, ares_host_callback callback, void *arg);
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
@@ -249,21 +275,29 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf,
int alen, unsigned char **s, long *enclen);
#if !defined(HAVE_STRUCT_IN6_ADDR) && !defined(s6_addr)
struct in6_addr {
/*
* NOTE: before c-ares 1.6.1 we would most often use the system in6_addr
* struct below when ares itself was built, but many apps would use this
* private version since the header checked a HAVE_* define for it. Starting
* with 1.6.1 we always declare and use our own to stop relying on the
* system's one.
*/
struct ares_in6_addr {
union {
unsigned char _S6_u8[16];
} _S6_un;
};
#define s6_addr _S6_un._S6_u8
#endif
/*
* TODO: the structs 'addrttl' and 'addr6ttl' really should get their names
* prefixed with ares_ to keep them in our own "name space".
*/
struct addrttl {
struct in_addr ipaddr;
int ttl;
};
struct addr6ttl {
struct in6_addr ip6addr;
struct ares_in6_addr ip6addr;
int ttl;
};
@@ -278,12 +312,12 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
struct hostent **host,
struct addrttl *addrttls, int *naddrttls);
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
struct hostent **host,
struct addr6ttl *addrttls, int *naddrttls);
struct hostent **host,
struct addr6ttl *addrttls, int *naddrttls);
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
int addrlen, int family, struct hostent **host);
int ares_parse_ns_reply(const unsigned char *abuf, int alen,
struct hostent **host);
struct hostent **host);
void ares_free_string(void *str);
void ares_free_hostent(struct hostent *host);
const char *ares_strerror(int code);

43
ares/ares_dup.3 Normal file
View File

@@ -0,0 +1,43 @@
.\" $Id$
.\"
.\" Copyright (C) 2007-2008 by Daniel Stenberg
.\"
.\" 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_DUP 3 "2 Dec 2008"
.SH NAME
ares_dup \- Duplicate a resolver channel
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_dup(ares_channel *\fIchannel\fP, ares_channel \fIsource\fP)
.fi
.SH DESCRIPTION
The \fBares_dup(3)\fP function duplicates an existing communications channel
for name service lookups. If it returns successfully, \fBares_dup(3)\fP will
set the variable pointed to by \fIchannel\fP to a handle used to identify the
name service channel. The caller should invoke \fIares_destroy(3)\fP on the
handle when the channel is no longer needed.
The \fBares_dup_options\fP function also initializes a name service channel,
with additional options set exactly as the \fIsource\fP channel has them
configured.
.SH SEE ALSO
.BR ares_destroy(3),
.BR ares_init(3)
.SH AVAILABILITY
ares_dup(3) was added in c-ares 1.6.0
.SH AUTHOR
Daniel Stenberg

View File

@@ -17,6 +17,9 @@
#include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
@@ -174,3 +177,14 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf,
*/
return (n) ? n - 1 : n;
}
/* Like ares_expand_name but returns EBADRESP in case of invalid input. */
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
char **s, long *enclen)
{
int status = ares_expand_name(encoded, abuf, alen, s, enclen);
if (status == ARES_EBADNAME)
status = ARES_EBADRESP;
return status;
}

View File

@@ -17,6 +17,9 @@
#include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

View File

@@ -52,8 +52,7 @@
struct addr_query {
/* Arguments passed to ares_gethostbyaddr() */
ares_channel channel;
union ares_addr addr;
int family;
struct ares_addr addr;
ares_host_callback callback;
void *arg;
@@ -66,8 +65,8 @@ static void addr_callback(void *arg, int status, int timeouts,
unsigned char *abuf, int alen);
static void end_aquery(struct addr_query *aquery, int status,
struct hostent *host);
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
static void ptr_rr_name(char *name, int family, union ares_addr *addr);
static int file_lookup(struct ares_addr *addr, struct hostent **host);
static void ptr_rr_name(char *name, const struct ares_addr *addr);
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
int family, ares_host_callback callback, void *arg)
@@ -95,10 +94,10 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
}
aquery->channel = channel;
if (family == AF_INET)
memcpy(&aquery->addr.addr4, addr, sizeof(struct in_addr));
memcpy(&aquery->addr.addrV4, addr, sizeof(struct in_addr));
else
memcpy(&aquery->addr.addr6, addr, sizeof(struct in6_addr));
aquery->family = family;
memcpy(&aquery->addr.addrV6, addr, sizeof(struct in6_addr));
aquery->addr.family = family;
aquery->callback = callback;
aquery->arg = arg;
aquery->remaining_lookups = channel->lookups;
@@ -119,13 +118,13 @@ static void next_lookup(struct addr_query *aquery)
switch (*p)
{
case 'b':
ptr_rr_name(name, aquery->family, &aquery->addr);
ptr_rr_name(name, &aquery->addr);
aquery->remaining_lookups = p + 1;
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
aquery);
return;
case 'f':
status = file_lookup(&aquery->addr, aquery->family, &host);
status = file_lookup(&aquery->addr, &host);
/* this status check below previously checked for !ARES_ENOTFOUND,
but we should not assume that this single error code is the one
@@ -150,11 +149,11 @@ static void addr_callback(void *arg, int status, int timeouts,
aquery->timeouts += timeouts;
if (status == ARES_SUCCESS)
{
if (aquery->family == AF_INET)
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4,
if (aquery->addr.family == AF_INET)
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4,
sizeof(struct in_addr), AF_INET, &host);
else
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr6,
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV6,
sizeof(struct in6_addr), AF_INET6, &host);
end_aquery(aquery, status, host);
}
@@ -173,7 +172,7 @@ static void end_aquery(struct addr_query *aquery, int status,
free(aquery);
}
static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
static int file_lookup(struct ares_addr *addr, struct hostent **host)
{
FILE *fp;
int status;
@@ -226,21 +225,21 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
return ARES_EFILE;
}
}
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
while ((status = ares__get_hostent(fp, addr->family, host)) == ARES_SUCCESS)
{
if (family != (*host)->h_addrtype)
if (addr->family != (*host)->h_addrtype)
{
ares_free_hostent(*host);
continue;
}
if (family == AF_INET)
if (addr->family == AF_INET)
{
if (memcmp((*host)->h_addr, &addr->addr4, sizeof(struct in_addr)) == 0)
if (memcmp((*host)->h_addr, &addr->addrV4, sizeof(struct in_addr)) == 0)
break;
}
else if (family == AF_INET6)
else if (addr->family == AF_INET6)
{
if (memcmp((*host)->h_addr, &addr->addr6, sizeof(struct in6_addr)) == 0)
if (memcmp((*host)->h_addr, &addr->addrV6, sizeof(struct in6_addr)) == 0)
break;
}
ares_free_hostent(*host);
@@ -253,11 +252,11 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
return status;
}
static void ptr_rr_name(char *name, int family, union ares_addr *addr)
static void ptr_rr_name(char *name, const struct ares_addr *addr)
{
if (family == AF_INET)
if (addr->family == AF_INET)
{
unsigned long laddr = ntohl(addr->addr4.s_addr);
unsigned long laddr = ntohl(addr->addrV4.s_addr);
int a1 = (int)((laddr >> 24) & 0xff);
int a2 = (int)((laddr >> 16) & 0xff);
int a3 = (int)((laddr >> 8) & 0xff);
@@ -266,14 +265,17 @@ static void ptr_rr_name(char *name, int family, union ares_addr *addr)
}
else
{
unsigned char *bytes = (unsigned char *)&addr->addr6.s6_addr;
unsigned char *bytes = (unsigned char *)&addr->addrV6.s6_addr;
/* There are too many arguments to do this in one line using
* minimally C89-compliant compilers */
sprintf(name,
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.",
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4);
sprintf(name+strlen(name),
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,

View File

@@ -74,13 +74,13 @@ static void end_hquery(struct host_query *hquery, int status,
static int fake_hostent(const char *name, int family, ares_host_callback callback,
void *arg);
static int file_lookup(const char *name, int family, struct hostent **host);
static void sort_addresses(struct hostent *host, struct apattern *sortlist,
static void sort_addresses(struct hostent *host, const struct apattern *sortlist,
int nsort);
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
static void sort6_addresses(struct hostent *host, const struct apattern *sortlist,
int nsort);
static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist,
int nsort);
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
static int get6_address_index(const struct in6_addr *addr, const struct apattern *sortlist,
int nsort);
void ares_gethostbyname(ares_channel channel, const char *name, int family,
@@ -245,8 +245,8 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
numdots++;
}
}
/* if we don't have 3 dots, it is illegal
/* if we don't have 3 dots, it is illegal
* (although inet_addr doesn't think so).
*/
if (numdots != 3)
@@ -289,6 +289,33 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
return 1;
}
/* This is an API method */
int ares_gethostbyname_file(ares_channel channel, const char *name,
int family, struct hostent **host)
{
int result;
/* We only take the channel to ensure that ares_init() been called. */
if(channel == NULL)
{
/* Anything will do, really. This seems fine, and is consistent with
other error cases. */
*host = NULL;
return ARES_ENOTFOUND;
}
/* Just chain to the internal implementation we use here; it's exactly
* what we want.
*/
result = file_lookup(name, family, host);
if(result != ARES_SUCCESS)
{
/* We guarantee a NULL hostent on failure. */
*host = NULL;
}
return result;
}
static int file_lookup(const char *name, int family, struct hostent **host)
{
FILE *fp;
@@ -364,7 +391,7 @@ static int file_lookup(const char *name, int family, struct hostent **host)
return status;
}
static void sort_addresses(struct hostent *host, struct apattern *sortlist,
static void sort_addresses(struct hostent *host, const struct apattern *sortlist,
int nsort)
{
struct in_addr a1, a2;
@@ -394,7 +421,8 @@ static void sort_addresses(struct hostent *host, struct apattern *sortlist,
/* Find the first entry in sortlist which matches addr. Return nsort
* if none of them match.
*/
static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
static int get_address_index(const struct in_addr *addr,
const struct apattern *sortlist,
int nsort)
{
int i;
@@ -405,13 +433,13 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
continue;
if (sortlist[i].type == PATTERN_MASK)
{
if ((addr->s_addr & sortlist[i].mask.addr.addr4.s_addr)
== sortlist[i].addr.addr4.s_addr)
if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
== sortlist[i].addrV4.s_addr)
break;
}
else
{
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addr.addr4.s_addr,
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
sortlist[i].mask.bits))
break;
}
@@ -419,7 +447,7 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
return i;
}
static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
static void sort6_addresses(struct hostent *host, const struct apattern *sortlist,
int nsort)
{
struct in6_addr a1, a2;
@@ -449,8 +477,9 @@ static void sort6_addresses(struct hostent *host, struct apattern *sortlist,
/* Find the first entry in sortlist which matches addr. Return nsort
* if none of them match.
*/
static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
int nsort)
static int get6_address_index(const struct in6_addr *addr,
const struct apattern *sortlist,
int nsort)
{
int i;
@@ -458,7 +487,7 @@ static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
{
if (sortlist[i].family != AF_INET6)
continue;
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addr.addr6.s6_addr, sortlist[i].mask.bits))
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addrV6.s6_addr, sortlist[i].mask.bits))
break;
}
return i;

View File

@@ -0,0 +1,84 @@
.\" $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_GETHOSTBYNAME 3 "25 July 1998"
.SH NAME
ares_gethostbyname_file \- Lookup a name in the system's hosts file
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_gethostbyname_file(ares_channel \fIchannel\fP, const char *\fIname\fP,
.B int \fIfamily\fP, struct hostent **host)
.fi
.SH DESCRIPTION
The
.B ares_gethostbyname_file
function performs a host lookup by name against the system's hosts file (or equivalent local hostname database).
The
.IR channel
parameter is required, but no asynchronous queries are performed. Instead, the
lookup is done via the same mechanism used to perform 'f' lookups
(see the
.I lookups
options field in \fIares_init_options(3)\fP).
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.
.PP
The return value indicates whether the query succeeded and, if not, how it
failed. It may have any of the following values:
.TP 19
.B ARES_SUCCESS
The host lookup completed successfully and
.I host
now points to the result (and must be freed with \fIares_free_hostent(3)\fP).
.TP 19
.B ARES_ENOTFOUND
The hostname
.I name
was not found.
.TP 19
.B ARES_EFILE
There was a file I/O error while performing the lookup.
.TP 19
.B ARES_ENOMEM
Memory was exhausted.
.PP
On successful completion of the query, the pointer pointed to by
.I host
points to a
.B struct hostent
containing the address of the host returned by the lookup. The user must
free the memory pointed to by
.IR host
when finished with it by calling \fIares_free_hostent(3)\fP. If the lookup did
not complete successfully,
.I host
will be
.BR NULL .
.SH AVAILABILITY
Added in c-ares 1.5.4
.SH SEE ALSO
.BR ares_gethostbyname (3),
.BR ares_free_hostent (3),
.BR ares_init_options (3)
.SH AUTHOR
Brad Spencer
.br
Copyright 1998 by the Massachusetts Institute of Technology.

View File

@@ -225,6 +225,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, struct hosten
We do this by determining our own domain name, then searching the string
for this domain name and removing it.
*/
#ifdef HAVE_GETHOSTNAME
if (niquery->flags & ARES_NI_NOFQDN)
{
char buf[255];
@@ -237,6 +238,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, struct hosten
*end = 0;
}
}
#endif
niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name),
service);
return;

View File

@@ -33,6 +33,12 @@
int ares_getopt(int nargc, char * const nargv[], const char *ostr);
#if defined(WATT32)
#undef optarg
#undef optind
#undef opterr
#endif
extern char *optarg;
extern int optind;
extern int opterr;

View File

@@ -154,7 +154,7 @@ recursion for you. Recursion must be handled by the application calling ares
if \fIARES_FLAG_NORECURSE\fP is set.
.TP 23
.B ARES_FLAG_STAYOPEN
Do not close communciations sockets when the number of active queries
Do not close communications sockets when the number of active queries
drops to zero.
.TP 23
.B ARES_FLAG_NOSEARCH
@@ -185,7 +185,8 @@ A configuration file could not be read.
.B ARES_ENOMEM
The process's available memory was exhausted.
.SH SEE ALSO
.BR ares_destroy (3)
.BR ares_destroy(3),
.BR ares_dup(3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br

View File

@@ -159,6 +159,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->servers = NULL;
channel->sock_state_cb = NULL;
channel->sock_state_cb_data = NULL;
channel->sock_create_cb = NULL;
channel->sock_create_cb_data = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
@@ -179,7 +181,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
*/
if (status == ARES_SUCCESS) {
status = init_by_options(channel, options, optmask);
status = init_by_options(channel, options, optmask);
if (status != ARES_SUCCESS)
DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
ares_strerror(status)));
@@ -257,6 +259,40 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
return ARES_SUCCESS;
}
/* ares_dup() duplicates a channel handle with all its options and returns a
new channel handle */
int ares_dup(ares_channel *dest, ares_channel src)
{
struct ares_options opts;
int rc;
int optmask;
*dest = NULL; /* in case of failure return NULL explicitly */
/* First get the options supported by the old ares_save_options() function,
which is most of them */
rc = ares_save_options(src, &opts, &optmask);
if(rc)
return rc;
/* Then create the new channel with those options */
rc = ares_init_options(dest, &opts, optmask);
/* destroy the options copy to not leak any memory */
ares_destroy_options(&opts);
if(rc)
return rc;
/* Now clone the options that ares_save_options() doesn't support. */
(*dest)->sock_create_cb = src->sock_create_cb;
(*dest)->sock_create_cb_data = src->sock_create_cb_data;
return ARES_SUCCESS; /* everything went fine */
}
/* Save options from initialized channel */
int ares_save_options(ares_channel channel, struct ares_options *options,
int *optmask)
@@ -269,10 +305,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
if (!ARES_CONFIG_CHECK(channel))
return ARES_ENODATA;
/* Traditionally the optmask wasn't saved in the channel struct so it was
recreated here. ROTATE is the first option that has no struct field of
its own in the public config struct */
(*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
(channel->optmask & ARES_OPT_ROTATE);
/* Copy easy stuff */
options->flags = channel->flags;
@@ -355,7 +395,7 @@ static int init_by_options(ares_channel channel,
if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
channel->ndots = options->ndots;
if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
channel->rotate = options->rotate;
channel->rotate = 1;
if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
channel->udp_port = options->udp_port;
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
@@ -426,11 +466,14 @@ static int init_by_options(ares_channel channel,
return ARES_ENOMEM;
for (i = 0; i < options->nsort; i++)
{
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]), sizeof(struct apattern));
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
sizeof(struct apattern));
}
channel->nsort = options->nsort;
}
channel->optmask = optmask;
return ARES_SUCCESS;
}
@@ -966,7 +1009,9 @@ static int init_by_defaults(ares_channel channel)
*/
size_t len = 64;
int res;
channel->ndomains = 0; /* default to none */
#ifdef HAVE_GETHOSTNAME
hostname = malloc(len);
if(!hostname) {
rc = ARES_ENOMEM;
@@ -994,7 +1039,6 @@ static int init_by_defaults(ares_channel channel)
} while(0);
channel->ndomains = 0; /* default to none */
if (strchr(hostname, '.')) {
/* a dot was found */
@@ -1010,6 +1054,7 @@ static int init_by_defaults(ares_channel channel)
}
channel->ndomains = 1;
}
#endif
}
if (channel->nsort == -1) {
@@ -1179,8 +1224,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
/* Lets see if it is CIDR */
/* First we'll try IPv6 */
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
&pat.addr.addr6,
sizeof(pat.addr.addr6))) > 0)
&pat.addrV6,
sizeof(pat.addrV6))) > 0)
{
pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits;
@@ -1189,8 +1234,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_ENOMEM;
}
if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
sizeof(pat.addr.addr4))) > 0)
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
sizeof(pat.addrV4))) > 0)
{
pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits;
@@ -1199,13 +1244,13 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_ENOMEM;
}
/* See if it is just a regular IP */
else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
{
if (ipbufpfx[0])
{
memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = '\0';
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
natural_mask(&pat);
}
else
@@ -1420,17 +1465,17 @@ static void natural_mask(struct apattern *pat)
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
* but portable.
*/
addr.s_addr = ntohl(pat->addr.addr4.s_addr);
addr.s_addr = ntohl(pat->addrV4.s_addr);
/* This is out of date in the CIDR world, but some people might
* still rely on it.
*/
if (IN_CLASSA(addr.s_addr))
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSA_NET);
pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(addr.s_addr))
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
else
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
}
#endif
/* initialize an rc4 key. If possible a cryptographically secure random key
@@ -1503,9 +1548,17 @@ static int init_id_key(rc4_key* key,int key_data_len)
return ARES_SUCCESS;
}
short ares__generate_new_id(rc4_key* key)
unsigned short ares__generate_new_id(rc4_key* key)
{
short r=0;
unsigned short r=0;
ares__rc4(key, (unsigned char *)&r, sizeof(r));
return r;
}
void ares_set_socket_callback(ares_channel channel,
ares_sock_create_callback cb,
void *data)
{
channel->sock_create_cb = cb;
channel->sock_create_cb_data = data;
}

View File

@@ -17,6 +17,9 @@
#include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

View File

@@ -83,7 +83,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
status = ares_expand_name(aptr, abuf, alen, &hostname, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
@@ -95,7 +95,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
if (host)
{
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
/* Allocate addresses and aliases; ancount gives an upper bound for
both. */
addrs = malloc(ancount * sizeof(struct in_addr));
if (!addrs)
{
@@ -115,7 +116,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
addrs = NULL;
aliases = NULL;
}
naddrs = 0;
naliases = 0;
@@ -123,7 +124,7 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
if (status != ARES_SUCCESS)
break;
aptr += len;
@@ -176,7 +177,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen,
naliases++;
/* Decode the RR data and replace the hostname with it. */
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
free(hostname);

View File

@@ -84,7 +84,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
status = ares_expand_name(aptr, abuf, alen, &hostname, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
@@ -123,7 +123,7 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
if (status != ARES_SUCCESS)
break;
aptr += len;
@@ -176,7 +176,8 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
naliases++;
/* Decode the RR data and replace the hostname with it. */
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
free(hostname);

View File

@@ -73,7 +73,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
status = ares_expand_name( aptr, abuf, alen, &hostname, &len );
status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len);
if ( status != ARES_SUCCESS )
return status;
if ( aptr + len + QFIXEDSZ > abuf + alen )
@@ -96,7 +96,7 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
for ( i = 0; i < ( int ) ancount; i++ )
{
/* Decode the RR up to the data field. */
status = ares_expand_name( aptr, abuf, alen, &rr_name, &len );
status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len );
if ( status != ARES_SUCCESS )
break;
aptr += len;
@@ -113,7 +113,8 @@ int ares_parse_ns_reply( const unsigned char* abuf, int alen,
if ( rr_class == C_IN && rr_type == T_NS )
{
/* Decode the RR data and add it to the nameservers list */
status = ares_expand_name( aptr, abuf, alen, &rr_data, &len );
status = ares__expand_name_for_response( aptr, abuf, alen, &rr_data,
&len);
if ( status != ARES_SUCCESS )
{
break;

View File

@@ -55,6 +55,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
char *ptrname, *hostname, *rr_name, *rr_data;
struct hostent *hostent;
int aliascnt = 0;
int alias_alloc = 8;
char ** aliases;
/* Set *host to NULL for all failure cases. */
@@ -72,7 +73,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
/* Expand the name from the question, and skip past the question. */
aptr = abuf + HFIXEDSZ;
status = ares_expand_name(aptr, abuf, alen, &ptrname, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len);
if (status != ARES_SUCCESS)
return status;
if (aptr + len + QFIXEDSZ > abuf + alen)
@@ -84,7 +85,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
/* Examine each answer resource record (RR) in turn. */
hostname = NULL;
aliases = malloc(8 * sizeof(char *));
aliases = malloc(alias_alloc * sizeof(char *));
if (!aliases)
{
free(ptrname);
@@ -93,7 +94,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
for (i = 0; i < (int)ancount; i++)
{
/* Decode the RR up to the data field. */
status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
if (status != ARES_SUCCESS)
break;
aptr += len;
@@ -111,7 +112,8 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
&& strcasecmp(rr_name, ptrname) == 0)
{
/* Decode the RR data and set hostname to it. */
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
if (hostname)
@@ -125,14 +127,23 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
}
strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
aliascnt++;
if ((aliascnt%8)==0)
aliases = realloc(aliases, (aliascnt/16+1) * sizeof(char *));
if (aliascnt >= alias_alloc) {
char **ptr;
alias_alloc *= 2;
ptr = realloc(aliases, alias_alloc * sizeof(char *));
if(!ptr) {
status = ARES_ENOMEM;
break;
}
aliases = ptr;
}
}
if (rr_class == C_IN && rr_type == T_CNAME)
{
/* Decode the RR data and replace ptrname with it. */
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data,
&len);
if (status != ARES_SUCCESS)
break;
free(ptrname);

View File

@@ -115,6 +115,16 @@
# define writev(s,ptr,cnt) ares_writev(s,ptr,cnt)
#endif
struct ares_addr {
int family;
union {
struct in_addr addr4;
struct in6_addr addr6;
} addr;
};
#define addrV4 addr.addr4
#define addrV6 addr.addr6
struct query;
struct send_request {
@@ -213,17 +223,17 @@ struct query_server_info {
#define PATTERN_MASK 0x1
#define PATTERN_CIDR 0x2
union ares_addr {
struct in_addr addr4;
struct in6_addr addr6;
};
struct apattern {
union ares_addr addr;
union
{
union ares_addr addr;
unsigned short bits;
struct in_addr addr4;
struct in6_addr addr6;
} addr;
union
{
struct in_addr addr4;
struct in6_addr addr6;
unsigned short bits;
} mask;
int family;
unsigned short type;
@@ -253,6 +263,8 @@ struct ares_channeldata {
int nsort;
char *lookups;
int optmask; /* the option bitfield passed in at init time */
/* Server addresses and communications state */
struct server_state *servers;
int nservers;
@@ -284,6 +296,9 @@ struct ares_channeldata {
ares_sock_state_cb sock_state_cb;
void *sock_state_cb_data;
ares_sock_create_callback sock_create_cb;
void *sock_create_cb_data;
};
/* return true if now is exactly check time or later */
@@ -302,8 +317,11 @@ void ares__close_sockets(ares_channel channel, struct server_state *server);
int ares__get_hostent(FILE *fp, int family, struct hostent **host);
int ares__read_line(FILE *fp, char **buf, int *bufsize);
void ares__free_query(struct query *query);
short ares__generate_new_id(rc4_key* key);
unsigned short ares__generate_new_id(rc4_key* key);
struct timeval ares__tvnow(void);
int ares__expand_name_for_response(const unsigned char *encoded,
const unsigned char *abuf, int alen,
char **s, long *enclen);
#if 0 /* Not used */
long ares__tvdiff(struct timeval t1, struct timeval t2);
#endif

View File

@@ -715,6 +715,7 @@ void ares__send_query(ares_channel channel, struct query *query,
{
struct send_request *sendreq;
struct server_state *server;
int timeplus;
server = &channel->servers[query->server];
if (query->using_tcp)
@@ -778,9 +779,11 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
timeplus = channel->timeout << (query->try / channel->nservers);
timeplus = (timeplus * (9 + (rand () & 7))) / 16;
query->timeout = *now;
ares__timeadd(&query->timeout,
channel->timeout << (query->try / channel->nservers));
timeplus);
/* Keep track of queries bucketed by timeout, so we can process
* timeout events quickly.
*/
@@ -805,68 +808,51 @@ void ares__send_query(ares_channel channel, struct query *query,
static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */)
{
#undef SETBLOCK
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
#if defined(USE_BLOCKING_SOCKETS)
return 0; /* returns success */
#elif defined(HAVE_FCNTL_O_NONBLOCK)
/* most recent unix versions */
int flags;
flags = fcntl(sockfd, F_GETFL, 0);
if (FALSE != nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
#undef SETBLOCK
#define SETBLOCK 1
#endif
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
#elif defined(HAVE_IOCTL_FIONBIO)
/* older unix versions */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
#ifdef WATT32
char flags;
#else
/* Windows? */
/* Windows */
unsigned long flags;
#endif
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
/* presumably for Amiga */
#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
/* Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING
return 0; /* returns success */
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#else
# error "no non-blocking method was found/used/set"
#endif
}
@@ -914,6 +900,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
return -1;
}
#ifdef TCP_NODELAY
/*
* Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in
* configure_socket). In general, in DNS lookups we're pretty much interested
@@ -927,6 +914,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
closesocket(s);
return -1;
}
#endif
/* Connect to the server. */
memset(&sockin, 0, sizeof(sockin));
@@ -944,6 +932,17 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
}
}
if (channel->sock_create_cb)
{
int err = channel->sock_create_cb(s, SOCK_STREAM,
channel->sock_create_cb_data);
if (err < 0)
{
closesocket(s);
return err;
}
}
SOCK_STATE_CALLBACK(channel, s, 1, 0);
server->tcp_buffer_pos = 0;
server->tcp_socket = s;
@@ -984,6 +983,17 @@ static int open_udp_socket(ares_channel channel, struct server_state *server)
}
}
if (channel->sock_create_cb)
{
int err = channel->sock_create_cb(s, SOCK_DGRAM,
channel->sock_create_cb_data);
if (err < 0)
{
closesocket(s);
return err;
}
}
SOCK_STATE_CALLBACK(channel, s, 1, 0);
server->udp_socket = s;

View File

@@ -17,6 +17,9 @@
#include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
@@ -67,7 +70,7 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
key->y = y;
}
static struct query* find_query_by_id(ares_channel channel, int id)
static struct query* find_query_by_id(ares_channel channel, unsigned short id)
{
unsigned short qid;
struct list_node* list_head;
@@ -92,15 +95,15 @@ static struct query* find_query_by_id(ares_channel channel, int id)
performed per id generation. In practice this search should happen only
once per newly generated id
*/
static int generate_unique_id(ares_channel channel)
static unsigned short generate_unique_id(ares_channel channel)
{
int id;
unsigned short id;
do {
id = ares__generate_new_id(&channel->id_key);
} while (find_query_by_id(channel,id));
id = ares__generate_new_id(&channel->id_key);
} while (find_query_by_id(channel, id));
return id;
return (unsigned short)id;
}
void ares_query(ares_channel channel, const char *name, int dnsclass,

View File

@@ -24,9 +24,7 @@ ares_save_options \- Save configuration values obtained from initialized ares_ch
.B void ares_save_options(ares_channel \fIchannel\fP, struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
.fi
.SH DESCRIPTION
The
.B ares_save_options
function saves the channel data identified by
The \fBares_save_options(3)\fP function saves the channel data identified by
.IR channel ,
into the options struct identified by
.IR options ,
@@ -38,11 +36,18 @@ The resultant options and optmask are then able to be
passed directly to ares_init_options. When the options
are no longer needed, ares_destroy_options should be called
to free any associated memory.
.SH NOTE
Since c-ares 1.6.0 the ares_options struct has been "locked" meaning that it
won't be extended to cover new funtions. This function will remain
functioning, but it can only return config data that can be represented in
this config struct, which may no longer be the complete set of config
options. \fBares_dup(3)\fP will not have that restriction.
.SH SEE ALSO
.BR ares_destroy_options (3),
.BR ares_init_options (3)
.BR ares_init_options (3),
.BR ares_dup (3)
.SH AVAILABILITY
ares_save_options(3) was added in c-ares 1.4.0
.SH AUTHOR
Brad House
.br

View File

@@ -60,7 +60,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
char *s;
const char *p;
int status, ndots;
/* If name only yields one domain to search, then we don't have
* to keep extra state, so just do an ares_query().
*/
@@ -148,7 +148,7 @@ static void search_callback(void *arg, int status, int timeouts,
struct search_query *squery = (struct search_query *) arg;
ares_channel channel = squery->channel;
char *s;
squery->timeouts += timeouts;
/* Stop searching unless we got a non-fatal error. */
@@ -161,7 +161,7 @@ static void search_callback(void *arg, int status, int timeouts,
if (squery->trying_as_is)
squery->status_as_is = status;
/*
/*
* If we ever get ARES_ENODATA along the way, record that; if the search
* should run to the very end and we got at least one ARES_ENODATA,
* then callers like ares_gethostbyname() may want to try a T_A search
@@ -290,10 +290,10 @@ static int single_domain(ares_channel channel, const char *name, char **s)
if (status != ARES_SUCCESS)
return status;
}
else
else
{
error = ERRNO;
switch(error)
error = errno;
switch(error)
{
case ENOENT:
case ESRCH:
@@ -301,7 +301,7 @@ static int single_domain(ares_channel channel, const char *name, char **s)
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n",
DEBUGF(fprintf(stderr, "Error opening file: %s\n",
hostaliases));
*s = NULL;
return ARES_EFILE;

View File

@@ -17,6 +17,9 @@
#include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

View File

@@ -0,0 +1,24 @@
.\" $Id$
.\"
.TH ARES_SET_SOCKET_CALLBACK 3 "2 Dec 2008"
.SH NAME
ares_set_socket_callback \- Set a socket creation callback
.SH SYNOPSIS
.nf
int ares_set_socket_callback(ares_channel \fIchannel\fP,
ares_sock_create_callback \fIcallback\fP,
void *\fIuserdata\fP)
.fi
.SH DESCRIPTION
This function sets a \fIcallback\fP in the given ares channel handle. This
callback function will be invoked after the socket has been created, and
connected to the remote server. The callback must return ARES_SUCCESS if
things are fine, or use the standard ares error codes to signal errors
back. Returned errors will abort the ares operation.
.SH SEE ALSO
.BR ares_init_options (3)
.SH AVAILABILITY
ares_set_socket_callback(3) was added in c-ares 1.6.0
.SH AUTHOR
Gregor Jasny

View File

@@ -4,12 +4,12 @@
#define ARES__VERSION_H
#define ARES_VERSION_MAJOR 1
#define ARES_VERSION_MINOR 5
#define ARES_VERSION_PATCH 4
#define ARES_VERSION_MINOR 6
#define ARES_VERSION_PATCH 1
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
#define ARES_VERSION_STR "1.5.4-CVS"
#define ARES_VERSION_STR "1.6.1-CVS"
#ifdef __cplusplus
extern "C" {

View File

@@ -1,6 +1,44 @@
#!/bin/sh
${LIBTOOLIZE:-libtoolize} --copy --automake --force
# The logic for finding the right libtoolize is taken from libcurl's buildconf
#--------------------------------------------------------------------------
# findtool works as 'which' but we use a different name to make it more
# obvious we aren't using 'which'! ;-)
#
findtool(){
file="$1"
old_IFS=$IFS; IFS=':'
for path in $PATH
do
IFS=$old_IFS
# echo "checks for $file in $path" >&2
if test -f "$path/$file"; then
echo "$path/$file"
return
fi
done
IFS=$old_IFS
}
# this approach that tries 'glibtool' first is some kind of work-around for
# some BSD-systems I believe that use to provide the GNU libtool named
# glibtool, with 'libtool' being something completely different.
libtool=`findtool glibtool 2>/dev/null`
if test ! -x "$libtool"; then
libtool=`findtool ${LIBTOOL:-libtool}`
fi
if test -z "$LIBTOOLIZE"; then
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
# $libtool is already the full path
libtoolize="${libtool}ize"
else
libtoolize=`findtool $LIBTOOLIZE`
fi
${libtoolize} --copy --automake --force
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
${AUTOHEADER:-autoheader}
${AUTOCONF:-autoconf}

View File

@@ -76,9 +76,12 @@
/* FUNCTIONS */
/* ---------------------------------------------------------------- */
/* Define if you have the ioctlsocket function. */
/* Define if you have the ioctlsocket function. */
#define HAVE_IOCTLSOCKET 1
/* Define if you have a working ioctlsocket FIONBIO function. */
#define HAVE_IOCTLSOCKET_FIONBIO 1
/* Define if you have the strcasecmp function. */
/* #define HAVE_STRCASECMP 1 */
@@ -94,6 +97,9 @@
/* Define if you have the strnicmp function. */
#define HAVE_STRNICMP 1
/* Define if you have the gethostname function. */
#define HAVE_GETHOSTNAME 1
/* Define if you have the recv function. */
#define HAVE_RECV 1
@@ -162,6 +168,15 @@
#define SOCKET int
#define NS_INADDRSZ 4
#define HAVE_ARPA_NAMESER_H 1
#define HAVE_ARPA_INET_H 1
#define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_NETINET_TCP_H 1
#define HAVE_AF_INET6 1
#define HAVE_PF_INET6 1
#define HAVE_STRUCT_IN6_ADDR 1
#define HAVE_STRUCT_SOCKADDR_IN6 1
#undef HAVE_WINSOCK_H
#undef HAVE_WINSOCK2_H
#undef HAVE_WS2TCPIP_H

View File

@@ -4,6 +4,8 @@ dnl Version not hardcoded here. Fetched later from ares_version.h
AC_INIT([c-ares], [-],
[c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares])
CARES_OVERRIDE_AUTOCONF
AC_CONFIG_SRCDIR([ares_ipv6.h])
AM_CONFIG_HEADER([config.h])
AM_MAINTAINER_MODE
@@ -12,6 +14,8 @@ CARES_CHECK_OPTION_DEBUG
CARES_CHECK_OPTION_OPTIMIZE
CARES_CHECK_OPTION_WARNINGS
CARES_CHECK_PATH_SEPARATOR
dnl SED is mandatory for configure process and libtool.
dnl Set it now, allowing it to be changed later.
AC_PATH_PROG([SED], [sed], [not_found],
@@ -95,22 +99,6 @@ CARES_PROCESS_DEBUG_BUILD_OPTS
AM_CONDITIONAL(DEBUGBUILD, test x$want_debug = xyes)
AM_CONDITIONAL(CURLDEBUG, test x$want_debug = xyes)
dnl skip libtool C++ and Fortran compiler checks
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
m4_defun([AC_PROG_CXX],[])
m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])])
m4_defun([AC_PROG_CXXCPP],[true])
m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])])
m4_defun([AC_PROG_F77],[])
dnl skip libtool C++ and Fortran linker checks
m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])])
m4_defun([AC_LIBTOOL_CXX],[])
m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])])
m4_defun([AC_LIBTOOL_CXXCPP],[true])
m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])])
m4_defun([AC_LIBTOOL_F77],[])
dnl force libtool to build static libraries with PIC on AMD64-Linux & FreeBSD
AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
case $host in
@@ -342,9 +330,7 @@ then
fi
if test "$HAVE_GETHOSTBYNAME" = "1"; then
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
else
if test "$HAVE_GETHOSTBYNAME" != "1"; then
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
fi
@@ -553,12 +539,19 @@ CURL_CHECK_FUNC_RECVFROM
CURL_CHECK_FUNC_SEND
CURL_CHECK_MSG_NOSIGNAL
CARES_CHECK_FUNC_FCNTL
CARES_CHECK_FUNC_FREEADDRINFO
CARES_CHECK_FUNC_GETADDRINFO
CARES_CHECK_FUNC_GETHOSTBYADDR
CARES_CHECK_FUNC_GETHOSTBYNAME
CARES_CHECK_FUNC_GETHOSTNAME
CARES_CHECK_FUNC_GETSERVBYPORT_R
CARES_CHECK_FUNC_INET_NTOP
CARES_CHECK_FUNC_INET_PTON
CARES_CHECK_FUNC_IOCTL
CARES_CHECK_FUNC_IOCTLSOCKET
CARES_CHECK_FUNC_IOCTLSOCKET_CAMEL
CARES_CHECK_FUNC_SETSOCKOPT
CARES_CHECK_FUNC_STRCASECMP
CARES_CHECK_FUNC_STRCMPI
CARES_CHECK_FUNC_STRDUP
@@ -851,8 +844,6 @@ dnl and get the types of five of its arguments.
CURL_CHECK_FUNC_GETNAMEINFO
CURL_CHECK_NONBLOCKING_SOCKET
AC_C_BIGENDIAN(
[AC_DEFINE(ARES_BIG_ENDIAN, 1,
[define this if ares is built for a big endian system])],
@@ -883,6 +874,9 @@ if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
[a suitable file/device to read random data from])
fi
CARES_CHECK_OPTION_NONBLOCKING
CARES_CHECK_NONBLOCKING_SOCKET
CARES_PRIVATE_LIBS="$LIBS"
AC_SUBST(CARES_PRIVATE_LIBS)

View File

@@ -16,7 +16,7 @@
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
# serial 45
# serial 46
dnl CARES_CHECK_COMPILER
@@ -875,6 +875,13 @@ AC_DEFUN([CARES_SET_COMPILER_WARNING_OPTS], [
tmp_CFLAGS="$tmp_CFLAGS -Wdeclaration-after-statement"
fi
#
dnl Only gcc 4.3 or later
if test "$compiler_num" -ge "403"; then
tmp_CFLAGS="$tmp_CFLAGS -Wtype-limits -Wold-style-declaration"
tmp_CFLAGS="$tmp_CFLAGS -Wmissing-parameter-type -Wempty-body"
tmp_CFLAGS="$tmp_CFLAGS -Wclobbered -Wignored-qualifiers"
fi
#
fi
#
dnl Do not issue warnings for code in system include paths.

View File

@@ -16,7 +16,7 @@
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
# serial 2
# serial 3
dnl CARES_CHECK_OPTION_DEBUG
@@ -52,6 +52,38 @@ AC_HELP_STRING([--disable-debug],[Disable debug build options]),
])
dnl CARES_CHECK_OPTION_NONBLOCKING
dnl -------------------------------------------------
dnl Verify if configure has been invoked with option
dnl --enable-nonblocking or --disable-nonblocking, and
dnl set shell variable want_nonblocking as appropriate.
AC_DEFUN([CARES_CHECK_OPTION_NONBLOCKING], [
AC_BEFORE([$0],[CARES_CHECK_NONBLOCKING_SOCKET])dnl
AC_MSG_CHECKING([whether to enable non-blocking communications])
OPT_NONBLOCKING="default"
AC_ARG_ENABLE(nonblocking,
AC_HELP_STRING([--enable-nonblocking],[Enable non-blocking communications])
AC_HELP_STRING([--disable-nonblocking],[Disable non-blocking communications]),
OPT_NONBLOCKING=$enableval)
case "$OPT_NONBLOCKING" in
no)
dnl --disable-nonblocking option used
want_nonblocking="no"
;;
default)
dnl configure option not specified
want_nonblocking="yes"
;;
*)
dnl --enable-nonblocking option used
want_nonblocking="yes"
;;
esac
AC_MSG_RESULT([$want_nonblocking])
])
dnl CARES_CHECK_OPTION_OPTIMIZE
dnl -------------------------------------------------
dnl Verify if configure has been invoked with option
@@ -140,3 +172,43 @@ AC_HELP_STRING([--disable-warnings],[Disable strict compiler warnings]),
esac
AC_MSG_RESULT([$want_warnings])
])
dnl CARES_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket into non-blocking state.
AC_DEFUN([CARES_CHECK_NONBLOCKING_SOCKET], [
AC_REQUIRE([CARES_CHECK_OPTION_NONBLOCKING])dnl
AC_REQUIRE([CARES_CHECK_FUNC_FCNTL])dnl
AC_REQUIRE([CARES_CHECK_FUNC_IOCTL])dnl
AC_REQUIRE([CARES_CHECK_FUNC_IOCTLSOCKET])dnl
AC_REQUIRE([CARES_CHECK_FUNC_IOCTLSOCKET_CAMEL])dnl
AC_REQUIRE([CARES_CHECK_FUNC_SETSOCKOPT])dnl
#
tst_method="unknown"
if test "$want_nonblocking" = "yes"; then
AC_MSG_CHECKING([how to set a socket into non-blocking mode])
if test "x$ac_cv_func_fcntl_o_nonblock" = "xyes"; then
tst_method="fcntl O_NONBLOCK"
elif test "x$ac_cv_func_ioctl_fionbio" = "xyes"; then
tst_method="ioctl FIONBIO"
elif test "x$ac_cv_func_ioctlsocket_fionbio" = "xyes"; then
tst_method="ioctlsocket FIONBIO"
elif test "x$ac_cv_func_ioctlsocket_camel_fionbio" = "xyes"; then
tst_method="IoctlSocket FIONBIO"
elif test "x$ac_cv_func_setsockopt_so_nonblock" = "xyes"; then
tst_method="setsockopt SO_NONBLOCK"
fi
AC_MSG_RESULT([$tst_method])
if test "$tst_method" = "unknown"; then
AC_MSG_WARN([cannot determine non-blocking socket method.])
fi
fi
if test "$tst_method" = "unknown"; then
AC_DEFINE_UNQUOTED(USE_BLOCKING_SOCKETS, 1,
[Define to disable non-blocking sockets.])
AC_MSG_WARN([non-blocking sockets disabled.])
fi
])

File diff suppressed because it is too large Load Diff

103
ares/m4/cares-override.m4 Normal file
View File

@@ -0,0 +1,103 @@
#***************************************************************************
# $Id$
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
# serial 2
dnl CARES_OVERRIDE_AUTOCONF
dnl -------------------------------------------------
dnl Placing a call to this macro in configure.ac after
dnl the one to AC_INIT will make macros in this file
dnl visible to the rest of the compilation overriding
dnl those from Autoconf.
AC_DEFUN([CARES_OVERRIDE_AUTOCONF], [
AC_BEFORE([$0],[AC_PROG_LIBTOOL])
# using cares-override.m4
])
dnl Override some Libtool tests
dnl -------------------------------------------------
dnl This is done to prevent Libtool 1.5.X from doing
dnl unnecesary C++, Fortran and Java tests and reduce
dnl resulting configure script by nearly 300 Kb.
m4_define([AC_LIBTOOL_LANG_CXX_CONFIG],[:])
m4_define([AC_LIBTOOL_LANG_F77_CONFIG],[:])
m4_define([AC_LIBTOOL_LANG_GCJ_CONFIG],[:])
dnl Override Autoconf's AC_LANG_PROGRAM (C)
dnl -------------------------------------------------
dnl This is done to prevent compiler warning
dnl 'function declaration isn't a prototype'
dnl in function main. This requires at least
dnl a c89 compiler and does not suport K&R.
m4_define([AC_LANG_PROGRAM(C)],
[$1
int main (void)
{
$2
;
return 0;
}])
dnl Override Autoconf's AC_LANG_CALL (C)
dnl -------------------------------------------------
dnl This is a backport of Autoconf's 2.60 with the
dnl embedded comments that hit the resulting script
dnl removed. This is done to reduce configure size
dnl and use fixed macro across Autoconf versions.
m4_define([AC_LANG_CALL(C)],
[AC_LANG_PROGRAM([$1
m4_if([$2], [main], ,
[
#ifdef __cplusplus
extern "C"
#endif
char $2 ();])], [return $2 ();])])
dnl Override Autoconf's AC_LANG_FUNC_LINK_TRY (C)
dnl -------------------------------------------------
dnl This is a backport of Autoconf's 2.60 with the
dnl embedded comments that hit the resulting script
dnl removed. This is done to reduce configure size
dnl and use fixed macro across Autoconf versions.
m4_define([AC_LANG_FUNC_LINK_TRY(C)],
[AC_LANG_PROGRAM(
[
#define $1 innocuous_$1
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $1
#ifdef __cplusplus
extern "C"
#endif
char $1 ();
#if defined __stub_$1 || defined __stub___$1
choke me
#endif
], [return $1 ();])])
dnl Override Autoconf's PATH_SEPARATOR check
dnl -------------------------------------------------
dnl This is done to ensure that the same check is
dnl used across different Autoconf versions and to
dnl allow us to use this macro early enough in the
dnl configure script.
m4_define([_AS_PATH_SEPARATOR_PREPARE],
[CARES_CHECK_PATH_SEPARATOR
m4_define([$0],[])])
m4_define([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
[CARES_CHECK_PATH_SEPARATOR
m4_define([$0],[])])

74
ares/m4/cares-system.m4 Normal file
View File

@@ -0,0 +1,74 @@
#***************************************************************************
# $Id$
#
# Copyright (C) 2008 by Daniel Stenberg et al
#
# 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.
#
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
# serial 2
dnl CARES_CHECK_PATH_SEPARATOR
dnl -------------------------------------------------
dnl Check and compute the path separator for us. This
dnl path separator is the symbol used to diferentiate
dnl or separate paths inside the PATH environment var.
AC_DEFUN([CARES_CHECK_PATH_SEPARATOR], [
if test -z "$cares_cv_PATH_SEPARATOR"; then
if test -z "$PATH"; then
AC_MSG_ERROR([PATH not set. Cannot continue without PATH being set.])
fi
dnl Directory count in PATH when using a colon separator.
tst_dirs_col=0
tst_save_IFS=$IFS; IFS=':'
for tst_dir in $PATH; do
IFS=$tst_save_IFS
test -d "$tst_dir" && tst_dirs_col=`expr $tst_dirs_col + 1`
done
IFS=$tst_save_IFS
dnl Directory count in PATH when using a semicolon separator.
tst_dirs_sem=0
tst_save_IFS=$IFS; IFS=';'
for tst_dir in $PATH; do
IFS=$tst_save_IFS
test -d "$tst_dir" && tst_dirs_sem=`expr $tst_dirs_sem + 1`
done
IFS=$tst_save_IFS
if test $tst_dirs_sem -eq $tst_dirs_col; then
dnl When both counting methods give the same result we do not want to
dnl chose one over the other, and consider auto-detection not possible.
if test -z "$PATH_SEPARATOR"; then
dnl Stop dead until user provides PATH_SEPARATOR definition.
AC_MSG_ERROR([PATH_SEPARATOR not set. Cannot continue without it.])
fi
else
dnl Separator with the greater directory count is the auto-detected one.
if test $tst_dirs_sem -gt $tst_dirs_col; then
tst_auto_separator=';'
else
tst_auto_separator=':'
fi
if test -z "$PATH_SEPARATOR"; then
dnl Simply use the auto-detected one when not already set.
PATH_SEPARATOR="$tst_auto_separator"
fi
fi
cares_cv_PATH_SEPARATOR="$PATH_SEPARATOR"
fi
AC_SUBST([PATH_SEPARATOR])
AC_SUBST([PATH])
])

View File

@@ -107,6 +107,18 @@
#define ssize_t int
#endif
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
#define HAVE_SYS_TIME_H
#endif
#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
#define HAVE_UNISTD_H 1
#endif
#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
#define HAVE_SYS_UIO_H
#endif
#endif /* HAVE_CONFIG_H */
/*
@@ -123,22 +135,6 @@
#undef VERSION
#undef PACKAGE
/*
* Assume a few thing unless they're set by configure
*/
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
#define HAVE_SYS_TIME_H
#endif
#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
#define HAVE_UNISTD_H 1
#endif
#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
#define HAVE_SYS_UIO_H
#endif
/* IPv6 compatibility */
#if !defined(HAVE_AF_INET6)
#if defined(HAVE_PF_INET6)

View File

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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2009, 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
@@ -27,6 +27,8 @@ AC_PREREQ(2.57)
dnl We don't know the version number "statically" so we use a dash here
AC_INIT([curl], [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
CURL_OVERRIDE_AUTOCONF
dnl configure script copyright
AC_COPYRIGHT([Copyright (c) 1998 - 2008 Daniel Stenberg, <daniel@haxx.se>
This configure script may be copied, distributed and modified under the
@@ -40,6 +42,8 @@ CURL_CHECK_OPTION_DEBUG
CURL_CHECK_OPTION_OPTIMIZE
CURL_CHECK_OPTION_WARNINGS
CURL_CHECK_PATH_SEPARATOR
dnl SED is mandatory for configure process and libtool.
dnl Set it now, allowing it to be changed later.
AC_PATH_PROG([SED], [sed], [not_found],
@@ -153,22 +157,6 @@ AC_LIBTOOL_WIN32_DLL
CURL_PROCESS_DEBUG_BUILD_OPTS
dnl skip libtool C++ and Fortran compiler checks
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
m4_defun([AC_PROG_CXX],[])
m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])])
m4_defun([AC_PROG_CXXCPP],[true])
m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])])
m4_defun([AC_PROG_F77],[])
dnl skip libtool C++ and Fortran linker checks
m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])])
m4_defun([AC_LIBTOOL_CXX],[])
m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])])
m4_defun([AC_LIBTOOL_CXXCPP],[true])
m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])])
m4_defun([AC_LIBTOOL_F77],[])
dnl force libtool to build static libraries with PIC on AMD64-Linux & FreeBSD
AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
case $host in
@@ -658,9 +646,7 @@ then
fi
if test "$HAVE_GETHOSTBYNAME" = "1"; then
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
else
if test "$HAVE_GETHOSTBYNAME" != "1"; then
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
fi
@@ -832,24 +818,20 @@ if test "$ipv6" = "yes"; then
curl_ipv6_msg="enabled"
fi
dnl **********************************************************************
dnl Check how non-blocking sockets are set
dnl **********************************************************************
AC_ARG_ENABLE(nonblocking,
AC_HELP_STRING([--enable-nonblocking],[Enable detecting how to do it])
AC_HELP_STRING([--disable-nonblocking],[Disable non-blocking socket detection]),
[
if test "$enableval" = "no" ; then
AC_MSG_WARN([non-blocking sockets disabled])
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
[to disable NON-BLOCKING connections])
# Check if struct sockaddr_in6 have sin6_scope_id member
if test "$ipv6" = yes; then
AC_MSG_CHECKING([if struct sockaddr_in6 has sin6_scope_id member])
AC_TRY_COMPILE([
#include <sys/types.h>
#include <netinet/in.h>] ,
struct sockaddr_in6 s; s.sin6_scope_id = 0; , have_sin6_scope_id=yes)
if test "$have_sin6_scope_id" = yes; then
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID, 1, [Define to 1 if struct sockaddr_in6 has the sin6_scope_id member])
else
CURL_CHECK_NONBLOCKING_SOCKET
AC_MSG_RESULT([no])
fi
],
[
CURL_CHECK_NONBLOCKING_SOCKET
])
fi
dnl **********************************************************************
dnl Check if the operating system allows programs to write to their own argv[]
@@ -1196,32 +1178,19 @@ if test X"$OPT_SSL" != Xno; then
if test "$PKGTEST" = "yes"; then
dnl Detect the pkg-config tool, as it may have extra info about the
dnl openssl installation we can use. I *believe* this is what we are
dnl expected to do on really recent Redhat Linux hosts.
CURL_CHECK_PKGCONFIG(openssl)
AC_PATH_PROG( PKGCONFIG, pkg-config, no, $PATH:/usr/bin:/usr/local/bin)
if test "$PKGCONFIG" != "no" ; then
AC_MSG_CHECKING([OpenSSL options with pkg-config])
SSL_LIBS=`$PKGCONFIG --libs-only-l openssl 2>/dev/null`
SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl 2>/dev/null`
SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl 2>/dev/null`
$PKGCONFIG --exists openssl
SSL_EXISTS=$?
LIB_OPENSSL=`echo $SSL_LDFLAGS | sed -e 's/-L//g'`
if test "$SSL_EXISTS" -eq "0"; then
SSL_LIBS=`$PKGCONFIG --libs-only-l openssl 2>/dev/null`
SSL_LDFLAGS=`$PKGCONFIG --libs-only-L openssl 2>/dev/null`
SSL_CPPFLAGS=`$PKGCONFIG --cflags-only-I openssl 2>/dev/null`
LIB_OPENSSL=`echo $SSL_LDFLAGS | sed -e 's/-L//g'`
dnl use the values pkg-config reported
LIBS="$LIBS $SSL_LIBS"
CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS"
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
AC_MSG_RESULT([found])
else
AC_MSG_RESULT([no])
fi
dnl use the values pkg-config reported
LIBS="$LIBS $SSL_LIBS"
CPPFLAGS="$CPPFLAGS $SSL_CPPFLAGS"
LDFLAGS="$LDFLAGS $SSL_LDFLAGS"
fi
fi
@@ -1562,7 +1531,7 @@ if test X"$OPENSSL_ENABLED" = X"1"; then
fi
dnl ----------------------------------------------------
dnl FIX: only check for GnuTLS if OpenSSL is not enabled
dnl check for GnuTLS
dnl ----------------------------------------------------
dnl Default to compiler & linker defaults for GnuTLS files & libraries.
@@ -1576,29 +1545,51 @@ AC_HELP_STRING([--without-gnutls], [disable GnuTLS detection]),
if test "$OPENSSL_ENABLED" != "1"; then
if test X"$OPT_GNUTLS" != Xno; then
AC_MSG_NOTICE([OPT_GNUTLS is $OPT_GNUTLS])
addld=""
if test "x$OPT_GNUTLS" = "xyes"; then
check=`libgnutls-config --version 2>/dev/null`
if test -n "$check"; then
addlib=`libgnutls-config --libs`
addcflags=`libgnutls-config --cflags`
version=`libgnutls-config --version`
gtlsprefix=`libgnutls-config --prefix`
fi
check=`libgnutls-config --version 2>/dev/null`
if test -n "$check"; then
addlib=`libgnutls-config --libs`
addcflags=`libgnutls-config --cflags`
version=`libgnutls-config --version`
gtlslib=`libgnutls-config --prefix`/lib$libsuff
fi
else
addlib=`$OPT_GNUTLS/bin/libgnutls-config --libs`
addcflags=`$OPT_GNUTLS/bin/libgnutls-config --cflags`
version=`$OPT_GNUTLS/bin/libgnutls-config --version 2>/dev/null`
gtlsprefix=$OPT_GNUTLS
if test -z "$version"; then
version="unknown"
fi
gtlslib=$OPT_GNUTLS/lib$libsuff
fi
if test -z "$version"; then
CURL_CHECK_PKGCONFIG(gnutls)
if test "$PKGCONFIG" != "no" ; then
addlib=`$PKGCONFIG --libs-only-l gnutls`
addld=`$PKGCONFIG --libs-only-L gnutls`
addcflags=`$PKGCONFIG --cflags-only-I gnutls`
version=`$PKGCONFIG --modversion gnutls`
gtlslib=`echo $addld | $SED -e 's/-L//'`
fi
fi
if test -z "$version"; then
dnl lots of efforts, still no go
version="unknown"
fi
if test -n "$addlib"; then
CLEANLIBS="$LIBS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEADLDFLAGS="$LDFLAGS"
LIBS="$LIBS $addlib"
LDFLAGS="$LDFLAGS $addld"
if test "$addcflags" != "-I/usr/include"; then
CPPFLAGS="$CPPFLAGS $addcflags"
fi
@@ -1619,14 +1610,16 @@ if test "$OPENSSL_ENABLED" != "1"; then
if test "x$USE_GNUTLS" = "xyes"; then
AC_MSG_NOTICE([detected GnuTLS version $version])
dnl when shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
dnl due to this
if test -n "$gtlslib"; then
dnl when shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
dnl due to this
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$gtlsprefix/lib$libsuff"
export LD_LIBRARY_PATH
AC_MSG_NOTICE([Added $gtlsprefix/lib$libsuff to LD_LIBRARY_PATH])
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$gtlslib"
export LD_LIBRARY_PATH
AC_MSG_NOTICE([Added $gtlslib to LD_LIBRARY_PATH])
fi
fi
fi
@@ -1651,13 +1644,15 @@ if test "$OPENSSL_ENABLED" != "1" -a "$GNUTLS_ENABLED" != "1"; then
if test X"$OPT_NSS" != Xno; then
if test "x$OPT_NSS" = "xyes"; then
check=`pkg-config --version 2>/dev/null`
if test -n "$check"; then
addlib=`pkg-config --libs nss`
addcflags=`pkg-config --cflags nss`
version=`pkg-config --modversion nss`
nssprefix=`pkg-config --variable=prefix nss`
fi
CURL_CHECK_PKGCONFIG(nss)
if test "$PKGCONFIG" != "no" ; then
addlib=`$PKGCONFIG --libs nss`
addcflags=`$PKGCONFIG --cflags nss`
version=`$PKGCONFIG --modversion nss`
nssprefix=`$PKGCONFIG --variable=prefix nss`
fi
else
# Without pkg-config, we'll kludge in some defaults
addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl"
@@ -2014,19 +2009,28 @@ CURL_CHECK_FUNC_SEND
CURL_CHECK_MSG_NOSIGNAL
CURL_CHECK_FUNC_ALARM
CURL_CHECK_FUNC_FCNTL
CURL_CHECK_FUNC_FDOPEN
CURL_CHECK_FUNC_FREEADDRINFO
CURL_CHECK_FUNC_FREEIFADDRS
CURL_CHECK_FUNC_FTRUNCATE
CURL_CHECK_FUNC_GETADDRINFO
CURL_CHECK_FUNC_GETHOSTBYADDR
CURL_CHECK_FUNC_GETHOSTBYADDR_R
CURL_CHECK_FUNC_GETHOSTBYNAME
CURL_CHECK_FUNC_GETHOSTBYNAME_R
CURL_CHECK_FUNC_GETHOSTNAME
CURL_CHECK_FUNC_GETIFADDRS
CURL_CHECK_FUNC_GETSERVBYPORT_R
CURL_CHECK_FUNC_GMTIME_R
CURL_CHECK_FUNC_INET_NTOA_R
CURL_CHECK_FUNC_INET_NTOP
CURL_CHECK_FUNC_INET_PTON
CURL_CHECK_FUNC_IOCTL
CURL_CHECK_FUNC_IOCTLSOCKET
CURL_CHECK_FUNC_IOCTLSOCKET_CAMEL
CURL_CHECK_FUNC_LOCALTIME_R
CURL_CHECK_FUNC_SETSOCKOPT
CURL_CHECK_FUNC_SIGACTION
CURL_CHECK_FUNC_SIGINTERRUPT
CURL_CHECK_FUNC_SIGNAL
@@ -2062,8 +2066,6 @@ AC_CHECK_FUNCS([basename \
closesocket \
fork \
geteuid \
gethostbyaddr \
getifaddrs \
getpass_r \
getppid \
getprotobyname \
@@ -2169,6 +2171,15 @@ if test "$disable_poll" = "no"; then
fi dnl poll() was found
fi dnl poll()-check is not disabled
dnl ************************************************************
dnl enable non-blocking communications
dnl
CURL_CHECK_OPTION_NONBLOCKING
CURL_CHECK_NONBLOCKING_SOCKET
dnl ************************************************************
dnl nroff tool stuff
dnl
AC_PATH_PROG( PERL, perl, ,
$PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )

View File

@@ -1,4 +1,4 @@
Updated: Sep 24, 2008 (http://curl.haxx.se/docs/faq.html)
Updated: Jan 14, 2009 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -119,10 +119,10 @@ FAQ
libcurl
A free and easy-to-use client-side URL transfer library, supporting FTP,
FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE and LDAP. libcurl
supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos,
HTTP form based upload, proxies, cookies, user+password authentication,
file transfer resume, http proxy tunneling and more!
FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE, LDAP and LDAPS.
libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
kerberos, HTTP form based upload, proxies, cookies, user+password
authentication, file transfer resume, http proxy tunneling and more!
libcurl is highly portable, it builds and works identically on numerous
platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX,
@@ -137,8 +137,8 @@ FAQ
A command line tool for getting or sending files using URL syntax.
Since curl uses libcurl, it supports a range of common Internet protocols,
currently including HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, DICT,
TELNET and FILE.
currently including HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, LDAP, LDAPS,
DICT, TELNET and FILE.
We pronounce curl and cURL with an initial k sound: [kurl].
@@ -227,11 +227,11 @@ FAQ
Project cURL is entirely free and open. No person gets paid for developing
(lib)curl. We do this voluntarily on our spare time.
We get some help from companies. Contactor Data hosts the curl web site,
Haxx owns the curl web site's domain and sourceforge.net hosts project
services we take advantage from, like the bug tracker. Also, some companies
have sponsored certain parts of the development in the past and I hope some
will continue to do so in the future.
We get some help from companies. CAG Contactor hosts the curl web site, Haxx
owns the curl web site's domain and sourceforge.net hosts project services
we take advantage from, like the bug tracker. Also, some companies have
sponsored certain parts of the development in the past and I hope some will
continue to do so in the future.
If you want to support our project, consider a donation or a banner-program
or even better: by helping us coding, documenting, testing etc.
@@ -299,7 +299,7 @@ FAQ
as used by numerous applications that include libcurl binaries in their
distribution packages (like Adobe Acrobat Reader and Google Earth).
More than 80 known named companies use curl in commercial environments and
More than 90 known named companies use curl in commercial environments and
products. More than 100 known named open source projects depend on
(lib)curl.

View File

@@ -77,7 +77,7 @@ different bindings exist at the time of this writing.
September 2000, kerberos4 support was added.
In November 2000 started the work on a test suite for curl. It was later
re-written from scratch again.
re-written from scratch again. The libcurl major SONAME number was set to 1.
January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or
MPL). The MIT license is extremely liberal and can be used combined with GPL
@@ -88,7 +88,7 @@ deemed "GPL incompatible".)
curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
also introduced libcurl's ability to do persistent connections. 24000 lines of
code.
code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
The first experimental ftps:// support was added in March 2001.
@@ -129,7 +129,12 @@ December 2003, full-fledged SSL for FTP is supported.
January 2004: curl 7.11.0 introduced large file support.
June 2004: curl 7.12.0 introduced IDN support. 10 official web mirrors.
June 2004:
curl 7.12.0 introduced IDN support. 10 official web mirrors.
This release bumped the major SONAME to 3 due to the removal of the
curl_formparse() function
August 2004:
Curl and libcurl 7.12.1
@@ -144,10 +149,38 @@ August 2004:
April 2005:
GnuTLS can now optionally be used for the secure layer when curl is built.
GnuTLS can now optionally be used for the secure layer when curl is built.
September 2005:
TFTP support was added.
TFTP support was added.
More than 100,000 unique visitors of the curl web site. 25 mirrors.
April 2006:
Added the multi_socket() API
September 2006:
The major SONAME number for libcurl was bumped to 4 due to the removal of
ftp third party transfer support.
November 2006:
Added SCP and SFTP support
February 2007:
Added support for the Mozilla NSS library to do the SSL/TLS stuff
November 2008:
Command line options: 128
curl_easy_setopt() options: 158
Public functions in libcurl: 58
Known libcurl bindings: 37
Contributors: 683
145,000 unique visitors. >100 GB downloaded.
More than 100,000 unique visitors of the curl web site. 25 mirrors.

View File

@@ -673,8 +673,9 @@ Minix
Configure and compile with:
./configure CONFIG_SHELL=/bin/bigsh CC=cc LD=cc AR=/usr/bin/aal \
GREP=grep CPPFLAGS=-D_POSIX_SOURCE=1
GREP=grep CPPFLAGS='-D_POSIX_SOURCE=1 -I/usr/local/include'
make
chmem =256000 src/curl
GCC
---
@@ -686,6 +687,7 @@ Minix
./configure CONFIG_SHELL=/bin/bigsh CC=gcc AR=/usr/gnu/bin/gar GREP=grep
make
chmem =256000 src/curl
Symbian OS
@@ -782,9 +784,13 @@ REDUCING SIZE
--without-ssl (disables support for SSL/TLS)
--without-zlib (disables support for on-the-fly decompression)
The GNU linker has a number of options to reduce the size of the libcurl
dynamic libraries on some platforms even further. Specify them by giving
the options -Wl,-Bsymbolic and -Wl,-s on the gcc command-line.
The GNU compiler and linker have a number of options that can reduce the
size of the libcurl dynamic libraries on some platforms even further.
Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
configure command-line:
CFLAGS="-ffunction-sections -fdata-sections" \
LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
Be sure also to strip debugging symbols from your binaries after
compiling using 'strip' (or the appropriate variant if cross-compiling).
If space is really tight, you may be able to remove some unneeded
@@ -826,9 +832,14 @@ PORTS
- Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1
- AVR32 Linux
- ARM INTEGRITY
- ARM iPhone OS
- Cell Linux
- Cell Cell OS
- HP-PA HP-UX 9.X 10.X 11.X
- HP-PA Linux
- HP3000 MPE/iX
- MicroBlaze uClinux
- MIPS IRIX 6.2, 6.5
- MIPS Linux
- OS/400
@@ -848,7 +859,6 @@ PORTS
- StrongARM (and other ARM) RISC OS 3.1, 4.02
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6
- StrongARM NetBSD 1.4.1
- ARM INTEGRITY
- Symbian OS (P.I.P.S.) 9.x
- TPF
- Ultrix 4.3a
@@ -878,6 +888,7 @@ PORTS
- m68k OpenBSD
- m88k dg-dgux5.4R3.00
- s390 Linux
- x86_64 Linux
- XScale/PXA250 Linux 2.4
- Nios II uClinux

View File

@@ -3,7 +3,24 @@ 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!
58. It seems sensible to be able to use CURLOPT_NOBODY and
62. CURLOPT_TIMEOUT does not work properly with the regular multi and
multi_socket interfaces. The work-around for apps is to simply remove the
easy handle once the time is up. See also:
http://curl.haxx.se/bug/view.cgi?id=2501457
61. If an upload using Expect: 100-continue receives an HTTP 417 response,
it ought to be automatically resent without the Expect:. A workaround is
for the client application to redo the transfer after disabling Expect:.
http://curl.haxx.se/mail/archive-2008-02/0043.html
60. libcurl closes the connection if an HTTP 401 reply is received while it
is waiting for the the 100-continue response.
http://curl.haxx.se/mail/lib-2008-08/0462.html
59. If the CURLOPT_PORT option is used on an FTP URL like
"ftp://example.com/file;type=A" the ";type=A" is stripped off.
58. It seems sensible to be able to use CURLOPT_NOBODY and
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html

View File

@@ -182,6 +182,7 @@ Edin Kadribasic
Eduard Bloch
Eetu Ojanen
Ellis Pritchard
Emanuele Bovisio
Emil Romanus
Emiliano Ida
Enrico Scholz
@@ -257,10 +258,12 @@ Henrik Storner
Hzhijun
Ian Ford
Ian Gulliver
Ian Lynagh
Ian Turner
Ian Wilkes
Ignacio Vazquez-Abrams
Igor Franchuk
Igor Novoseltsev
Igor Polyakov
Ilguiz Latypov
Ilja van Sprundel
@@ -317,6 +320,7 @@ John Kelly
John Lask
John Lightsey
John McGowan
John Wilkinson
Johnny Luong
Jon Grubbs
Jon Travis
@@ -348,6 +352,7 @@ Katie Wang
Kees Cook
Keith MacDonald
Keith McGuigan
Keith Mok
Ken Hirsch
Ken Rastatter
Kent Boortz
@@ -407,6 +412,7 @@ Markus Moeller
Markus Oberhumer
Martijn Koster
Martin C. Martin
Martin Drasar
Martin Hedenfalk
Martin Skinner
Marty Kuhrt
@@ -422,12 +428,14 @@ Matthew Blain
Matthew Clarke
Maurice Barnum
Max Katsev
Maxim Ivanov
Maxim Perenesenko
Mekonikum
Mettgut Jamalla
Michael Benedict
Michael Calmer
Michael Curtis
Michael Goffioul
Michael Jahn
Michael Jerris
Michael Mealling
@@ -441,6 +449,7 @@ Mike Bytnar
Mike Dobbs
Mike Hommey
Mike Protts
Mike Revi
Miklos Nemeth
Mitz Wark
Mohamed Lrhazi
@@ -475,6 +484,7 @@ Olaf Stueben
Olaf St<53>ben
Oren Tirosh
P R Schaffner
Pascal Terjan
Patrick Bihan-Faou
Patrick Monnerat
Patrick Smith
@@ -606,6 +616,7 @@ Steve Lhomme
Steve Little
Steve Marx
Steve Oliphant
Steve Roskowski
Steven Bazyl
Steven G. Johnson
Stoned Elipot

113
docs/TODO
View File

@@ -15,16 +15,13 @@
1.1 Zero-copy interface
1.2 More data sharing
1.3 struct lifreq
1.4 Get IP address
1.5 c-ares ipv6
1.6 configure-based info in public headers
1.7 signal-based resolver timeouts
1.4 signal-based resolver timeouts
2. libcurl - multi interface
2.1 More non-blocking
2.2 Pause transfers
2.3 Remove easy interface internally
2.4 Avoid having to remove/readd handles
2.2 Remove easy interface internally
2.3 Avoid having to remove/readd handles
2.4 Fix HTTP Pipelining for PUT
3. Documentation
3.1 More and better
@@ -39,9 +36,8 @@
4.7 ASCII support
5. HTTP
5.1 Other HTTP versions with CONNECT
5.2 Better persistency for HTTP 1.0
5.3 support FF3 sqlite cookie files
5.1 Better persistency for HTTP 1.0
5.2 support FF3 sqlite cookie files
6. TELNET
6.1 ditch stdin
@@ -52,14 +48,13 @@
7. SSL
7.1 Disable specific versions
7.2 Provide mutex locking API
7.3 dumpcert
7.4 Evaluate SSL patches
7.5 Cache OpenSSL contexts
7.6 Export session ids
7.7 Provide callback for cert verification
7.8 Support other SSL libraries
7.9 Support SRP on the TLS layer
7.10 improve configure --with-ssl
7.3 Evaluate SSL patches
7.4 Cache OpenSSL contexts
7.5 Export session ids
7.6 Provide callback for cert verification
7.7 Support other SSL libraries
7.8 Support SRP on the TLS layer
7.9 improve configure --with-ssl
8. GnuTLS
8.1 Make NTLM work without OpenSSL functions
@@ -132,37 +127,7 @@
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
To support ipv6 interface addresses for network interfaces properly.
1.4 Get IP address
Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
GET_FTP_DATA_IP. Return a string with the used IP.
1.5 c-ares ipv6
Make libcurl built with c-ares use c-ares' IPv6 abilities. They weren't
present when we first added c-ares support but they have been added since!
When this is done and works, we can actually start considering making c-ares
powered libcurl the default build (which of course would require that we'd
bundle the c-ares source code in the libcurl source code releases).
1.6 configure-based info in public headers
Make the public headers include the proper system includes based on what was
present at the time when configure was run. Currently, the sys/select.h
header is for example included by curl/multi.h only on specific platforms we
know MUST have it. This is error-prone. We therefore want the header files to
adapt to configure results. Those results must be stored in a new header and
they must use a curl name space, i.e not be HAVE_* prefix (as that would risk
a collision with other apps that use libcurl and that runs configure).
Work on this has been started but hasn't been finished, and the initial patch
and some details are found here:
http://curl.haxx.se/mail/lib-2006-12/0084.html
The remaining problems to solve involve the platforms that can't run
configure.
1.7 signal-based resolver timeouts
1.4 signal-based resolver timeouts
libcurl built without an asynchronous resolver library uses alarm() to time
out DNS lookups. When a timeout occurs, this causes libcurl to jump from the
@@ -181,17 +146,7 @@
Make sure we don't ever loop because of non-blocking sockets returning
EWOULDBLOCK or similar. The GnuTLS connection etc.
2.2 Pause transfers
Make transfers treated more carefully. We need a way to tell libcurl we have
data to write, as the current system expects us to upload data each time the
socket is writable and there is no way to say that we want to upload data
soon just not right now, without that aborting the upload. The opposite
situation should be possible as well, that we tell libcurl we're ready to
accept read data. Today libcurl feeds the data as soon as it is available for
reading, no matter what.
2.3 Remove easy interface internally
2.2 Remove easy interface internally
Make curl_easy_perform() a wrapper-function that simply creates a multi
handle, adds the easy handle to it, runs curl_multi_perform() until the
@@ -200,7 +155,7 @@
internally use and assume the multi interface. The select()-loop should use
curl_multi_socket().
2.4 Avoid having to remove/readd handles
2.3 Avoid having to remove/readd handles
curl_multi_handle_control() - this can control the easy handle (while) added
to a multi handle in various ways:
@@ -217,6 +172,13 @@
o RESUME?
2.4 Fix HTTP Pipelining for PUT
HTTP Pipelining can be a way to greatly enhance performance for multiple
serial requests and currently libcurl only supports that for HEAD and GET
requests but it should also be possible for PUT.
3. Documentation
3.1 More and better
@@ -269,18 +231,12 @@
5. HTTP
5.1 Other HTTP versions with CONNECT
When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
never been reported as causing trouble to anyone, but should be considered to
use the HTTP version the user has chosen.
5.2 Better persistency for HTTP 1.0
5.1 Better persistency for HTTP 1.0
"Better" support for persistent connections over HTTP 1.0
http://curl.haxx.se/bug/feature.cgi?id=1089001
5.3 support FF3 sqlite cookie files
5.2 support FF3 sqlite cookie files
Firefox 3 is changing from its former format to a a sqlite database instead.
We should consider how (lib)curl can/should support this.
@@ -323,17 +279,12 @@ to provide the data to send.
library, so that the same application code can use mutex-locking
independently of OpenSSL or GnutTLS being used.
7.3 dumpcert
Anton Fedorov's "dumpcert" patch:
http://curl.haxx.se/mail/lib-2004-03/0088.html
7.4 Evaluate SSL patches
7.3 Evaluate SSL patches
Evaluate/apply Gertjan van Wingerde's SSL patches:
http://curl.haxx.se/mail/lib-2004-03/0087.html
7.5 Cache OpenSSL contexts
7.4 Cache OpenSSL contexts
"Look at SSL cafile - quick traces look to me like these are done on every
request as well, when they should only be necessary once per ssl context (or
@@ -343,7 +294,7 @@ to provide the data to send.
style connections are re-used. It will make us use slightly more memory but
it will libcurl do less creations and deletions of SSL contexts.
7.6 Export session ids
7.5 Export session ids
Add an interface to libcurl that enables "session IDs" to get
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
@@ -351,24 +302,24 @@ to provide the data to send.
the state from such a buffer at a later date - this is used by mod_ssl for
apache to implement and SSL session ID cache".
7.7 Provide callback for cert verification
7.6 Provide callback for cert verification
OpenSSL supports a callback for customised verification of the peer
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
it be? There's so much that could be done if it were!
7.8 Support other SSL libraries
7.7 Support other SSL libraries
Make curl's SSL layer capable of using other free SSL libraries. Such as
MatrixSSL (http://www.matrixssl.org/).
7.9 Support SRP on the TLS layer
7.8 Support SRP on the TLS layer
Peter Sylvester's patch for SRP on the TLS layer. Awaits OpenSSL support for
this, no need to support this in libcurl before there's an OpenSSL release
that does it.
7.10 improve configure --with-ssl
7.9 improve configure --with-ssl
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
then NSS...

View File

@@ -28,7 +28,7 @@ curl-config \- Get information about a libcurl installation
.B curl-config [options]
.SH DESCRIPTION
.B curl-config
displays information about a previous curl and libcurl installation.
displays information about the curl and libcurl installation.
.SH OPTIONS
.IP "--ca"
Displays the built-in path to the CA cert bundle this libcurl uses.
@@ -36,7 +36,7 @@ Displays the built-in path to the CA cert bundle this libcurl uses.
Displays the compiler used to build libcurl.
.IP "--cflags"
Set of compiler options (CFLAGS) to use when compiling files that use
libcurl. Currently that is only thw include path to the curl include files.
libcurl. Currently that is only the include path to the curl include files.
.IP "--checkfor [version]"
Specify the oldest possible libcurl version string you want, and this
script will return 0 if the current installation is new enough or it
@@ -46,7 +46,7 @@ enough. (Added in 7.15.4)
Lists what particular main features the installed libcurl was built with. At
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
any particular order. The keywords will be separated by newlines. There may be
none, one or several keywords in the list.
none, one, or several keywords in the list.
.IP "--help"
Displays the available options.
.IP "--libs"
@@ -61,7 +61,7 @@ Lists what particular protocols the installed libcurl was built to support. At
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
be listed using uppercase and are separated by newlines. There may be none,
one or several protocols in the list. (Added in 7.13.0)
one, or several protocols in the list. (Added in 7.13.0)
.IP "--static-libs"
Shows the complete set of libs and other linker options you will need in order
to link your application with libcurl statically. (Added in 7.17.1)

View File

@@ -135,7 +135,7 @@ Pass the data to the HTTP server as a cookie. It is supposedly the
data previously received from the server in a "Set-Cookie:" line.
The data should be in the format "NAME1=VALUE1; NAME2=VALUE2".
If no '=' letter is used in the line, it is treated as a filename to use to
If no '=' symbol is used in the line, it is treated as a filename to use to
read previously stored cookie lines from, which should be used in this session
if they match. Using this method also activates the "cookie parser" which will
make curl record incoming cookies too, which may be handy if you're using this
@@ -197,7 +197,7 @@ If this option is used several times, the last specified file name will be
used.
.IP "-C/--continue-at <offset>"
Continue/Resume a previous file transfer at the given offset. The given offset
is the exact number of bytes that will be skipped counted from the beginning
is the exact number of bytes that will be skipped, counting from the beginning
of the source file before it is transferred to the destination. If used with
uploads, the FTP server command SIZE will not be used by curl.
@@ -228,7 +228,7 @@ of a form field you may use \fI--data-urlencode\fP.
If any of these options is used more than once on the same command line, the
data pieces specified will be merged together with a separating
&-letter. Thus, using '-d name=daniel -d skill=lousy' would generate a post
&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post
chunk that looks like \&'name=daniel&skill=lousy'.
If you start the data with the letter @, the rest should be a file name to
@@ -256,11 +256,11 @@ curl using one of the following syntaxes:
.RS
.IP "content"
This will make curl URL-encode the content and pass that on. Just be careful
so that the content doesn't contain any = or @ letters, as that will then make
so that the content doesn't contain any = or @ symbols, as that will then make
the syntax match one of the other cases below!
.IP "=content"
This will make curl URL-encode the content and pass that on. The preceding =
letter is not included in the data.
symbol is not included in the data.
.IP "name=content"
This will make curl URL-encode the content part and pass that on. Note that
the name part is expected to be URL-encoded already.
@@ -286,8 +286,8 @@ difference.
(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
active FTP transfers. Curl will normally always first attempt to use EPRT,
then LPRT before using PORT, but with this option, it will use PORT right
away. EPRT and LPRT are extensions to the original FTP protocol, may not work
on all servers but enable more functionality in a better way than the
away. EPRT and LPRT are extensions to the original FTP protocol, and may not work
on all servers, but they enable more functionality in a better way than the
traditional PORT command.
Since curl 7.19.0, \fB--eprt\fP can be used to explicitly enable EPRT again
@@ -326,7 +326,7 @@ engines. Note that not all (or none) of the engines may be available at
run-time.
.IP "--environment"
(RISC OS ONLY) Sets a range of environment variables, using the names the -w
option supports, to easier allow extraction of useful information after having
option supports, to allow easier extraction of useful information after having
run curl.
.IP "--egd-file <file>"
(SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket
@@ -473,7 +473,7 @@ submit button. This causes curl to POST data using the Content-Type
multipart/form-data according to RFC1867. This enables uploading of binary
files etc. To force the 'content' part to be a file, prefix the file name
with an @ sign. To just get the content part from a file, prefix the file name
with the letter <. The difference between @ and < is then that @ makes a file
with the symbol <. The difference between @ and < is then that @ makes a file
get attached in the post as a file upload, while the < makes a text field and
just get the contents for that text field from a file.
@@ -732,7 +732,7 @@ re-send the following request using the same unmodified method.
.IP "--location-trusted"
(HTTP/HTTPS) Like \fI-L/--location\fP, but will allow sending the name +
password to all hosts that the site may redirect to. This may or may not
introduce a security breach if the site redirects you do a site to which
introduce a security breach if the site redirects you to a site to which
you'll send your authentication info (which is plaintext in the case of HTTP
Basic authentication).
@@ -776,7 +776,7 @@ Very similar to \fI--netrc\fP, but this option makes the .netrc usage
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
designed by Microsoft and is used in their web applications. It is primarily
meant as a support for Kerberos5 authentication but may be also used along
with another authentication methods. For more information see IETF draft
with another authentication method. For more information see IETF draft
draft-brezak-spnego-http-04.txt.
If you want to enable Negotiate for your proxy authentication, then use
@@ -1201,7 +1201,7 @@ received by curl that is hidden in normal cases, and a line starting with '*'
means additional info provided by curl.
Note that if you only want HTTP headers in the output, \fI-i/--include\fP
might be option you're looking for.
might be the option you're looking for.
If you think this option still doesn't give you enough details, consider using
\fI--trace\fP or \fI--trace-ascii\fP instead.
@@ -1255,12 +1255,12 @@ format from stdin you write "@-".
The variables present in the output format will be substituted by the value or
text that curl thinks fit, as described below. All variables are specified
as %{variable_name} and to output a normal % you just it them as
as %{variable_name} and to output a normal % you just write them as
%%. You can output a newline by using \\n, a carriage return with \\r and a tab
space with \\t.
.B NOTE:
The %-letter is a special letter in the win32-environment, where all
The %-symbol is a special symbol in the win32-environment, where all
occurrences of % must be doubled when using this option.
The variables available at this point are:
@@ -1456,7 +1456,7 @@ Sets the proxy server to use if no protocol-specific proxy is set.
list of host names that shouldn't go through any proxy. If set to a asterisk
\&'*' only, it matches all hosts.
.SH EXIT CODES
There exists a bunch of different error codes and their corresponding error
There are a bunch of different error codes and their corresponding error
messages that may appear during bad conditions. At the time of this writing,
the exit codes are:
.IP 1
@@ -1464,7 +1464,7 @@ Unsupported protocol. This build of curl has no support for this protocol.
.IP 2
Failed to initialize.
.IP 3
URL malformat. The syntax was not correct.
URL malformed. The syntax was not correct.
.IP 5
Couldn't resolve proxy. The given proxy host could not be resolved.
.IP 6
@@ -1545,67 +1545,67 @@ Unknown TELNET option specified.
.IP 49
Malformed telnet option.
.IP 51
The peer's SSL certificate or SSH MD5 fingerprint was not ok
The peer's SSL certificate or SSH MD5 fingerprint was not ok.
.IP 52
The server didn't reply anything, which here is considered an error.
.IP 53
SSL crypto engine not found
SSL crypto engine not found.
.IP 54
Cannot set SSL crypto engine as default
Cannot set SSL crypto engine as default.
.IP 55
Failed sending network data
Failed sending network data.
.IP 56
Failure in receiving network data
Failure in receiving network data.
.IP 58
Problem with the local certificate
Problem with the local certificate.
.IP 59
Couldn't use specified SSL cipher
Couldn't use specified SSL cipher.
.IP 60
Peer certificate cannot be authenticated with known CA certificates
Peer certificate cannot be authenticated with known CA certificates.
.IP 61
Unrecognized transfer encoding
Unrecognized transfer encoding.
.IP 62
Invalid LDAP URL
Invalid LDAP URL.
.IP 63
Maximum file size exceeded
Maximum file size exceeded.
.IP 64
Requested FTP SSL level failed
Requested FTP SSL level failed.
.IP 65
Sending the data requires a rewind that failed
Sending the data requires a rewind that failed.
.IP 66
Failed to initialise SSL Engine
Failed to initialise SSL Engine.
.IP 67
The user name, password, or similar was not accepted and curl failed to log in
The user name, password, or similar was not accepted and curl failed to log in.
.IP 68
File not found on TFTP server
File not found on TFTP server.
.IP 69
Permission problem on TFTP server
Permission problem on TFTP server.
.IP 70
Out of disk space on TFTP server
Out of disk space on TFTP server.
.IP 71
Illegal TFTP operation
Illegal TFTP operation.
.IP 72
Unknown TFTP transfer ID
Unknown TFTP transfer ID.
.IP 73
File already exists (TFTP)
File already exists (TFTP).
.IP 74
No such user (TFTP)
No such user (TFTP).
.IP 75
Character conversion failed
Character conversion failed.
.IP 76
Character conversion functions required
Character conversion functions required.
.IP 77
Problem with reading the SSL CA cert (path? access rights?)
Problem with reading the SSL CA cert (path? access rights?).
.IP 78
The resource referenced in the URL does not exist
The resource referenced in the URL does not exist.
.IP 79
An unspecified error occurred during the SSH session
An unspecified error occurred during the SSH session.
.IP 80
Failed to shut down the SSL connection
Failed to shut down the SSL connection.
.IP 82
Could not load CRL file, missing or wrong format (added in 7.19.0)
Could not load CRL file, missing or wrong format (added in 7.19.0).
.IP 83
Issuer check failed (added in 7.19.0)
Issuer check failed (added in 7.19.0).
.IP XX
More error codes will appear here in future releases. The existing ones
are meant to never change.

View File

@@ -12,5 +12,5 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
COMPLICATED_EXAMPLES = \
curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \
ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c

460
docs/examples/evhiperfifo.c Normal file
View File

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

View File

@@ -180,12 +180,17 @@ static void event_cb(int fd, short kind, void *userp)
{
GlobalInfo *g = (GlobalInfo*) userp;
CURLMcode rc;
(void)kind; /* unused */
int action =
(kind&EV_READ?CURL_CSELECT_IN:0)|
(kind&EV_WRITE?CURL_CSELECT_OUT:0);
do {
rc = curl_multi_socket(g->multi, fd, &g->still_running);
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("event_cb: curl_multi_socket", rc);
mcode_or_die("event_cb: curl_multi_socket_action", rc);
check_run_count(g);
if ( g->still_running <= 0 ) {
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
@@ -206,9 +211,10 @@ static void timer_cb(int fd, short kind, void *userp)
(void)kind;
do {
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
rc = curl_multi_socket_action(g->multi,
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
} while (rc == CURLM_CALL_MULTI_PERFORM);
mcode_or_die("timer_cb: curl_multi_socket", rc);
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
check_run_count(g);
}
@@ -337,11 +343,9 @@ static void new_conn(char *url, GlobalInfo *g )
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
rc =curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc);
do {
rc = curl_multi_socket_all(g->multi, &g->still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
mcode_or_die("new_conn: curl_multi_socket_all", rc);
check_run_count(g);
/* note that the add_handle() will set a time-out to trigger very soon so
that the necessary socket_action() call will be called by this app */
}
/* This gets called whenever data is received from the fifo */
@@ -400,7 +404,6 @@ static int init_fifo (GlobalInfo *g)
int main(int argc, char **argv)
{
GlobalInfo g;
CURLMcode rc;
(void)argc;
(void)argv;
@@ -409,13 +412,16 @@ int main(int argc, char **argv)
init_fifo(&g);
g.multi = curl_multi_init();
evtimer_set(&g.timer_event, timer_cb, &g);
/* setup the generic multi interface options we want */
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
do {
rc = curl_multi_socket_all(g.multi, &g.still_running);
} while (CURLM_CALL_MULTI_PERFORM == rc);
/* we don't call any curl_multi_socket*() function yet as we have no handles
added! */
event_dispatch();
curl_multi_cleanup(g.multi);
return 0;

View File

@@ -21,6 +21,7 @@ int main(void)
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Accept: moo");
chunk = curl_slist_append(chunk, "Another: yes");
/* request with the built-in Accept: */
curl_easy_setopt(curl, CURLOPT_URL, "localhost");

View File

@@ -31,7 +31,7 @@ the connection you want to pause or unpause.
The \fBbitmask\fP argument is a set of bits that sets the new state of the
connection. The following bits can be used:
.IP CURLPAUSE_RECV
Pause receiving data. There will be no data received on this conneciton until
Pause receiving data. There will be no data received on this connection until
this function is called again without this bit set. Thus, the write callback
(\fICURLOPT_WRITEFUNCTION\fP) won't be called.
.IP CURLPAUSE_SEND

View File

@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH curl_easy_setopt 3 "28 Oct 2008" "libcurl 7.19.1" "libcurl Manual"
.TH curl_easy_setopt 3 "11 Dec 2008" "libcurl 7.19.3" "libcurl Manual"
.SH NAME
curl_easy_setopt \- set options for a curl easy handle
.SH SYNOPSIS
@@ -72,7 +72,7 @@ preceding the data (like HTTP).
A parameter set to 1 tells the library to shut off the built-in progress meter
completely.
Future versions of libcurl is likely to not have any built-in progress meter
Future versions of libcurl are likely to not have any built-in progress meter
at all.
.IP CURLOPT_NOSIGNAL
Pass a long. If it is 1, libcurl will not use any functions that
@@ -83,7 +83,7 @@ to still set/use all timeout options etc, without risking getting signals.
If this option is set and libcurl has been built with the standard name
resolver, timeouts will not occur while the name resolve takes place.
Consider building libcurl with ares support to enable asynchronous DNS
Consider building libcurl with c-ares support to enable asynchronous DNS
lookups, which enables nice timeouts for name resolves without signals.
.PP
.SH CALLBACK OPTIONS
@@ -101,7 +101,7 @@ From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will
cause writing to this connection to become paused. See
\fIcurl_easy_pause(3)\fP for further details.
This function may be called with zero bytes data if the transfered file is
This function may be called with zero bytes data if the transferred file is
empty.
Set this option to NULL to get the internal default function. The internal
@@ -140,7 +140,7 @@ that memory area. Returning 0 will signal end-of-file to the library and cause
it to stop the current transfer.
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the
server expected it, like when you've told you will upload N bytes and you
server expected it, like when you've said you will upload N bytes and you
upload less than N bytes), you may experience that the server "hangs" waiting
for the rest of the data that won't come.
@@ -152,7 +152,7 @@ From 7.18.0, the function can return CURL_READFUNC_PAUSE which then will cause
reading from this connection to become paused. See \fIcurl_easy_pause(3)\fP
for further details.
If you set the callback pointer to NULL, or doesn't set it at all, the default
If you set the callback pointer to NULL, or don't set it at all, the default
internal read function will be used. It is simply doing an fread() on the FILE
* stream set with \fICURLOPT_READDATA\fP.
.IP CURLOPT_READDATA
@@ -164,7 +164,7 @@ read function, this data must be a valid readable FILE *.
If you're using libcurl as a win32 DLL, you MUST use a
\fICURLOPT_READFUNCTION\fP if you set this option.
This option is also known with the older name \fICURLOPT_INFILE\fP, the name
This option was also known by the older name \fICURLOPT_INFILE\fP, the name
\fICURLOPT_READDATA\fP was introduced in 7.9.7.
.IP CURLOPT_IOCTLFUNCTION
Function pointer that should match the \fIcurl_ioctl_callback\fP prototype
@@ -336,7 +336,7 @@ This function will get called on all new connections made to a server, during
the SSL negotiation. The SSL_CTX pointer will be a new one every time.
To use this properly, a non-trivial amount of knowledge of the openssl
libraries is necessary. Using this function allows for example to use openssl
libraries is necessary. For example, using this function allows you to use openssl
callbacks to add additional validation code for certificates, and even to
change the actual URI of an HTTPS request (example used in the lib509 test
case). See also the example section for a replacement of the key, certificate
@@ -421,7 +421,7 @@ response codes will slip through, especially when authentication is involved
(response codes 401 and 407).
You might get some amounts of headers transferred before this situation is
detected, like for when a "100-continue" is received as a response to a
detected, like when a "100-continue" is received as a response to a
POST/PUT and a 401 or 407 is received immediately afterwards.
.SH NETWORK OPTIONS
.IP CURLOPT_URL
@@ -433,9 +433,9 @@ attempt to guess which protocol to use based on the given host name. If the
given protocol of the set URL is not supported, libcurl will return on error
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP or
\fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed info
on which protocols that are supported.
on which protocols are supported.
The string given to CURLOPT_URL must be url-encoded and following the RFC 2396
The string given to CURLOPT_URL must be url-encoded and follow RFC 2396
(http://curl.haxx.se/rfc/rfc2396.txt).
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
@@ -456,7 +456,7 @@ tunnel through the HTTP proxy. Such tunneling is activated with
\fICURLOPT_HTTPPROXYTUNNEL\fP.
libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP,
\fBall_proxy\fP etc, if any of those is set. The \fICURLOPT_PROXY\fP option
\fBall_proxy\fP etc, if any of those are set. The \fICURLOPT_PROXY\fP option
does however override any possibly set environment variables.
Setting the proxy string to "" (an empty string) will explicitly disable the
@@ -480,16 +480,16 @@ given HTTP proxy. There is a big difference between using a proxy and to
tunnel through it. If you don't know what this means, you probably don't want
this tunneling option.
.IP CURLOPT_INTERFACE
Pass a char * as parameter. This set the interface name to use as outgoing
network interface. The name can be an interface name, an IP address or a host
Pass a char * as parameter. This sets the interface name to use as outgoing
network interface. The name can be an interface name, an IP address, or a host
name.
.IP CURLOPT_LOCALPORT
Pass a long. This sets the local port number of the socket used for
connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and
you are recommended to use \fICURLOPT_LOCALPORTRANGE\fP as well when this is
set. Note that port numbers are only valid 1 - 65535. (Added in 7.15.2)
set. Note that the only valid port numbers are 1 - 65535. (Added in 7.15.2)
.IP CURLOPT_LOCALPORTRANGE
Pass a long. This is the number of attempts libcurl should do to find a
Pass a long. This is the number of attempts libcurl should make to find a
working local port number. It starts with the given \fICURLOPT_LOCALPORT\fP
and adds one to the number for each retry. Setting this to 1 or below will
make libcurl do only one try for the exact port number. Note that port numbers
@@ -503,8 +503,8 @@ caching, or set to -1 to make the cached entries remain forever. By default,
libcurl caches this info for 60 seconds.
NOTE: the name resolve functions of various libc implementations don't re-read
name server information unless explicitly told so (by for example calling
\fIres_init(3)\fP. This may cause libcurl to keep using the older server even
name server information unless explicitly told so (for example, by calling
\fIres_init(3)\fP). This may cause libcurl to keep using the older server even
if DHCP has updated the server info, and this may look like a DNS cache issue
to the casual libcurl-app user.
.IP CURLOPT_DNS_USE_GLOBAL_CACHE
@@ -560,8 +560,8 @@ Pass a long, set to one of the values described below.
.RS
.IP CURL_NETRC_OPTIONAL
The use of your \fI~/.netrc\fP file is optional, and information in the URL is
to be preferred. The file will be scanned with the host and user name (to
find the password only) or with the host only, to find the first user name and
to be preferred. The file will be scanned for the host and user name (to
find the password only) or for the host only, to find the first user name and
password after that \fImachine\fP, which ever information is not specified in
the URL.
@@ -572,7 +572,7 @@ The library will ignore the file and use only the information in the URL.
This is the default.
.IP CURL_NETRC_REQUIRED
This value tells the library that use of the file is required, to ignore the
information in the URL, and to search the file with the host only.
information in the URL, and to search the file for the host only.
.RE
Only machine name, user name and password are taken into account
(init macros and similar things aren't supported).
@@ -586,9 +586,9 @@ option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to
find a .netrc file in the current user's home directory. (Added in 7.10.9)
.IP CURLOPT_USERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection. Use \fICURLOPT_HTTPAUTH\fP to decide authentication method.
the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method.
When using NTLM, you can set domain by prepending it to the user name and
When using NTLM, you can set the domain by prepending it to the user name and
separating the domain and name with a forward (/) or backward slash (\\). Like
this: "domain/user:password" or "domain\\user:password". Some HTTP servers (on
Windows) support this style even for Basic authentication.
@@ -602,17 +602,14 @@ to prevent accidental information leakage.
.IP CURLOPT_PROXYUSERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide
authentication method.
the authentication method.
.IP CURLOPT_USERNAME
Pass a char * as parameter, which should be pointing to the zero terminated
user name to use for the transfer.
The CURLOPT_USERNAME option should be used in same way as the
\fICURLOPT_USERPWD\fP is used. In comparison to \fICURLOPT_USERPWD\fP the
CURLOPT_USERNAME allows the username to contain colon, like in following
example: "sip:user@example.com". Note the CURLOPT_USERNAME option is an
alternative way to set the user name. There is no meaning to use it together
with the \fICURLOPT_USERPWD\fP option.
\fBCURLOPT_USERNAME\fP sets the user name to be used in protocol
authentication. You should not use this option together with the (older)
CURLOPT_USERPWD option.
In order to specify the password to be used in conjunction with the user name
use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1)
@@ -621,15 +618,15 @@ Pass a char * as parameter, which should be pointing to the zero terminated
password to use for the transfer.
The CURLOPT_PASSWORD option should be used in conjunction with
as the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
.IP CURLOPT_PROXYUSERNAME
Pass a char * as parameter, which should be pointing to the zero terminated
user name to use for the transfer while connecting to Proxy.
The CURLOPT_PROXYUSERNAME option should be used in same way as the
\fICURLOPT_PROXYUSERPWD\fP is used. In comparison to \fICURLOPT_PROXYUSERPWD\fP
the CURLOPT_PROXYUSERNAME allows the username to contain colon,
like in following example: "sip:user@example.com".
the CURLOPT_PROXYUSERNAME allows the username to contain a colon,
like in the following example: "sip:user@example.com".
Note the CURLOPT_PROXYUSERNAME option is an alternative way to set the user name
while connecting to Proxy. There is no meaning to use it together
with the \fICURLOPT_PROXYUSERPWD\fP option.
@@ -641,12 +638,12 @@ Pass a char * as parameter, which should be pointing to the zero terminated
password to use for the transfer while connecting to Proxy.
The CURLOPT_PROXYPASSWORD option should be used in conjunction with
as the \fICURLOPT_PROXYUSERNAME\fP option. (Added in 7.19.1)
the \fICURLOPT_PROXYUSERNAME\fP option. (Added in 7.19.1)
.IP CURLOPT_HTTPAUTH
Pass a long as parameter, which is set to a bitmask, to tell libcurl what
Pass a long as parameter, which is set to a bitmask, to tell libcurl which
authentication method(s) you want it to use. The available bits are listed
below. If more than one bit is set, libcurl will first query the site to see
what authentication methods it supports and then pick the best one you allow
which authentication methods it supports and then pick the best one you allow
it to use. For some methods, this will induce an extra network round-trip. Set
the actual name and password with the \fICURLOPT_USERPWD\fP option or
with the \fICURLOPT_USERNAME\fP and the \fICURLOPT_USERPASSWORD\fP options.
@@ -654,18 +651,25 @@ with the \fICURLOPT_USERNAME\fP and the \fICURLOPT_USERPASSWORD\fP options.
.RS
.IP CURLAUTH_BASIC
HTTP Basic authentication. This is the default choice, and the only method
that is in wide-spread use and supported virtually everywhere. This is sending
that is in wide-spread use and supported virtually everywhere. This sends
the user name and password over the network in plain text, easily captured by
others.
.IP CURLAUTH_DIGEST
HTTP Digest authentication. Digest authentication is defined in RFC2617 and
is a more secure way to do authentication over public networks than the
regular old-fashioned Basic method.
.IP CURLAUTH_DIGEST_IE
HTTP Digest authentication with an IE flavor. Digest authentication is
defined in RFC2617 and is a more secure way to do authentication over public
networks than the regular old-fashioned Basic method. The IE flavor is simply
that libcurl will use a special "quirk" that IE is known to have used before
version 7 and that some servers require the client to use. (This define was
added in 7.19.3)
.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
applications. It is primarily meant as a support for Kerberos5 authentication
but may be also used along with another authentication methods. For more
but may also be used along with other authentication methods. For more
information see IETF draft draft-brezak-spnego-http-04.txt.
You need to build libcurl with a suitable GSS-API library for this to work.
@@ -686,7 +690,7 @@ libcurl pick any it finds suitable. libcurl will automatically select the one it
finds most secure.
.RE
.IP CURLOPT_PROXYAUTH
Pass a long as parameter, which is set to a bitmask, to tell libcurl what
Pass a long as parameter, which is set to a bitmask, to tell libcurl which
authentication method(s) you want it to use for your proxy authentication. If
more than one bit is set, libcurl will first query the site to see what
authentication methods it supports and then pick the best one you allow it to
@@ -732,13 +736,20 @@ redirections have been followed, the next redirect will cause an error
Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for
an infinite number of redirects (which is the default)
.IP CURLOPT_POSTREDIR
A parameter set to 1 tells the library to respect RFC 2616/10.3.2 and not
convert POST requests into GET requests when following a 301 redirection. The
non-RFC behaviour is ubiquitous in web browsers, so the library does the
conversion by default to maintain consistency. However, a server may requires
a POST to remain a POST after such a redirection. This option is meaningful
only when setting \fICURLOPT_FOLLOWLOCATION\fP. (Added in 7.17.1)
(This option was known as CURLOPT_POST301 up to 7.19.0)
Pass a bitmask to control how libcurl acts on redirects after POSTs that get a
301 or 302 response back. A parameter with bit 0 set (value
\fBCURL_REDIR_POST_301\fP) tells the library to respect RFC 2616/10.3.2 and
not convert POST requests into GET requests when following a 301
redirection. Setting bit 1 (value CURL_REDIR_POST_302) makes libcurl maintain
the request method after a 302 redirect. CURL_REDIR_POST_ALL is a convenience
define that sets both bits.
The non-RFC behaviour is ubiquitous in web browsers, so the library does the
conversion by default to maintain consistency. However, a server may require a
POST to remain a POST after such a redirection. This option is meaningful only
when setting \fICURLOPT_FOLLOWLOCATION\fP. (Added in 7.17.1) (This option was
known as CURLOPT_POST301 up to 7.19.0 as it only supported the 301 way before
then)
.IP CURLOPT_PUT
A parameter set to 1 tells the library to use HTTP PUT to transfer data. The
data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
@@ -836,7 +847,7 @@ copy. In any case, the size must not be changed after
.IP CURLOPT_HTTPPOST
Tells libcurl you want a multipart/formdata HTTP POST to be made and you
instruct what data to pass on to the server. Pass a pointer to a linked list
of curl_httppost structs as parameter. . The easiest way to create such a
of curl_httppost structs as parameter. The easiest way to create such a
list, is to use \fIcurl_formadd(3)\fP as documented. The data in this list
must remain intact until you close this curl handle again with
\fIcurl_easy_cleanup(3)\fP.
@@ -863,10 +874,10 @@ curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire
list. If you add a header that is otherwise generated and used by libcurl
internally, your added one will be used instead. If you add a header with no
contents as in 'Accept:' (no data on the right side of the colon), the
content as in 'Accept:' (no data on the right side of the colon), the
internally used header will get disabled. Thus, using this option you can add
new headers, replace internal headers and remove internal headers. To add a
header with no contents, make the contents be two quotes: \&"". The headers
header with no content, make the content be two quotes: \&"". The headers
included in the linked list must not be CRLF-terminated, because curl adds
CRLF after each header item. Failure to comply with this will result in
strange bugs because the server will most likely ignore part of the headers
@@ -920,7 +931,7 @@ dumped to a file.
Given an empty or non-existing file or by passing the empty string (""), this
option will enable cookies for this curl handle, making it understand and
parse received cookies and then use matching cookies in future request.
parse received cookies and then use matching cookies in future requests.
If you use this option multiple times, you just add more files to read.
Subsequent files will add more cookies.
@@ -941,7 +952,7 @@ about this possibly lethal situation.
Pass a long set to 1 to mark this as a new cookie "session". It will force
libcurl to ignore all cookies it is about to load that are "session cookies"
from the previous session. By default, libcurl always stores and loads all
cookies, independent if they are session cookies are not. Session cookies are
cookies, independent if they are session cookies or not. Session cookies are
cookies without expiry date and they are meant to be alive and existing for
this "session" only.
.IP CURLOPT_COOKIELIST
@@ -955,7 +966,7 @@ all cookies known by cURL to the file specified by \fICURLOPT_COOKIEJAR\fP.
(Added in 7.17.1)
.IP CURLOPT_HTTPGET
Pass a long. If the long is 1, this forces the HTTP request to get back
to GET. usable if a POST, HEAD, PUT or a custom request have been used
to GET. Usable if a POST, HEAD, PUT, or a custom request has been used
previously using the same curl handle.
When setting \fICURLOPT_HTTPGET\fP to 1, it will automatically set
@@ -992,17 +1003,17 @@ option is set to zero. (added in 7.16.2)
.SH FTP OPTIONS
.IP CURLOPT_FTPPORT
Pass a pointer to a zero terminated string as parameter. It will be used to
get the IP address to use for the ftp PORT instruction. The PORT instruction
get the IP address to use for the FTP PORT instruction. The PORT instruction
tells the remote server to connect to our specified IP address. The string may
be a plain IP address, a host name, an network interface name (under Unix) or
just a '-' letter to let the library use your systems default IP
be a plain IP address, a host name, a network interface name (under Unix) or
just a '-' symbol to let the library use your system's default IP
address. Default FTP operations are passive, and thus won't use PORT.
You disable PORT again and go back to using the passive version by setting
this option to NULL.
.IP CURLOPT_QUOTE
Pass a pointer to a linked list of FTP or SFTP commands to pass to
the server prior to your ftp request. This will be done before any
the server prior to your FTP request. This will be done before any
other commands are issued (even before the CWD command for FTP). The
linked list should be a fully valid list of 'struct curl_slist' structs
properly filled in with text strings. Use \fIcurl_slist_append(3)\fP
@@ -1017,7 +1028,7 @@ rename, rm, rmdir, symlink (see
(SFTP support added in 7.16.3)
.IP CURLOPT_POSTQUOTE
Pass a pointer to a linked list of FTP or SFTP commands to pass to the
server after your ftp transfer request. The linked list should be a
server after your FTP transfer request. The linked list should be a
fully valid list of struct curl_slist structs properly filled in as
described for \fICURLOPT_QUOTE\fP. Disable this operation again by
setting a NULL to this option.
@@ -1040,7 +1051,7 @@ might not include subdirectories and symbolic links.
(This option was known as CURLOPT_FTPLISTONLY up to 7.16.4)
.IP CURLOPT_APPEND
A parameter set to 1 tells the library to append to the remote file instead of
overwrite it. This is only useful when uploading to an ftp site.
overwrite it. This is only useful when uploading to an FTP site.
(This option was known as CURLOPT_FTPAPPEND up to 7.16.4)
.IP CURLOPT_FTP_USE_EPRT
@@ -1091,7 +1102,7 @@ from the 227-response. (Added in 7.14.2)
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
.IP CURLOPT_USE_SSL
Pass a long using one of the values from below, to make libcurl use your
desired level of SSL for the ftp transfer. (Added in 7.11.0)
desired level of SSL for the FTP transfer. (Added in 7.11.0)
(This option was known as CURLOPT_FTP_SSL up to 7.16.4, and the constants
were known as CURLFTPSSL_*)
@@ -1111,11 +1122,11 @@ Pass a long using one of the values from below, to alter how libcurl issues
\fICURLOPT_USE_SSL\fP). (Added in 7.12.2)
.RS
.IP CURLFTPAUTH_DEFAULT
Allow libcurl to decide
Allow libcurl to decide.
.IP CURLFTPAUTH_SSL
Try "AUTH SSL" first, and only if that fails try "AUTH TLS"
Try "AUTH SSL" first, and only if that fails try "AUTH TLS".
.IP CURLFTPAUTH_TLS
Try "AUTH TLS" first, and only if that fails try "AUTH SSL"
Try "AUTH TLS" first, and only if that fails try "AUTH SSL".
.RE
.IP CURLOPT_FTP_SSL_CCC
If enabled, this option makes libcurl use CCC (Clear Command Channel). It
@@ -1143,7 +1154,7 @@ argument should be one of the following alternatives:
.RS
.IP CURLFTPMETHOD_MULTICWD
libcurl does a single CWD operation for each path part in the given URL. For
deep hierarchies this means very many commands. This is how RFC1738 says it
deep hierarchies this means many commands. This is how RFC1738 says it
should be done. This is the default but the slowest behavior.
.IP CURLFTPMETHOD_NOCWD
libcurl does no CWD at all. libcurl will do SIZE, RETR, STOR etc and give a
@@ -1155,7 +1166,7 @@ compliant than 'nocwd' but without the full penalty of 'multicwd'.
.RE
.SH PROTOCOL OPTIONS
.IP CURLOPT_TRANSFERTEXT
A parameter set to 1 tells the library to use ASCII mode for ftp transfers,
A parameter set to 1 tells the library to use ASCII mode for FTP transfers,
instead of the default binary transfer. For win32 systems it does not set the
stdout to binary mode. This option can be usable when transferring text data
between systems with different views on certain characters, such as newlines
@@ -1163,7 +1174,7 @@ or similar.
libcurl does not do a complete ASCII conversion when doing ASCII transfers
over FTP. This is a known limitation/flaw that nobody has rectified. libcurl
simply sets the mode to ascii and performs a standard transfer.
simply sets the mode to ASCII and performs a standard transfer.
.IP CURLOPT_PROXY_TRANSFER_MODE
Pass a long. If the value is set to 1 (one), it tells libcurl to set the
transfer mode (binary or ASCII) for FTP transfers done via an HTTP proxy, by
@@ -1194,16 +1205,21 @@ 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 used
instead of GET or HEAD when doing an HTTP request, or instead of LIST or NLST
when doing an ftp directory listing. This is useful for doing DELETE or other
when doing a 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.
Note that libcurl will still act and assume the keyword it would use if you
didn't set your custom one is the one in use and it will act according to
that. Thus, changing this to a HEAD when libcurl otherwise would do a GET
might cause libcurl to act funny, and similar. To switch to a proper HEAD, use
\fICURLOPT_NOBODY\fP, to switch to a proper POST, use \fICURLOPT_POST\fP or
\fICURLOPT_POSTFIELDS\fP and so on.
When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
something, you don't actually change how libcurl behaves or acts in regards to
the particular request method, it will only change the actual string sent in
the request.
For example: if you tell libcurl to do a HEAD request, but then change the
request to a "GET" with \fBCURLOPT_CUSTOMREQUEST\fP you'll still see libcurl
act as if it sent a HEAD even when it does send a GET.
To switch to a proper HEAD, use \fICURLOPT_NOBODY\fP, to switch to a proper
POST, use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and so on.
Restore to the internal default by setting this to NULL.
@@ -1284,10 +1300,10 @@ value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP
or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP and FTP.
The last modification time of a file is not always known and in such instances
this feature will have no effect even if the given time condition would have
not been met.
this feature will have no effect even if the given time condition would not have
been met.
.IP CURLOPT_TIMEVALUE
Pass a long as parameter. This should be the time in seconds since 1 jan 1970,
Pass a long as parameter. This should be the time in seconds since 1 Jan 1970,
and the time will be used in a condition as specified with
\fICURLOPT_TIMECONDITION\fP.
.SH CONNECTION OPTIONS
@@ -1315,32 +1331,32 @@ Pass a long as parameter. It contains the time in seconds that the transfer
should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider
it too slow and abort.
.IP CURLOPT_MAX_SEND_SPEED_LARGE
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
average during the transfer, the transfer will pause to keep the average rate
less than or equal to the parameter value. Defaults to unlimited
speed. (Added in 7.15.5)
Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in
bytes per second) on cumulative average during the transfer, the transfer will
pause to keep the average rate less than or equal to the parameter value.
Defaults to unlimited speed. (Added in 7.15.5)
.IP CURLOPT_MAX_RECV_SPEED_LARGE
Pass a curl_off_t as parameter. If a download exceeds this speed on
cumulative average during the transfer, the transfer will pause to keep the
average rate less than or equal to the parameter value. Defaults to unlimited
speed. (Added in 7.15.5)
Pass a curl_off_t as parameter. If a download exceeds this speed (counted in
bytes per second) on cumulative average during the transfer, the transfer will
pause to keep the average rate less than or equal to the parameter
value. Defaults to unlimited speed. (Added in 7.15.5)
.IP CURLOPT_MAXCONNECTS
Pass a long. The set number will be the persistent connection cache size. The
set amount will be the maximum amount of simultaneously open connections that
libcurl may cache in this easy handle. Default is 5, and there isn't much
point in changing this value unless you are perfectly aware of how this work
and changes libcurl's behaviour. This concerns connection using any of the
point in changing this value unless you are perfectly aware of how this works
and changes libcurl's behaviour. This concerns connections using any of the
protocols that support persistent connections.
When reaching the maximum limit, curl closes the oldest one in the cache to
prevent the number of open connections to increase.
prevent increasing the number of open connections.
If you already have performed transfers with this curl handle, setting a
smaller MAXCONNECTS than before may cause open connections to get closed
unnecessarily.
Note that if you add this easy handle to a multi handle, this setting is not
being acknowledged, but you must instead use \fIcurl_multi_setopt(3)\fP and
acknowledged, and you must instead use \fIcurl_multi_setopt(3)\fP and
the \fICURLMOPT_MAXCONNECTS\fP option.
.IP CURLOPT_CLOSEPOLICY
(Obsolete) This option does nothing.
@@ -1353,10 +1369,10 @@ what it does. Set this to 0 to have libcurl attempt re-using an existing
connection (default behavior).
.IP CURLOPT_FORBID_REUSE
Pass a long. Set to 1 to make the next transfer explicitly close the
connection when done. Normally, libcurl keep all connections alive when done
with one transfer in case there comes a succeeding one that can re-use them.
connection when done. Normally, libcurl keeps all connections alive when done
with one transfer in case a succeeding one follows that can re-use them.
This option should be used with caution and only if you understand what it
does. Set to 0 to have libcurl keep the connection open for possibly later
does. Set to 0 to have libcurl keep the connection open for possible later
re-use (default behavior).
.IP CURLOPT_CONNECTTIMEOUT
Pass a long. It should contain the maximum time in seconds that you allow the
@@ -1381,13 +1397,14 @@ resolve addresses using more than one version of IP. The allowed values are:
.IP CURL_IPRESOLVE_WHATEVER
Default, resolves addresses to all IP versions that your system allows.
.IP CURL_IPRESOLVE_V4
Resolve to ipv4 addresses.
Resolve to IPv4 addresses.
.IP CURL_IPRESOLVE_V6
Resolve to ipv6 addresses.
Resolve to IPv6 addresses.
.RE
.IP CURLOPT_CONNECT_ONLY
Pass a long. If the parameter equals 1, it tells the library to perform all
the required proxy authentication and connection setup, but no data transfer.
This option is useful only on HTTP URLs.
This option is useful with the \fICURLINFO_LASTSOCKET\fP option to
\fIcurl_easy_getinfo(3)\fP. The library can set up the connection and then the
@@ -1492,14 +1509,14 @@ even indicate an accessible file.
Note that option is by default set to the system path where libcurl's cacert
bundle is assumed to be stored, as established at build time.
When built against NSS this is the directory that the NSS certificate
When built against NSS, this is the directory that the NSS certificate
database resides in.
.IP CURLOPT_ISSUERCERT
Pass a char * to a zero terminated string naming a file holding a CA
certificate in PEM format. If the option is set, an additional check against
the peer certificate is performed to verify the issuer is indeed the one
associated with the certificate provided by the option. This additional check
is useful in multi-level PKI where one need to enforce the peer certificate is
is useful in multi-level PKI where one needs to enforce that the peer certificate is
from a specific branch of the tree.
This option makes sense only when used in combination with the
@@ -1540,7 +1557,7 @@ found in the CRL does not trigger this specific error. (Added in 7.19.0)
.IP CURLOPT_CERTINFO
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
this enabled, libcurl (if built with OpenSSL) will extract lots of information
and data about the certificate's in the certificate chain used in the SSL
and data about the certificates in the certificate chain used in the SSL
connection. This data is then possible to extract after a transfer using
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
7.19.1)
@@ -1557,7 +1574,7 @@ Pass a long as parameter.
This option determines whether libcurl verifies that the server cert is for
the server it is known as.
When negotiating an SSL connection, the server sends a certificate indicating
When negotiating a SSL connection, the server sends a certificate indicating
its identity.
When \fICURLOPT_SSL_VERIFYHOST\fP is 2, that certificate must indicate that
@@ -1576,15 +1593,14 @@ certificate.
The default, since 7.10, is 2.
The checking this option controls is of the identity that the server
\fIclaims\fP. The server could be lying. To control lying, see
\fICURLOPT_SSL_VERIFYPEER\fP.
This option controls checking the server's claimed identity. The server could
be lying. To control lying, see \fICURLOPT_SSL_VERIFYPEER\fP.
.IP CURLOPT_SSL_CIPHER_LIST
Pass a char *, pointing to a zero terminated string holding the list of
ciphers to use for the SSL connection. The list must be syntactically correct,
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.
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.
For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA',
\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
@@ -1593,7 +1609,7 @@ compile OpenSSL.
You'll find more details about cipher lists on this URL:
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
For NSS valid examples of cipher lists include 'rsa_rc4_128_md5',
For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
\'rsa_aes_128_sha\', etc. With NSS you don't add/remove ciphers. If one uses
this option then all known ciphers are disabled and only those passed in
are enabled.
@@ -1608,9 +1624,9 @@ cache. Note that while nothing ever should get hurt by attempting to reuse SSL
session-IDs, there seem to be broken SSL implementations in the wild that may
require you to disable this in order for you to succeed. (Added in 7.16.0)
.IP CURLOPT_KRBLEVEL
Pass a char * as parameter. Set the kerberos security level for FTP; this
also enables kerberos awareness. This is a string, 'clear', 'safe',
'confidential' or \&'private'. If the string is set but doesn't match one
Pass a char * as parameter. Set the kerberos security level for FTP; this also
enables kerberos awareness. This is a string, \&'clear', \&'safe',
\&'confidential' or \&'private'. If the string is set but doesn't match one
of these, 'private' will be used. Set the string to NULL to disable kerberos
support for FTP.
@@ -1651,7 +1667,7 @@ share handle. See \fIcurl_share_setopt(3)\fP for details.
If you add a share that is set to share cookies, your easy handle will use
that cookie cache and get the cookie engine enabled. If you unshare an object
that were using cookies (or change to another object that doesn't share
that was using cookies (or change to another object that doesn't share
cookies), the easy handle will get its cookie engine disabled.
Data that the share object is not set to share will be dealt with the usual
@@ -1660,12 +1676,12 @@ way, as if no share was used.
Pass a long as a parameter, containing the value of the permissions that will
be assigned to newly created files on the remote server. The default value is
\fI0644\fP, but any valid value can be used. The only protocols that can use
this are \fIsftp://\fP, \fIscp://\fP and \fIfile://\fP. (Added in 7.16.4)
this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. (Added in 7.16.4)
.IP CURLOPT_NEW_DIRECTORY_PERMS
Pass a long as a parameter, containing the value of the permissions that will
be assigned to newly created directories on the remote server. The default
value is \fI0755\fP, but any valid value can be used. The only protocols that
can use this are \fIsftp://\fP, \fIscp://\fP and \fIfile://\fP.
can use this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP.
(Added in 7.16.4)
.SH TELNET OPTIONS
.IP CURLOPT_TELNETOPTIONS

View File

@@ -106,8 +106,9 @@ long which gives the length of the buffer.
Tells libcurl to use the \fICURLOPT_READFUNCTION\fP callback to get data. The
parameter you pass to \fICURLFORM_STREAM\fP is the pointer passed on to the
read callback's fourth argument. If you want the part to look like a file
upload one, set the \fICURLFORM_FILENAME\fP parameter as well. (Option added
in libcurl 7.18.2)
upload one, set the \fICURLFORM_FILENAME\fP parameter as well. Note that when
using \fICURLFORM_STREAM\fP, \fICURLFORM_CONTENTSLENGTH\fP must also be set
with the total expected length of the part. (Option added in libcurl 7.18.2)
.IP CURLFORM_ARRAY
Another possibility to send options to curl_formadd() is the
\fBCURLFORM_ARRAY\fP option, that passes a struct curl_forms array pointer as

View File

@@ -13,7 +13,7 @@ curl_formfree - free a previously build multipart/formdata HTTP POST chain
.SH DESCRIPTION
curl_formfree() is used to clean up data previously built/appended with
\fIcurl_formadd(3)\fP. This must be called when the data has been used, which
typically means after the \fIcurl_easy_perform(3)\fP has been called.
typically means after \fIcurl_easy_perform(3)\fP has been called.
.SH RETURN VALUE
None
.SH "SEE ALSO"

View File

@@ -4,7 +4,7 @@
.\"
.TH curl_formget 3 "20 June 2006" "libcurl 7.15.5" "libcurl Manual"
.SH NAME
curl_formget - serialize a previously build multipart/formdata HTTP POST chain
curl_formget - serialize a previously built multipart/formdata HTTP POST chain
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp

View File

@@ -4,7 +4,7 @@
.\"
.TH curl_getdate 3 "12 Aug 2005" "libcurl 7.0" "libcurl Manual"
.SH NAME
curl_getdate - Convert an date string to number of seconds since January 1,
curl_getdate - Convert a date string to number of seconds since January 1,
1970
.SH SYNOPSIS
.B #include <curl/curl.h>
@@ -27,7 +27,7 @@ items:
.TP 0.8i
.B calendar date items
Can be specified several ways. Month names can only be three-letter english
abbrivations, numbers can be zero-prefixed and the year may use 2 or 4 digits.
abbreviations, numbers can be zero-prefixed and the year may use 2 or 4 digits.
Examples: 06 Nov 1994, 06-Nov-94 and Nov-94 6.
.TP
.B time of the day items
@@ -96,5 +96,5 @@ The former version of this function was built with yacc and was not only very
large, it was also never quite understood and it wasn't possible to build with
non-GNU tools since only GNU Bison could make it thread-safe!
The rewrite was done for 7.12.2. The new one is much smaller and use simpler
The rewrite was done for 7.12.2. The new one is much smaller and uses simpler
code.

View File

@@ -24,7 +24,7 @@ to find the specified name, it returns a null pointer.
.SH NOTE
Under unix operating systems, there isn't any point in returning an allocated
memory, although other systems won't work properly if this isn't done. The
unix implementation thus have to suffer slightly from the drawbacks of other
unix implementation thus has to suffer slightly from the drawbacks of other
systems.
.SH "SEE ALSO"
.BR getenv "(3C), "

View File

@@ -23,7 +23,7 @@ effect as one call.
The flags option is a bit pattern that tells libcurl exactly what features to
init, as described below. Set the desired bits by ORing the values together.
In normal operation, you must specify CURL_GLOBAL_ALL. Don't use any other
value unless you are familiar with and mean to control internal operations of
value unless you are familiar with it and mean to control internal operations of
libcurl.
\fBThis function is not thread safe.\fP You must not call it when any other

View File

@@ -28,7 +28,7 @@ curl_mvsprintf - formatted output conversion
.br
.BI "char *curl_mvaprintf(const char *" format ", va_list " args ");"
.SH DESCRIPTION
These are all functions that produces output according to a format string and
These are all functions that produce output according to a format string and
given arguments. These are mostly clones of the well-known C-style functions
and there will be no detailed explanation of all available formatting rules
and usage here.
@@ -83,8 +83,8 @@ future. They will instead be made "available" by source code access only, and
then as curlx_-prefixed functions. See lib/README.curlx for further details.
.SH RETURN VALUE
The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to
a newly allocated string, or NULL it it failed.
a newly allocated string, or NULL if it failed.
All other functions return the number of character they actually outputed.
All other functions return the number of characters they actually outputted.
.SH "SEE ALSO"
.BR printf "(3), " sprintf "(3), " fprintf "(3), " vprintf "(3) "

View File

@@ -2,7 +2,7 @@
.\"
.TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
.SH NAME
curl_multi_assign \- set data to associated with an internal socket
curl_multi_assign \- set data to association with an internal socket
.SH SYNOPSIS
#include <curl/curl.h>
@@ -34,7 +34,7 @@ In a typical application you allocate a struct or at least use some kind of
semi-dynamic data for each socket that we must wait for action on when using
the \fIcurl_multi_socket(3)\fP approach.
When our socket-callback get called by libcurl and we get to know about yet
When our socket-callback gets called by libcurl and we get to know about yet
another socket to wait for, we can use \fIcurl_multi_assign(3)\fP to point out
the particular data so that when we get updates about this same socket again,
we don't have to find the struct associated with this socket by ourselves.

View File

@@ -17,9 +17,9 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
This function extracts file descriptor information from a given multi_handle.
libcurl returns its fd_set sets. The application can use these to select() on,
but be sure to FD_ZERO them before calling this function as
\fIcurl_multi_fdset(3)\fP only adds its own descriptors it doesn't zero or
otherwise remove any other. The \fIcurl_multi_perform(3)\fP function should be
called as soon as one of them are ready to be read from or written to.
\fIcurl_multi_fdset(3)\fP only adds its own descriptors, it doesn't zero or
otherwise remove any others. The \fIcurl_multi_perform(3)\fP function should be
called as soon as one of them is ready to be read from or written to.
If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when
this function returns. Otherwise it will contain the higher descriptor number

View File

@@ -29,7 +29,7 @@ is emptied.
calling \fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or
\fIcurl_easy_cleanup(3)\fP.
The 'CURLMsg' struct is very simple and only contain very basic information.
The 'CURLMsg' struct is very simple and only contains 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):
@@ -48,7 +48,7 @@ When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that
is done, and then \fBresult\fP contains the return code for the easy handle
that just completed.
At this point, there is no other \fBmsg\fP types defined.
At this point, there are no other \fBmsg\fP types defined.
.SH "RETURN VALUE"
A pointer to a filled-in struct, or NULL if it failed or ran out of
structs. It also writes the number of messages left in the queue (after this

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 referred to as a multi handle on some places in the
multi-functions, sometimes referred to as a multi handle in 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

@@ -32,12 +32,12 @@ 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". Do note that \fIcurl_multi_perform(3)\fP
will return \fICURLM_CALL_MULTI_PERFORM\fP only when it wants to be called
again \fBimmediately\fP. When things are fine and there are nothing immediate
again \fBimmediately\fP. When things are fine and there is nothing immediate
it wants done, it'll return \fICURLM_OK\fP and you need to wait for \&"action"
and then call this function again.
NOTE that this only returns errors etc regarding the whole multi stack. There
might still have occurred problems on individual transfers even when this
NOTE that this only returns errors etc regarding the whole multi stack. Problems
still might have occurred on individual transfers even when this
function returns \fICURLM_OK\fP.
.SH "TYPICAL USAGE"
Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's

View File

@@ -21,7 +21,7 @@ You can only set one option in each function call.
.IP CURLMOPT_SOCKETFUNCTION
Pass a pointer to a function matching the \fBcurl_socket_callback\fP
prototype. The \fIcurl_multi_socket(3)\fP functions inform the application
about updates in the socket (file descriptor) status by doing none, one or
about updates in the socket (file descriptor) status by doing none, one, or
multiple calls to the curl_socket_callback given in the \fBparam\fP
argument. They update the status with changes since the previous time a
\fIcurl_multi_socket(3)\fP function was called. If the given callback pointer
@@ -38,7 +38,7 @@ Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi
handle will make it attempt to perform HTTP Pipelining as far as possible for
transfers using this handle. This means that if you add a second request that
can use an already existing connection, the second request will be \&"piped"
on the same connection rather than being executed in parallell. (Added in
on the same connection rather than being executed in parallel. (Added in
7.16.0)
.IP CURLMOPT_TIMERFUNCTION
Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP
@@ -63,11 +63,11 @@ simultaneously open connections that libcurl may cache. Default is 10, and
libcurl will enlarge the size for each added easy handle to make it fit 4
times the number of added easy handles.
By setting this option, you can prevent the cache size to grow beyond the
By setting this option, you can prevent the cache size from growing beyond the
limit set by you.
When the cache is full, curl closes the oldest one in the cache to prevent the
number of open connections to increase.
number of open connections from increasing.
This option is for the multi handle's use only, when using the easy interface
you should instead use the \fICURLOPT_MAXCONNECTS\fP option.

View File

@@ -44,7 +44,7 @@ is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out
which easy handle that completed.
The \fBcurl_multi_socket_action(3)\fP functions inform the application about
updates in the socket (file descriptor) status by doing none, one or multiple
updates in the socket (file descriptor) status by doing none, one, or multiple
calls to the socket callback function set with the CURLMOPT_SOCKETFUNCTION
option to \fIcurl_multi_setopt(3)\fP. They update the status with changes
since the previous time the callback was called.
@@ -64,7 +64,7 @@ equivalent to \fIcurl_multi_socket_action(3)\fP with \fBev_bitmask\fP set to
Force libcurl to (re-)check all its internal sockets and transfers instead of
just a single one by calling \fBcurl_multi_socket_all(3)\fP. Note that there
should not exist any reasons to use this function!
should not be any reason to use this function!
.SH "CALLBACK DETAILS"
The socket \fBcallback\fP function uses a prototype like this
@@ -121,8 +121,8 @@ In modern libcurls, \fICURLM_CALL_MULTI_PERFORM\fP or
\fICURLM_CALL_MULTI_SOKCET\fP should not be returned and no application needs
to care about them.
NOTE that the return code is for the whole multi stack. There might still have
occurred problems on individual transfers even when one of these functions
NOTE that the return code is for the whole multi stack. Problems still might have
occurred on individual transfers even when one of these functions
return OK.
.SH "TYPICAL USAGE"
1. Create a multi handle
@@ -147,7 +147,7 @@ call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP
8. Go back to step 6.
.SH AVAILABILITY
This function was added in libcurl 7.15.4, although deemed stable since
This function was added in libcurl 7.15.4, and is deemed stable since
7.16.0.
\fIcurl_multi_socket(3)\fP is deprecated, use

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 referred to as a share handle on some places in the
share-functions, sometimes referred to as a share handle in 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

@@ -31,7 +31,7 @@ prototype:
void unlock_function(CURL *handle, curl_lock_data data, void *userptr);
\fIdata\fP defines what data libcurl wants to unlock, and you must make sure
that only one lick is given at any time for each kind of data.
that only one lock is given at any time for each kind of data.
\fIuserptr\fP is the pointer you set with \fICURLSHOPT_USERDATA\fP.
.IP CURLSHOPT_SHARE
@@ -51,7 +51,7 @@ This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that
the specified \fIparameter\fP will no longer be shared. Valid values are
the same as those for \fICURLSHOPT_SHARE\fP.
.IP CURLSHOPT_USERDATA
The \fIparameter\fP allows you to specify a pointer to data that will passed
The \fIparameter\fP allows you to specify a pointer to data that will be passed
to the lock_function and unlock_function each time it is called.
.SH RETURN VALUE
CURLSHE_OK (zero) means that the option was set properly, non-zero means an

View File

@@ -21,7 +21,7 @@ first \fIlen\fP characters of \fIstr1\fP.
.sp
These functions are provided by libcurl to enable applications to compare
strings in a truly portable manner. There are no standard portable case
insensitive string comparison functions. These two works on all platforms.
insensitive string comparison functions. These two work on all platforms.
.SH AVAILABILITY
These functions will be removed from the public libcurl API in a near
future. They will instead be made "available" by source code access only, and

View File

@@ -34,7 +34,7 @@ Returns a pointer to a filled in struct with information about various
run-time features in libcurl. \fItype\fP should be set to the version of this
functionality by the time you write your program. This way, libcurl will
always return a proper struct that your program understands, while programs in
the future might get an different struct. CURLVERSION_NOW will be the most
the future might get a different struct. CURLVERSION_NOW will be the most
recent one for the library you have installed:
data = curl_version_info(CURLVERSION_NOW);
@@ -74,8 +74,8 @@ typedef struct {
} curl_version_info_data;
.fi
\fIage\fP describes what age of this struct this is. The number depends on how
new libcurl you're using. You are however guaranteed to get a struct that you
\fIage\fP describes what the age of this struct is. The number depends on how
new the libcurl you're using is. You are however guaranteed to get a struct that you
have a matching struct for in the header, as you tell libcurl your "age" with
the input argument.
@@ -126,15 +126,15 @@ allows libcurl to use the current user and the current user's password without
the app having to pass them on. (Added in 7.13.2)
.IP CURL_VERSION_CONV
libcurl was built with support for character conversions, as provided by the
CUURLOPT_CONV_* callbacks. (Added in 7.15.4)
CURLOPT_CONV_* callbacks. (Added in 7.15.4)
.RE
\fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
has no SSL support, this is NULL.
\fIssl_version_num\fP is the numerical OpenSSL version value as defined by the
OpenSSL project. If libcurl has no SSL support, this is 0.
\fIlibz_version\fP is an ascii string (there is no numerical version). If
\fIlibz_version\fP is an ASCII string (there is no numerical version). If
libcurl has no libz support, this is NULL.
\fIprotocols\fP is a pointer to an array of char * pointers, containing the

View File

@@ -26,13 +26,13 @@
libcurl-errors \- error codes in libcurl
.SH DESCRIPTION
This man page includes most, if not all, available error codes in libcurl.
Why they occur and possibly what you can do to fix the problem.
Why they occur and possibly what you can do to fix the problem are also included.
.SH "CURLcode"
Almost all "easy" interface functions return a CURLcode error code. No matter
what, using the \fIcurl_easy_setopt(3)\fP option \fICURLOPT_ERRORBUFFER\fP is
a good idea as it will give you a human readable error string that may offer
more details about the error cause than just the error code
does. \fIcurl_easy_strerror(3)\fP can be called to get an error string from a
more details about the cause of the error than just the error code.
\fIcurl_easy_strerror(3)\fP can be called to get an error string from a
given CURLcode number.
CURLcode is one of the following:
@@ -55,7 +55,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 an FTP server, libcurl expects to get a certain reply
After connecting to a FTP server, libcurl expects to get a certain reply
back. This error code implies that it got a strange or bad reply. The given
remote server is probably not an OK FTP server.
.IP "CURLE_REMOTE_ACCESS_DENIED (9)"
@@ -73,7 +73,7 @@ fails to parse that line, this return code is passed back.
.IP "CURLE_FTP_CANT_GET_HOST (15)"
An internal failure to lookup the host used for the new connection.
.IP "CURLE_FTP_COULDNT_SET_TYPE (17)"
Received an error when trying to set the transfer mode to binary or ascii.
Received an error when trying to set the transfer mode to binary or ASCII.
.IP "CURLE_PARTIAL_FILE (18)"
A file transfer was shorter or larger than expected. This happens when the
server first reports an expected transfer size, and then delivers data that
@@ -94,19 +94,19 @@ An error occurred when writing received data to a local file, or an error was
returned to libcurl from a write callback.
.IP "CURLE_UPLOAD_FAILED (25)"
Failed starting the upload. For FTP, the server typically denied the STOR
command. The error buffer usually contains the server's explanation to this.
command. The error buffer usually contains the server's explanation for this.
(This error code was formerly known as CURLE_FTP_COULDNT_STOR_FILE.)
.IP "CURLE_READ_ERROR (26)"
There was a problem reading a local file or an error returned by the read
callback.
.IP "CURLE_OUT_OF_MEMORY (27)"
A memory allocation request failed. This is serious badness and
things are severely screwed up if this ever occur.
things are severely screwed up if this ever occurs.
.IP "CURLE_OPERATION_TIMEDOUT (28)"
Operation timeout. The specified time-out period was reached according to the
conditions.
.IP "CURLE_FTP_PORT_FAILED (30)"
The FTP PORT command returned error. This mostly happen when you haven't
The FTP PORT command returned error. This mostly happens when you haven't
specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP.
.IP "CURLE_FTP_COULDNT_USE_REST (31)"
The FTP REST command returned error. This should never happen if the server is
@@ -162,52 +162,52 @@ Failed sending network data.
.IP "CURLE_RECV_ERROR (56)"
Failure with receiving network data.
.IP "CURLE_SSL_CERTPROBLEM (58)"
problem with the local client certificate
problem with the local client certificate.
.IP "CURLE_SSL_CIPHER (59)"
Couldn't use specified cipher
Couldn't use specified cipher.
.IP "CURLE_SSL_CACERT (60)"
Peer certificate cannot be authenticated with known CA certificates
Peer certificate cannot be authenticated with known CA certificates.
.IP "CURLE_BAD_CONTENT_ENCODING (61)"
Unrecognized transfer encoding
Unrecognized transfer encoding.
.IP "CURLE_LDAP_INVALID_URL (62)"
Invalid LDAP URL
Invalid LDAP URL.
.IP "CURLE_FILESIZE_EXCEEDED (63)"
Maximum file size exceeded
Maximum file size exceeded.
.IP "CURLE_USE_SSL_FAILED (64)"
Requested FTP SSL level failed
Requested FTP SSL level failed.
.IP "CURLE_SEND_FAIL_REWIND (65)"
When doing a send operation curl had to rewind the data to retransmit, but the
rewinding operation failed
rewinding operation failed.
.IP "CURLE_SSL_ENGINE_INITFAILED (66)"
Initiating the SSL Engine failed
Initiating the SSL Engine failed.
.IP "CURLE_LOGIN_DENIED (67)"
The remote server denied curl to login (Added in 7.13.1)
.IP "CURLE_TFTP_NOTFOUND (68)"
File not found on TFTP server
File not found on TFTP server.
.IP "CURLE_TFTP_PERM (69)"
Permission problem on TFTP server
Permission problem on TFTP server.
.IP "CURLE_REMOTE_DISK_FULL (70)"
Out of disk space on the server
Out of disk space on the server.
.IP "CURLE_TFTP_ILLEGAL (71)"
Illegal TFTP operation
Illegal TFTP operation.
.IP "CURLE_TFTP_UNKNOWNID (72)"
Unknown TFTP transfer ID
Unknown TFTP transfer ID.
.IP "CURLE_REMOTE_FILE_EXISTS (73)"
File already exists and will not be overwritten
File already exists and will not be overwritten.
.IP "CURLE_TFTP_NOSUCHUSER (74)"
This error should never be returned by a properly functioning TFTP server
This error should never be returned by a properly functioning TFTP server.
.IP "CURLE_CONV_FAILED (75)"
Character conversion failed
Character conversion failed.
.IP "CURLE_CONV_REQD (76)"
Caller must register conversion callbacks
Caller must register conversion callbacks.
.IP "CURLE_SSL_CACERT_BADFILE (77)"
Problem with reading the SSL CA cert (path? access rights?)
.IP "CURLE_REMOTE_FILE_NOT_FOUND (78)"
The resource referenced in the URL does not exist
The resource referenced in the URL does not exist.
.IP "CURLE_SSH (79)"
An unspecified error occurred during the SSH session
An unspecified error occurred during the SSH session.
.IP "CURLE_SSL_SHUTDOWN_FAILED (80)"
Failed to shut down the SSL connection
Failed to shut down the SSL connection.
.IP "CURLE_AGAIN (81)"
Socket is not ready for send/recv wait till it's ready and try again. This
return code is only returned from \fIcurl_easy_recv(3)\fP and
@@ -217,7 +217,7 @@ Failed to load CRL file (Added in 7.19.0)
.IP "CURLE_SSL_ISSUER_ERROR (83)"
Issuer check failed (Added in 7.19.0)
.IP "CURLE_OBSOLETE*"
These error codes will never be returned. They used to be used in an old libcurl
These error codes will never be returned. They were used in an old libcurl
version and are currently unused.
.SH "CURLMcode"
This is the generic return code used by functions in the libcurl multi

View File

@@ -121,7 +121,7 @@ again (possibly after having altered some options at your own choice).
.SH "MULTI_SOCKET"
Since 7.16.0, the \fIcurl_multi_socket(3)\fP function offers a way for
applications to not only avoid being forced to use select(), but it also
offers a much more high-performing API that will make a significant difference
offers a much more high-performance API that will make a significant difference
for applications using large numbers of simultaneous connections.
\fIcurl_multi_socket(3)\fP (and \fIcurl_multi_socket_all(3)\fP) is then used

View File

@@ -21,7 +21,7 @@
.\" * $Id$
.\" **************************************************************************
.\"
.TH libcurl-tutorial 3 "27 Feb 2007" "libcurl" "libcurl programming"
.TH libcurl-tutorial 3 "17 Nov 2008" "libcurl" "libcurl programming"
.SH NAME
libcurl-tutorial \- libcurl programming tutorial
.SH "Objective"
@@ -36,12 +36,12 @@ What will be generally referred to as 'the program' will be the collected
source code that you write that is using libcurl for transfers. The program
is outside libcurl and libcurl is outside of the program.
To get the more details on all options and functions described herein, please
To get more details on all options and functions described herein, please
refer to their respective man pages.
.SH "Building"
There are many different ways to build C programs. This chapter will assume a
unix-style build process. If you use a different build system, you can still
UNIX-style build process. If you use a different build system, you can still
read this to get general information that may apply to your environment as
well.
.IP "Compiling the Program"
@@ -72,8 +72,8 @@ if an installed libcurl has been built with SSL support enabled, use
$ curl-config --feature
And if SSL is supported, the keyword 'SSL' will be written to stdout,
possibly together with a few other features that can be on and off on
different libcurls.
possibly together with a few other features that could be either on or off on
for different libcurls.
See also the "Features libcurl Provides" further down.
.IP "autoconf macro"
@@ -87,7 +87,7 @@ The people behind libcurl have put a considerable effort to make libcurl work
on a large amount of different operating systems and environments.
You program libcurl the same way on all platforms that libcurl runs on. There
are only very few minor considerations that differs. If you just make sure to
are only very few minor considerations that differ. If you just make sure to
write your code portable enough, you may very well create yourself a very
portable program. libcurl shouldn't stop you from that.
@@ -113,7 +113,7 @@ should not tell libcurl to do this as well.
.IP CURL_GLOBAL_SSL
which only does anything on libcurls compiled and built SSL-enabled. On these
systems, this will make libcurl initialize the SSL library properly for this
application. This is only needed to do once for each application so if your
application. This only needs to be done once for each application so if your
program or another library already does this, this bit should not be needed.
.RE
@@ -167,11 +167,9 @@ something different. Alas, multiple requests using the same handle will use
the same options.
Many of the options you set in libcurl are "strings", pointers to data
terminated with a zero byte. Keep in mind that when you set strings with
\fIcurl_easy_setopt(3)\fP, libcurl will not copy the data. It will merely
point to the data. You MUST make sure that the data remains available for
libcurl to use until finished or until you use the same option again to point
to something else.
terminated with a zero byte. When you set strings with
\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't
need to be kept around in your application after being set[4].
One of the most basic properties to set in the handle is the URL. You set
your preferred URL to transfer with CURLOPT_URL in a manner similar to:
@@ -193,8 +191,8 @@ similar to this:
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
You can control what data your function get in the forth argument by setting
another property:
You can control what data your callback function gets in the fourth argument
by setting another property:
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
@@ -245,14 +243,20 @@ again. Mind you, it is even preferred that you re-use an existing handle if
you intend to make another transfer. libcurl will then attempt to re-use the
previous connection.
For some protocols, downloading a file can involve a complicated process of
logging in, setting the transfer mode, changing the current directory and
finally transferring the file data. libcurl takes care of all that
complication for you. Given simply the URL to a file, libcurl will take care
of all the details needed to get the file moved from one machine to another.
.SH "Multi-threading Issues"
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
it easy or multi or whatever) between multiple threads. Only use one handle in
one thread at a time.
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
handlers. Signals are used timeouting name resolves (during DNS lookup) - when
built without c-ares support and not on Windows..
handlers. Signals are used for timing out name resolves (during DNS lookup) -
when built without c-ares support and not on Windows.
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
then of course using the underlying SSL library multi-threaded and those libs
@@ -270,19 +274,18 @@ GnuTLS
NSS
is claimed to be thread-safe already without anything required
is claimed to be thread-safe already without anything required.
yassl
Required actions unknown
Required actions unknown.
When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1
for all handles. Everything will or might work fine except that timeouts are
not honored during the DNS lookup - which you can work around by building
libcurl with c-ares support. c-ares is a library that provides asynchronous
name resolves. Unfortunately, c-ares does not yet fully support IPv6. On some
platforms, libcurl simply will not function properly multi-threaded unless
this option is set.
name resolves. On some platforms, libcurl simply will not function properly
multi-threaded unless this option is set.
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
@@ -300,9 +303,9 @@ received output to study is also a clever way to get a better understanding
why the server behaves the way it does. Include headers in the normal body
output with CURLOPT_HEADER set 1.
Of course there are bugs left. We need to get to know about them to be able
Of course, there are bugs left. We need to know about them to be able
to fix them, so we're quite dependent on your bug reports! When you do report
suspected bugs in libcurl, please include as much details you possibly can: a
suspected bugs in libcurl, please include as many details as you possibly can: a
protocol dump that CURLOPT_VERBOSE produces, library version, as much as
possible of your code that uses libcurl, operating system name and version,
compiler name and version etc.
@@ -350,7 +353,7 @@ knowledge of the expected file size. So, set the upload file size using the
CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]:
.nf
/* in this example, file_size must be an off_t variable */
/* in this example, file_size must be an curl_off_t variable */
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
.fi
@@ -389,7 +392,7 @@ to the CURLOPT_USERPWD option like this:
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret");
There's a long time unix "standard" way of storing ftp user names and
There's a long time UNIX "standard" way of storing ftp user names and
passwords, namely in the $HOME/.netrc file. The file should be made private
so that only the user may read it (see also the "Security Considerations"
chapter), as it might contain the password in plain text. libcurl has the
@@ -421,11 +424,11 @@ To pass the known private key password to libcurl:
The previous chapter showed how to set user name and password for getting
URLs that require authentication. When using the HTTP protocol, there are
many different ways a client can provide those credentials to the server and
you can control what way libcurl will (attempt to) use. The default HTTP
you can control which way libcurl will (attempt to) use them. The default HTTP
authentication method is called 'Basic', which is sending the name and
password in clear-text in the HTTP request, base64-encoded. This is insecure.
At the time of this writing libcurl can be built to use: Basic, Digest, NTLM,
At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM,
Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use
with CURLOPT_HTTPAUTH as in:
@@ -472,7 +475,7 @@ CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the
upcoming request.
Ok, so what if you want to post binary data that also requires you to set the
Content-Type: header of the post? Well, binary posts prevents libcurl from
Content-Type: header of the post? Well, binary posts prevent libcurl from
being able to do strlen() on the data to figure out the size, so therefore we
must tell libcurl the size of the post data. Setting headers in libcurl
requests are done in a generic way, by building a list of our own headers and
@@ -499,7 +502,7 @@ then passing that list to libcurl.
While the simple examples above cover the majority of all cases where HTTP
POST operations are required, they don't do multi-part formposts. Multi-part
formposts were introduced as a better way to post (possibly large) binary data
and was first documented in the RFC1867. They're called multi-part because
and were first documented in the RFC1867. They're called multi-part because
they're built by a chain of parts, each being a single unit. Each part has its
own name and contents. You can in fact create and post a multi-part formpost
with the regular libcurl POST support described above, but that would require
@@ -508,7 +511,7 @@ easier, libcurl provides \fIcurl_formadd(3)\fP. Using this function, you add
parts to the form. When you're done adding parts, you post the whole form.
The following example sets two simple text parts with plain textual contents,
and then a file with binary contents and upload the whole thing.
and then a file with binary contents and uploads the whole thing.
.nf
struct curl_httppost *post=NULL;
@@ -537,7 +540,7 @@ headers. It means that each one of these separate parts get a few headers set
that describe the individual content-type, size etc. To enable your
application to handicraft this formpost even more, libcurl allows you to
supply your own set of custom headers to such an individual form part. You can
of course supply headers to as many parts you like, but this little example
of course supply headers to as many parts as you like, but this little example
will show how you set headers to one specific part when you add that to the
post handle:
@@ -559,8 +562,8 @@ post handle:
Since all options on an easyhandle are "sticky", they remain the same until
changed even if you do call \fIcurl_easy_perform(3)\fP, you may need to tell
curl to go back to a plain GET request if you intend to do such a one as your
next request. You force an easyhandle to back to GET by using the
curl to go back to a plain GET request if you intend to do one as your
next request. You force an easyhandle to go back to GET by using the
CURLOPT_HTTPGET option:
curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);
@@ -571,10 +574,10 @@ doing a POST. It will just make it POST without any data to send!
.SH "Showing Progress"
For historical and traditional reasons, libcurl has a built-in progress meter
that can be switched on and then makes it presents a progress meter in your
that can be switched on and then makes it present a progress meter in your
terminal.
Switch on the progress meter by, oddly enough, set CURLOPT_NOPROGRESS to
Switch on the progress meter by, oddly enough, setting CURLOPT_NOPROGRESS to
zero. This option is set to 1 by default.
For most applications however, the built-in progress meter is useless and
@@ -639,7 +642,7 @@ restrictions on what can actually happen. A requested URL that might not be a
HTTP URL will be still be passed to the HTTP proxy to deliver back to
libcurl. This happens transparently, and an application may not need to
know. I say "may", because at times it is very important to understand that
all operations over a HTTP proxy is using the HTTP protocol. For example, you
all operations over a HTTP proxy use the HTTP protocol. For example, you
can't invoke your own custom FTP commands or even proper FTP directory
listings.
@@ -770,7 +773,7 @@ Even if the connection is dropped, all connections involving SSL to the same
host again, will benefit from libcurl's session ID cache that drastically
reduces re-connection time.
FTP connections that are kept alive saves a lot of time, as the command-
FTP connections that are kept alive save a lot of time, as the command-
response round-trips are skipped, and also you don't risk getting blocked
without permission to login again like on many FTP servers only allowing N
persons to be logged in at the same time.
@@ -783,7 +786,7 @@ may also be added in the future.
Each easy handle will attempt to keep the last few connections alive for a
while in case they are to be used again. You can set the size of this "cache"
with the CURLOPT_MAXCONNECTS option. Default is 5. It is very seldom any
with the CURLOPT_MAXCONNECTS option. Default is 5. There is very seldom any
point in changing this value, and if you think of changing this it is often
just a matter of thinking again.
@@ -796,7 +799,7 @@ CURLOPT_FORBID_REUSE to 1.
.SH "HTTP Headers Used by libcurl"
When you use libcurl to do HTTP requests, it'll pass along a series of headers
automatically. It might be good for you to know and understand these ones. You
automatically. It might be good for you to know and understand these. You
can replace or remove them by using the CURLOPT_HTTPHEADER option.
.IP "Host"
@@ -820,7 +823,7 @@ this header.
.SH "Customizing Operations"
There is an ongoing development today where more and more protocols are built
upon HTTP for transport. This has obvious benefits as HTTP is a tested and
reliable protocol that is widely deployed and have excellent proxy-support.
reliable protocol that is widely deployed and has excellent proxy-support.
When you use one of these protocols, and even when doing other kinds of
programming you may need to change the traditional HTTP (or FTP or...)
@@ -836,14 +839,14 @@ for you. It is very simple to use:
curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "MYOWNRUQUEST");
When using the custom request, you change the request keyword of the actual
request you are performing. Thus, by default you make GET request but you can
request you are performing. Thus, by default you make a GET request but you can
also make a POST operation (as described before) and then replace the POST
keyword if you want to. You're the boss.
.IP "Modify Headers"
HTTP-like protocols pass a series of headers to the server when doing the
request, and you're free to pass any amount of extra headers that you
think fit. Adding headers are this easy:
think fit. Adding headers is this easy:
.nf
struct curl_slist *headers=NULL; /* init to NULL is important */
@@ -870,8 +873,8 @@ replace them by simply setting them too:
.IP "Delete Headers"
If you replace an existing header with one with no contents, you will prevent
the header from being sent. Like if you want to completely prevent the
\&"Accept:" header to be sent, you can disable it with code similar to this:
the header from being sent. For instance, if you want to completely prevent the
\&"Accept:" header from being sent, you can disable it with code similar to this:
headers = curl_slist_append(headers, "Accept:");
@@ -890,7 +893,7 @@ data size is unknown.
.IP "HTTP Version"
All HTTP requests includes the version number to tell the server which version
we support. libcurl speak HTTP 1.1 by default. Some very old servers don't
we support. libcurl speaks HTTP 1.1 by default. Some very old servers don't
like getting 1.1-requests and when dealing with stubborn old things like that,
you can tell libcurl to use 1.0 instead by doing something like this:
@@ -899,12 +902,12 @@ you can tell libcurl to use 1.0 instead by doing something like this:
.IP "FTP Custom Commands"
Not all protocols are HTTP-like, and thus the above may not help you when
you want to make for example your FTP transfers to behave differently.
you want to make, for example, your FTP transfers to behave differently.
Sending custom commands to a FTP server means that you need to send the
commands exactly as the FTP server expects them (RFC959 is a good guide
here), and you can only use commands that work on the control-connection
alone. All kinds of commands that requires data interchange and thus needs
alone. All kinds of commands that require data interchange and thus need
a data-connection must be left to libcurl's own judgment. Also be aware
that libcurl will do its very best to change directory to the target
directory before doing any transfer, so if you change directory (with CWD
@@ -944,7 +947,7 @@ combine with CURLOPT_NOBODY. If this option is set, no actual file content
transfer will be performed.
.IP "FTP Custom CUSTOMREQUEST"
If you do what list the contents of a FTP directory using your own defined FTP
If you do want to list the contents of a FTP directory using your own defined FTP
command, CURLOPT_CUSTOMREQUEST will do just that. "NLST" is the default one
for listing directories but you're free to pass in your idea of a good
alternative.
@@ -956,7 +959,7 @@ subsequent request to the server that matches the particular conditions
set. The conditions include that the domain name and path match and that the
cookie hasn't become too old.
In real-world cases, servers send new cookies to replace existing one to
In real-world cases, servers send new cookies to replace existing ones to
update them. Server use cookies to "track" users and to keep "sessions".
Cookies are sent from server to clients with the header Set-Cookie: and
@@ -969,11 +972,11 @@ to set a cookie string like this:
In many cases, that is not enough. You might want to dynamically save
whatever cookies the remote server passes to you, and make sure those cookies
are then use accordingly on later requests.
are then used accordingly on later requests.
One way to do this, is to save all headers you receive in a plain file and
when you make a request, you tell libcurl to read the previous headers to
figure out which cookies to use. Set header file to read cookies from with
figure out which cookies to use. Set the header file to read cookies from with
CURLOPT_COOKIEFILE.
The CURLOPT_COOKIEFILE option also automatically enables the cookie parser in
@@ -982,20 +985,20 @@ understand incoming cookies and they will just be ignored. However, when the
parser is enabled the cookies will be understood and the cookies will be kept
in memory and used properly in subsequent requests when the same handle is
used. Many times this is enough, and you may not have to save the cookies to
disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't
have to exist to enable the parser, so a common way to just enable the parser
and not read able might be to use a file name you know doesn't exist.
disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't have
to exist to enable the parser, so a common way to just enable the parser and
not read any cookies is to use the name of a file you know doesn't exist.
If you rather use existing cookies that you've previously received with your
Netscape or Mozilla browsers, you can make libcurl use that cookie file as
input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
If you would rather use existing cookies that you've previously received with
your Netscape or Mozilla browsers, you can make libcurl use that cookie file
as input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
automatically find out what kind of file it is and act accordingly.
The perhaps most advanced cookie operation libcurl offers, is saving the
Perhaps the most advanced cookie operation libcurl offers, is saving the
entire internal cookie state back into a Netscape/Mozilla formatted cookie
file. We call that the cookie-jar. When you set a file name with
CURLOPT_COOKIEJAR, that file name will be created and all received cookies
will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enabled
will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enables
cookies to get passed on properly between multiple handles without any
information getting lost.
@@ -1003,7 +1006,7 @@ information getting lost.
FTP transfers use a second TCP/IP connection for the data transfer. This is
usually a fact you can forget and ignore but at times this fact will come
back to haunt you. libcurl offers several different ways to custom how the
back to haunt you. libcurl offers several different ways to customize how the
second connection is being made.
libcurl can either connect to the server a second time or tell the server to
@@ -1090,19 +1093,17 @@ Many of the protocols libcurl supports send name and password unencrypted as
clear text (HTTP Basic authentication, FTP, TELNET etc). It is very easy for
anyone on your network or a network nearby yours, to just fire up a network
analyzer tool and eavesdrop on your passwords. Don't let the fact that HTTP
uses base64 encoded passwords fool you. They may not look readable at a first
glance, but they very easily "deciphered" by anyone within seconds.
To avoid this problem, use protocols that don't let snoopers see your
password: HTTPS, FTPS and FTP-kerberos are a few examples. HTTP Digest
authentication allows this too, but isn't supported by libcurl as of this
writing.
Basic uses base64 encoded passwords fool you. They may not look readable at a
first glance, but they very easily "deciphered" by anyone within seconds.
To avoid this problem, use HTTP athentication methods or other protocols that
don't let snoopers see your password: HTTP with Digest, NTLM or GSS
authentication, HTTPS, FTPS, SCP, SFTP and FTP-kerberos are a few examples.
.IP "Showing What You Do"
On a related issue, be aware that even in situations like when you have
problems with libcurl and ask someone for help, everything you reveal in order
to get best possible help might also impose certain security related
risks. Host names, user names, paths, operating system specifics etc (not to
risks. Host names, user names, paths, operating system specifics, etc (not to
mention passwords of course) may in fact be used by intruders to gain
additional information of a potential target.
@@ -1113,10 +1114,10 @@ information with faked data.
.SH "Multiple Transfers Using the multi Interface"
The easy interface as described in detail in this document is a synchronous
interface that transfers one file at a time and doesn't return until its
interface that transfers one file at a time and doesn't return until it is
done.
The multi interface on the other hand, allows your program to transfer
The multi interface, on the other hand, allows your program to transfer
multiple files in both directions at the same time, without forcing you
to use multiple threads. The name might make it seem that the multi
interface is for multi-threaded programs, but the truth is almost the
@@ -1128,7 +1129,7 @@ synchronizing many threads.
To use this interface, you are better off if you first understand the basics
of how to use the easy interface. The multi interface is simply a way to make
multiple transfers at the same time by adding up multiple easy handles in to
multiple transfers at the same time by adding up multiple easy handles into
a "multi stack".
You create the easy handles you want and you set all the options just like you
@@ -1137,7 +1138,7 @@ have been told above, and then you create a multi handle with
with \fIcurl_multi_add_handle(3)\fP.
When you've added the handles you have for the moment (you can still add new
ones at any time), you start the transfers by call
ones at any time), you start the transfers by calling
\fIcurl_multi_perform(3)\fP.
\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as
@@ -1156,7 +1157,7 @@ with the particular file descriptors libcurl uses for the moment.
When you then call select(), it'll return when one of the file handles signal
action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
what it wants to do. Take note that libcurl does also feature some time-out
code so we advice you to never use very long timeouts on select() before you
code so we advise you to never use very long timeouts on select() before you
call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally
every now and then even if none of its file descriptors have signaled
ready. Another precaution you should use: always call
@@ -1187,13 +1188,16 @@ to figure out success on each individual transfer.
.IP "[1]"
libcurl 7.10.3 and later have the ability to switch over to chunked
Transfer-Encoding in cases were HTTP uploads are done with data of an unknown
Transfer-Encoding in cases where HTTP uploads are done with data of an unknown
size.
.IP "[2]"
This happens on Windows machines when libcurl is built and used as a
DLL. However, you can still do this on Windows if you link with a static
library.
.IP "[3]"
The curl-config tool is generated at build-time (on unix-like systems) and
The curl-config tool is generated at build-time (on UNIX-like systems) and
should be installed with the 'make install' or similar instruction that
installs the library, header files, man pages etc.
.IP "[4]"
This behavior was different in versions before 7.17.0, where strings had to
remain valid past the end of the \fIcurl_easy_setopt(3)\fP call.

View File

@@ -4,7 +4,7 @@
.SH NAME
libcurl \- client-side URL transfers
.SH DESCRIPTION
This is an short overview on how to use libcurl in your C programs. There are
This is a short overview on how to use libcurl in your C programs. There are
specific man pages for each function mentioned in here. There are also the
\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
\fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for
@@ -25,14 +25,14 @@ 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
completed, the function return and you can continue. More details are found in
completed, the function returns 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 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. See further deails in the \fIlibcurl-multi(3)\fP man page.
even to easily download multiple files simultaneously using a single thread. See further details in the \fIlibcurl-multi(3)\fP man page.
You can have multiple easy handles share certain data, even if they are used
in different threads. This magic is setup using the share interface, as
@@ -106,7 +106,7 @@ do as many of your file transfers as possible using the same curl handle. When
you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
libcurl will be closed and forgotten.
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used in on
Note that the options set with \fIcurl_easy_setopt(3)\fP will be used on
every repeated \fIcurl_easy_perform(3)\fP call.
.SH "GLOBAL CONSTANTS"
@@ -161,7 +161,7 @@ and has a place to call the libcurl functions. Note that if multiple
modules in the program use libcurl, they all will separately call the
libcurl functions, and that's OK because only the first
\fIcurl_global_init()\fP and the last \fIcurl_global_cleanup()\fP in a
program changes anything. (libcurl uses a reference count in static
program change anything. (libcurl uses a reference count in static
memory).
In a C++ module, it is common to deal with the global constant

View File

@@ -1,38 +0,0 @@
#
# Build test apps for the Hiper project
# During dev at least, we use a static libcurl.
#
LDFLAGS = -lcrypt -lidn -lssl -lcrypto -lz -lresolv -L../ares/.libs \
-lcares
LIBCURL = -L../lib/.libs/ -lcurl
CFLAGS = -I../include -g
all: shiper hiper hipev ulimiter
hiper: hiper.o $(LIBCURL)
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
hiper.o: hiper.c
$(CC) $(CFLAGS) -c $<
hipev: hipev.o $(LIBCURL)
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS) -levent
hipev.o: hipev.c
$(CC) $(CFLAGS) -c $<
shiper: shiper.o $(LIBCURL)
$(CC) -o $@ $< $(LIBCURL) $(LDFLAGS)
shiper.o: shiper.c
$(CC) $(CFLAGS) -c $<
ulimiter: ulimiter.c
$(CC) -o $@ $<
clean:
rm -f hiper.o hiper shiper shiper.o *~ ulimiter
$(LIBCURL):
(cd ../lib && make)

View File

@@ -1,300 +0,0 @@
Date: January 5, 2006
Author: Daniel Stenberg
Status of project Hiper - high performance libcurl modifications
================================================================
What is Hiper
You won't find such a description in this document. See
http://curl.haxx.se/libcurl/hiper/ for further details.
Live Progress Info
During my work, I've posted occational updates on the curl-library mailing
list but more importantly done frequent updates of
http://curl.haxx.se/libcurl/hiper/schedule.html
Schedule
I took time off my regular job during Decemember 2005 and the first week of
January 2006 to work on hiper full-time.
Step 1 - Measure the Existing Solution
I started full-time work on project Hiper on December 1st 2005. I began by
putting together a test application that used the existing API to allow me
to properly and with accuracy measure execution and transfer speeds when
doing a large amount of transfers.
I soon discovered that it was impossible to do any sensible measurements by
using live and actual URLs since the transfers were too unrelialble and
uncontrolled. I then enhanced the current HTTP server in the curl test suite
and made that support a large amount of transfers and some extra magic
"commands" that would make the server either just sit "idle" or "stream"
(continuously sending data in a never-ending stream). I then wrote up two
files using the curl test suite file format and by acessing the properly
formatted URLs on my localhost the HTTP server would either run "idle" or
run "stream".
Having this working, I patched libcurl to always only recv() a single byte
off the network each time, just to make sure that the time spent on reading
data is constant and never very long.
I adjusted the test application (actually called 'hiper') to create Y idle
transfers and Z stream transfers, had it run for N seconds and then quit and
produce a summary on stdout. Now I got very solid and repeatable results. I
started to run repeated tests and save the results when I ran into the
dreaded 1024 socket maximum limit.
One side of the problem is that the fd_set type only allows 1024 file
descriptors (on my Linux), which I had to solve by simply making my own type
with room for more connections and do ugly typecasts in the code. The other
side of the problem is that user applications have a limit imposed by the
system on the maximum amount of file descriptors it can have open and I had
to work around that by writing a special tool that runs setuid root that
increases the limit, downgrades to a normal user again and then run the
command line of your choice. This second approach has to be used for both
'hiper' and the test HTTP server. (You need to build the HTTP server with
CURL_SWS_FORK_ENABLED defined to have it do forks since it isn't desirable
to do so when running the normal curl tests.)
Now I could run my test program without problems. I decided to run the tests
with 1 stream connection and a varying amount of idle ones. I did 1001,
2001, 3001, 5001 and 9001 connections and measured how long select() and
curl_multi_perform() (including the curl_multi_fdset() call) would take in
average, over a period of 20 seconds. I ran each test 5-6 times and I used
the average time of all the runs.
The times in number of microseconds:
Connections multi_perform select
1001 3504 951
2001 7606 1988
3001 11045 2715
5001 16406 4024
9001 32147 8030
Test system
CPU: Athlon XP 2800
RAM: 1 GB
Linux: 2.6
glibc: 2.3.5
libcurl: 7.15.1
The only reason I stopped at 9001 connections is that my test machine ran
out of avaiable memory by then as I ran the test server on the same machine,
and I didn't want to risk the test result accuracy by having it start using
the swap during the tests.
It means that at 9000 connections we spend 40ms for each socket action, even
when only one socket ever have action.
With these 32000 microseconds curl_multi_perform() takes for 9000
connections, it loops 18000 laps which makes less than 2 microseconds per
lap. (Of course counting time/laps is an oversimplification, but anyway.)
Hopefully we should achieve less than 10 microseconds for each call to
curl_multi_socket() for an active connection.
The timing graph displayed on the libevent site (duplicated on the hiper
project page) suggests that libevent is pretty much fixed at 50 microseconds
(although I don't know what test box was used in their testing, we can
compare the select()-times from my tests and see that they are at least
resonably close).
Summing up, the current ~40 ms spent at 9000 connections could then possibly
be lowered to something around 60 us!
Step 2 - Implement curl_multi_socket API
Most of the design decisions and debates about this new API have already
been held on the curl-library mailing list a long time ago so I had a basic
idea on what approach to use. The main ideas of the new API are simply:
1 - The application can use whatever event system it likes as it gets info
from libcurl about what file descriptors libcurl waits for what action
on. (The previous API returns fd_sets which is very select()-centric).
2 - When the application discovers action on a single socket, it calls
libcurl and informs that there was action on this particular socket and
libcurl can then act on that socket/transfer only and not care about
any other transfers. (The previous API always had to scan through all
the existing transfers.)
The idea is that curl_multi_socket() calls a given callback with information
about what socket to wait for what action on, and the callback only gets
called if the status of that socket has changed.
In the API draft from before, we have a timeout argument on a per socket
basis and we also allowed curl_multi_socket() to pass in an 'easy handle'
instead of socket to allow libcurl to shortcut a lookup and work on the
affected easy handle right away. Both these turned out to be bad ideas.
The timeout argument was removed from the socket callback since after much
thinking I came to the conclusion that we really don't want to handle
timeouts on a per socket basis. We need it on a per transfer (easy handle)
basis and thus we can't provide it in the callbacks in a nice way. Instead,
we have to offer a curl_multi_timeout() that returns the largest amount of
time we should wait before we call the "timeout action" of libcurl, to
trigger the proper internal timeout action on the affected transfer. To get
this to work, I added a struct to each easy handle in which we store an
"expire time" (if any). The structs are then "splay sorted" so that we can
add and remove times from the linked list and yet somewhat swiftly figure
out 1 - how long time there is until the next timer expires and 2 - which
timer (handle) should we take care of now. Of course, the upside of all this
is that we get a curl_multi_timeout() that should also work with old-style
applications that use curl_multi_perform().
The easy handle argument was removed fom the curl_multi_socket() function
because having it there would require the application to do a socket to easy
handle conversion on its own. I find it very unlikely that applications
would want to do that and since libcurl would need such a lookup on its own
anyway since we didn't want to force applications to do that translation
code (it would be optional), it seemed like an unnecessary option. I also
realized that when we use underlying libraries such as c-ares (for DNS
asynch resolving) there might in fact be more than one transfer waiting for
action on the same socket and thus it makes the lookup even tricker and even
less likely to ever get done by applications. Instead I created an internal
"socket to easy handles" hash table that given a socket (file descriptor)
returns a list of easy handles that waits for some action on that socket.
To make libcurl be able to report plain sockets in the socket callback, I
had to re-organize the internals of the curl_multi_fdset() etc so that the
conversion from sockets to fd_sets for that function is only done in the
last step before the data is returned. I also had to extend c-ares to get a
function that can return plain sockets, as that library too returned only
fd_sets and that is no longer good enough. The changes done to c-ares have
been committed and are available in the c-ares CVS repository destined to be
included in the upcoming c-ares 1.3.1 release.
The 'shiper' tool is the test application I wrote that uses the new
curl_multi_socket() in its current state. It seems to be working and it uses
the API as it is documented and supposed to work. It is still using
select(), because I needed that during development (like until I had the
socket hash implemented etc) and because I haven't yet learned how to use
libevent or similar.
The hiper/shiper tools are very simple and initiates lots of connections and
have them running for the test period and then kills them all.
Since I wasn't done with the implementation until early January I haven't
had time to run very many measurements and checks, but I have done a few
runs with up to a few hundred connections (with a single active one). The
curl_multi_socket() invoke then takes 3-6 microseconds in average (using the
read-only-1-byte-at-a-time hack). If this number does increase a lot when we
add connections, it certainly matches my in my opinion very ambitious goal.
We are now below the 60 microseconds "per socket action" goal. It is
destined to be somewhat higher the more connections we have since the hash
table gets more populated and the splay tree will grow etc.
Some tests at 7000 and 9000 connections showed that the socket hash lookup
is somewhat of a bottle neck. Its current implementation may be a bit too
limiting. It simply has a fixed-size array, and on each entry in the array
it has a linked list with entries. So the hash only checks which list to
scan through. The code I had used so for used a list with merely 7 slots (as
that is what the DNS hash uses) but with 7000 connections that would make an
average of 1000 nodes in each list to run through. I upped that to 97 slots
(I believe a prime is suitable) and noticed a significant speed increase. I
need to reconsider the hash implementation or use a rather large default
value like this. At 9000 connections I was still below 10us per call.
Status Right Now
The curl_multi_socket() API is implemented according to how it is
documented. The man pages for curl_multi_socket and curl_multi_timeout are
both committed to CVS and are available online for easy browsing:
http://curl.haxx.se/libcurl/c/curl_multi_socket.html
http://curl.haxx.se/libcurl/c/curl_multi_timeout.html
The hiper-5.patch I made available early morning January 5th, 2006 should
apply fine on a recent CVS checkout (at the time of this writing curl 7.15.1
is the latest public curl release but the hiper patch does not apply fine on
that).
What is Left for the curl_multi_socket API
1 - More measuring with more extreme number of connections
2 - More testing with actual URLs and complete from start to end transfers.
I'm quite sure we don't set expire times all over in the code properly, so
there is bound to be some timeout bugs left.
What it really takes is for me to commit the code and to make an official
release with it so that we get people "out there" to help out testing it.
What is Left for project Hiper
1 - Add HTTP pipelining support
2 - Add a zero (or at least close to zero) copy interface
Neither of these points have been planned or detailed exactly how they will
be implemented.
Roadmap Ahead
I plan and hope to return to full-time hiper work later on this spring or
possibly summer to continue where I pause now. Of course some spare time
might also be spent until then to get us moving forward.
---------------------------------------------------------------------------
April 11, 2006
While sitting staring on my screen trying to write up a *nice* sample script
using libevent, it strikes me that since libevent is pretty much based around
its structs that you setup for each event/file descriptor, my application
wants to figure out the correct struct that is associted with the file
descriptor that libcurl provides in the socket callback.
This feels like an operation most applications will need when using the
multi_socket API, so it feels like I should better try to figure out a decent
way to offer this basic functionality already in libcurl - and the fact that
we already have the file descriptors in a hash we can probably just as well
extend it somewhat and store some custom pointers as well.
We need to offer the app a way to set a private pointer to be associated with
the particular file descriptor, and then be able to provide that pointer on
subsequent callback calls.
---------------------------------------------------------------------------
April 20, 2006
I was wrong when I previously claimed we could have more than one easy handle
using the same socket. I've cleaned up and simplified code now to adjust to
this.
---------------------------------------------------------------------------
July 9, 2006
TODO: We need to alter how we use c-ares for getting info about its sockets,
as c-ares now provides a callback approach very similar to how libcurl is
about to work.
I'm adding a function called curl_multi_assign() that will set a private
pointer added to the internal libcurl hash table for the particular socket
passed in to this function:
CURLMcode curl_multi_assign(CURLM *multi_handle,
curl_socket_t sockfd,
void *sockp);
'sockp' being a custom pointer set by the application to be associated with
this socket. The socket has to be already existing and in-use by libcurl,
like having already called the callback telling about its existance.
The set hashp pointer will then be passed on to the callback in upcoming
calls when this same socket is used (in the brand new 'socketp' argument).
---------------------------------------------------------------------------
July 30, 2006
Shockingly stupid (of me not having realized this before), but we really need
to add a 'running_handles' argument to the curl_multi_socket() and
curl_multi_socket_all() prototypes so that the caller can get to know when
all the transfers are actually done!

View File

@@ -1,34 +0,0 @@
#!/usr/bin/perl
# 1) http://randomurl.com/body.php
# 2) http://random.yahoo.com/fast/ryl
# 3) http://www.uroulette.com/visit
# 1) very slow, responds with URL in body meta style:
# <meta http-equiv="refresh" content="0; url=http://www.webmasterworld.com/forum85/735.htm">
# 2) Responds with non-HTTP headers like:
# Status: 301
# Location: http://www.adaptive.net/
# 3) ordinary 30X code and Location:
my $url;
map { $url .= " http://www.uroulette.com/visit"; } (1 .. 12);
print $url."\n";
my $count=0;
open(DUMP, ">>dump");
while(1) {
my @getit = `curl -si $url`;
for my $l (@getit) {
if($l =~ /^Location: (.*)/) {
print DUMP "$1\n";
print STDERR "$count\r";
$count++;
}
}
}

View File

@@ -1,416 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Connect N connections. Z are idle, and X are active. Transfer as fast as
* possible.
*
* Run for a specific amount of time (10 secs for now). Output detailed timing
* information.
*
*/
/* The maximum number of simultanoues connections/transfers we support */
#define NCONNECTIONS 50000
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <sys/poll.h>
#include <curl/curl.h>
#define MICROSEC 1000000 /* number of microseconds in one second */
/* The maximum time (in microseconds) we run the test */
#define RUN_FOR_THIS_LONG (20*MICROSEC)
/* Number of loops (seconds) we allow the total download amount and alive
connections to remain the same until we bail out. Set this slightly higher
when using asynch supported libcurl. */
#define IDLE_TIME 10
struct globalinfo {
size_t dlcounter;
};
struct connection {
CURL *e;
int id; /* just a counter for easy browsing */
char *url;
size_t dlcounter;
struct globalinfo *global;
char error[CURL_ERROR_SIZE];
};
/* on port 8999 we run a modified (fork-) sws that supports pure idle and full
stream mode */
#define PORT "8999"
#define HOST "192.168.1.13"
#define URL_IDLE "http://" HOST ":" PORT "/1000"
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
static size_t
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct connection *c = (struct connection *)data;
c->dlcounter += realsize;
c->global->dlcounter += realsize;
#if 0
printf("%02d: %d, total %d\n",
c->id, c->dlcounter, c->global->dlcounter);
#endif
return realsize;
}
/* return the diff between two timevals, in us */
static long tvdiff(struct timeval *newer, struct timeval *older)
{
return (newer->tv_sec-older->tv_sec)*1000000+
(newer->tv_usec-older->tv_usec);
}
/* store the start time of the program in this variable */
static struct timeval timer;
static void timer_start(void)
{
/* capture the time of the start moment */
gettimeofday(&timer, NULL);
}
static struct timeval cont; /* at this moment we continued */
int still_running; /* keep number of running handles */
struct conncount {
long time_us;
long laps;
long maxtime;
};
static struct timeval timerpause;
static void timer_pause(void)
{
/* capture the time of the pause moment */
gettimeofday(&timerpause, NULL);
/* If we have a previous continue (all times except the first), we can now
store the time for a whole "lap" */
if(cont.tv_sec) {
long lap;
lap = tvdiff(&timerpause, &cont);
}
}
static long paused; /* amount of us we have been pausing */
static void timer_continue(void)
{
/* Capture the time of the restored operation moment, now calculate how long
time we were paused and added that to the 'paused' variable.
*/
gettimeofday(&cont, NULL);
paused += tvdiff(&cont, &timerpause);
}
static long total; /* amount of us from start to stop */
static void timer_total(void)
{
struct timeval stop;
/* Capture the time of the operation stopped moment, now calculate how long
time we were running and how much of that pausing.
*/
gettimeofday(&stop, NULL);
total = tvdiff(&stop, &timer);
}
struct globalinfo info;
struct connection *conns;
long selects;
long selectsalive;
long timeouts;
long perform;
long performalive;
long performselect;
long topselect;
int num_total;
int num_idle;
int num_active;
static void report(void)
{
int i;
long active = total - paused;
long numdl = 0;
for(i=0; i < num_total; i++) {
if(conns[i].dlcounter)
numdl++;
}
printf("Summary from %d simultanoues transfers (%d active)\n",
num_total, num_active);
printf("%d out of %d connections provided data\n", numdl, num_total);
printf("Total time: %ldus select(): %ldus curl_multi_perform(): %ldus\n",
total, paused, active);
printf("%d calls to curl_multi_perform() average %d alive "
"Average time: %dus\n",
perform, performalive/perform, active/perform);
printf("%d calls to select(), average %d alive "
"Average time: %dus\n",
selects, selectsalive/selects,
paused/selects);
printf(" Average number of readable connections per select() return: %d\n",
performselect/selects);
printf(" Max number of readable connections for a single select() "
"return: %d\n",
topselect);
printf("%ld select() timeouts\n", timeouts);
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
info.dlcounter,
info.dlcounter/(total/1000000),
total/info.dlcounter);
#if 0
for(i=1; i< num_total; i++) {
if(timecount[i].laps) {
printf("Time %d connections, average %ld max %ld (%ld laps) "
"average/conn: %ld\n",
i,
timecount[i].time_us/timecount[i].laps,
timecount[i].maxtime,
timecount[i].laps,
(timecount[i].time_us/timecount[i].laps)/i );
}
}
#endif
}
struct ourfdset {
char fdbuffer[NCONNECTIONS/8];
};
#define FD2_ZERO(x) FD_ZERO((fd_set *)x)
typedef struct ourfdset fd2_set;
int main(int argc, char **argv)
{
CURLM *multi_handle;
CURLMsg *msg;
CURLcode code = CURLE_OK;
CURLMcode mcode = CURLM_OK;
int rc;
int i;
int prevalive=-1;
int prevsamecounter=0;
int prevtotal = -1;
fd2_set fdsizecheck;
int selectmaxamount;
memset(&info, 0, sizeof(struct globalinfo));
selectmaxamount = sizeof(fdsizecheck) * 8;
printf("select() supports max %d connections\n", selectmaxamount);
if(argc < 3) {
printf("Usage: hiper [num idle] [num active]\n");
return 1;
}
num_idle = atoi(argv[1]);
num_active = atoi(argv[2]);
num_total = num_idle + num_active;
if(num_total > selectmaxamount) {
printf("Requested more connections than supported!\n");
return 4;
}
conns = calloc(num_total, sizeof(struct connection));
if(!conns) {
printf("Out of memory\n");
return 3;
}
if(num_total >= NCONNECTIONS) {
printf("Increase NCONNECTIONS!\n");
return 2;
}
/* init the multi stack */
multi_handle = curl_multi_init();
for(i=0; i< num_total; i++) {
CURL *e;
char *nl;
memset(&conns[i], 0, sizeof(struct connection));
if(i < num_idle)
conns[i].url = URL_IDLE;
else
conns[i].url = URL_ACTIVE;
#if 0
printf("%d: Add URL %s\n", i, conns[i].url);
#endif
e = curl_easy_init();
if(!e) {
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
return 2;
}
conns[i].e = e;
conns[i].id = i;
conns[i].global = &info;
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
#if 1
curl_easy_setopt(e, CURLOPT_VERBOSE, 1);
#endif
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
/* add the easy to the multi */
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
printf("curl_multi_add_handle() returned error for %d\n", i);
return 3;
}
}
/* we start some action by calling perform right away */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
timer_start();
while(still_running == num_total) {
struct timeval timeout;
int rc; /* select() return code */
long timeout_ms;
fd2_set fdread;
fd2_set fdwrite;
fd2_set fdexcep;
int maxfd;
FD2_ZERO(&fdread);
FD2_ZERO(&fdwrite);
FD2_ZERO(&fdexcep);
curl_multi_timeout(multi_handle, &timeout_ms);
/* set timeout to wait */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle,
(fd_set *)&fdread,
(fd_set *)&fdwrite,
(fd_set *)&fdexcep, &maxfd);
timer_pause();
selects++;
selectsalive += still_running;
rc = select(maxfd+1,
(fd_set *)&fdread,
(fd_set *)&fdwrite,
(fd_set *)&fdexcep, &timeout);
#if 0
/* Output this here to make it outside the timer */
printf("Running: %d (%d bytes)\n", still_running, info.dlcounter);
#endif
timer_continue();
switch(rc) {
case -1:
/* select error */
break;
case 0:
timeouts++;
default:
/* timeout or readable/writable sockets */
do {
perform++;
performalive += still_running;
}
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
performselect += rc;
if(rc > topselect)
topselect = rc;
break;
}
if(total > RUN_FOR_THIS_LONG) {
printf("Stopped after %ldus\n", total);
break;
}
if(prevalive != still_running) {
printf("%d connections alive\n", still_running);
}
prevalive = still_running;
timer_total(); /* calculate the total time spent so far */
}
if(still_running != num_total) {
/* something made connections fail, extract the reason and tell */
int msgs_left;
struct connection *cptr;
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) {
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
}
}
}
curl_multi_cleanup(multi_handle);
/* cleanup all the easy handles */
for(i=0; i< num_total; i++)
curl_easy_cleanup(conns[i].e);
report();
return code;
}

View File

@@ -1,410 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Connect N connections. Z are idle, and X are active. Transfer as fast as
* possible.
*
* Output detailed timing information.
*
* Uses libevent.
*
*/
/* The maximum number of simultanoues connections/transfers we support */
#define NCONNECTIONS 50000
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <sys/poll.h>
#include <curl/curl.h>
#include <event.h> /* for libevent */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MICROSEC 1000000 /* number of microseconds in one second */
/* The maximum time (in microseconds) we run the test */
#define RUN_FOR_THIS_LONG (5*MICROSEC)
/* Number of loops (seconds) we allow the total download amount and alive
connections to remain the same until we bail out. Set this slightly higher
when using asynch supported libcurl. */
#define IDLE_TIME 10
struct globalinfo {
size_t dlcounter;
};
struct connection {
CURL *e;
int id; /* just a counter for easy browsing */
char *url;
size_t dlcounter;
struct globalinfo *global;
char error[CURL_ERROR_SIZE];
};
/* this is the struct associated with each file descriptor libcurl tells us
it is dealing with */
struct fdinfo {
/* create a link list of fdinfo structs */
struct fdinfo *next;
struct fdinfo *prev;
curl_socket_t sockfd;
CURL *easy;
int action; /* as set by libcurl */
long timeout; /* as set by libcurl */
struct event ev; /* */
int evset; /* true if the 'ev' struct has been used in a event_set() call */
CURLM *multi; /* pointer to the multi handle */
int *running_handles; /* pointer to the running_handles counter */
};
static struct fdinfo *allsocks;
static int running_handles;
/* we have the timerevent global so that when the final socket-based event is
done, we can remove the timerevent as well */
static struct event timerevent;
static void update_timeout(CURLM *multi_handle);
/* called from libevent on action on a particular socket ("event") */
static void eventcallback(int fd, short type, void *userp)
{
struct fdinfo *fdp = (struct fdinfo *)userp;
CURLMcode rc;
fprintf(stderr, "EVENT callback type %d\n", type);
/* tell libcurl to deal with the transfer associated with this socket */
do {
rc = curl_multi_socket(fdp->multi, fd, fdp->running_handles);
} while (rc == CURLM_CALL_MULTI_PERFORM);
if(rc) {
fprintf(stderr, "curl_multi_socket() returned %d\n", (int)rc);
}
fprintf(stderr, "running_handles: %d\n", *fdp->running_handles);
if(!*fdp->running_handles) {
/* last transfer is complete, kill pending timeout */
fprintf(stderr, "last transfer done, kill timeout\n");
if(evtimer_pending(&timerevent, NULL))
evtimer_del(&timerevent);
}
else
update_timeout(fdp->multi);
}
/* called from libevent when our timer event expires */
static void timercallback(int fd, short type, void *userp)
{
(void)fd; /* not used for this */
(void)type; /* ignored in here */
CURLM *multi_handle = (CURLM *)userp;
int running_handles;
CURLMcode rc;
fprintf(stderr, "EVENT timeout\n");
/* tell libcurl to deal with the transfer associated with this socket */
do {
rc = curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT,
&running_handles);
} while (rc == CURLM_CALL_MULTI_PERFORM);
if(running_handles)
/* Get the current timeout value from libcurl and set a new timeout */
update_timeout(multi_handle);
}
static void remsock(struct fdinfo *f)
{
if(!f)
/* did not find socket to remove! */
return;
if(f->evset)
event_del(&f->ev);
if(f->prev)
f->prev->next = f->next;
if(f->next)
f->next->prev = f->prev;
else
/* this was the last entry */
allsocks = NULL;
}
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
int action)
{
fdp->sockfd = s;
fdp->action = action;
fdp->easy = easy;
if(fdp->evset)
/* first remove the existing event if the old setup was used */
event_del(&fdp->ev);
/* now use and add the current socket setup to libevent. The EV_PERSIST is
the key here as otherwise libevent will automatically remove the event
when it occurs the first time */
event_set(&fdp->ev, fdp->sockfd,
(action&CURL_POLL_IN?EV_READ:0)|
(action&CURL_POLL_OUT?EV_WRITE:0)| EV_PERSIST,
eventcallback, fdp);
fdp->evset=1;
fprintf(stderr, "event_add() for fd %d\n", s);
/* We don't use any socket-specific timeout but intead we use a single
global one. This is (mostly) because libcurl doesn't expose any
particular socket- based timeout value. */
event_add(&fdp->ev, NULL);
}
static void addsock(curl_socket_t s, CURL *easy, int action, CURLM *multi)
{
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
fdp->multi = multi;
fdp->running_handles = &running_handles;
setsock(fdp, s, easy, action);
if(allsocks) {
fdp->next = allsocks;
allsocks->prev = fdp;
/* now set allsocks to point to the new struct */
allsocks = fdp;
}
else
allsocks = fdp;
/* Set this association in libcurl */
curl_multi_assign(multi, s, fdp);
}
/* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */
#define PORT "8999"
#define HOST "127.0.0.1"
#define URL_IDLE "http://" HOST ":" PORT "/1000"
#if 1
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
#else
#define URL_ACTIVE "http://localhost/"
#endif
static int socket_callback(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
void *cbp, /* callback pointer */
void *socketp) /* socket pointer */
{
struct fdinfo *fdp = (struct fdinfo *)socketp;
char *whatstr[]={
"none",
"IN",
"OUT",
"INOUT",
"REMOVE"};
fprintf(stderr, "socket %d easy %p what %s\n", s, easy,
whatstr[what]);
if(what == CURL_POLL_REMOVE)
remsock(fdp);
else {
if(!fdp) {
/* not previously known, add it and set association */
printf("Add info for socket %d %s%s\n", s,
what&CURL_POLL_IN?"READ":"",
what&CURL_POLL_OUT?"WRITE":"" );
addsock(s, easy, what, cbp);
}
else {
/* we already know about it, just change action/timeout */
printf("Changing info for socket %d from %d to %d\n",
s, fdp->action, what);
setsock(fdp, s, easy, what);
}
}
return 0; /* return code meaning? */
}
static size_t
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct connection *c = (struct connection *)data;
(void)ptr;
c->dlcounter += realsize;
c->global->dlcounter += realsize;
printf("%02d: %d, total %d\n",
c->id, c->dlcounter, c->global->dlcounter);
return realsize;
}
struct globalinfo info;
struct connection *conns;
int num_total;
int num_idle;
int num_active;
static void update_timeout(CURLM *multi_handle)
{
long timeout_ms;
struct timeval timeout;
/* Since we need a global timeout to occur after a given time of inactivity,
we use a single timeout-event. Get the timeout value from libcurl, and
update it after every call to libcurl. */
curl_multi_timeout(multi_handle, &timeout_ms);
/* convert ms to timeval */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
evtimer_add(&timerevent, &timeout);
}
int main(int argc, char **argv)
{
CURLM *multi_handle;
CURLMsg *msg;
CURLcode code = CURLE_OK;
int i;
memset(&info, 0, sizeof(struct globalinfo));
if(argc < 3) {
printf("Usage: hiper-event [num idle] [num active]\n");
return 1;
}
num_idle = atoi(argv[1]);
num_active = atoi(argv[2]);
num_total = num_idle + num_active;
conns = calloc(num_total, sizeof(struct connection));
if(!conns) {
printf("Out of memory\n");
return 3;
}
if(num_total >= NCONNECTIONS) {
printf("Too many connections requested, increase NCONNECTIONS!\n");
return 2;
}
event_init(); /* Initalize the event library */
printf("About to do %d connections\n", num_total);
/* init the multi stack */
multi_handle = curl_multi_init();
/* initialize the timeout event */
evtimer_set(&timerevent, timercallback, multi_handle);
for(i=0; i< num_total; i++) {
CURL *e;
memset(&conns[i], 0, sizeof(struct connection));
if(i < num_idle)
conns[i].url = URL_IDLE;
else
conns[i].url = URL_ACTIVE;
e = curl_easy_init();
if(!e) {
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
return 2;
}
conns[i].e = e;
conns[i].id = i;
conns[i].global = &info;
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
curl_easy_setopt(e, CURLOPT_VERBOSE, 0);
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
/* add the easy to the multi */
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
printf("curl_multi_add_handle() returned error for %d\n", i);
return 3;
}
}
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, multi_handle);
/* we start the action by calling *socket_all() */
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle,
&running_handles));
/* update timeout */
update_timeout(multi_handle);
/* event_dispatch() runs the event main loop. It ends when no events are
left to wait for. */
event_dispatch();
{
/* something made connections fail, extract the reason and tell */
int msgs_left;
struct connection *cptr;
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) {
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
printf("%d => (%d) %s\n",
cptr->id, msg->data.result, cptr->error);
}
}
}
curl_multi_cleanup(multi_handle);
/* cleanup all the easy handles */
for(i=0; i< num_total; i++)
curl_easy_cleanup(conns[i].e);
return code;
}

View File

@@ -1,557 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Connect N connections. Z are idle, and X are active. Transfer as fast as
* possible.
*
* Run for a specific amount of time (10 secs for now). Output detailed timing
* information.
*
* The same is hiper.c but instead using the new *socket() API instead of the
* "old" *perform() call.
*
* Uses a select() approach but only for keeping the code simple and
* stand-alone. See hipev.c for a libevent-based example.
*
*/
/* The maximum number of simultanoues connections/transfers we support */
#define NCONNECTIONS 50000
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <sys/poll.h>
#include <curl/curl.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MICROSEC 1000000 /* number of microseconds in one second */
/* The maximum time (in microseconds) we run the test */
#define RUN_FOR_THIS_LONG (5*MICROSEC)
/* Number of loops (seconds) we allow the total download amount and alive
connections to remain the same until we bail out. Set this slightly higher
when using asynch supported libcurl. */
#define IDLE_TIME 10
struct ourfdset {
/* __fds_bits is what the Linux glibc headers use when they declare the
fd_set struct so by using this we can actually avoid the typecase for the
FD_SET() macro usage but it would hardly be portable */
char __fds_bits[NCONNECTIONS/8];
};
#define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset))
typedef struct ourfdset fd2_set;
struct globalinfo {
size_t dlcounter;
};
struct connection {
CURL *e;
int id; /* just a counter for easy browsing */
char *url;
size_t dlcounter;
struct globalinfo *global;
char error[CURL_ERROR_SIZE];
};
struct fdinfo {
/* create a link list of fdinfo structs */
struct fdinfo *next;
struct fdinfo *prev;
curl_socket_t sockfd;
CURL *easy;
int action; /* as set by libcurl */
long timeout; /* as set by libcurl */
};
static struct fdinfo *allsocks;
static struct fdinfo *findsock(curl_socket_t s)
{
/* return the struct for the given socket */
struct fdinfo *fdp = allsocks;
while(fdp) {
if(fdp->sockfd == s)
break;
fdp = fdp->next;
}
return fdp; /* a struct pointer or NULL */
}
static void remsock(curl_socket_t s)
{
struct fdinfo *fdp = allsocks;
while(fdp) {
if(fdp->sockfd == s)
break;
fdp = fdp->next;
}
if(!fdp)
/* did not find socket to remove! */
return;
if(fdp->prev)
fdp->prev->next = fdp->next;
if(fdp->next)
fdp->next->prev = fdp->prev;
else
/* this was the last entry */
allsocks = NULL;
}
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
int action)
{
fdp->sockfd = s;
fdp->action = action;
fdp->easy = easy;
}
static void addsock(curl_socket_t s, CURL *easy, int action)
{
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
setsock(fdp, s, easy, action);
if(allsocks) {
fdp->next = allsocks;
allsocks->prev = fdp;
/* now set allsocks to point to the new struct */
allsocks = fdp;
}
else
allsocks = fdp;
}
static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd)
{
struct fdinfo *fdp = allsocks;
int writable=0;
FD2_ZERO(fdread);
FD2_ZERO(fdwrite);
*maxfd = 0;
#if 0
printf("Wait for: ");
#endif
while(fdp) {
if(fdp->action & CURL_POLL_IN) {
FD_SET(fdp->sockfd, (fd_set *)fdread);
}
if(fdp->action & CURL_POLL_OUT) {
FD_SET(fdp->sockfd, (fd_set *)fdwrite);
writable++;
}
#if 0
printf("%d (%s%s) ",
fdp->sockfd,
(fdp->action & CURL_POLL_IN)?"r":"",
(fdp->action & CURL_POLL_OUT)?"w":"");
#endif
if(fdp->sockfd > *maxfd)
*maxfd = fdp->sockfd;
fdp = fdp->next;
}
#if 0
if(writable)
printf("Check for %d writable sockets\n", writable);
#endif
}
/* on port 8999 we run a fork enabled sws that supports 'idle' and 'stream' */
#define PORT "8999"
#define HOST "192.168.1.13"
#define URL_IDLE "http://" HOST ":" PORT "/1000"
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
static int socket_callback(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
void *userp) /* "private" pointer */
{
struct fdinfo *fdp;
printf("socket %d easy %p what %d\n", s, easy, what);
if(what == CURL_POLL_REMOVE)
remsock(s);
else {
fdp = findsock(s);
if(!fdp) {
addsock(s, easy, what);
}
else {
/* we already know about it, just change action/timeout */
printf("Changing info for socket %d from %d to %d\n",
s, fdp->action, what);
setsock(fdp, s, easy, what);
}
}
return 0; /* return code meaning? */
}
static size_t
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct connection *c = (struct connection *)data;
c->dlcounter += realsize;
c->global->dlcounter += realsize;
#if 0
printf("%02d: %d, total %d\n",
c->id, c->dlcounter, c->global->dlcounter);
#endif
return realsize;
}
/* return the diff between two timevals, in us */
static long tvdiff(struct timeval *newer, struct timeval *older)
{
return (newer->tv_sec-older->tv_sec)*1000000+
(newer->tv_usec-older->tv_usec);
}
/* store the start time of the program in this variable */
static struct timeval timer;
static void timer_start(void)
{
/* capture the time of the start moment */
gettimeofday(&timer, NULL);
}
static struct timeval cont; /* at this moment we continued */
int still_running; /* keep number of running handles */
struct conncount {
long time_us;
long laps;
long maxtime;
};
static struct timeval timerpause;
static void timer_pause(void)
{
/* capture the time of the pause moment */
gettimeofday(&timerpause, NULL);
/* If we have a previous continue (all times except the first), we can now
store the time for a whole "lap" */
if(cont.tv_sec) {
long lap;
lap = tvdiff(&timerpause, &cont);
}
}
static long paused; /* amount of us we have been pausing */
static void timer_continue(void)
{
/* Capture the time of the restored operation moment, now calculate how long
time we were paused and added that to the 'paused' variable.
*/
gettimeofday(&cont, NULL);
paused += tvdiff(&cont, &timerpause);
}
static long total; /* amount of us from start to stop */
static void timer_total(void)
{
struct timeval stop;
/* Capture the time of the operation stopped moment, now calculate how long
time we were running and how much of that pausing.
*/
gettimeofday(&stop, NULL);
total = tvdiff(&stop, &timer);
}
struct globalinfo info;
struct connection *conns;
long selects;
long timeouts;
long multi_socket;
long performalive;
long performselect;
long topselect;
int num_total;
int num_idle;
int num_active;
static void report(void)
{
int i;
long active = total - paused;
long numdl = 0;
for(i=0; i < num_total; i++) {
if(conns[i].dlcounter)
numdl++;
}
printf("Summary from %d simultanoues transfers (%d active)\n",
num_total, num_active);
printf("%d out of %d connections provided data\n", numdl, num_total);
printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n",
total, paused, active);
printf("%d calls to select() "
"Average time: %dus\n",
selects, paused/selects);
printf(" Average number of readable connections per select() return: %d\n",
performselect/selects);
printf(" Max number of readable connections for a single select() "
"return: %d\n",
topselect);
printf("%ld calls to multi_socket(), "
"Average time: %ldus\n",
multi_socket, active/multi_socket);
printf("%ld select() timeouts\n", timeouts);
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
info.dlcounter,
info.dlcounter/(total/1000000),
total/info.dlcounter);
}
int main(int argc, char **argv)
{
CURLM *multi_handle;
CURLMsg *msg;
CURLcode code = CURLE_OK;
CURLMcode mcode = CURLM_OK;
int rc;
int i;
fd2_set fdsizecheck;
int selectmaxamount;
struct fdinfo *fdp;
char act;
int running_handles;
memset(&info, 0, sizeof(struct globalinfo));
selectmaxamount = sizeof(fdsizecheck) * 8;
printf("select() supports max %d connections\n", selectmaxamount);
if(argc < 3) {
printf("Usage: hiper [num idle] [num active]\n");
return 1;
}
num_idle = atoi(argv[1]);
num_active = atoi(argv[2]);
num_total = num_idle + num_active;
if(num_total > selectmaxamount) {
printf("Requested more connections than supported!\n");
return 4;
}
conns = calloc(num_total, sizeof(struct connection));
if(!conns) {
printf("Out of memory\n");
return 3;
}
if(num_total >= NCONNECTIONS) {
printf("Too many connections requested, increase NCONNECTIONS!\n");
return 2;
}
printf("About to do %d connections\n", num_total);
/* init the multi stack */
multi_handle = curl_multi_init();
for(i=0; i< num_total; i++) {
CURL *e;
char *nl;
memset(&conns[i], 0, sizeof(struct connection));
if(i < num_idle)
conns[i].url = URL_IDLE;
else
conns[i].url = URL_ACTIVE;
e = curl_easy_init();
if(!e) {
printf("curl_easy_init() for handle %d failed, exiting!\n", i);
return 2;
}
conns[i].e = e;
conns[i].id = i;
conns[i].global = &info;
curl_easy_setopt(e, CURLOPT_URL, conns[i].url);
curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, writecallback);
curl_easy_setopt(e, CURLOPT_WRITEDATA, &conns[i]);
curl_easy_setopt(e, CURLOPT_VERBOSE, 0);
curl_easy_setopt(e, CURLOPT_ERRORBUFFER, conns[i].error);
curl_easy_setopt(e, CURLOPT_PRIVATE, &conns[i]);
/* add the easy to the multi */
if(CURLM_OK != curl_multi_add_handle(multi_handle, e)) {
printf("curl_multi_add_handle() returned error for %d\n", i);
return 3;
}
}
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, socket_callback);
curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL);
/* we start the action by calling *socket() right away */
while(CURLM_CALL_MULTI_PERFORM == curl_multi_socket_all(multi_handle,
&running_handles));
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
timer_start();
timer_pause();
while(1) {
struct timeval timeout;
int rc; /* select() return code */
long timeout_ms;
fd2_set fdread;
fd2_set fdwrite;
int maxfd;
curl_multi_timeout(multi_handle, &timeout_ms);
/* set timeout to wait */
timeout.tv_sec = timeout_ms/1000;
timeout.tv_usec = (timeout_ms%1000)*1000;
/* convert file descriptors from the transfers to fd_sets */
fdinfo2fdset(&fdread, &fdwrite, &maxfd);
selects++;
rc = select(maxfd+1,
(fd_set *)&fdread,
(fd_set *)&fdwrite,
NULL, &timeout);
switch(rc) {
case -1:
/* select error */
break;
case 0:
timeouts++;
curl_multi_socket(multi_handle, CURL_SOCKET_TIMEOUT, &running_handles);
break;
default:
/* timeout or readable/writable sockets */
for(i=0, fdp = allsocks; fdp; fdp = fdp->next) {
act = 0;
if((fdp->action & CURL_POLL_IN) &&
FD_ISSET(fdp->sockfd, &fdread)) {
act |= CURL_POLL_IN;
i++;
}
if((fdp->action & CURL_POLL_OUT) &&
FD_ISSET(fdp->sockfd, &fdwrite)) {
act |= CURL_POLL_OUT;
i++;
}
if(act) {
multi_socket++;
timer_continue();
if(act & CURL_POLL_OUT)
act--;
curl_multi_socket(multi_handle, fdp->sockfd, &running_handles);
timer_pause();
}
}
performselect += rc;
if(rc > topselect)
topselect = rc;
break;
}
timer_total(); /* calculate the total time spent so far */
if(total > RUN_FOR_THIS_LONG) {
printf("Stopped after %ldus\n", total);
break;
}
}
if(still_running != num_total) {
/* something made connections fail, extract the reason and tell */
int msgs_left;
struct connection *cptr;
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
if (msg->msg == CURLMSG_DONE) {
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &cptr);
printf("%d => (%d) %s", cptr->id, msg->data.result, cptr->error);
}
}
}
curl_multi_cleanup(multi_handle);
/* cleanup all the easy handles */
for(i=0; i< num_total; i++)
curl_easy_cleanup(conns[i].e);
report();
return code;
}

View File

@@ -1,101 +0,0 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*
* Little tool to raise the amount of maximum file descriptor and then run the
* given command line (using the hard-coded uid/gid).
*
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <errno.h>
#include <string.h> /* for errno translation */
/* ulimiter
*
* Source code inspiration from:
* http://www.cs.wisc.edu/condor/condorg/linux_scalability.html
*/
#define UID 1000 /* the user who must run this */
#define GID 1000 /* group id to run the program as */
/* Number of open files to increase to */
#define NEW_MAX 10000
int main(int argc, char *argv[])
{
int ret;
struct rlimit rl;
char *brgv[20];
int brgc=argc-1;
int i;
for(i=1; i< argc; i++)
brgv[i-1]=argv[i];
brgv[i-1]=NULL; /* terminate the list */
if(getuid() != UID) {
fprintf(stderr, "Only uid %d is allowed to run this\n", UID);
return 1;
}
ret = getrlimit(RLIMIT_NOFILE, &rl);
if(ret != 0) {
fprintf(stderr, "Unable to read open file limit.\n"
"(getrlimit(RLIMIT_NOFILE, &rl) failed)\n"
"(%d, %s)", errno, strerror(errno));
return 1;
}
fprintf(stderr, "Limit was %d (max %d), setting to %d\n",
rl.rlim_cur, rl.rlim_max, NEW_MAX);
rl.rlim_cur = rl.rlim_max = NEW_MAX;
ret = setrlimit(RLIMIT_NOFILE, &rl);
if(ret != 0) {
fprintf(stderr, "Unable to set open file limit.\n"
"(setrlimit(RLIMIT_NOFILE, &rl) failed)\n"
"(%d, %s)", errno, strerror(errno));
return 1;
}
ret = getrlimit(RLIMIT_NOFILE, &rl);
if(ret != 0) {
fprintf(stderr, "Unable to read new open file limit.\n"
"(getrlimit(RLIMIT_NOFILE, &rl) failed)\n"
"(%d, %s)", errno, strerror(errno));
return 1;
}
if(rl.rlim_cur < NEW_MAX) {
fprintf(stderr, "Failed to set new open file limit.\n"
"Limit is %d, expected %d\n",
rl.rlim_cur, NEW_MAX);
return 1;
}
if(setgid(GID) != 0) {
fprintf(stderr, "setgid failed (%d, %s)\n", errno, strerror(errno));
return 1;
}
if(setuid(UID) != 0) {
fprintf(stderr, "setuid failed (%d, %s)\n", errno, strerror(errno));
return 1;
}
ret = execv(brgv[0], brgv);
fprintf(stderr, "execl returned, failure\n"
"returned %d, errno is %d (%s)\n",
ret, errno, strerror(errno));
return 1;
}

View File

@@ -474,8 +474,9 @@ typedef enum {
#define CURLAUTH_DIGEST (1<<1) /* Digest */
#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
#define CURLAUTH_NTLM (1<<3) /* NTLM */
#define CURLAUTH_ANY ~0 /* all types set */
#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, 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
@@ -438,6 +438,32 @@
# endif
# endif
/* ===================================== */
/* SunPro Compilers */
/* ===================================== */
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#include <sys/types.h>
#include <stdint.h>
# define CURL_TYPEOF_CURL_OFF_T off_t
# define CURL_SIZEOF_CURL_OFF_T 8
# if defined(__amd64) || defined(__sparcv9)
# define CURL_SIZEOF_LONG 8
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_FORMAT_OFF_T "%ld"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_SIZEOF_LONG 4
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_FORMAT_OFF_T "%lld"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
/* ===================================== */
/* KEEP MSVC THE PENULTIMATE ENTRY */
/* ===================================== */
@@ -468,7 +494,7 @@
/* ===================================== */
#elif defined(__GNUC__)
# if defined(__i386__)
# if defined(__i386__) || defined(__ppc__)
# define CURL_SIZEOF_LONG 4
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
@@ -477,7 +503,7 @@
# define CURL_SIZEOF_CURL_OFF_T 8
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__x86_64__)
# elif defined(__x86_64__) || defined(__ppc64__)
# define CURL_SIZEOF_LONG 8
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, 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
@@ -27,17 +27,17 @@
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2008 Daniel Stenberg, <daniel@haxx.se>."
#define LIBCURL_COPYRIGHT "1996 - 2009 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.19.1-CVS"
#define LIBCURL_VERSION "7.19.3-CVS"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 19
#define LIBCURL_VERSION_PATCH 1
#define LIBCURL_VERSION_PATCH 3
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -54,7 +54,7 @@
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 0x071301
#define LIBCURL_VERSION_NUM 0x071303
/*
* This is the date and time when the full source package was created. The

View File

@@ -8,7 +8,7 @@ TARGETS = libcurl_wc.dll libcurl_wc_imp.lib libcurl_wc.lib
CC = wcc386
CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm -bt=nt &
CFLAGS = -3s -mf -d3 -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm -bt=nt &
-bd -d+ -dWIN32 -dCURL_CA_BUNDLE=getenv("CURL_CA_BUNDLE") &
-dBUILDING_LIBCURL -dHAVE_SPNEGO=1 -dENABLE_IPV6 &
-dDEBUG=1 -dCURLDEBUG -d_WIN32_WINNT=0x0501 -dWINBERAPI=__declspec(cdecl) &
@@ -17,9 +17,10 @@ CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm -bt=
#
# Change to suite.
#
ZLIB_ROOT = ..\..\..\zlib-1.2.3
USE_ZLIB = 0
USE_ARES = 0
ZLIB_ROOT = ..\..\..\zlib-1.2.3
USE_ZLIB = 0
USE_ARES = 0
USE_WATT32 = 0
!ifeq USE_ZLIB 1
CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I$(ZLIB_ROOT)
@@ -29,6 +30,10 @@ CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I$(ZLIB_ROOT)
CFLAGS += -dUSE_ARES -I..\ares
!endif
!ifeq USE_WATT32 1
CFLAGS += -dUSE_WATT32 -I$(%watt_root)\inc
!endif
OBJ_BASE = WC_Win32.obj
C_ARG = $(OBJ_BASE)\wcc386.arg
LINK_ARG = $(OBJ_BASE)\dyn\wlink.arg
@@ -121,7 +126,12 @@ $(LINK_ARG): $(__MAKEFILES__)
@%append $^@ file { $(OBJS_DYN) }
@%append $^@ option quiet, map, caseexact, eliminate, implib=libcurl_wc_imp.lib,
@%append $^@ res=$(RESOURCE) libpath $(%watcom)\lib386;$(%watcom)\lib386\nt
@%append $^@ library clib3r.lib, wldap32.lib, ws2_32.lib
@%append $^@ library clib3s.lib, wldap32.lib
!ifeq USE_WATT32 1
@%append $^@ library $(%watt_root)\lib\wattcpw_imp.lib
!else
@%append $^@ library ws2_32.lib
!endif
!ifeq USE_ZLIB 1
@%append $^@ library $(ZLIB_ROOT)\zlib.lib
!endif
@@ -141,9 +151,9 @@ $(OBJ_DIR)\file.obj: file.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h progress.h sendf.h &
escape.h file.h speedcheck.h getinfo.h transfer.h url.h memory.h &
parsedate.h ..\include\curl\mprintf.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h &
progress.h sendf.h escape.h file.h speedcheck.h getinfo.h transfer.h &
url.h memory.h parsedate.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\timeval.obj: timeval.c timeval.h setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\base64.obj: base64.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -151,111 +161,114 @@ $(OBJ_DIR)\base64.obj: base64.c setup.h config-win32.h ..\include\curl\curlbuild
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h urldata.h cookie.h ..\include\curl\curl.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
easyif.h curl_base64.h memory.h memdebug.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h easyif.h curl_base64.h memory.h memdebug.h
$(OBJ_DIR)\hostip.obj: hostip.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h inet_ntop.h ..\include\curl\mprintf.h memory.h &
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h inet_ntop.h ..\include\curl\mprintf.h memory.h &
memdebug.h
$(OBJ_DIR)\progress.obj: progress.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h progress.h &
..\include\curl\mprintf.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
progress.h ..\include\curl\mprintf.h
$(OBJ_DIR)\formdata.obj: formdata.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h easyif.h strequal.h memory.h ..\include\curl\mprintf.h &
memdebug.h
llist.h curl_addrinfo.h splay.h easyif.h strequal.h memory.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\cookie.obj: cookie.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\mprintf.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h urldata.h cookie.h ..\include\curl\curl.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
strequal.h strtok.h sendf.h memory.h share.h strtoofft.h memdebug.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h strequal.h strtok.h sendf.h memory.h share.h &
strtoofft.h rawstr.h memdebug.h
$(OBJ_DIR)\http.obj: http.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
easyif.h progress.h curl_base64.h strequal.h sslgen.h http_digest.h &
http_ntlm.h http_negotiate.h url.h share.h http.h memory.h select.h &
parsedate.h strtoofft.h multiif.h ..\include\curl\mprintf.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h &
transfer.h sendf.h easyif.h progress.h curl_base64.h strequal.h &
sslgen.h http_digest.h http_ntlm.h http_negotiate.h url.h share.h &
http.h memory.h select.h parsedate.h strtoofft.h multiif.h rawstr.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\sendf.obj: sendf.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h sendf.h connect.h sslgen.h ssh.h multiif.h &
..\include\curl\mprintf.h memory.h strerror.h easyif.h memdebug.h
llist.h curl_addrinfo.h splay.h sendf.h connect.h sslgen.h ssh.h &
multiif.h ..\include\curl\mprintf.h memory.h strerror.h easyif.h &
memdebug.h
$(OBJ_DIR)\ftp.obj: ftp.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h sendf.h easyif.h if2ip.h progress.h transfer.h escape.h &
http.h socks.h ftp.h strtoofft.h strequal.h sslgen.h connect.h &
strerror.h memory.h inet_ntop.h select.h parsedate.h sockaddr.h &
multiif.h url.h ..\include\curl\mprintf.h memdebug.h
llist.h curl_addrinfo.h splay.h sendf.h easyif.h if2ip.h progress.h &
transfer.h escape.h http.h socks.h ftp.h strtoofft.h strequal.h &
sslgen.h connect.h strerror.h inet_ntop.h inet_pton.h select.h &
parsedate.h sockaddr.h multiif.h url.h ..\include\curl\mprintf.h &
memory.h memdebug.h
$(OBJ_DIR)\url.obj: url.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h netrc.h sslgen.h &
transfer.h sendf.h progress.h strequal.h strerror.h escape.h strtok.h &
share.h content_encoding.h http_digest.h http_negotiate.h select.h &
multiif.h easyif.h speedcheck.h ftp.h dict.h telnet.h tftp.h http.h &
file.h curl_ldap.h ssh.h url.h connect.h inet_ntop.h http_ntlm.h &
socks.h ..\include\curl\mprintf.h memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h netrc.h &
sslgen.h transfer.h sendf.h progress.h strequal.h strerror.h escape.h &
strtok.h share.h content_encoding.h http_digest.h http_negotiate.h &
select.h multiif.h easyif.h speedcheck.h rawstr.h ftp.h dict.h telnet.h &
tftp.h http.h file.h curl_ldap.h ssh.h url.h connect.h inet_ntop.h &
http_ntlm.h socks.h ..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\dict.obj: dict.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
progress.h strequal.h dict.h ..\include\curl\mprintf.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h &
transfer.h sendf.h progress.h strequal.h dict.h rawstr.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\if2ip.obj: if2ip.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h if2ip.h
..\include\curl\curlrules.h setup_once.h inet_ntop.h strequal.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h if2ip.h &
..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\speedcheck.obj: speedcheck.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
sendf.h multiif.h speedcheck.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h sendf.h multiif.h speedcheck.h
$(OBJ_DIR)\ldap.obj: ldap.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h escape.h &
transfer.h strequal.h strtok.h curl_ldap.h memory.h curl_base64.h &
..\include\curl\mprintf.h memdebug.h
..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\ssluse.obj: ssluse.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h url.h inet_pton.h &
ssluse.h connect.h strequal.h select.h sslgen.h &
..\include\curl\mprintf.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
url.h inet_pton.h ssluse.h connect.h strequal.h select.h sslgen.h &
rawstr.h ..\include\curl\mprintf.h
$(OBJ_DIR)\version.obj: version.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h sslgen.h ..\include\curl\mprintf.h
llist.h curl_addrinfo.h splay.h sslgen.h ..\include\curl\mprintf.h
$(OBJ_DIR)\getenv.obj: getenv.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
@@ -266,7 +279,8 @@ $(OBJ_DIR)\escape.obj: escape.c setup.h config-win32.h ..\include\curl\curlbuild
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
memory.h urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h &
hash.h llist.h splay.h easyif.h ..\include\curl\mprintf.h memdebug.h
hash.h llist.h curl_addrinfo.h splay.h easyif.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\mprintf.obj: mprintf.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\mprintf.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
@@ -277,31 +291,32 @@ $(OBJ_DIR)\telnet.obj: telnet.c setup.h config-win32.h ..\include\curl\curlbuild
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h &
telnet.h connect.h ..\include\curl\mprintf.h arpa_telnet.h memory.h &
select.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h &
transfer.h sendf.h telnet.h connect.h ..\include\curl\mprintf.h &
arpa_telnet.h memory.h select.h strequal.h rawstr.h memdebug.h
$(OBJ_DIR)\netrc.obj: netrc.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
netrc.h strequal.h strtok.h memory.h ..\include\curl\mprintf.h &
netrc.h strequal.h strtok.h memory.h rawstr.h ..\include\curl\mprintf.h &
memdebug.h
$(OBJ_DIR)\getinfo.obj: getinfo.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h getinfo.h memory.h sslgen.h connect.h memdebug.h
llist.h curl_addrinfo.h splay.h getinfo.h memory.h sslgen.h connect.h &
memdebug.h
$(OBJ_DIR)\transfer.obj: transfer.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h strtoofft.h strequal.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
netrc.h content_encoding.h transfer.h sendf.h speedcheck.h progress.h &
http.h url.h getinfo.h sslgen.h http_digest.h http_ntlm.h &
http_negotiate.h share.h memory.h select.h multiif.h easyif.h &
..\include\curl\mprintf.h memdebug.h
..\include\curl\multi.h ..\include\curl\curl.h rawstr.h urldata.h &
cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h netrc.h content_encoding.h transfer.h sendf.h &
speedcheck.h progress.h http.h url.h getinfo.h sslgen.h http_digest.h &
http_ntlm.h http_negotiate.h share.h memory.h select.h multiif.h &
easyif.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\strequal.obj: strequal.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h strequal.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
@@ -312,10 +327,10 @@ $(OBJ_DIR)\easy.obj: easy.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h urldata.h cookie.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
transfer.h sslgen.h url.h getinfo.h share.h strdup.h memory.h &
progress.h easyif.h select.h sendf.h http_ntlm.h connect.h &
..\include\curl\mprintf.h memdebug.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h transfer.h sslgen.h url.h getinfo.h share.h &
strdup.h memory.h progress.h easyif.h select.h sendf.h http_ntlm.h &
connect.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\security.obj: security.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\krb4.obj: krb4.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -327,13 +342,14 @@ $(OBJ_DIR)\memdebug.obj: memdebug.c setup.h config-win32.h ..\include\curl\curlb
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
..\include\curl\mprintf.h urldata.h cookie.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h memory.h &
memdebug.h
$(OBJ_DIR)\http_chunks.obj: http_chunks.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
urldata.h cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h &
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
content_encoding.h http.h memory.h easyif.h ..\include\curl\mprintf.h &
memdebug.h
$(OBJ_DIR)\strtok.obj: strtok.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -343,26 +359,28 @@ $(OBJ_DIR)\connect.obj: connect.c setup.h config-win32.h ..\include\curl\curlbui
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h urldata.h cookie.h ..\include\curl\curl.h &
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h splay.h &
sendf.h if2ip.h strerror.h connect.h memory.h select.h url.h multiif.h &
sockaddr.h inet_ntop.h inet_pton.h sslgen.h memdebug.h
formdata.h timeval.h http_chunks.h hostip.h hash.h llist.h &
curl_addrinfo.h splay.h sendf.h if2ip.h strerror.h connect.h memory.h &
select.h url.h multiif.h sockaddr.h inet_ntop.h sslgen.h memdebug.h
$(OBJ_DIR)\llist.obj: llist.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h llist.h memory.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memdebug.h
$(OBJ_DIR)\hash.obj: hash.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h hash.h llist.h memory.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h memdebug.h
..\include\curl\curlrules.h setup_once.h hash.h llist.h &
..\include\curl\mprintf.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h memory.h &
..\include\curl\curl.h memdebug.h
$(OBJ_DIR)\multi.obj: multi.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h transfer.h url.h connect.h progress.h memory.h easyif.h &
multiif.h sendf.h http.h memdebug.h
llist.h curl_addrinfo.h splay.h transfer.h url.h connect.h progress.h &
easyif.h multiif.h sendf.h http.h ..\include\curl\mprintf.h memory.h &
memdebug.h
$(OBJ_DIR)\content_encoding.obj: content_encoding.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\share.obj: share.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -370,15 +388,15 @@ $(OBJ_DIR)\share.obj: share.c setup.h config-win32.h ..\include\curl\curlbuild.h
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h share.h memory.h memdebug.h
llist.h curl_addrinfo.h splay.h share.h memory.h memdebug.h
$(OBJ_DIR)\http_digest.obj: http_digest.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
urldata.h cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h strequal.h &
curl_base64.h curl_md5.h http_digest.h strtok.h url.h memory.h easyif.h &
..\include\curl\mprintf.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
rawstr.h curl_base64.h curl_md5.h http_digest.h strtok.h url.h memory.h &
easyif.h ..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\md5.obj: md5.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h curl_md5.h
$(OBJ_DIR)\http_negotiate.obj: http_negotiate.c setup.h config-win32.h &
@@ -388,8 +406,8 @@ $(OBJ_DIR)\http_ntlm.obj: http_ntlm.c setup.h config-win32.h &
urldata.h cookie.h ..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h easyif.h sendf.h &
strequal.h curl_base64.h http_ntlm.h url.h memory.h ssluse.h &
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h easyif.h &
sendf.h rawstr.h curl_base64.h http_ntlm.h url.h memory.h ssluse.h &
..\include\curl\mprintf.h memdebug.h
$(OBJ_DIR)\inet_pton.obj: inet_pton.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
@@ -402,53 +420,54 @@ $(OBJ_DIR)\strerror.obj: strerror.c setup.h config-win32.h ..\include\curl\curlb
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
strerror.h urldata.h cookie.h formdata.h timeval.h http_chunks.h &
hostip.h hash.h llist.h splay.h ..\include\curl\mprintf.h
hostip.h hash.h llist.h curl_addrinfo.h splay.h &
..\include\curl\mprintf.h
$(OBJ_DIR)\hostares.obj: hostares.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h multiif.h connect.h select.h ..\include\curl\mprintf.h &
memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h multiif.h inet_pton.h connect.h select.h &
..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\hostasyn.obj: hostasyn.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\hostip4.obj: hostip4.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h inet_pton.h ..\include\curl\mprintf.h memory.h &
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h inet_pton.h ..\include\curl\mprintf.h memory.h &
memdebug.h
$(OBJ_DIR)\hostip6.obj: hostip6.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h inet_pton.h connect.h ..\include\curl\mprintf.h &
memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h inet_pton.h connect.h &
..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\hostsyn.obj: hostsyn.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h ..\include\curl\mprintf.h memory.h memdebug.h
$(OBJ_DIR)\hostthre.obj: hostthre.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h share.h &
strerror.h url.h multiif.h ..\include\curl\mprintf.h inet_ntop.h &
memory.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
share.h strerror.h url.h multiif.h inet_pton.h &
..\include\curl\mprintf.h inet_ntop.h memory.h memdebug.h
$(OBJ_DIR)\inet_ntop.obj: inet_ntop.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
..\include\curl\mprintf.h ..\include\curl\curl.h &
@@ -458,13 +477,13 @@ $(OBJ_DIR)\parsedate.obj: parsedate.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h
..\include\curl\multi.h ..\include\curl\curl.h rawstr.h parsedate.h
$(OBJ_DIR)\select.obj: select.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
urldata.h cookie.h formdata.h timeval.h http_chunks.h hostip.h hash.h &
llist.h splay.h connect.h select.h
llist.h curl_addrinfo.h splay.h connect.h select.h
$(OBJ_DIR)\gtls.obj: gtls.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -472,16 +491,17 @@ $(OBJ_DIR)\sslgen.obj: sslgen.c setup.h config-win32.h ..\include\curl\curlbuild
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sslgen.h ssluse.h gtls.h &
nssg.h qssl.h sendf.h strequal.h url.h memory.h progress.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sslgen.h &
ssluse.h gtls.h nssg.h qssl.h sendf.h rawstr.h url.h memory.h &
progress.h memdebug.h
$(OBJ_DIR)\tftp.obj: tftp.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h urldata.h cookie.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h transfer.h sendf.h tftp.h &
progress.h connect.h strerror.h sockaddr.h url.h &
..\include\curl\mprintf.h memory.h select.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h &
transfer.h sendf.h tftp.h progress.h connect.h strerror.h sockaddr.h &
url.h ..\include\curl\mprintf.h memory.h select.h memdebug.h
$(OBJ_DIR)\splay.obj: splay.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h splay.h
$(OBJ_DIR)\strdup.obj: strdup.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -491,8 +511,8 @@ $(OBJ_DIR)\socks.obj: socks.c setup.h config-win32.h ..\include\curl\curlbuild.h
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h strequal.h &
select.h connect.h socks.h memdebug.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
strequal.h select.h connect.h socks.h memdebug.h
$(OBJ_DIR)\ssh.obj: ssh.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\nss.obj: nss.c setup.h config-win32.h ..\include\curl\curlbuild.h &
@@ -500,19 +520,18 @@ $(OBJ_DIR)\nss.obj: nss.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h formdata.h timeval.h &
http_chunks.h hostip.h hash.h llist.h splay.h sendf.h url.h connect.h &
strequal.h select.h sslgen.h ..\include\curl\mprintf.h
http_chunks.h hostip.h hash.h llist.h curl_addrinfo.h splay.h sendf.h &
url.h connect.h strequal.h select.h sslgen.h ..\include\curl\mprintf.h
$(OBJ_DIR)\qssl.obj: qssl.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h
$(OBJ_DIR)\rawstr.obj: rawstr.c setup.h config-win32.h ..\include\curl\curlbuild.h &
..\include\curl\curlrules.h setup_once.h ..\include\curl\curl.h &
..\include\curl\curlver.h ..\include\curl\curlrules.h &
..\include\curl\easy.h ..\include\curl\multi.h ..\include\curl\curl.h &
strerror.h urldata.h cookie.h formdata.h timeval.h http_chunks.h &
hostip.h hash.h llist.h splay.h ..\include\curl\mprintf.h
$(OBJ_DIR)\curl_addrinfo.o: curl_addrinfo.c setup.h config-win32.h &
..\include\curl\curlrules.h setup_once.h rawstr.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h
$(OBJ_DIR)\curl_addrinfo.obj: curl_addrinfo.c setup.h config-win32.h &
..\include\curl\curlbuild.h ..\include\curl\curlrules.h setup_once.h &
..\include\curl\curl.h ..\include\curl\curlver.h &
..\include\curl\curlrules.h ..\include\curl\easy.h &
..\include\curl\multi.h ..\include\curl\curl.h curl_addrinfo.h &
..\include\curl\mprintf.h memory.h memdebug.h
..\include\curl\mprintf.h memory.h memdebug.h

View File

@@ -5,7 +5,7 @@
## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3)
##
## Usage:
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1]
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [IDN=1] [SSPI=1] [IPV6=1] [LDAPS=1] [DYN=1]
##
## Hint: you can also set environment vars to control the build, f.e.:
## set ZLIB_PATH=c:/zlib-1.2.3
@@ -21,12 +21,16 @@ ZLIB_PATH = ../../zlib-1.2.3
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8g
OPENSSL_PATH = ../../openssl-0.9.8i
endif
# Edit the path below to point to the base of your LibSSH2 package.
ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.18
endif
# Edit the path below to point to the base of your libidn package.
ifndef LIBIDN_PATH
LIBIDN_PATH = ../../libidn-1.11
endif
# Edit the path below to point to the base of your Novell LDAP NDK.
ifndef LDAP_SDK
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
@@ -72,6 +76,11 @@ ifdef ZLIB
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
DLL_LIBS += -L$(ZLIB_PATH) -lz
endif
ifdef IDN
INCLUDES += -I"$(LIBIDN_PATH)/include"
CFLAGS += -DUSE_LIBIDN
DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn
endif
ifdef SSPI
CFLAGS += -DUSE_WINDOWS_SSPI
endif

View File

@@ -20,7 +20,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8h
OPENSSL_PATH = ../../openssl-0.9.8i
endif
# Edit the path below to point to the base of your LibSSH2 package.
@@ -28,6 +28,11 @@ ifndef LIBSSH2_PATH
LIBSSH2_PATH = ../../libssh2-0.18
endif
# Edit the path below to point to the base of your libidn package.
ifndef LIBIDN_PATH
LIBIDN_PATH = ../../libidn-1.11
endif
ifndef INSTDIR
INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
endif
@@ -183,6 +188,10 @@ else
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
endif
endif
ifdef WITH_IDN
INCLUDES += -I$(LIBIDN_PATH)/include
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
endif
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include
@@ -417,6 +426,9 @@ else
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
@echo $(DL)#define HAVE_FREEADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
@echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@
@@ -443,8 +455,6 @@ else
@echo $(DL)#define _LARGEFILE 1$(DL) >> $@
ifdef ENABLE_IPV6
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
@echo $(DL)#define HAVE_FREEADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETADDRINFO 1$(DL) >> $@
endif
endif
@echo $(DL)#define USE_MANUAL 1$(DL) >> $@
@@ -452,12 +462,13 @@ endif
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@
@echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
@@ -536,6 +547,10 @@ endif
ifdef WITH_SSH2
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
@echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@
endif
ifdef WITH_IDN
@echo $(DL)#define HAVE_LIBIDN 1$(DL) >> $@
@echo $(DL)#define HAVE_TLD_H 1$(DL) >> $@
endif
@echo $(DL)#ifdef __GNUC__$(DL) >> $@
@echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@

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