Compare commits

...

136 Commits

Author SHA1 Message Date
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
184 changed files with 5805 additions and 1702 deletions

170
CHANGES
View File

@@ -6,6 +6,176 @@
Changelog Changelog
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) Version 7.19.1 (5 November 2008)
Daniel Stenberg (4 Nov 2008) Daniel Stenberg (4 Nov 2008)

View File

@@ -1,67 +1,42 @@
Curl and libcurl 7.19.1 Curl and libcurl 7.19.3
Public curl releases: 107 Public curl releases: 109
Command line options: 128 Command line options: 128
curl_easy_setopt() options: 158 curl_easy_setopt() options: 158
Public functions in libcurl: 58 Public functions in libcurl: 58
Known libcurl bindings: 37 Known libcurl bindings: 37
Contributors: 672 Contributors: 683
This release includes the following changes: This release includes the following changes:
o pkg-config can now show supported_protocols and supported_features o
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
This release includes the following bugfixes: This release includes the following bugfixes:
o MingW32 non-configure builds are now largefile feature enabled by default o build failure when disabling FTP but enabling GSS
o NetWare LIBC builds are now largefile feature enabled by default o fixed several calls to memory functions that didn't check return codes
o curl_easy_pause() could behave wrongly on unpause o memory leak for SSL connects with libcurl/NSS when CURLOPT_ISSUERCERT was
o cookies with invalid expire dates are now considered expired used
o HTTP pipelining over proxy o re-use of connections with the multi interface when multiple handles used
o fix regression in configure script which affected OpenSSL builds on MSYS the same server
o GnuTLS-based multi interface doing HTTPS over proxy failed o memory leak with HTTP GSS/kerberos authentication
o recv() failures cause CURLE_RECV_ERROR o removed the default use of "Pragma: no-cache"
o SFTP over SOCKS crash fixed o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
o thread-safety issues addressed for NSS-powered libcurls o bad fclose() after a fatal error in cookie code
o removed the use of mktime() and gmtime(_r)() in date parsing and conversions o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
o HTTP Digest with a blank realm did wrong o GSS authentication infinite loop problem
o CURLINFO_REDIRECT_URL didn't work with the multi interface o 550 response from SIZE no longer treated as missing file
o CURLOPT_RANGE now works for SFTP downloads o ftps:// control connections now use explicit protection level
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
This release includes the following known bugs: This release includes the following known bugs:
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html) 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 This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev, Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
Linus Nielsen Feltzing, Martin Drasar, Stefan Krause, Dmitry Kurochkin, Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski, Igor Novoseltsev,
Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden, Fred Machado, Ken Hirsch
Jamie Lokier, Emanuele Bovisio, Maxim Ivanov, Ian Lynagh, Daniel Egger,
Igor Novoseltsev, John Wilkinson, Pascal Terjan, Steve Roskowski,
Daniel Johnson
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@@ -1,18 +1,24 @@
To be addressed before 7.19.1 (planned release: November 2008) To be addressed in 7.19.3 (planned release: January 2009)
=============================
To be addressed in 7.19.2 (planned release: January 2009)
========================= =========================
188 - "Curl keep special character in filename when saving" bug #2192220 193 - Fix zero-byte file transfers
- Nobody has actually started for real on this
189 - "NTLM authentication and POST wrong behavior" bug #2203193 196 - #2351653 "crash in ConnectionExists"
- Being worked on in the bug tracker
190 - "Using NTLM proxy will lose form-data. Makes NTLM unusable." bug #2210686 197 - IIS-bug in Digest
191 - "proposed patch for curl/libssh2 bugfix" 199 - "Bug 2351645" adjustment of the patch Daniel S applied
http://curl.haxx.se/mail/archive-2008-10/0000.html - Suggested fix posted to list
200 - "afert redirect, the content length is not reset" by Shunlong Bai
192 - 201 - "bug: header data output to the body callback function after set header"
by Shunlong Bai
202 - "hangs up of application above libcurl" - problems with the multi_socket
implementation when using HTTP pipelining. Patch pending by
Igor Novoseltsev
203 -

View File

@@ -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 TYPE_IN_ADDR_T
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Check for in_addr_t: it is used to receive the return code of inet_addr() 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 /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva
dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat
dnl /usr/local/share/certs/ca-root.crt FreeBSD dnl /usr/local/share/certs/ca-root.crt FreeBSD
dnl /etc/ssl/cert.pem OpenBSD
dnl /etc/ssl/certs/ (ca path) SUSE dnl /etc/ssl/certs/ (ca path) SUSE
AC_DEFUN([CURL_CHECK_CA_BUNDLE], [ 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 \ /etc/pki/tls/certs/ca-bundle.crt \
/usr/share/ssl/certs/ca-bundle.crt \ /usr/share/ssl/certs/ca-bundle.crt \
/usr/local/share/certs/ca-root.crt \ /usr/local/share/certs/ca-root.crt \
/etc/ssl/cert.pem \
"$cac"; do "$cac"; do
if test -f "$a"; then if test -f "$a"; then
ca="$a" ca="$a"

View File

@@ -1,8 +1,66 @@
Changelog for the c-ares project Changelog for the c-ares project
* 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) * Nov 1 2008 (Daniel Stenberg)
- Carlo Contavalli added support for the glibc "rotate" option, as documented - 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 causes round robin selection of nameservers from among those listed. This
has the effect of spreading the query load among all listed servers, rather 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 include Makefile.inc
CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \ CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \ -DHAVE_IOCTLSOCKET_FIONBIO -DHAVE_STRUCT_IN6_ADDR \
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \ -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -DHAVE_SYS_TIME_H \
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \ -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
-DHAVE_PROCESS_H -DHAVE_ARPA_NAMESER_H -DHAVE_SYS_SOCKET_H \ -DHAVE_ARPA_NAMESER_H -DHAVE_ARPA_INET_H -DHAVE_SYS_SOCKET_H \
-DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H -DHAVE_NETINET_TCP_H \ -DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H -DHAVE_NETINET_TCP_H \
-DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND -DHAVE_GETTIMEOFDAY \ -DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND -DHAVE_GETTIMEOFDAY \
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \ -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_ARG6='int' -DRECVFROM_TYPE_RETV='int' \
-DRECVFROM_TYPE_ARG5='struct sockaddr' -DHAVE_RECVFROM \ -DRECVFROM_TYPE_ARG5='struct sockaddr' -DHAVE_RECVFROM \
-DRECVFROM_TYPE_ARG2_IS_VOID -DHAVE_STRDUP -DHAVE_NETDB_H \ -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 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_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \ ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \
ares_getsock.3 ares_parse_ns_reply.3 \ ares_getsock.3 ares_parse_ns_reply.3 ares_dup.3 \
ares_destroy_options.3 ares_save_options.3 ares_destroy_options.3 ares_save_options.3 ares_gethostbyname_file.3 \
ares_set_socket_callback.3

View File

@@ -350,12 +350,14 @@ endif
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FCNTL_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_GETHOSTBYADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYNAME 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_GETPROTOBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@ @echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_ADDR 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_LL 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ @echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@

View File

@@ -26,7 +26,7 @@ OBJ_DIR = VC6_obj
DEF_FILE = cares.def DEF_FILE = cares.def
!if "$(USE_WATT32)" == "1" !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 EX_LIBS = $(WATT_ROOT)\lib\wattcpvc_imp.lib
!else !else
@@ -124,9 +124,11 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
@echo ares_inet_net_pton >> $@ @echo ares_inet_net_pton >> $@
@echo ares_inet_ntop >> $@ @echo ares_inet_ntop >> $@
@echo ares_inet_pton >> $@ @echo ares_inet_pton >> $@
@echo ares_writev >> $@
@echo ares_getnameinfo >> $@ @echo ares_getnameinfo >> $@
@echo ares_parse_aaaa_reply >> $@ @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 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) 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 public.
The full source code is available in the 'c-ares' release archives, and in the The full source code is available in the 'c-ares' release archives, and in the
'ares' subdir of the curl CVS source repostitory. 'ares' subdir of the curl CVS source repository.
If you find bugs, correct flaws, have questions or have comments in general in If you find bugs, correct flaws, have questions or have comments in general in
regard to c-ares (or by all means the original ares too), get in touch with us regard to c-ares (or by all means the original ares too), get in touch with us

View File

@@ -1,11 +1,25 @@
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.0 release:
Changed:
o Added support for the glibc "rotate" resolv.conf option (or ARES_OPT_ROTATE)
o Added ares_gethostbyname_file()
o Added ares_dup()
o Added ares_set_socket_callback()
Fixed:
o improved configure detection of several functions o improved configure detection of several functions
o improved source code portability o improved source code portability
o adig supports a regular numerical dotted IP address for the -s option
o handling of EINPROGRESS for UDP connects
o ares_parse_ptr_reply() would cause a buffer to shrink instead of expand if a
reply contained 8 or more records
o buildconf works on OS X
Thanks go to these friendly people for their efforts and contributions: Thanks go to these friendly people for their efforts and contributions:
Yang Tse, Charles Hardin, Carlo Contavalli, Brad Spencer, Gerald Combs,
and obviously Daniel Stenberg Gregor Jasny
Have fun! 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 TYPE_IN_ADDR_T
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Check for in_addr_t: it is used to receive the return code of inet_addr() 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) #if defined(WIN32) && !defined(WATT32)
#include <winsock.h> #include <winsock.h>
#else #else
#include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $Id$ */
/* Copyright 1998 by the Massachusetts Institute of Technology. /* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2007 by Daniel Stenberg * Copyright (C) 2007-2008 by Daniel Stenberg
* *
* Permission to use, copy, modify, and distribute this * Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without * software and its documentation for any purpose and without
@@ -29,10 +29,11 @@
#include <sys/types.h> #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 /* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
libc5-based Linux systems. Only include it on system that are known to libc5-based Linux systems. Only include it on system that are known to
require it! */ require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) #if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
@@ -51,8 +52,8 @@
# include <winsock2.h> # include <winsock2.h>
# include <ws2tcpip.h> # include <ws2tcpip.h>
#else #else
#include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h>
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -180,12 +181,28 @@ typedef void (*ares_sock_state_cb)(void *data,
struct apattern; 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 { struct ares_options {
int flags; int flags;
int timeout; /* in seconds or milliseconds, depending on options */ int timeout; /* in seconds or milliseconds, depending on options */
int tries; int tries;
int ndots; int ndots;
int rotate;
unsigned short udp_port; unsigned short udp_port;
unsigned short tcp_port; unsigned short tcp_port;
int socket_send_buffer_size; int socket_send_buffer_size;
@@ -212,14 +229,21 @@ typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
struct hostent *hostent); struct hostent *hostent);
typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts, typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
char *node, char *service); 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(ares_channel *channelptr);
int ares_init_options(ares_channel *channelptr, struct ares_options *options, int ares_init_options(ares_channel *channelptr, struct ares_options *options,
int optmask); int optmask);
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); 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_destroy(ares_channel channel);
void ares_cancel(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, void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
ares_callback callback, void *arg); ares_callback callback, void *arg);
void ares_query(ares_channel channel, const char *name, int dnsclass, void ares_query(ares_channel channel, const char *name, int dnsclass,
@@ -228,6 +252,8 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
int type, ares_callback callback, void *arg); int type, ares_callback callback, void *arg);
void ares_gethostbyname(ares_channel channel, const char *name, int family, void ares_gethostbyname(ares_channel channel, const char *name, int family,
ares_host_callback callback, void *arg); 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, void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
int family, ares_host_callback callback, void *arg); int family, ares_host_callback callback, void *arg);
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,

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" #include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif

View File

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

View File

@@ -52,8 +52,7 @@
struct addr_query { struct addr_query {
/* Arguments passed to ares_gethostbyaddr() */ /* Arguments passed to ares_gethostbyaddr() */
ares_channel channel; ares_channel channel;
union ares_addr addr; struct ares_addr addr;
int family;
ares_host_callback callback; ares_host_callback callback;
void *arg; void *arg;
@@ -66,8 +65,8 @@ static void addr_callback(void *arg, int status, int timeouts,
unsigned char *abuf, int alen); unsigned char *abuf, int alen);
static void end_aquery(struct addr_query *aquery, int status, static void end_aquery(struct addr_query *aquery, int status,
struct hostent *host); struct hostent *host);
static int file_lookup(union ares_addr *addr, int family, struct hostent **host); static int file_lookup(struct ares_addr *addr, struct hostent **host);
static void ptr_rr_name(char *name, int family, union ares_addr *addr); static void ptr_rr_name(char *name, struct ares_addr *addr);
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
int family, ares_host_callback callback, void *arg) 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; aquery->channel = channel;
if (family == AF_INET) if (family == AF_INET)
memcpy(&aquery->addr.addr4, addr, sizeof(struct in_addr)); memcpy(&aquery->addr.addrV4, addr, sizeof(struct in_addr));
else else
memcpy(&aquery->addr.addr6, addr, sizeof(struct in6_addr)); memcpy(&aquery->addr.addrV6, addr, sizeof(struct in6_addr));
aquery->family = family; aquery->addr.family = family;
aquery->callback = callback; aquery->callback = callback;
aquery->arg = arg; aquery->arg = arg;
aquery->remaining_lookups = channel->lookups; aquery->remaining_lookups = channel->lookups;
@@ -119,13 +118,13 @@ static void next_lookup(struct addr_query *aquery)
switch (*p) switch (*p)
{ {
case 'b': case 'b':
ptr_rr_name(name, aquery->family, &aquery->addr); ptr_rr_name(name, &aquery->addr);
aquery->remaining_lookups = p + 1; aquery->remaining_lookups = p + 1;
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
aquery); aquery);
return; return;
case 'f': 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, /* this status check below previously checked for !ARES_ENOTFOUND,
but we should not assume that this single error code is the one 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; aquery->timeouts += timeouts;
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
if (aquery->family == AF_INET) if (aquery->addr.family == AF_INET)
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4, status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4,
sizeof(struct in_addr), AF_INET, &host); sizeof(struct in_addr), AF_INET, &host);
else 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); sizeof(struct in6_addr), AF_INET6, &host);
end_aquery(aquery, status, host); end_aquery(aquery, status, host);
} }
@@ -173,7 +172,7 @@ static void end_aquery(struct addr_query *aquery, int status,
free(aquery); 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; FILE *fp;
int status; int status;
@@ -226,21 +225,21 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
return ARES_EFILE; 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); ares_free_hostent(*host);
continue; 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; 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; break;
} }
ares_free_hostent(*host); ares_free_hostent(*host);
@@ -253,11 +252,11 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
return status; return status;
} }
static void ptr_rr_name(char *name, int family, union ares_addr *addr) static void ptr_rr_name(char *name, 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 a1 = (int)((laddr >> 24) & 0xff);
int a2 = (int)((laddr >> 16) & 0xff); int a2 = (int)((laddr >> 16) & 0xff);
int a3 = (int)((laddr >> 8) & 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 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, 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.",
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4, 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[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 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[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 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, bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,

View File

@@ -245,8 +245,8 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
numdots++; 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). * (although inet_addr doesn't think so).
*/ */
if (numdots != 3) if (numdots != 3)
@@ -289,6 +289,33 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
return 1; 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) static int file_lookup(const char *name, int family, struct hostent **host)
{ {
FILE *fp; FILE *fp;
@@ -405,13 +432,13 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
continue; continue;
if (sortlist[i].type == PATTERN_MASK) if (sortlist[i].type == PATTERN_MASK)
{ {
if ((addr->s_addr & sortlist[i].mask.addr.addr4.s_addr) if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
== sortlist[i].addr.addr4.s_addr) == sortlist[i].addrV4.s_addr)
break; break;
} }
else 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)) sortlist[i].mask.bits))
break; break;
} }
@@ -458,7 +485,7 @@ static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
{ {
if (sortlist[i].family != AF_INET6) if (sortlist[i].family != AF_INET6)
continue; 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; break;
} }
return i; 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 We do this by determining our own domain name, then searching the string
for this domain name and removing it. for this domain name and removing it.
*/ */
#ifdef HAVE_GETHOSTNAME
if (niquery->flags & ARES_NI_NOFQDN) if (niquery->flags & ARES_NI_NOFQDN)
{ {
char buf[255]; char buf[255];
@@ -237,6 +238,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, struct hosten
*end = 0; *end = 0;
} }
} }
#endif
niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name), niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name),
service); service);
return; return;

View File

@@ -33,6 +33,12 @@
int ares_getopt(int nargc, char * const nargv[], const char *ostr); 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 char *optarg;
extern int optind; extern int optind;
extern int opterr; 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. if \fIARES_FLAG_NORECURSE\fP is set.
.TP 23 .TP 23
.B ARES_FLAG_STAYOPEN .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. drops to zero.
.TP 23 .TP 23
.B ARES_FLAG_NOSEARCH .B ARES_FLAG_NOSEARCH
@@ -185,7 +185,8 @@ A configuration file could not be read.
.B ARES_ENOMEM .B ARES_ENOMEM
The process's available memory was exhausted. The process's available memory was exhausted.
.SH SEE ALSO .SH SEE ALSO
.BR ares_destroy (3) .BR ares_destroy(3),
.BR ares_dup(3)
.SH AUTHOR .SH AUTHOR
Greg Hudson, MIT Information Systems Greg Hudson, MIT Information Systems
.br .br

View File

@@ -159,6 +159,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->servers = NULL; channel->servers = NULL;
channel->sock_state_cb = NULL; channel->sock_state_cb = NULL;
channel->sock_state_cb_data = NULL; channel->sock_state_cb_data = NULL;
channel->sock_create_cb = NULL;
channel->sock_create_cb_data = NULL;
channel->last_server = 0; channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec; 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) { if (status == ARES_SUCCESS) {
status = init_by_options(channel, options, optmask); status = init_by_options(channel, options, optmask);
if (status != ARES_SUCCESS) if (status != ARES_SUCCESS)
DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
ares_strerror(status))); ares_strerror(status)));
@@ -257,6 +259,40 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
return ARES_SUCCESS; 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 */ /* Save options from initialized channel */
int ares_save_options(ares_channel channel, struct ares_options *options, int ares_save_options(ares_channel channel, struct ares_options *options,
int *optmask) int *optmask)
@@ -269,10 +305,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
if (!ARES_CONFIG_CHECK(channel)) if (!ARES_CONFIG_CHECK(channel))
return ARES_ENODATA; 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| (*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_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS| 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 */ /* Copy easy stuff */
options->flags = channel->flags; options->flags = channel->flags;
@@ -355,7 +395,7 @@ static int init_by_options(ares_channel channel,
if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
channel->ndots = options->ndots; channel->ndots = options->ndots;
if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1) 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) if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
channel->udp_port = options->udp_port; channel->udp_port = options->udp_port;
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1) 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; return ARES_ENOMEM;
for (i = 0; i < options->nsort; i++) 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->nsort = options->nsort;
} }
channel->optmask = optmask;
return ARES_SUCCESS; return ARES_SUCCESS;
} }
@@ -966,7 +1009,9 @@ static int init_by_defaults(ares_channel channel)
*/ */
size_t len = 64; size_t len = 64;
int res; int res;
channel->ndomains = 0; /* default to none */
#ifdef HAVE_GETHOSTNAME
hostname = malloc(len); hostname = malloc(len);
if(!hostname) { if(!hostname) {
rc = ARES_ENOMEM; rc = ARES_ENOMEM;
@@ -994,7 +1039,6 @@ static int init_by_defaults(ares_channel channel)
} while(0); } while(0);
channel->ndomains = 0; /* default to none */
if (strchr(hostname, '.')) { if (strchr(hostname, '.')) {
/* a dot was found */ /* a dot was found */
@@ -1010,6 +1054,7 @@ static int init_by_defaults(ares_channel channel)
} }
channel->ndomains = 1; channel->ndomains = 1;
} }
#endif
} }
if (channel->nsort == -1) { if (channel->nsort == -1) {
@@ -1179,8 +1224,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
/* Lets see if it is CIDR */ /* Lets see if it is CIDR */
/* First we'll try IPv6 */ /* First we'll try IPv6 */
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf, if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
&pat.addr.addr6, &pat.addrV6,
sizeof(pat.addr.addr6))) > 0) sizeof(pat.addrV6))) > 0)
{ {
pat.type = PATTERN_CIDR; pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits; pat.mask.bits = (unsigned short)bits;
@@ -1189,8 +1234,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_ENOMEM; return ARES_ENOMEM;
} }
if (ipbufpfx[0] && if (ipbufpfx[0] &&
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4, (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
sizeof(pat.addr.addr4))) > 0) sizeof(pat.addrV4))) > 0)
{ {
pat.type = PATTERN_CIDR; pat.type = PATTERN_CIDR;
pat.mask.bits = (unsigned short)bits; pat.mask.bits = (unsigned short)bits;
@@ -1199,13 +1244,13 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
return ARES_ENOMEM; return ARES_ENOMEM;
} }
/* See if it is just a regular IP */ /* 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]) if (ipbufpfx[0])
{ {
memcpy(ipbuf, str, (int)(q-str)); memcpy(ipbuf, str, (int)(q-str));
ipbuf[(int)(q-str)] = '\0'; 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); natural_mask(&pat);
} }
else 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, /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
* but portable. * 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 /* This is out of date in the CIDR world, but some people might
* still rely on it. * still rely on it.
*/ */
if (IN_CLASSA(addr.s_addr)) 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)) 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 else
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET); pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
} }
#endif #endif
/* initialize an rc4 key. If possible a cryptographically secure random key /* 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; 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)); ares__rc4(key, (unsigned char *)&r, sizeof(r));
return 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" #include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif

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; char *ptrname, *hostname, *rr_name, *rr_data;
struct hostent *hostent; struct hostent *hostent;
int aliascnt = 0; int aliascnt = 0;
int alias_alloc = 8;
char ** aliases; char ** aliases;
/* Set *host to NULL for all failure cases. */ /* Set *host to NULL for all failure cases. */
@@ -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. */ /* Examine each answer resource record (RR) in turn. */
hostname = NULL; hostname = NULL;
aliases = malloc(8 * sizeof(char *)); aliases = malloc(alias_alloc * sizeof(char *));
if (!aliases) if (!aliases)
{ {
free(ptrname); free(ptrname);
@@ -125,8 +126,16 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
} }
strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1); strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
aliascnt++; aliascnt++;
if ((aliascnt%8)==0) if (aliascnt >= alias_alloc) {
aliases = realloc(aliases, (aliascnt/16+1) * sizeof(char *)); 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) if (rr_class == C_IN && rr_type == T_CNAME)

View File

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

View File

@@ -805,68 +805,51 @@ void ares__send_query(ares_channel channel, struct query *query,
static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */) int nonblock /* TRUE or FALSE */)
{ {
#undef SETBLOCK #if defined(USE_BLOCKING_SOCKETS)
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK return 0; /* returns success */
#elif defined(HAVE_FCNTL_O_NONBLOCK)
/* most recent unix versions */ /* most recent unix versions */
int flags; int flags;
flags = fcntl(sockfd, F_GETFL, 0); flags = fcntl(sockfd, F_GETFL, 0);
if (FALSE != nonblock) if (FALSE != nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); 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 */ /* older unix versions */
int flags; int flags;
flags = nonblock; flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags); return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0) #elif defined(HAVE_IOCTLSOCKET_FIONBIO)
#ifdef WATT32 #ifdef WATT32
char flags; char flags;
#else #else
/* Windows? */ /* Windows */
unsigned long flags; unsigned long flags;
#endif #endif
flags = nonblock; flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags); return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
/* presumably for Amiga */
/* Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock); 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 */ /* BeOS */
long b = nonblock ? 1 : 0; long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING #else
return 0; /* returns success */ # error "no non-blocking method was found/used/set"
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#endif #endif
} }
@@ -914,6 +897,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
return -1; return -1;
} }
#ifdef TCP_NODELAY
/* /*
* Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in * 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 * configure_socket). In general, in DNS lookups we're pretty much interested
@@ -927,6 +911,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
closesocket(s); closesocket(s);
return -1; return -1;
} }
#endif
/* Connect to the server. */ /* Connect to the server. */
memset(&sockin, 0, sizeof(sockin)); memset(&sockin, 0, sizeof(sockin));
@@ -944,6 +929,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); SOCK_STATE_CALLBACK(channel, s, 1, 0);
server->tcp_buffer_pos = 0; server->tcp_buffer_pos = 0;
server->tcp_socket = s; server->tcp_socket = s;
@@ -984,6 +980,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); SOCK_STATE_CALLBACK(channel, s, 1, 0);
server->udp_socket = s; server->udp_socket = s;

View File

@@ -17,6 +17,9 @@
#include "setup.h" #include "setup.h"
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif
@@ -67,7 +70,7 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
key->y = y; 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; unsigned short qid;
struct list_node* list_head; 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 performed per id generation. In practice this search should happen only
once per newly generated id 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 { do {
id = ares__generate_new_id(&channel->id_key); id = ares__generate_new_id(&channel->id_key);
} while (find_query_by_id(channel,id)); } while (find_query_by_id(channel, id));
return id; return (unsigned short)id;
} }
void ares_query(ares_channel channel, const char *name, int dnsclass, 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) .B void ares_save_options(ares_channel \fIchannel\fP, struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
The The \fBares_save_options(3)\fP function saves the channel data identified by
.B ares_save_options
function saves the channel data identified by
.IR channel , .IR channel ,
into the options struct identified by into the options struct identified by
.IR options , .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 passed directly to ares_init_options. When the options
are no longer needed, ares_destroy_options should be called are no longer needed, ares_destroy_options should be called
to free any associated memory. 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 .SH SEE ALSO
.BR ares_destroy_options (3), .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 .SH AUTHOR
Brad House Brad House
.br .br

View File

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

@@ -1,6 +1,44 @@
#!/bin/sh #!/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 ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
${AUTOHEADER:-autoheader} ${AUTOHEADER:-autoheader}
${AUTOCONF:-autoconf} ${AUTOCONF:-autoconf}

View File

@@ -76,9 +76,12 @@
/* FUNCTIONS */ /* FUNCTIONS */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* Define if you have the ioctlsocket function. */ /* Define if you have the ioctlsocket function. */
#define HAVE_IOCTLSOCKET 1 #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 if you have the strcasecmp function. */
/* #define HAVE_STRCASECMP 1 */ /* #define HAVE_STRCASECMP 1 */
@@ -94,6 +97,9 @@
/* Define if you have the strnicmp function. */ /* Define if you have the strnicmp function. */
#define HAVE_STRNICMP 1 #define HAVE_STRNICMP 1
/* Define if you have the gethostname function. */
#define HAVE_GETHOSTNAME 1
/* Define if you have the recv function. */ /* Define if you have the recv function. */
#define HAVE_RECV 1 #define HAVE_RECV 1
@@ -162,6 +168,15 @@
#define SOCKET int #define SOCKET int
#define NS_INADDRSZ 4 #define NS_INADDRSZ 4
#define HAVE_ARPA_NAMESER_H 1 #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_WINSOCK_H
#undef HAVE_WINSOCK2_H #undef HAVE_WINSOCK2_H
#undef HAVE_WS2TCPIP_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], [-], AC_INIT([c-ares], [-],
[c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares]) [c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares])
CARES_OVERRIDE_AUTOCONF
AC_CONFIG_SRCDIR([ares_ipv6.h]) AC_CONFIG_SRCDIR([ares_ipv6.h])
AM_CONFIG_HEADER([config.h]) AM_CONFIG_HEADER([config.h])
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
@@ -12,6 +14,8 @@ CARES_CHECK_OPTION_DEBUG
CARES_CHECK_OPTION_OPTIMIZE CARES_CHECK_OPTION_OPTIMIZE
CARES_CHECK_OPTION_WARNINGS CARES_CHECK_OPTION_WARNINGS
CARES_CHECK_PATH_SEPARATOR
dnl SED is mandatory for configure process and libtool. dnl SED is mandatory for configure process and libtool.
dnl Set it now, allowing it to be changed later. dnl Set it now, allowing it to be changed later.
AC_PATH_PROG([SED], [sed], [not_found], 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(DEBUGBUILD, test x$want_debug = xyes)
AM_CONDITIONAL(CURLDEBUG, 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 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)]) AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
case $host in case $host in
@@ -342,9 +330,7 @@ then
fi fi
if test "$HAVE_GETHOSTBYNAME" = "1"; then if test "$HAVE_GETHOSTBYNAME" != "1"; then
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
else
AC_MSG_ERROR([couldn't find libraries for gethostbyname()]) AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
fi fi
@@ -553,12 +539,19 @@ CURL_CHECK_FUNC_RECVFROM
CURL_CHECK_FUNC_SEND CURL_CHECK_FUNC_SEND
CURL_CHECK_MSG_NOSIGNAL CURL_CHECK_MSG_NOSIGNAL
CARES_CHECK_FUNC_FCNTL
CARES_CHECK_FUNC_FREEADDRINFO CARES_CHECK_FUNC_FREEADDRINFO
CARES_CHECK_FUNC_GETADDRINFO CARES_CHECK_FUNC_GETADDRINFO
CARES_CHECK_FUNC_GETHOSTBYADDR
CARES_CHECK_FUNC_GETHOSTBYNAME
CARES_CHECK_FUNC_GETHOSTNAME CARES_CHECK_FUNC_GETHOSTNAME
CARES_CHECK_FUNC_GETSERVBYPORT_R CARES_CHECK_FUNC_GETSERVBYPORT_R
CARES_CHECK_FUNC_INET_NTOP CARES_CHECK_FUNC_INET_NTOP
CARES_CHECK_FUNC_INET_PTON 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_STRCASECMP
CARES_CHECK_FUNC_STRCMPI CARES_CHECK_FUNC_STRCMPI
CARES_CHECK_FUNC_STRDUP CARES_CHECK_FUNC_STRDUP
@@ -851,8 +844,6 @@ dnl and get the types of five of its arguments.
CURL_CHECK_FUNC_GETNAMEINFO CURL_CHECK_FUNC_GETNAMEINFO
CURL_CHECK_NONBLOCKING_SOCKET
AC_C_BIGENDIAN( AC_C_BIGENDIAN(
[AC_DEFINE(ARES_BIG_ENDIAN, 1, [AC_DEFINE(ARES_BIG_ENDIAN, 1,
[define this if ares is built for a big endian system])], [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]) [a suitable file/device to read random data from])
fi fi
CARES_CHECK_OPTION_NONBLOCKING
CARES_CHECK_NONBLOCKING_SOCKET
CARES_PRIVATE_LIBS="$LIBS" CARES_PRIVATE_LIBS="$LIBS"
AC_SUBST(CARES_PRIVATE_LIBS) AC_SUBST(CARES_PRIVATE_LIBS)

View File

@@ -16,7 +16,7 @@
#*************************************************************************** #***************************************************************************
# File version for 'aclocal' use. Keep it a single number. # File version for 'aclocal' use. Keep it a single number.
# serial 45 # serial 46
dnl CARES_CHECK_COMPILER dnl CARES_CHECK_COMPILER
@@ -875,6 +875,13 @@ AC_DEFUN([CARES_SET_COMPILER_WARNING_OPTS], [
tmp_CFLAGS="$tmp_CFLAGS -Wdeclaration-after-statement" tmp_CFLAGS="$tmp_CFLAGS -Wdeclaration-after-statement"
fi 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 fi
# #
dnl Do not issue warnings for code in system include paths. 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. # File version for 'aclocal' use. Keep it a single number.
# serial 2 # serial 3
dnl CARES_CHECK_OPTION_DEBUG 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 CARES_CHECK_OPTION_OPTIMIZE
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Verify if configure has been invoked with option dnl Verify if configure has been invoked with option
@@ -140,3 +172,43 @@ AC_HELP_STRING([--disable-warnings],[Disable strict compiler warnings]),
esac esac
AC_MSG_RESULT([$want_warnings]) 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 #define ssize_t int
#endif #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 */ #endif /* HAVE_CONFIG_H */
/* /*
@@ -123,22 +135,6 @@
#undef VERSION #undef VERSION
#undef PACKAGE #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 */ /* IPv6 compatibility */
#if !defined(HAVE_AF_INET6) #if !defined(HAVE_AF_INET6)
#if defined(HAVE_PF_INET6) #if defined(HAVE_PF_INET6)

View File

@@ -27,6 +27,8 @@ AC_PREREQ(2.57)
dnl We don't know the version number "statically" so we use a dash here 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/]) AC_INIT([curl], [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
CURL_OVERRIDE_AUTOCONF
dnl configure script copyright dnl configure script copyright
AC_COPYRIGHT([Copyright (c) 1998 - 2008 Daniel Stenberg, <daniel@haxx.se> AC_COPYRIGHT([Copyright (c) 1998 - 2008 Daniel Stenberg, <daniel@haxx.se>
This configure script may be copied, distributed and modified under the This configure script may be copied, distributed and modified under the
@@ -40,6 +42,8 @@ CURL_CHECK_OPTION_DEBUG
CURL_CHECK_OPTION_OPTIMIZE CURL_CHECK_OPTION_OPTIMIZE
CURL_CHECK_OPTION_WARNINGS CURL_CHECK_OPTION_WARNINGS
CURL_CHECK_PATH_SEPARATOR
dnl SED is mandatory for configure process and libtool. dnl SED is mandatory for configure process and libtool.
dnl Set it now, allowing it to be changed later. dnl Set it now, allowing it to be changed later.
AC_PATH_PROG([SED], [sed], [not_found], AC_PATH_PROG([SED], [sed], [not_found],
@@ -153,22 +157,6 @@ AC_LIBTOOL_WIN32_DLL
CURL_PROCESS_DEBUG_BUILD_OPTS 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 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)]) AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
case $host in case $host in
@@ -658,9 +646,7 @@ then
fi fi
if test "$HAVE_GETHOSTBYNAME" = "1"; then if test "$HAVE_GETHOSTBYNAME" != "1"; then
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
else
AC_MSG_ERROR([couldn't find libraries for gethostbyname()]) AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
fi fi
@@ -832,25 +818,6 @@ if test "$ipv6" = "yes"; then
curl_ipv6_msg="enabled" curl_ipv6_msg="enabled"
fi 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])
else
CURL_CHECK_NONBLOCKING_SOCKET
fi
],
[
CURL_CHECK_NONBLOCKING_SOCKET
])
dnl ********************************************************************** dnl **********************************************************************
dnl Check if the operating system allows programs to write to their own argv[] dnl Check if the operating system allows programs to write to their own argv[]
dnl ********************************************************************** dnl **********************************************************************
@@ -2014,19 +1981,28 @@ CURL_CHECK_FUNC_SEND
CURL_CHECK_MSG_NOSIGNAL CURL_CHECK_MSG_NOSIGNAL
CURL_CHECK_FUNC_ALARM CURL_CHECK_FUNC_ALARM
CURL_CHECK_FUNC_FCNTL
CURL_CHECK_FUNC_FDOPEN CURL_CHECK_FUNC_FDOPEN
CURL_CHECK_FUNC_FREEADDRINFO CURL_CHECK_FUNC_FREEADDRINFO
CURL_CHECK_FUNC_FREEIFADDRS
CURL_CHECK_FUNC_FTRUNCATE CURL_CHECK_FUNC_FTRUNCATE
CURL_CHECK_FUNC_GETADDRINFO CURL_CHECK_FUNC_GETADDRINFO
CURL_CHECK_FUNC_GETHOSTBYADDR
CURL_CHECK_FUNC_GETHOSTBYADDR_R CURL_CHECK_FUNC_GETHOSTBYADDR_R
CURL_CHECK_FUNC_GETHOSTBYNAME
CURL_CHECK_FUNC_GETHOSTBYNAME_R CURL_CHECK_FUNC_GETHOSTBYNAME_R
CURL_CHECK_FUNC_GETHOSTNAME CURL_CHECK_FUNC_GETHOSTNAME
CURL_CHECK_FUNC_GETIFADDRS
CURL_CHECK_FUNC_GETSERVBYPORT_R CURL_CHECK_FUNC_GETSERVBYPORT_R
CURL_CHECK_FUNC_GMTIME_R CURL_CHECK_FUNC_GMTIME_R
CURL_CHECK_FUNC_INET_NTOA_R CURL_CHECK_FUNC_INET_NTOA_R
CURL_CHECK_FUNC_INET_NTOP CURL_CHECK_FUNC_INET_NTOP
CURL_CHECK_FUNC_INET_PTON 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_LOCALTIME_R
CURL_CHECK_FUNC_SETSOCKOPT
CURL_CHECK_FUNC_SIGACTION CURL_CHECK_FUNC_SIGACTION
CURL_CHECK_FUNC_SIGINTERRUPT CURL_CHECK_FUNC_SIGINTERRUPT
CURL_CHECK_FUNC_SIGNAL CURL_CHECK_FUNC_SIGNAL
@@ -2062,8 +2038,6 @@ AC_CHECK_FUNCS([basename \
closesocket \ closesocket \
fork \ fork \
geteuid \ geteuid \
gethostbyaddr \
getifaddrs \
getpass_r \ getpass_r \
getppid \ getppid \
getprotobyname \ getprotobyname \
@@ -2169,6 +2143,15 @@ if test "$disable_poll" = "no"; then
fi dnl poll() was found fi dnl poll() was found
fi dnl poll()-check is not disabled 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, , AC_PATH_PROG( PERL, perl, ,
$PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin ) $PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )

View File

@@ -77,7 +77,7 @@ different bindings exist at the time of this writing.
September 2000, kerberos4 support was added. September 2000, kerberos4 support was added.
In November 2000 started the work on a test suite for curl. It was later 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 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 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 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 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. 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. 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: August 2004:
Curl and libcurl 7.12.1 Curl and libcurl 7.12.1
@@ -144,10 +149,38 @@ August 2004:
April 2005: 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: 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

@@ -782,9 +782,13 @@ REDUCING SIZE
--without-ssl (disables support for SSL/TLS) --without-ssl (disables support for SSL/TLS)
--without-zlib (disables support for on-the-fly decompression) --without-zlib (disables support for on-the-fly decompression)
The GNU linker has a number of options to reduce the size of the libcurl The GNU compiler and linker have a number of options that can reduce the
dynamic libraries on some platforms even further. Specify them by giving size of the libcurl dynamic libraries on some platforms even further.
the options -Wl,-Bsymbolic and -Wl,-s on the gcc command-line. 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 Be sure also to strip debugging symbols from your binaries after
compiling using 'strip' (or the appropriate variant if cross-compiling). compiling using 'strip' (or the appropriate variant if cross-compiling).
If space is really tight, you may be able to remove some unneeded If space is really tight, you may be able to remove some unneeded
@@ -826,9 +830,14 @@ PORTS
- Alpha OpenVMS V7.1-1H2 - Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1 - Alpha Tru64 v5.0 5.1
- AVR32 Linux - AVR32 Linux
- ARM INTEGRITY
- ARM iPhone OS
- Cell Linux
- Cell Cell OS
- HP-PA HP-UX 9.X 10.X 11.X - HP-PA HP-UX 9.X 10.X 11.X
- HP-PA Linux - HP-PA Linux
- HP3000 MPE/iX - HP3000 MPE/iX
- MicroBlaze uClinux
- MIPS IRIX 6.2, 6.5 - MIPS IRIX 6.2, 6.5
- MIPS Linux - MIPS Linux
- OS/400 - OS/400
@@ -848,7 +857,6 @@ PORTS
- StrongARM (and other ARM) RISC OS 3.1, 4.02 - StrongARM (and other ARM) RISC OS 3.1, 4.02
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6 - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
- StrongARM NetBSD 1.4.1 - StrongARM NetBSD 1.4.1
- ARM INTEGRITY
- Symbian OS (P.I.P.S.) 9.x - Symbian OS (P.I.P.S.) 9.x
- TPF - TPF
- Ultrix 4.3a - Ultrix 4.3a
@@ -878,6 +886,7 @@ PORTS
- m68k OpenBSD - m68k OpenBSD
- m88k dg-dgux5.4R3.00 - m88k dg-dgux5.4R3.00
- s390 Linux - s390 Linux
- x86_64 Linux
- XScale/PXA250 Linux 2.4 - XScale/PXA250 Linux 2.4
- Nios II uClinux - Nios II uClinux

View File

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

113
docs/TODO
View File

@@ -15,16 +15,13 @@
1.1 Zero-copy interface 1.1 Zero-copy interface
1.2 More data sharing 1.2 More data sharing
1.3 struct lifreq 1.3 struct lifreq
1.4 Get IP address 1.4 signal-based resolver timeouts
1.5 c-ares ipv6
1.6 configure-based info in public headers
1.7 signal-based resolver timeouts
2. libcurl - multi interface 2. libcurl - multi interface
2.1 More non-blocking 2.1 More non-blocking
2.2 Pause transfers 2.2 Remove easy interface internally
2.3 Remove easy interface internally 2.3 Avoid having to remove/readd handles
2.4 Avoid having to remove/readd handles 2.4 Fix HTTP Pipelining for PUT
3. Documentation 3. Documentation
3.1 More and better 3.1 More and better
@@ -39,9 +36,8 @@
4.7 ASCII support 4.7 ASCII support
5. HTTP 5. HTTP
5.1 Other HTTP versions with CONNECT 5.1 Better persistency for HTTP 1.0
5.2 Better persistency for HTTP 1.0 5.2 support FF3 sqlite cookie files
5.3 support FF3 sqlite cookie files
6. TELNET 6. TELNET
6.1 ditch stdin 6.1 ditch stdin
@@ -52,14 +48,13 @@
7. SSL 7. SSL
7.1 Disable specific versions 7.1 Disable specific versions
7.2 Provide mutex locking API 7.2 Provide mutex locking API
7.3 dumpcert 7.3 Evaluate SSL patches
7.4 Evaluate SSL patches 7.4 Cache OpenSSL contexts
7.5 Cache OpenSSL contexts 7.5 Export session ids
7.6 Export session ids 7.6 Provide callback for cert verification
7.7 Provide callback for cert verification 7.7 Support other SSL libraries
7.8 Support other SSL libraries 7.8 Support SRP on the TLS layer
7.9 Support SRP on the TLS layer 7.9 improve configure --with-ssl
7.10 improve configure --with-ssl
8. GnuTLS 8. GnuTLS
8.1 Make NTLM work without OpenSSL functions 8.1 Make NTLM work without OpenSSL functions
@@ -132,37 +127,7 @@
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete. SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
To support ipv6 interface addresses for network interfaces properly. To support ipv6 interface addresses for network interfaces properly.
1.4 Get IP address 1.4 signal-based resolver timeouts
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
libcurl built without an asynchronous resolver library uses alarm() to time 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 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 Make sure we don't ever loop because of non-blocking sockets returning
EWOULDBLOCK or similar. The GnuTLS connection etc. EWOULDBLOCK or similar. The GnuTLS connection etc.
2.2 Pause transfers 2.2 Remove easy interface internally
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
Make curl_easy_perform() a wrapper-function that simply creates a multi 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 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 internally use and assume the multi interface. The select()-loop should use
curl_multi_socket(). 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 curl_multi_handle_control() - this can control the easy handle (while) added
to a multi handle in various ways: to a multi handle in various ways:
@@ -217,6 +172,13 @@
o RESUME? 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. Documentation
3.1 More and better 3.1 More and better
@@ -269,18 +231,12 @@
5. HTTP 5. HTTP
5.1 Other HTTP versions with CONNECT 5.1 Better persistency for HTTP 1.0
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
"Better" support for persistent connections over HTTP 1.0 "Better" support for persistent connections over HTTP 1.0
http://curl.haxx.se/bug/feature.cgi?id=1089001 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. Firefox 3 is changing from its former format to a a sqlite database instead.
We should consider how (lib)curl can/should support this. 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 library, so that the same application code can use mutex-locking
independently of OpenSSL or GnutTLS being used. independently of OpenSSL or GnutTLS being used.
7.3 dumpcert 7.3 Evaluate SSL patches
Anton Fedorov's "dumpcert" patch:
http://curl.haxx.se/mail/lib-2004-03/0088.html
7.4 Evaluate SSL patches
Evaluate/apply Gertjan van Wingerde's SSL patches: Evaluate/apply Gertjan van Wingerde's SSL patches:
http://curl.haxx.se/mail/lib-2004-03/0087.html 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 "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 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 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. 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 Add an interface to libcurl that enables "session IDs" to get
exported/imported. Cris Bailiff said: "OpenSSL has functions which can 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 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". 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 OpenSSL supports a callback for customised verification of the peer
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could 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! 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 Make curl's SSL layer capable of using other free SSL libraries. Such as
MatrixSSL (http://www.matrixssl.org/). 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 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 this, no need to support this in libcurl before there's an OpenSSL release
that does it. 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, make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
then NSS... then NSS...

View File

@@ -12,5 +12,5 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
COMPLICATED_EXAMPLES = \ COMPLICATED_EXAMPLES = \
curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \ curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \
ghiper.c hiperfifo.c htmltidy.c multithread.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; GlobalInfo *g = (GlobalInfo*) userp;
CURLMcode rc; CURLMcode rc;
(void)kind; /* unused */
int action =
(kind&EV_READ?CURL_CSELECT_IN:0)|
(kind&EV_WRITE?CURL_CSELECT_OUT:0);
do { 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); } 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); check_run_count(g);
if ( g->still_running <= 0 ) { if ( g->still_running <= 0 ) {
fprintf(MSG_OUT, "last transfer done, kill timeout\n"); 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; (void)kind;
do { 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); } 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); 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); "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
rc =curl_multi_add_handle(g->multi, conn->easy); 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_add_handle", rc);
do {
rc = curl_multi_socket_all(g->multi, &g->still_running); /* note that the add_handle() will set a time-out to trigger very soon so
} while (CURLM_CALL_MULTI_PERFORM == rc); that the necessary socket_action() call will be called by this app */
mcode_or_die("new_conn: curl_multi_socket_all", rc);
check_run_count(g);
} }
/* This gets called whenever data is received from the fifo */ /* 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) int main(int argc, char **argv)
{ {
GlobalInfo g; GlobalInfo g;
CURLMcode rc;
(void)argc; (void)argc;
(void)argv; (void)argv;
@@ -409,13 +412,16 @@ int main(int argc, char **argv)
init_fifo(&g); init_fifo(&g);
g.multi = curl_multi_init(); g.multi = curl_multi_init();
evtimer_set(&g.timer_event, timer_cb, &g); 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_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g); curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb); curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g); curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
do {
rc = curl_multi_socket_all(g.multi, &g.still_running); /* we don't call any curl_multi_socket*() function yet as we have no handles
} while (CURLM_CALL_MULTI_PERFORM == rc); added! */
event_dispatch(); event_dispatch();
curl_multi_cleanup(g.multi); curl_multi_cleanup(g.multi);
return 0; return 0;

View File

@@ -1315,15 +1315,15 @@ Pass a long as parameter. It contains the time in seconds that the transfer
should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider
it too slow and abort. it too slow and abort.
.IP CURLOPT_MAX_SEND_SPEED_LARGE .IP CURLOPT_MAX_SEND_SPEED_LARGE
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in
average during the transfer, the transfer will pause to keep the average rate bytes per second) on cumulative average during the transfer, the transfer will
less than or equal to the parameter value. Defaults to unlimited pause to keep the average rate less than or equal to the parameter value.
speed. (Added in 7.15.5) Defaults to unlimited speed. (Added in 7.15.5)
.IP CURLOPT_MAX_RECV_SPEED_LARGE .IP CURLOPT_MAX_RECV_SPEED_LARGE
Pass a curl_off_t as parameter. If a download exceeds this speed on Pass a curl_off_t as parameter. If a download exceeds this speed (counted in
cumulative average during the transfer, the transfer will pause to keep the bytes per second) on cumulative average during the transfer, the transfer will
average rate less than or equal to the parameter value. Defaults to unlimited pause to keep the average rate less than or equal to the parameter
speed. (Added in 7.15.5) value. Defaults to unlimited speed. (Added in 7.15.5)
.IP CURLOPT_MAXCONNECTS .IP CURLOPT_MAXCONNECTS
Pass a long. The set number will be the persistent connection cache size. The Pass a long. The set number will be the persistent connection cache size. The
set amount will be the maximum amount of simultaneously open connections that set amount will be the maximum amount of simultaneously open connections that
@@ -1388,6 +1388,7 @@ Resolve to ipv6 addresses.
.IP CURLOPT_CONNECT_ONLY .IP CURLOPT_CONNECT_ONLY
Pass a long. If the parameter equals 1, it tells the library to perform all 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. 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 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 \fIcurl_easy_getinfo(3)\fP. The library can set up the connection and then the

View File

@@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH libcurl-tutorial 3 "27 Feb 2007" "libcurl" "libcurl programming" .TH libcurl-tutorial 3 "17 Nov 2008" "libcurl" "libcurl programming"
.SH NAME .SH NAME
libcurl-tutorial \- libcurl programming tutorial libcurl-tutorial \- libcurl programming tutorial
.SH "Objective" .SH "Objective"
@@ -41,7 +41,7 @@ refer to their respective man pages.
.SH "Building" .SH "Building"
There are many different ways to build C programs. This chapter will assume a 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 read this to get general information that may apply to your environment as
well. well.
.IP "Compiling the Program" .IP "Compiling the Program"
@@ -167,11 +167,9 @@ something different. Alas, multiple requests using the same handle will use
the same options. the same options.
Many of the options you set in libcurl are "strings", pointers to data Many of the options you set in libcurl are "strings", pointers to data
terminated with a zero byte. Keep in mind that when you set strings with terminated with a zero byte. When you set strings with
\fIcurl_easy_setopt(3)\fP, libcurl will not copy the data. It will merely \fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't
point to the data. You MUST make sure that the data remains available for need to be kept around in your application after being set[4].
libcurl to use until finished or until you use the same option again to point
to something else.
One of the most basic properties to set in the handle is the URL. You set One of the most basic properties to set in the handle is the URL. You set
your preferred URL to transfer with CURLOPT_URL in a manner similar to: your preferred URL to transfer with CURLOPT_URL in a manner similar to:
@@ -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 you intend to make another transfer. libcurl will then attempt to re-use the
previous connection. 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" .SH "Multi-threading Issues"
The first basic rule is that you must \fBnever\fP share a libcurl handle (be 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 it easy or multi or whatever) between multiple threads. Only use one handle in
one thread at a time. one thread at a time.
libcurl is completely thread safe, except for two issues: signals and SSL/TLS libcurl is completely thread safe, except for two issues: signals and SSL/TLS
handlers. Signals are used timeouting name resolves (during DNS lookup) - when handlers. Signals are used for timing out name resolves (during DNS lookup) -
built without c-ares support and not on Windows.. 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 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 then of course using the underlying SSL library multi-threaded and those libs
@@ -350,7 +354,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]: CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]:
.nf .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); curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
.fi .fi
@@ -389,7 +393,7 @@ to the CURLOPT_USERPWD option like this:
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret"); 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 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" 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 chapter), as it might contain the password in plain text. libcurl has the
@@ -1194,6 +1198,9 @@ 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 DLL. However, you can still do this on Windows if you link with a static
library. library.
.IP "[3]" .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 should be installed with the 'make install' or similar instruction that
installs the library, header files, man pages etc. 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

@@ -31,13 +31,13 @@
/* This is the version number of the libcurl package from which this header /* This is the version number of the libcurl package from which this header
file origins: */ file origins: */
#define LIBCURL_VERSION "7.19.1-CVS" #define LIBCURL_VERSION "7.19.3-CVS"
/* The numeric version number is also available "in parts" by using these /* The numeric version number is also available "in parts" by using these
defines: */ defines: */
#define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 19 #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 /* This is the numeric version of the libcurl version number, meant for easier
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
@@ -54,7 +54,7 @@
and it is always a greater number in a more recent release. It makes and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work. comparisons with greater than and less than work.
*/ */
#define LIBCURL_VERSION_NUM 0x071301 #define LIBCURL_VERSION_NUM 0x071303
/* /*
* This is the date and time when the full source package was created. The * This is the date and time when the full source package was created. The

View File

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

View File

@@ -20,7 +20,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8h OPENSSL_PATH = ../../openssl-0.9.8i
endif endif
# Edit the path below to point to the base of your LibSSH2 package. # 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 LIBSSH2_PATH = ../../libssh2-0.18
endif 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 ifndef INSTDIR
INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
endif endif
@@ -183,6 +188,10 @@ else
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
endif endif
endif endif
ifdef WITH_IDN
INCLUDES += -I$(LIBIDN_PATH)/include
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
endif
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include INCLUDES += -I$(SDK_LIBC)/include
@@ -452,12 +461,13 @@ endif
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FCNTL_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_GETHOSTBYADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@ @echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@ @echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@ @echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_ADDR 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_LL 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
@@ -536,6 +546,10 @@ endif
ifdef WITH_SSH2 ifdef WITH_SSH2
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@ @echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
@echo $(DL)#define HAVE_LIBSSH2_H 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 endif
@echo $(DL)#ifdef __GNUC__$(DL) >> $@ @echo $(DL)#ifdef __GNUC__$(DL) >> $@
@echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@ @echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@

View File

@@ -7,13 +7,13 @@ objs = o.base64 o.connect o.cookie o.dict \
o.dllinit o.easy o.escape o.file \ o.dllinit o.easy o.escape o.file \
o.formdata o.ftp o.getenv \ o.formdata o.ftp o.getenv \
o.getinfo o.getpass o.hostip \ o.getinfo o.getpass o.hostip \
o.hostip4 o.hostsyn o.http \ o.hostip4 o.hostsyn o.http \
o.http_chunks o.inet_ntop o.inet_pton o.if2ip o.krb4 o.ldap \ o.http_chunks o.inet_ntop o.inet_pton o.if2ip o.krb4 o.ldap \
o.memdebug o.mprintf o.netrc o.parsedate o.progress \ o.memdebug o.mprintf o.netrc o.parsedate o.progress \
o.security o.select o.sendf o.speedcheck o.ssluse \ o.security o.select o.sendf o.speedcheck o.ssluse \
o.strequal o.strtok o.telnet o.timeval \ o.strequal o.strtok o.telnet o.timeval \
o.transfer o.url o.version o.strtoofft o.sslgen o.gtls \ o.transfer o.url o.version o.strtoofft o.sslgen o.gtls \
o.rawstr o.rawstr o.curl_addrinfo
# Compile options: # Compile options:
linkopts = -o libcurl linkopts = -o libcurl
@@ -33,6 +33,9 @@ o.connect: c.connect
o.cookie: c.cookie o.cookie: c.cookie
gcc $(compileropts) -c -o cookie.o c.cookie gcc $(compileropts) -c -o cookie.o c.cookie
o.curl_addrinfo: c.curl_addrinfo
gcc $(compileropts) -c -o curl_addrinfo.o c.curl_addrinfo
o.dict: c.dict o.dict: c.dict
gcc $(compileropts) -c -o dict.o c.dict gcc $(compileropts) -c -o dict.o c.dict

View File

@@ -426,62 +426,63 @@ clean:
# #
X_OBJS= \ X_OBJS= \
$(DIROBJ)\base64.obj \ $(DIROBJ)\base64.obj \
$(DIROBJ)\connect.obj \
$(DIROBJ)\content_encoding.obj \
$(DIROBJ)\cookie.obj \ $(DIROBJ)\cookie.obj \
$(DIROBJ)\transfer.obj \ $(DIROBJ)\curl_addrinfo.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\escape.obj \ $(DIROBJ)\escape.obj \
$(DIROBJ)\file.obj \
$(DIROBJ)\formdata.obj \ $(DIROBJ)\formdata.obj \
$(DIROBJ)\ftp.obj \ $(DIROBJ)\ftp.obj \
$(DIROBJ)\http.obj \
$(DIROBJ)\http_chunks.obj \
$(DIROBJ)\ldap.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\telnet.obj \
$(DIROBJ)\parsedate.obj \
$(DIROBJ)\getenv.obj \ $(DIROBJ)\getenv.obj \
$(DIROBJ)\getinfo.obj \
$(DIROBJ)\gtls.obj \ $(DIROBJ)\gtls.obj \
$(DIROBJ)\inet_pton.obj \ $(DIROBJ)\hash.obj \
$(DIROBJ)\hostip.obj \
$(DIROBJ)\hostasyn.obj \
$(DIROBJ)\hostsyn.obj \
$(DIROBJ)\hostares.obj \ $(DIROBJ)\hostares.obj \
$(DIROBJ)\hostthre.obj \ $(DIROBJ)\hostasyn.obj \
$(DIROBJ)\hostip.obj \
$(DIROBJ)\hostip4.obj \ $(DIROBJ)\hostip4.obj \
$(DIROBJ)\hostip6.obj \ $(DIROBJ)\hostip6.obj \
$(DIROBJ)\inet_ntop.obj \ $(DIROBJ)\hostsyn.obj \
$(DIROBJ)\if2ip.obj \ $(DIROBJ)\hostthre.obj \
$(DIROBJ)\mprintf.obj \ $(DIROBJ)\http.obj \
$(DIROBJ)\netrc.obj \ $(DIROBJ)\http_chunks.obj \
$(DIROBJ)\progress.obj \
$(DIROBJ)\sendf.obj \
$(DIROBJ)\speedcheck.obj \
$(DIROBJ)\sslgen.obj \
$(DIROBJ)\ssluse.obj \
$(DIROBJ)\timeval.obj \
$(DIROBJ)\url.obj \
$(DIROBJ)\file.obj \
$(DIROBJ)\getinfo.obj \
$(DIROBJ)\version.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\strequal.obj \
$(DIROBJ)\strtok.obj \
$(DIROBJ)\strtoofft.obj \
$(DIROBJ)\connect.obj \
$(DIROBJ)\hash.obj \
$(DIROBJ)\llist.obj \
$(DIROBJ)\share.obj \
$(DIROBJ)\multi.obj \
$(DIROBJ)\http_digest.obj \ $(DIROBJ)\http_digest.obj \
$(DIROBJ)\http_negotiate.obj \ $(DIROBJ)\http_negotiate.obj \
$(DIROBJ)\http_ntlm.obj \ $(DIROBJ)\http_ntlm.obj \
$(DIROBJ)\if2ip.obj \
$(DIROBJ)\inet_ntop.obj \
$(DIROBJ)\inet_pton.obj \
$(DIROBJ)\ldap.obj \
$(DIROBJ)\llist.obj \
$(DIROBJ)\md5.obj \ $(DIROBJ)\md5.obj \
$(DIROBJ)\memdebug.obj \ $(DIROBJ)\memdebug.obj \
$(DIROBJ)\strerror.obj \ $(DIROBJ)\mprintf.obj \
$(DIROBJ)\select.obj \ $(DIROBJ)\multi.obj \
$(DIROBJ)\content_encoding.obj \ $(DIROBJ)\netrc.obj \
$(DIROBJ)\tftp.obj \ $(DIROBJ)\parsedate.obj \
$(DIROBJ)\splay.obj \ $(DIROBJ)\progress.obj \
$(DIROBJ)\socks.obj \
$(DIROBJ)\rawstr.obj \ $(DIROBJ)\rawstr.obj \
$(DIROBJ)\select.obj \
$(DIROBJ)\sendf.obj \
$(DIROBJ)\share.obj \
$(DIROBJ)\socks.obj \
$(DIROBJ)\speedcheck.obj \
$(DIROBJ)\splay.obj \
$(DIROBJ)\sslgen.obj \
$(DIROBJ)\ssluse.obj \
$(DIROBJ)\strequal.obj \
$(DIROBJ)\strerror.obj \
$(DIROBJ)\strtok.obj \
$(DIROBJ)\strtoofft.obj \
$(DIROBJ)\telnet.obj \
$(DIROBJ)\tftp.obj \
$(DIROBJ)\timeval.obj \
$(DIROBJ)\transfer.obj \
$(DIROBJ)\url.obj \
$(DIROBJ)\version.obj \
$(RESOURCE) $(RESOURCE)
all : $(TARGET) all : $(TARGET)

View File

@@ -239,130 +239,3 @@ size_t Curl_base64_encode(struct SessionHandle *data,
return strlen(base64data); /* return the length of the new data */ return strlen(base64data); /* return the length of the new data */
} }
/* ---- End of Base64 Encoding ---- */ /* ---- End of Base64 Encoding ---- */
/************* TEST HARNESS STUFF ****************/
#ifdef TEST_ENCODE
/* encoding test harness. Read in standard input and write out the length
* returned by Curl_base64_encode, followed by the base64'd data itself
*/
#include <stdio.h>
#define TEST_NEED_SUCK
void *suck(int *);
int main(int argc, argv_item_t argv[], char **envp)
{
char *base64;
size_t base64Len;
unsigned char *data;
int dataLen;
struct SessionHandle *handle = NULL;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so Curl_base64_encode can translate properly */
handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 1;
}
#endif
data = (unsigned char *)suck(&dataLen);
base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
fprintf(stderr, "%zu\n", base64Len);
fprintf(stdout, "%s\n", base64);
free(base64); free(data);
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
return 0;
}
#endif
#ifdef TEST_DECODE
/* decoding test harness. Read in a base64 string from stdin and write out the
* length returned by Curl_base64_decode, followed by the decoded data itself
*
* gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
*/
#include <stdio.h>
#define TEST_NEED_SUCK
void *suck(int *);
int main(int argc, argv_item_t argv[], char **envp)
{
char *base64;
int base64Len;
unsigned char *data;
int dataLen;
int i, j;
#ifdef CURL_DOES_CONVERSIONS
/* get a Curl handle so main can translate properly */
struct SessionHandle *handle = curl_easy_init();
if(handle == NULL) {
fprintf(stderr, "Error: curl_easy_init failed\n");
return 1;
}
#endif
base64 = (char *)suck(&base64Len);
dataLen = Curl_base64_decode(base64, &data);
fprintf(stderr, "%d\n", dataLen);
for(i=0; i < dataLen; i+=0x10) {
printf("0x%02x: ", i);
for(j=0; j < 0x10; j++)
if((j+i) < dataLen)
printf("%02x ", data[i+j]);
else
printf(" ");
printf(" | ");
for(j=0; j < 0x10; j++)
if((j+i) < dataLen) {
#ifdef CURL_DOES_CONVERSIONS
if(CURLE_OK !=
Curl_convert_from_network(handle, &data[i+j], (size_t)1))
data[i+j] = '.';
#endif /* CURL_DOES_CONVERSIONS */
printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
} else
break;
puts("");
}
#ifdef CURL_DOES_CONVERSIONS
curl_easy_cleanup(handle);
#endif
free(base64); free(data);
return 0;
}
#endif
#ifdef TEST_NEED_SUCK
/* this function 'sucks' in as much as possible from stdin */
void *suck(int *lenptr)
{
int cursize = 8192;
unsigned char *buf = NULL;
int lastread;
int len = 0;
do {
cursize *= 2;
buf = realloc(buf, cursize);
memset(buf + len, 0, cursize - len);
lastread = fread(buf + len, 1, cursize - len, stdin);
len += lastread;
} while(!feof(stdin));
lenptr[0] = len;
return (void *)buf;
}
#endif

View File

@@ -29,7 +29,8 @@
#define HAVE_GETHOSTBYADDR 1 #define HAVE_GETHOSTBYADDR 1
#define HAVE_INET_ADDR 1 #define HAVE_INET_ADDR 1
#define HAVE_INTTYPES_H 1 #define HAVE_INTTYPES_H 1
#define HAVE_IOCTLSOCKET_CASE 1 #define HAVE_IOCTLSOCKET_CAMEL 1
#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
#define HAVE_LIBCRYPTO 1 #define HAVE_LIBCRYPTO 1
#define HAVE_LIBSSL 1 #define HAVE_LIBSSL 1
#define HAVE_LIBZ 1 #define HAVE_LIBZ 1

View File

@@ -54,7 +54,8 @@
#define HAVE_RAND_STATUS 1 #define HAVE_RAND_STATUS 1
#define HAVE_RAND_EGD 1 #define HAVE_RAND_EGD 1
#define HAVE_FIONBIO 1 #define HAVE_IOCTL 1
#define HAVE_IOCTL_FIONBIO 1
#define RETSIGTYPE void #define RETSIGTYPE void

View File

@@ -283,6 +283,9 @@
/* Define if you have the `strlcpy' function. */ /* Define if you have the `strlcpy' function. */
#undef HAVE_STRLCPY #undef HAVE_STRLCPY
/* Define if you have the <stropts.h> header file. */
#define HAVE_STROPTS_H
/* Define if you have the `strstr' function. */ /* Define if you have the `strstr' function. */
#define HAVE_STRSTR #define HAVE_STRSTR
@@ -392,9 +395,14 @@
/* Define to `unsigned' if <sys/types.h> does not define. */ /* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t #undef size_t
#define IOCTL_3_ARGS /* Define if you have the ioctl function. */
#define HAVE_IOCTL
#define HAVE_FIONBIO /* Define if you have a working ioctl FIONBIO function. */
#define HAVE_IOCTL_FIONBIO
/* Define if you have a working ioctl SIOCGIFADDR function. */
#define HAVE_IOCTL_SIOCGIFADDR
/* to disable LDAP */ /* to disable LDAP */
#undef CURL_DISABLE_LDAP #undef CURL_DISABLE_LDAP

View File

@@ -378,12 +378,11 @@
/* Define to `int' if <sys/types.h> does not define. */ /* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t #undef ssize_t
/* this is a quick hack. I hope it's correct. */ /* Define if you have the ioctl function. */
#define ifr_dstaddr ifr_addr #define HAVE_IOCTL
#define IOCTL_3_ARGS /* Define if you have a working ioctl FIONBIO function. */
#define HAVE_IOCTL_FIONBIO
#define HAVE_FIONBIO
/* to disable LDAP */ /* to disable LDAP */
#define CURL_DISABLE_LDAP #define CURL_DISABLE_LDAP

View File

@@ -111,9 +111,6 @@
/* Define to 1 if you have the <des.h> header file. */ /* Define to 1 if you have the <des.h> header file. */
/* #undef HAVE_DES_H */ /* #undef HAVE_DES_H */
/* disabled non-blocking sockets */
/* #undef HAVE_DISABLED_NONBLOCKING */
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1 #define HAVE_DLFCN_H 1
@@ -129,8 +126,11 @@
/* Define to 1 if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1 #define HAVE_FCNTL_H 1
/* use FIONBIO for non-blocking sockets */ /* Define to 1 if you have the fcntl function. */
#define HAVE_FIONBIO 1 #define HAVE_FCNTL 1
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#define HAVE_FCNTL_O_NONBLOCK 1
/* Define to 1 if you have the `fork' function. */ /* Define to 1 if you have the `fork' function. */
/*#define HAVE_FORK 1*/ /*#define HAVE_FORK 1*/
@@ -231,11 +231,23 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1 #define HAVE_INTTYPES_H 1
/* use ioctlsocket() for non-blocking sockets */ /* Define to 1 if you have the ioctl function. */
#define HAVE_IOCTL 1
/* Define to 1 if you have a working ioctl FIONBIO function. */
#define HAVE_IOCTL_FIONBIO 1
/* Define to 1 if you have the ioctlsocket function. */
/* #undef HAVE_IOCTLSOCKET */ /* #undef HAVE_IOCTLSOCKET */
/* use Ioctlsocket() for non-blocking sockets */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */
/* #undef HAVE_IOCTLSOCKET_CASE */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */
/* Define to 1 if you have the IoctlSocket camel case function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL */
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
/* Define to 1 if you have the <io.h> header file. */ /* Define to 1 if you have the <io.h> header file. */
/* #undef HAVE_IO_H */ /* #undef HAVE_IO_H */
@@ -361,9 +373,6 @@
/* Define to 1 if you have the <openssl/x509.h> header file. */ /* Define to 1 if you have the <openssl/x509.h> header file. */
/*#define HAVE_OPENSSL_X509_H 1*/ /*#define HAVE_OPENSSL_X509_H 1*/
/* use O_NONBLOCK for non-blocking sockets */
#define HAVE_O_NONBLOCK 1
/* Define to 1 if you have the <pem.h> header file. */ /* Define to 1 if you have the <pem.h> header file. */
/* #undef HAVE_PEM_H */ /* #undef HAVE_PEM_H */
@@ -427,6 +436,12 @@
/* Define to 1 if you have the `setrlimit' function. */ /* Define to 1 if you have the `setrlimit' function. */
/*#define HAVE_SETRLIMIT 1*/ /*#define HAVE_SETRLIMIT 1*/
/* Define to 1 if you have the setsockopt function. */
/* #undef HAVE_SETSOCKOPT */
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
/* Define to 1 if you have the <sgtty.h> header file. */ /* Define to 1 if you have the <sgtty.h> header file. */
/*#define HAVE_SGTTY_H 1*/ /*#define HAVE_SGTTY_H 1*/
@@ -454,9 +469,6 @@
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
/* use SO_NONBLOCK for non-blocking sockets */
/* #undef HAVE_SO_NONBLOCK */
/* Define this if you have the SPNEGO library fbopenssl */ /* Define this if you have the SPNEGO library fbopenssl */
/* #undef HAVE_SPNEGO */ /* #undef HAVE_SPNEGO */
@@ -715,6 +727,9 @@
/* Define if you want to enable c-ares support */ /* Define if you want to enable c-ares support */
/* #undef USE_ARES */ /* #undef USE_ARES */
/* Define to disable non-blocking sockets */
/* #undef USE_BLOCKING_SOCKETS */
/* if GnuTLS is enabled */ /* if GnuTLS is enabled */
/* #undef USE_GNUTLS */ /* #undef USE_GNUTLS */

View File

@@ -104,9 +104,6 @@
/* #undef HAVE_DES_H */ /* #undef HAVE_DES_H */
#define HAVE_DES_H 1 #define HAVE_DES_H 1
/* disabled non-blocking sockets */
/* #undef HAVE_DISABLED_NONBLOCKING */
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ /* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ /* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 #define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
@@ -121,9 +118,11 @@
/* Define to 1 if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1 #define HAVE_FCNTL_H 1
/* use FIONBIO for non-blocking sockets */ /* Define to 1 if you have the fcntl function. */
/* #undef HAVE_FIONBIO */ #define HAVE_FCNTL 1
#define HAVE_FIONBIO 1
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
#define HAVE_FCNTL_O_NONBLOCK 1
/* Define to 1 if you have the `fork' function. */ /* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */ /* #undef HAVE_FORK */
@@ -217,11 +216,23 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1 #define HAVE_INTTYPES_H 1
/* use ioctlsocket() for non-blocking sockets */ /* Define to 1 if you have the ioctl function. */
#define HAVE_IOCTL 1
/* Define to 1 if you have a working ioctl FIONBIO function. */
#define HAVE_IOCTL_FIONBIO 1
/* Define to 1 if you have the ioctlsocket function. */
/* #undef HAVE_IOCTLSOCKET */ /* #undef HAVE_IOCTLSOCKET */
/* use Ioctlsocket() for non-blocking sockets */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */
/* #undef HAVE_IOCTLSOCKET_CASE */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */
/* Define to 1 if you have the IoctlSocket camel case function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL */
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
/* Define to 1 if you have the <io.h> header file. */ /* Define to 1 if you have the <io.h> header file. */
/* #undef HAVE_IO_H */ /* #undef HAVE_IO_H */
@@ -328,9 +339,6 @@
/* #undef HAVE_OPENSSL_X509_H */ /* #undef HAVE_OPENSSL_X509_H */
#define HAVE_OPENSSL_X509_H 1 #define HAVE_OPENSSL_X509_H 1
/* use O_NONBLOCK for non-blocking sockets */
/* #undef HAVE_O_NONBLOCK 1 */
/* Define to 1 if you have the <pem.h> header file. */ /* Define to 1 if you have the <pem.h> header file. */
/* #undef HAVE_PEM_H */ /* #undef HAVE_PEM_H */
#define HAVE_PEM_H 1 #define HAVE_PEM_H 1
@@ -380,6 +388,12 @@
/* Define to 1 if you have the `setrlimit' function. */ /* Define to 1 if you have the `setrlimit' function. */
#define HAVE_SETRLIMIT 1 #define HAVE_SETRLIMIT 1
/* Define to 1 if you have the setsockopt function. */
/* #undef HAVE_SETSOCKOPT */
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
/* Define to 1 if you have the <sgtty.h> header file. */ /* Define to 1 if you have the <sgtty.h> header file. */
/* #undef HAVE_SGTTY_H 1 */ /* #undef HAVE_SGTTY_H 1 */
@@ -407,9 +421,6 @@
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
/* use SO_NONBLOCK for non-blocking sockets */
/* #undef HAVE_SO_NONBLOCK */
/* Define this if you have the SPNEGO library fbopenssl */ /* Define this if you have the SPNEGO library fbopenssl */
/* #undef HAVE_SPNEGO */ /* #undef HAVE_SPNEGO */
@@ -602,6 +613,9 @@
/* Define if you want to enable ares support */ /* Define if you want to enable ares support */
/* #undef USE_ARES */ /* #undef USE_ARES */
/* Define to disable non-blocking sockets */
/* #undef USE_BLOCKING_SOCKETS */
/* if GnuTLS is enabled */ /* if GnuTLS is enabled */
/* #undef USE_GNUTLS */ /* #undef USE_GNUTLS */

View File

@@ -157,9 +157,12 @@
/* Define if you have the inet_addr function. */ /* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1 #define HAVE_INET_ADDR 1
/* Define if you have the ioctlsocket function. */ /* Define if you have the ioctlsocket function. */
#define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET 1
/* Define if you have a working ioctlsocket FIONBIO function. */
#define HAVE_IOCTLSOCKET_FIONBIO 1
/* Define if you have the perror function. */ /* Define if you have the perror function. */
#define HAVE_PERROR 1 #define HAVE_PERROR 1

View File

@@ -145,9 +145,12 @@
/* Define if you have the inet_addr function. */ /* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1 #define HAVE_INET_ADDR 1
/* Define if you have the ioctlsocket function. */ /* Define if you have the ioctlsocket function. */
#define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET 1
/* Define if you have a working ioctlsocket FIONBIO function. */
#define HAVE_IOCTLSOCKET_FIONBIO 1
/* Define if you have the perror function. */ /* Define if you have the perror function. */
#define HAVE_PERROR 1 #define HAVE_PERROR 1

View File

@@ -19,13 +19,15 @@
#define HAVE_ARPA_INET_H 1 #define HAVE_ARPA_INET_H 1
#define HAVE_FCNTL_H 1 #define HAVE_FCNTL_H 1
#define HAVE_FIONBIO 1
#define HAVE_GETADDRINFO 1 #define HAVE_GETADDRINFO 1
#define HAVE_GETNAMEINFO 1 #define HAVE_GETNAMEINFO 1
#define HAVE_GETPROTOBYNAME 1 #define HAVE_GETPROTOBYNAME 1
#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTIMEOFDAY 1
#define HAVE_IO_H 1 #define HAVE_IO_H 1
#define HAVE_IOCTL 1
#define HAVE_IOCTL_FIONBIO 1
#define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET 1
#define HAVE_IOCTLSOCKET_FIONBIO 1
#define HAVE_LOCALE_H 1 #define HAVE_LOCALE_H 1
#define HAVE_LONGLONG 1 #define HAVE_LONGLONG 1
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1

View File

@@ -59,7 +59,7 @@
#include <stdlib.h> /* required for free() prototype, without it, this crashes */ #include <stdlib.h> /* required for free() prototype, without it, this crashes */
#endif /* on macos 68K */ #endif /* on macos 68K */
#if (defined(HAVE_FIONBIO) && defined(NETWARE)) #if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
#include <sys/filio.h> #include <sys/filio.h>
#endif #endif
#ifdef NETWARE #ifdef NETWARE
@@ -91,7 +91,6 @@
#include "multiif.h" #include "multiif.h"
#include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "inet_ntop.h" #include "inet_ntop.h"
#include "inet_pton.h"
#include "sslgen.h" /* for Curl_ssl_check_cxn() */ #include "sslgen.h" /* for Curl_ssl_check_cxn() */
/* The last #include file should be: */ /* The last #include file should be: */
@@ -190,64 +189,47 @@ long Curl_timeleft(struct connectdata *conn,
int Curl_nonblock(curl_socket_t sockfd, /* operate on this */ int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */) int nonblock /* TRUE or FALSE */)
{ {
#undef SETBLOCK #if defined(USE_BLOCKING_SOCKETS)
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK return 0; /* returns success */
#elif defined(HAVE_FCNTL_O_NONBLOCK)
/* most recent unix versions */ /* most recent unix versions */
int flags; int flags;
flags = fcntl(sockfd, F_GETFL, 0); flags = fcntl(sockfd, F_GETFL, 0);
if(FALSE != nonblock) if(FALSE != nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); 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 */ /* older unix versions */
int flags; int flags;
flags = nonblock; flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags); return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0) #elif defined(HAVE_IOCTLSOCKET_FIONBIO)
/* Windows? */
/* Windows */
unsigned long flags; unsigned long flags;
flags = nonblock; flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags); return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
/* presumably for Amiga */
/* Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock); 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 */ /* BeOS */
long b = nonblock ? 1 : 0; long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING #else
return 0; /* returns success */ # error "no non-blocking method was found/used/set"
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if(SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#endif #endif
} }
@@ -866,12 +848,14 @@ singleipconnect(struct connectdata *conn,
switch (error) { switch (error) {
case EINPROGRESS: case EINPROGRESS:
case EWOULDBLOCK: case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK #if defined(EAGAIN)
#if (EAGAIN) != (EWOULDBLOCK)
/* On some platforms EAGAIN and EWOULDBLOCK are the /* On some platforms EAGAIN and EWOULDBLOCK are the
* same value, and on others they are different, hence * same value, and on others they are different, hence
* the odd #if * the odd #if
*/ */
case EAGAIN: case EAGAIN:
#endif
#endif #endif
rc = waitconnect(sockfd, timeout_ms); rc = waitconnect(sockfd, timeout_ms);
break; break;

View File

@@ -1003,7 +1003,8 @@ int Curl_cookie_output(struct CookieInfo *c, const char *dumphere)
format_ptr = get_netscape_format(co); format_ptr = get_netscape_format(co);
if(format_ptr == NULL) { if(format_ptr == NULL) {
fprintf(out, "#\n# Fatal libcurl error\n"); fprintf(out, "#\n# Fatal libcurl error\n");
fclose(out); if(!use_stdout)
fclose(out);
return 1; return 1;
} }
fprintf(out, "%s\n", format_ptr); fprintf(out, "%s\n", format_ptr);

View File

@@ -190,7 +190,8 @@ Curl_getaddrinfo_ex(const char *nodename,
*result = cafirst; *result = cafirst;
return error; /* This is not a CURLcode */ /* This is not a CURLcode */
return error;
} }
#endif /* HAVE_GETADDRINFO */ #endif /* HAVE_GETADDRINFO */
@@ -254,6 +255,8 @@ Curl_he2ai(const struct hostent *he, int port)
/* no input == no output! */ /* no input == no output! */
return NULL; return NULL;
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) { for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
int ss_size; int ss_size;
@@ -300,7 +303,7 @@ Curl_he2ai(const struct hostent *he, int port)
switch (ai->ai_family) { switch (ai->ai_family) {
case AF_INET: case AF_INET:
addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */ addr = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr)); memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
addr->sin_family = (unsigned short)(he->h_addrtype); addr->sin_family = (unsigned short)(he->h_addrtype);
@@ -309,7 +312,7 @@ Curl_he2ai(const struct hostent *he, int port)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
case AF_INET6: case AF_INET6:
addr6 = (struct sockaddr_in6 *)ai->ai_addr; /* storage area for this info */ addr6 = (void *)ai->ai_addr; /* storage area for this info */
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr)); memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
addr6->sin6_family = (unsigned short)(he->h_addrtype); addr6->sin6_family = (unsigned short)(he->h_addrtype);
@@ -330,6 +333,100 @@ Curl_he2ai(const struct hostent *he, int port)
} }
struct namebuff {
struct hostent hostentry;
union {
struct in_addr ina4;
#ifdef ENABLE_IPV6
struct in6_addr ina6;
#endif
} addrentry;
char *h_addr_list[2];
};
/*
* Curl_ip2addr()
*
* This function takes an internet address, in binary form, as input parameter
* along with its address family and the string version of the address, and it
* returns a Curl_addrinfo chain filled in correctly with information for the
* given address/host
*/
Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
{
Curl_addrinfo *ai;
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h;
struct namebuff *buf;
char *addrentry;
char *hoststr;
int addrsize;
DEBUGASSERT(inaddr && hostname);
buf = malloc(sizeof(struct namebuff));
if(!buf)
return NULL;
hoststr = strdup(hostname);
if(!hoststr) {
free(buf);
return NULL;
}
switch(af) {
case AF_INET:
addrsize = sizeof(struct in_addr);
addrentry = (void *)&buf->addrentry.ina4;
memcpy(addrentry, inaddr, sizeof(struct in_addr));
break;
#ifdef ENABLE_IPV6
case AF_INET6:
addrsize = sizeof(struct in6_addr);
addrentry = (void *)&buf->addrentry.ina6;
memcpy(addrentry, inaddr, sizeof(struct in6_addr));
break;
#endif
default:
free(hoststr);
free(buf);
return NULL;
}
h = &buf->hostentry;
h->h_name = hoststr;
h->h_aliases = NULL;
h->h_addrtype = (short)af;
h->h_length = (short)addrsize;
h->h_addr_list = &buf->h_addr_list[0];
h->h_addr_list[0] = addrentry;
h->h_addr_list[1] = NULL; /* terminate list of entries */
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port);
free(hoststr);
free(buf);
return ai;
}
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
/* /*
* curl_dofreeaddrinfo() * curl_dofreeaddrinfo()

View File

@@ -78,6 +78,8 @@ Curl_getaddrinfo_ex(const char *nodename,
Curl_addrinfo * Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port); Curl_he2ai(const struct hostent *he, int port);
Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
void void

View File

@@ -53,7 +53,9 @@
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>

View File

@@ -57,7 +57,9 @@
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>

View File

@@ -267,7 +267,7 @@ static const char * ContentTypeForFilename (const char *filename,
* extensions and pick the first we match! * extensions and pick the first we match!
*/ */
struct ContentType { struct ContentType {
const char *extension; char extension[6];
const char *type; const char *type;
}; };
static const struct ContentType ctts[]={ static const struct ContentType ctts[]={
@@ -275,7 +275,8 @@ static const char * ContentTypeForFilename (const char *filename,
{".jpg", "image/jpeg"}, {".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"}, {".jpeg", "image/jpeg"},
{".txt", "text/plain"}, {".txt", "text/plain"},
{".html", "text/html"} {".html", "text/html"},
{".xml", "application/xml"}
}; };
if(prevtype) if(prevtype)
@@ -1100,7 +1101,7 @@ static char *strippath(const char *fullfile)
free(filename); /* free temporary buffer */ free(filename); /* free temporary buffer */
return base; /* returns an allocated string! */ return base; /* returns an allocated string or NULL ! */
} }
/* /*
@@ -1207,8 +1208,15 @@ CURLcode Curl_getFormData(struct FormData **finalform,
if(post->more) { if(post->more) {
/* if multiple-file */ /* if multiple-file */
char *filebasename= char *filebasename= NULL;
(!file->showfilename)?strippath(file->contents):NULL; if(!file->showfilename) {
filebasename = strippath(file->contents);
if(!filebasename) {
Curl_formclean(&firstform);
free(boundary);
return CURLE_OUT_OF_MEMORY;
}
}
result = AddFormDataf(&form, &size, result = AddFormDataf(&form, &size,
"\r\n--%s\r\nContent-Disposition: " "\r\n--%s\r\nContent-Disposition: "
@@ -1729,7 +1737,7 @@ char *Curl_FormBoundary(void)
the same form won't be identical */ the same form won't be identical */
size_t i; size_t i;
static const char table16[]="abcdef0123456789"; static const char table16[]="0123456789abcdef";
retstring = malloc(BOUNDARY_LENGTH+1); retstring = malloc(BOUNDARY_LENGTH+1);

104
lib/ftp.c
View File

@@ -85,6 +85,7 @@
#include "connect.h" #include "connect.h"
#include "strerror.h" #include "strerror.h"
#include "inet_ntop.h" #include "inet_ntop.h"
#include "inet_pton.h"
#include "select.h" #include "select.h"
#include "parsedate.h" /* for the week day and month names */ #include "parsedate.h" /* for the week day and month names */
#include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */
@@ -149,9 +150,6 @@ static int ftp_getsock(struct connectdata *conn,
static CURLcode ftp_doing(struct connectdata *conn, static CURLcode ftp_doing(struct connectdata *conn,
bool *dophase_done); bool *dophase_done);
static CURLcode ftp_setup_connection(struct connectdata * conn); static CURLcode ftp_setup_connection(struct connectdata * conn);
#ifdef USE_SSL
static CURLcode ftps_setup_connection(struct connectdata * conn);
#endif
/* easy-to-use macro: */ /* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \ #define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \
@@ -188,7 +186,7 @@ const struct Curl_handler Curl_handler_ftp = {
const struct Curl_handler Curl_handler_ftps = { const struct Curl_handler Curl_handler_ftps = {
"FTPS", /* scheme */ "FTPS", /* scheme */
ftps_setup_connection, /* setup_connection */ ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */ ftp_do, /* do_it */
ftp_done, /* done */ ftp_done, /* done */
ftp_nextconnect, /* do_more */ ftp_nextconnect, /* do_more */
@@ -1105,41 +1103,39 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
(void)fcmd; /* not used in the IPv4 code */ (void)fcmd; /* not used in the IPv4 code */
if(ftpportstr) { if(ftpportstr) {
in_addr_t in; struct in_addr in;
/* First check if the given name is an IP address */ /* First check if the given string is an IP address */
in=inet_addr(ftpportstr); if(Curl_inet_pton(AF_INET, ftpportstr, &in) > 0) {
if(in != CURL_INADDR_NONE)
/* this is an IPv4 address */ /* this is an IPv4 address */
addr = Curl_ip2addr(in, ftpportstr, 0); addr = Curl_ip2addr(AF_INET, &in, ftpportstr, 0);
else { }
if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) { /* otherwise check if the given string is an interface */
/* The interface to IP conversion provided a dotted address */ else if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) {
in=inet_addr(myhost); /* The interface to IP conversion provided a dotted address */
addr = Curl_ip2addr(in, myhost, 0); if(Curl_inet_pton(AF_INET, myhost, &in) > 0)
} addr = Curl_ip2addr(AF_INET, &in, myhost, 0);
else if(strlen(ftpportstr)> 1) { }
/* might be a host name! */ else if(strlen(ftpportstr)> 1) {
struct Curl_dns_entry *h=NULL; /* might be a host name! */
int rc = Curl_resolv(conn, ftpportstr, 0, &h); struct Curl_dns_entry *h=NULL;
if(rc == CURLRESOLV_PENDING) int rc = Curl_resolv(conn, ftpportstr, 0, &h);
/* BLOCKING */ if(rc == CURLRESOLV_PENDING)
rc = Curl_wait_for_resolv(conn, &h); /* BLOCKING */
if(h) { rc = Curl_wait_for_resolv(conn, &h);
addr = h->addr; if(h) {
/* when we return from this function, we can forget about this entry addr = h->addr;
so we can unlock it now already */ /* when we return from this function, we can forget about this entry
Curl_resolv_unlock(data, h); so we can unlock it now already */
Curl_resolv_unlock(data, h);
freeaddr = FALSE; /* make sure we don't free 'addr' in this function freeaddr = FALSE; /* make sure we don't free 'addr' in this function
since it points to a DNS cache entry! */ since it points to a DNS cache entry! */
} /* (h) */ } /* (h) */
else { else {
infof(data, "Failed to resolve host name %s\n", ftpportstr); infof(data, "Failed to resolve host name %s\n", ftpportstr);
} }
} /* strlen */ } /* strlen */
} /* CURL_INADDR_NONE */
} /* ftpportstr */ } /* ftpportstr */
if(!addr) { if(!addr) {
@@ -2191,10 +2187,6 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
curl_off_t filesize; curl_off_t filesize;
char *buf = data->state.buffer; char *buf = data->state.buffer;
if((instate != FTP_STOR_SIZE) && (ftpcode == 550))
/* the file doesn't exist and we're not about to upload */
return CURLE_REMOTE_FILE_NOT_FOUND;
/* get the size from the ascii string: */ /* get the size from the ascii string: */
filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1; filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
@@ -2688,24 +2680,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
break; break;
case FTP_PBSZ: case FTP_PBSZ:
/* FIX: check response code */ NBFTPSENDF(conn, "PROT %c",
data->set.ftp_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
/* For TLS, the data connection can have one of two security levels. state(conn, FTP_PROT);
1) Clear (requested by 'PROT C')
2)Private (requested by 'PROT P')
*/
if(!conn->ssl[SECONDARYSOCKET].use) {
NBFTPSENDF(conn, "PROT %c",
data->set.ftp_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
state(conn, FTP_PROT);
}
else {
result = ftp_state_pwd(conn);
if(result)
return result;
}
break; break;
@@ -3170,7 +3147,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
case CURLE_UPLOAD_FAILED: case CURLE_UPLOAD_FAILED:
case CURLE_REMOTE_ACCESS_DENIED: case CURLE_REMOTE_ACCESS_DENIED:
case CURLE_FILESIZE_EXCEEDED: case CURLE_FILESIZE_EXCEEDED:
case CURLE_REMOTE_FILE_NOT_FOUND:
/* the connection stays alive fine even though this happened */ /* the connection stays alive fine even though this happened */
/* fall-through */ /* fall-through */
case CURLE_OK: /* doesn't affect the control connection's status */ case CURLE_OK: /* doesn't affect the control connection's status */
@@ -4185,14 +4161,4 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
return CURLE_OK; return CURLE_OK;
} }
#ifdef USE_SSL
static CURLcode ftps_setup_connection(struct connectdata * conn)
{
struct SessionHandle *data = conn->data;
conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL;
return ftp_setup_connection(conn);
}
#endif
#endif /* CURL_DISABLE_FTP */ #endif /* CURL_DISABLE_FTP */

View File

@@ -49,6 +49,8 @@
#include "parsedate.h" #include "parsedate.h"
#include "connect.h" /* for the connect timeout */ #include "connect.h" /* for the connect timeout */
#include "select.h" #include "select.h"
#include "rawstr.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
#include "memory.h" #include "memory.h"
@@ -263,6 +265,11 @@ Curl_gtls_connect(struct connectdata *conn,
struct in_addr addr; struct in_addr addr;
#endif #endif
if(conn->ssl[sockindex].state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
same connection */
return CURLE_OK;
if(!gtls_inited) if(!gtls_inited)
_Curl_gtls_init(); _Curl_gtls_init();
@@ -338,7 +345,7 @@ Curl_gtls_connect(struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) { if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
int protocol_priority[] = { GNUTLS_SSL3, 0 }; static const int protocol_priority[] = { GNUTLS_SSL3, 0 };
gnutls_protocol_set_priority(session, protocol_priority); gnutls_protocol_set_priority(session, protocol_priority);
if(rc < 0) if(rc < 0)
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;

View File

@@ -289,80 +289,6 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
return rc; return rc;
} }
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
struct namebuf6 {
struct hostent hostentry;
struct in6_addr addrentry;
char *h_addr_list[2];
};
/*
* Curl_ip2addr6() takes an ipv6 internet address as input parameter
* together with a pointer to the string version of the address, and it
* returns a Curl_addrinfo chain filled in correctly with information for this
* address/host.
*
* The input parameters ARE NOT checked for validity but they are expected
* to have been checked already when this is called.
*/
Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in,
const char *hostname, int port)
{
Curl_addrinfo *ai;
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h;
struct in6_addr *addrentry;
struct namebuf6 *buf;
char *hoststr;
DEBUGASSERT(in && hostname);
buf = malloc(sizeof(struct namebuf6));
if(!buf)
return NULL;
hoststr = strdup(hostname);
if(!hoststr) {
free(buf);
return NULL;
}
addrentry = &buf->addrentry;
memcpy(addrentry, in, sizeof(struct in6_addr));
h = &buf->hostentry;
h->h_name = hoststr;
h->h_aliases = NULL;
h->h_addrtype = AF_INET6;
h->h_length = sizeof(struct in6_addr);
h->h_addr_list = &buf->h_addr_list[0];
h->h_addr_list[0] = (char*)addrentry;
h->h_addr_list[1] = NULL; /* terminate list of entries */
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port);
free(hoststr);
free(buf);
return ai;
}
#endif /* CURLRES_IPV6 */
/* /*
* Curl_getaddrinfo() - when using ares * Curl_getaddrinfo() - when using ares
@@ -379,22 +305,24 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
{ {
char *bufp; char *bufp;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
in_addr_t in = inet_addr(hostname); struct in_addr in;
int family = PF_INET; int family = PF_INET;
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
struct in6_addr in6; struct in6_addr in6;
#endif /* CURLRES_IPV6 */ #endif /* CURLRES_IPV6 */
*waitp = FALSE; *waitp = FALSE;
if(in != CURL_INADDR_NONE) { /* First check if this is an IPv4 address string */
if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
/* This is a dotted IP address 123.123.123.123-style */ /* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(in, hostname, port); return Curl_ip2addr(AF_INET, &in, hostname, port);
} }
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
/* Otherwise, check if this is an IPv6 address string */
if (Curl_inet_pton (AF_INET6, hostname, &in6) > 0) { if (Curl_inet_pton (AF_INET6, hostname, &in6) > 0) {
/* This must be an IPv6 address literal. */ /* This must be an IPv6 address literal. */
return Curl_ip2addr6(&in6, hostname, port); return Curl_ip2addr(AF_INET6, &in6, hostname, port);
} }
switch(data->set.ip_version) { switch(data->set.ip_version) {

View File

@@ -724,88 +724,3 @@ Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
return Curl_he2ai(orig, port); return Curl_he2ai(orig, port);
} }
#endif /* CURLRES_ADDRINFO_COPY */ #endif /* CURLRES_ADDRINFO_COPY */
/***********************************************************************
* Only for plain-ipv4 and c-ares builds (NOTE: c-ares builds can be IPv6
* enabled)
**********************************************************************/
#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
struct namebuf4 {
struct hostent hostentry;
struct in_addr addrentry;
char *h_addr_list[2];
};
/*
* Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
* together with a pointer to the string version of the address, and it
* returns a Curl_addrinfo chain filled in correctly with information for this
* address/host.
*
* The input parameters ARE NOT checked for validity but they are expected
* to have been checked already when this is called.
*/
Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
{
Curl_addrinfo *ai;
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size save
#pragma pointer_size short
#pragma message disable PTRMISMATCH
#endif
struct hostent *h;
struct in_addr *addrentry;
struct namebuf4 *buf;
char *hoststr;
DEBUGASSERT(hostname);
buf = malloc(sizeof(struct namebuf4));
if(!buf)
return NULL;
hoststr = strdup(hostname);
if(!hoststr) {
free(buf);
return NULL;
}
addrentry = &buf->addrentry;
#ifdef _CRAYC
/* On UNICOS, s_addr is a bit field and for some reason assigning to it
* doesn't work. There must be a better fix than this ugly hack.
*/
memcpy(addrentry, &num, SIZEOF_in_addr);
#else
addrentry->s_addr = num;
#endif
h = &buf->hostentry;
h->h_name = hoststr;
h->h_aliases = NULL;
h->h_addrtype = AF_INET;
h->h_length = sizeof(struct in_addr);
h->h_addr_list = &buf->h_addr_list[0];
h->h_addr_list[0] = (char*)addrentry;
h->h_addr_list[1] = NULL; /* terminate list of entries */
#if defined(VMS) && \
defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
#pragma pointer_size restore
#pragma message enable PTRMISMATCH
#endif
ai = Curl_he2ai(h, port);
free(hoststr);
free(buf);
return ai;
}
#endif /* CURLRES_IPV4 || CURLRES_ARES */

View File

@@ -104,11 +104,6 @@
#define ares_destroy(x) do {} while(0) #define ares_destroy(x) do {} while(0)
#endif #endif
#if defined(CURLRES_IPV6) && defined(CURLRES_ARES)
Curl_addrinfo *Curl_ip2addr6(struct in6_addr *in,
const char *hostname, int port);
#endif
struct addrinfo; struct addrinfo;
struct hostent; struct hostent;
struct SessionHandle; struct SessionHandle;
@@ -224,10 +219,6 @@ CURLcode Curl_addrinfo6_callback(void *arg,
Curl_addrinfo *ai); Curl_addrinfo *ai);
/* [ipv4/ares only] Creates a Curl_addrinfo struct from a numerical-only IP
address */
Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port);
/* Clone a Curl_addrinfo struct, works protocol independently */ /* Clone a Curl_addrinfo struct, works protocol independently */
Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port); Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);

View File

@@ -118,20 +118,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
#endif #endif
Curl_addrinfo *ai = NULL; Curl_addrinfo *ai = NULL;
struct hostent *h = NULL; struct hostent *h = NULL;
in_addr_t in; struct in_addr in;
struct hostent *buf = NULL; struct hostent *buf = NULL;
#ifdef CURL_DISABLE_VERBOSE_STRINGS #ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)conn; (void)conn;
#endif #endif
(void)port; /* unused in IPv4 code */
*waitp = 0; /* don't wait, we act synchronously */ *waitp = 0; /* don't wait, we act synchronously */
if(1 == Curl_inet_pton(AF_INET, hostname, &in)) if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
/* This is a dotted IP address 123.123.123.123-style */ /* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(in, hostname, port); return Curl_ip2addr(AF_INET, &in, hostname, port);
#if defined(HAVE_GETHOSTBYNAME_R) #if defined(HAVE_GETHOSTBYNAME_R)
/* /*

View File

@@ -70,6 +70,7 @@
#include "strerror.h" #include "strerror.h"
#include "url.h" #include "url.h"
#include "multiif.h" #include "multiif.h"
#include "inet_pton.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -665,14 +666,13 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
{ {
struct hostent *h = NULL; struct hostent *h = NULL;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
in_addr_t in; struct in_addr in;
*waitp = 0; /* don't wait, we act synchronously */ *waitp = 0; /* don't wait, we act synchronously */
in = inet_addr(hostname); if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
if(in != CURL_INADDR_NONE)
/* This is a dotted IP address 123.123.123.123-style */ /* This is a dotted IP address 123.123.123.123-style */
return Curl_ip2addr(in, hostname, port); return Curl_ip2addr(AF_INET, &in, hostname, port);
/* fire up a new resolver thread! */ /* fire up a new resolver thread! */
if(init_resolve_thread(conn, hostname, port, NULL)) { if(init_resolve_thread(conn, hostname, port, NULL)) {

View File

@@ -114,11 +114,13 @@
static int http_getsock_do(struct connectdata *conn, static int http_getsock_do(struct connectdata *conn,
curl_socket_t *socks, curl_socket_t *socks,
int numsocks); int numsocks);
static CURLcode https_connecting(struct connectdata *conn, bool *done);
#ifdef USE_SSL #ifdef USE_SSL
static CURLcode https_connecting(struct connectdata *conn, bool *done);
static int https_getsock(struct connectdata *conn, static int https_getsock(struct connectdata *conn,
curl_socket_t *socks, curl_socket_t *socks,
int numsocks); int numsocks);
#else
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
#endif #endif
/* /*
@@ -246,8 +248,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
char *authorization; char *authorization;
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
char **userp; char **userp;
char *user; const char *user;
char *pwd; const char *pwd;
if(proxy) { if(proxy) {
userp = &conn->allocptr.proxyuserpwd; userp = &conn->allocptr.proxyuserpwd;
@@ -456,6 +458,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
} }
if(pickhost || pickproxy) { if(pickhost || pickproxy) {
/* In case this is GSS auth, the newurl field is already allocated so
we must make sure to free it before allocating a new one. As figured
out in bug #2284386 */
Curl_safefree(data->req.newurl);
data->req.newurl = strdup(data->change.url); /* clone URL */ data->req.newurl = strdup(data->change.url); /* clone URL */
if(!data->req.newurl) if(!data->req.newurl)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -493,6 +499,90 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
return code; return code;
} }
/*
* Output the correct authentication header depending on the auth type
* and whether or not it is to a proxy.
*/
static CURLcode
output_auth_headers(struct connectdata *conn,
struct auth *authstatus,
const char *request,
const char *path,
bool proxy)
{
struct SessionHandle *data = conn->data;
const char *auth=NULL;
CURLcode result = CURLE_OK;
#ifndef CURL_DISABLE_CRYPTO_AUTH
(void)request;
(void)path;
#endif
#ifdef HAVE_GSSAPI
if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
data->state.negotiate.context &&
!GSS_ERROR(data->state.negotiate.status)) {
auth="GSS-Negotiate";
result = Curl_output_negotiate(conn, proxy);
if(result)
return result;
authstatus->done = TRUE;
data->state.negotiate.state = GSS_AUTHSENT;
}
else
#endif
#ifdef USE_NTLM
if(authstatus->picked == CURLAUTH_NTLM) {
auth="NTLM";
result = Curl_output_ntlm(conn, proxy);
if(result)
return result;
}
else
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(authstatus->picked == CURLAUTH_DIGEST) {
auth="Digest";
result = Curl_output_digest(conn,
proxy,
(const unsigned char *)request,
(const unsigned char *)path);
if(result)
return result;
}
else
#endif
if(authstatus->picked == CURLAUTH_BASIC) {
/* Basic */
if((proxy && conn->bits.proxy_user_passwd &&
!checkheaders(data, "Proxy-authorization:")) ||
(!proxy && conn->bits.user_passwd &&
!checkheaders(data, "Authorization:"))) {
auth="Basic";
result = http_output_basic(conn, proxy);
if(result)
return result;
}
/* NOTE: this function should set 'done' TRUE, as the other auth
functions work that way */
authstatus->done = TRUE;
}
if(auth) {
infof(data, "%s auth using %s with user '%s'\n",
proxy?"Proxy":"Server", auth,
proxy?(conn->proxyuser?conn->proxyuser:""):
(conn->user?conn->user:""));
authstatus->multi = (bool)(!authstatus->done);
}
else
authstatus->multi = FALSE;
return CURLE_OK;
}
/** /**
* Curl_http_output_auth() setups the authentication headers for the * Curl_http_output_auth() setups the authentication headers for the
* host/proxy and the correct authentication * host/proxy and the correct authentication
@@ -516,7 +606,6 @@ http_output_auth(struct connectdata *conn,
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
const char *auth=NULL;
struct auth *authhost; struct auth *authhost;
struct auth *authproxy; struct auth *authproxy;
@@ -550,66 +639,12 @@ http_output_auth(struct connectdata *conn,
/* Send proxy authentication header if needed */ /* Send proxy authentication header if needed */
if(conn->bits.httpproxy && if(conn->bits.httpproxy &&
(conn->bits.tunnel_proxy == proxytunnel)) { (conn->bits.tunnel_proxy == proxytunnel)) {
#ifdef HAVE_GSSAPI result = output_auth_headers(conn, authproxy, request, path, TRUE);
if((authproxy->picked == CURLAUTH_GSSNEGOTIATE) && if(result)
data->state.negotiate.context && return result;
!GSS_ERROR(data->state.negotiate.status)) { }
auth="GSS-Negotiate";
result = Curl_output_negotiate(conn, TRUE);
if(result)
return result;
authproxy->done = TRUE;
}
else
#endif
#ifdef USE_NTLM
if(authproxy->picked == CURLAUTH_NTLM) {
auth="NTLM";
result = Curl_output_ntlm(conn, TRUE);
if(result)
return result;
}
else
#endif
if(authproxy->picked == CURLAUTH_BASIC) {
/* Basic */
if(conn->bits.proxy_user_passwd &&
!checkheaders(data, "Proxy-authorization:")) {
auth="Basic";
result = http_output_basic(conn, TRUE);
if(result)
return result;
}
/* NOTE: http_output_basic() should set 'done' TRUE, as the other auth
functions work that way */
authproxy->done = TRUE;
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
else if(authproxy->picked == CURLAUTH_DIGEST) {
auth="Digest";
result = Curl_output_digest(conn,
TRUE, /* proxy */
(const unsigned char *)request,
(const unsigned char *)path);
if(result)
return result;
}
#else
(void)request;
(void)path;
#endif
if(auth) {
infof(data, "Proxy auth using %s with user '%s'\n",
auth, conn->proxyuser?conn->proxyuser:"");
authproxy->multi = (bool)(!authproxy->done);
}
else
authproxy->multi = FALSE;
}
else else
#else #else
(void)request;
(void)path;
(void)proxytunnel; (void)proxytunnel;
#endif /* CURL_DISABLE_PROXY */ #endif /* CURL_DISABLE_PROXY */
/* we have no proxy so let's pretend we're done authenticating /* we have no proxy so let's pretend we're done authenticating
@@ -621,66 +656,9 @@ http_output_auth(struct connectdata *conn,
if(!data->state.this_is_a_follow || if(!data->state.this_is_a_follow ||
conn->bits.netrc || conn->bits.netrc ||
!data->state.first_host || !data->state.first_host ||
Curl_raw_equal(data->state.first_host, conn->host.name) || data->set.http_disable_hostname_check_before_authentication ||
data->set.http_disable_hostname_check_before_authentication) { Curl_raw_equal(data->state.first_host, conn->host.name)) {
result = output_auth_headers(conn, authhost, request, path, FALSE);
/* Send web authentication header if needed */
{
auth = NULL;
#ifdef HAVE_GSSAPI
if((authhost->picked == CURLAUTH_GSSNEGOTIATE) &&
data->state.negotiate.context &&
!GSS_ERROR(data->state.negotiate.status)) {
auth="GSS-Negotiate";
result = Curl_output_negotiate(conn, FALSE);
if(result)
return result;
authhost->done = TRUE;
}
else
#endif
#ifdef USE_NTLM
if(authhost->picked == CURLAUTH_NTLM) {
auth="NTLM";
result = Curl_output_ntlm(conn, FALSE);
if(result)
return result;
}
else
#endif
{
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(authhost->picked == CURLAUTH_DIGEST) {
auth="Digest";
result = Curl_output_digest(conn,
FALSE, /* not a proxy */
(const unsigned char *)request,
(const unsigned char *)path);
if(result)
return result;
} else
#endif
if(authhost->picked == CURLAUTH_BASIC) {
if(conn->bits.user_passwd &&
!checkheaders(data, "Authorization:")) {
auth="Basic";
result = http_output_basic(conn, FALSE);
if(result)
return result;
}
/* basic is always ready */
authhost->done = TRUE;
}
}
if(auth) {
infof(data, "Server auth using %s with user '%s'\n",
auth, conn->user);
authhost->multi = (bool)(!authhost->done);
}
else
authhost->multi = FALSE;
}
} }
else else
authhost->done = TRUE; authhost->done = TRUE;
@@ -730,24 +708,39 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
* If the provided authentication is wanted as one out of several accepted * If the provided authentication is wanted as one out of several accepted
* types (using &), we OR this authentication type to the authavail * types (using &), we OR this authentication type to the authavail
* variable. * variable.
*
* Note:
*
* ->picked is first set to the 'want' value (one or more bits) before the
* request is sent, and then it is again set _after_ all response 401/407
* headers have been received but then only to a single preferred method
* (bit).
*
*/ */
#ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI
if(checkprefix("GSS-Negotiate", start) || if(checkprefix("GSS-Negotiate", start) ||
checkprefix("Negotiate", start)) { checkprefix("Negotiate", start)) {
int neg;
*availp |= CURLAUTH_GSSNEGOTIATE; *availp |= CURLAUTH_GSSNEGOTIATE;
authp->avail |= CURLAUTH_GSSNEGOTIATE; authp->avail |= CURLAUTH_GSSNEGOTIATE;
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
/* if exactly this is wanted, go */ if(data->state.negotiate.state == GSS_AUTHSENT) {
int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); /* if we sent GSS authentication in the outgoing request and we get this
back, we're in trouble */
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
else {
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
if(neg == 0) { if(neg == 0) {
DEBUGASSERT(!data->req.newurl); DEBUGASSERT(!data->req.newurl);
data->req.newurl = strdup(data->change.url); data->req.newurl = strdup(data->change.url);
data->state.authproblem = (data->req.newurl == NULL); if(!data->req.newurl)
} return CURLE_OUT_OF_MEMORY;
else { data->state.authproblem = FALSE;
infof(data, "Authentication problem. Ignoring this.\n"); /* we received GSS auth info and we dealt with it fine */
data->state.authproblem = TRUE; data->state.negotiate.state = GSS_AUTHRECV;
} }
} }
} }
@@ -1822,18 +1815,12 @@ static int http_getsock_do(struct connectdata *conn,
return GETSOCK_WRITESOCK(0); return GETSOCK_WRITESOCK(0);
} }
#ifdef USE_SSL
static CURLcode https_connecting(struct connectdata *conn, bool *done) static CURLcode https_connecting(struct connectdata *conn, bool *done)
{ {
CURLcode result; CURLcode result;
DEBUGASSERT((conn) && (conn->protocol & PROT_HTTPS)); DEBUGASSERT((conn) && (conn->protocol & PROT_HTTPS));
if(conn->ssl[FIRSTSOCKET].use) {
/* in some circumstances, this already has SSL enabled and then we don't
need to connect SSL again */
*done = TRUE;
return CURLE_OK;
}
/* perform SSL initialization for this socket */ /* perform SSL initialization for this socket */
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done); result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
if(result) if(result)
@@ -1841,6 +1828,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
to prevent (bad) re-use or similar */ to prevent (bad) re-use or similar */
return result; return result;
} }
#endif
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
/* This function is OpenSSL-specific. It should be made to query the generic /* This function is OpenSSL-specific. It should be made to query the generic
@@ -2318,11 +2306,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
} }
http->p_pragma =
(!checkheaders(data, "Pragma:") &&
(conn->bits.httpproxy && !conn->bits.tunnel_proxy) )?
"Pragma: no-cache\r\n":NULL;
http->p_accept = checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n"; http->p_accept = checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
if(( (HTTPREQ_POST == httpreq) || if(( (HTTPREQ_POST == httpreq) ||
@@ -2468,7 +2451,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
"%s" /* range */ "%s" /* range */
"%s" /* user agent */ "%s" /* user agent */
"%s" /* host */ "%s" /* host */
"%s" /* pragma */
"%s" /* accept */ "%s" /* accept */
"%s" /* accept-encoding */ "%s" /* accept-encoding */
"%s" /* referer */ "%s" /* referer */
@@ -2488,7 +2470,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
*data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)? *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
conn->allocptr.uagent:"", conn->allocptr.uagent:"",
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
http->p_pragma?http->p_pragma:"",
http->p_accept?http->p_accept:"", http->p_accept?http->p_accept:"",
(data->set.str[STRING_ENCODING] && (data->set.str[STRING_ENCODING] &&
*data->set.str[STRING_ENCODING] && *data->set.str[STRING_ENCODING] &&

View File

@@ -105,8 +105,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
(2 == sscanf(header, "%255[^=]=%1023[^\r\n,]", (2 == sscanf(header, "%255[^=]=%1023[^\r\n,]",
value, content)) ) { value, content)) ) {
if(!strcmp("\"\"", content)) { if(!strcmp("\"\"", content)) {
/* for the name="" case where we get only the "" in the content variable, /* for the name="" case where we get only the "" in the content
* simply clear the content then * variable, simply clear the content then
*/ */
content[0]=0; content[0]=0;
} }

View File

@@ -23,46 +23,43 @@
#include "setup.h" #include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> # include <unistd.h>
#endif #endif
#include "if2ip.h"
/*
* This test can probably be simplified to #if defined(SIOCGIFADDR) and
* moved after the following includes.
*/
#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN__) && \
!defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
!defined(__AMIGA__) && !defined(__minix) && !defined(__SYMBIAN32__) && \
!defined(__WATCOMC__)
#if defined(HAVE_GETIFADDRS)
/*
* glibc provides getifaddrs() to provide a list of all interfaces and their
* addresses.
*/
#include <ifaddrs.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> # include <sys/socket.h>
#endif #endif
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> # include <netinet/in.h>
#endif #endif
#ifdef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> # include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
#ifdef HAVE_IFADDRS_H
# include <ifaddrs.h>
#endif
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
#ifdef VMS
# include <inet.h>
#endif #endif
#include "inet_ntop.h" #include "inet_ntop.h"
#include "strequal.h" #include "strequal.h"
#include "if2ip.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -71,6 +68,10 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
/* ------------------------------------------------------------------ */
#if defined(HAVE_GETIFADDRS)
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size) char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
{ {
struct ifaddrs *iface, *head; struct ifaddrs *iface, *head;
@@ -78,10 +79,12 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
if (getifaddrs(&head) >= 0) { if (getifaddrs(&head) >= 0) {
for (iface=head; iface != NULL; iface=iface->ifa_next) { for (iface=head; iface != NULL; iface=iface->ifa_next) {
if ((iface->ifa_addr->sa_family == af) && if ((iface->ifa_addr != NULL) &&
(iface->ifa_addr->sa_family == af) &&
curl_strequal(iface->ifa_name, interface)) { curl_strequal(iface->ifa_name, interface)) {
void *addr; void *addr;
char scope[12]=""; char scope[12]="";
#ifdef ENABLE_IPV6
if (af == AF_INET6) { if (af == AF_INET6) {
unsigned int scopeid; unsigned int scopeid;
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr; addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
@@ -91,6 +94,7 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
snprintf(scope, sizeof(scope), "%%%u", scopeid); snprintf(scope, sizeof(scope), "%%%u", scopeid);
} }
else else
#endif
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr; addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
ip = (char *) Curl_inet_ntop(af, addr, buf, buf_size); ip = (char *) Curl_inet_ntop(af, addr, buf, buf_size);
strlcat(buf, scope, buf_size); strlcat(buf, scope, buf_size);
@@ -102,49 +106,7 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
return ip; return ip;
} }
#else #elif defined(HAVE_IOCTL_SIOCGIFADDR)
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_TIME_H
/* This must be before net/if.h for AIX 3.2 to enjoy life */
#include <sys/time.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef VMS
#include <inet.h>
#endif
#include "inet_ntop.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
#define SYS_ERROR -1 #define SYS_ERROR -1
@@ -170,18 +132,14 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
} }
memcpy(req.ifr_name, interface, len+1); memcpy(req.ifr_name, interface, len+1);
req.ifr_addr.sa_family = AF_INET; req.ifr_addr.sa_family = AF_INET;
#ifdef IOCTL_3_ARGS
if(SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) { if(SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) {
#else
if(SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) {
#endif
sclose(dummy); sclose(dummy);
return NULL; return NULL;
} }
else { else {
struct in_addr in; struct in_addr in;
struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr; struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_addr;
memcpy(&in, &s->sin_addr, sizeof(in)); memcpy(&in, &s->sin_addr, sizeof(in));
ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size); ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
} }
@@ -189,10 +147,9 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
} }
return ip; return ip;
} }
#endif
/* -- end of if2ip() -- */
#else #else
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size) char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
{ {
(void) af; (void) af;
@@ -201,4 +158,5 @@ char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
(void) buf_size; (void) buf_size;
return NULL; return NULL;
} }
#endif #endif

View File

@@ -50,7 +50,6 @@ struct ifreq {
/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the /* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
C code. */ C code. */
#define ifr_dstaddr ifr_addr
#define ifr_name ifr_ifrn.ifrn_name /* interface name */ #define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_addr ifr_ifru.ifru_addr /* address */

View File

@@ -74,9 +74,6 @@ Curl_inet_pton(int af, const char *src, void *dst)
case AF_INET: case AF_INET:
return (inet_pton4(src, (unsigned char *)dst)); return (inet_pton4(src, (unsigned char *)dst));
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
#ifndef AF_INET6
#define AF_INET6 (AF_MAX+1) /* just to let this compile */
#endif
case AF_INET6: case AF_INET6:
return (inet_pton6(src, (unsigned char *)dst)); return (inet_pton6(src, (unsigned char *)dst));
#endif #endif
@@ -114,6 +111,8 @@ inet_pton4(const char *src, unsigned char *dst)
if((pch = strchr(digits, ch)) != NULL) { if((pch = strchr(digits, ch)) != NULL) {
unsigned int val = *tp * 10 + (unsigned int)(pch - digits); unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
if(saw_digit && *tp == 0)
return (0);
if(val > 255) if(val > 255)
return (0); return (0);
*tp = (unsigned char)val; *tp = (unsigned char)val;
@@ -134,7 +133,6 @@ inet_pton4(const char *src, unsigned char *dst)
} }
if(octets < 4) if(octets < 4)
return (0); return (0);
/* bcopy(tmp, dst, INADDRSZ); */
memcpy(dst, tmp, INADDRSZ); memcpy(dst, tmp, INADDRSZ);
return (1); return (1);
} }
@@ -181,9 +179,8 @@ inet_pton6(const char *src, unsigned char *dst)
if(pch != NULL) { if(pch != NULL) {
val <<= 4; val <<= 4;
val |= (pch - xdigits); val |= (pch - xdigits);
if(val > 0xffff) if(++saw_xdigit > 4)
return (0); return (0);
saw_xdigit = 1;
continue; continue;
} }
if(ch == ':') { if(ch == ':') {
@@ -224,6 +221,8 @@ inet_pton6(const char *src, unsigned char *dst)
const long n = tp - colonp; const long n = tp - colonp;
long i; long i;
if(tp == endp)
return (0);
for (i = 1; i <= n; i++) { for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i]; endp[- i] = colonp[n - i];
colonp[n - i] = 0; colonp[n - i] = 0;
@@ -232,7 +231,6 @@ inet_pton6(const char *src, unsigned char *dst)
} }
if(tp != endp) if(tp != endp)
return (0); return (0);
/* bcopy(tmp, dst, IN6ADDRSZ); */
memcpy(dst, tmp, IN6ADDRSZ); memcpy(dst, tmp, IN6ADDRSZ);
return (1); return (1);
} }

View File

@@ -153,6 +153,8 @@ krb4_encode(void *app_data, const void *from, int length, int level, void **to,
{ {
struct krb4_data *d = app_data; struct krb4_data *d = app_data;
*to = malloc(length + 31); *to = malloc(length + 31);
if(!*to)
return -1;
if(level == prot_safe) if(level == prot_safe)
/* NOTE that the void* cast is safe, krb_mk_safe/priv don't modify the /* NOTE that the void* cast is safe, krb_mk_safe/priv don't modify the
* input buffer * input buffer

View File

@@ -48,6 +48,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
$(TMP_DIR)/connect.o \ $(TMP_DIR)/connect.o \
$(TMP_DIR)/content_encoding.o \ $(TMP_DIR)/content_encoding.o \
$(TMP_DIR)/cookie.o \ $(TMP_DIR)/cookie.o \
$(TMP_DIR)/curl_addrinfo.o \
$(TMP_DIR)/dict.o \ $(TMP_DIR)/dict.o \
$(TMP_DIR)/easy.o \ $(TMP_DIR)/easy.o \
$(TMP_DIR)/escape.o \ $(TMP_DIR)/escape.o \

View File

@@ -17,7 +17,7 @@ OBJS = amigaos.c base64.c connect.c content_encoding.c cookie.c dict.c easy.c \
ldap.c llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \ ldap.c llist.c md5.c memdebug.c mprintf.c multi.c netrc.c parsedate.c \
progress.c security.c select.c sendf.c share.c speedcheck.c ssluse.c \ progress.c security.c select.c sendf.c share.c speedcheck.c ssluse.c \
strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c \ strequal.c strtok.c telnet.c timeval.c transfer.c url.c version.c \
sslgen.c gtls.c strerror.c rawstr.c sslgen.c gtls.c strerror.c rawstr.c curl_addrinfo.c
all: $(OBJS:.c=.o) all: $(OBJS:.c=.o)
ar cru libcurl.a $(OBJS:.c=.o) ar cru libcurl.a $(OBJS:.c=.o)

View File

@@ -620,22 +620,27 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
easy->easy_handle->dns.hostcachetype = HCACHE_NONE; easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
} }
/* we must call Curl_done() here (if we still "own it") so that we don't if(easy->easy_conn) {
leave a half-baked one around */
if(easy->easy_conn &&
(easy->easy_conn->data == easy->easy_handle)) {
/* Curl_done() clears the conn->data field to lose the association /* we must call Curl_done() here (if we still "own it") so that we don't
between the easy handle and the connection leave a half-baked one around */
if (easy->easy_conn->data == easy->easy_handle) {
Note that this ignores the return code simply because there's nothing /* Curl_done() clears the conn->data field to lose the association
really useful to do with it anyway! */ between the easy handle and the connection
(void)Curl_done(&easy->easy_conn, easy->result, premature);
if(easy->easy_conn) Note that this ignores the return code simply because there's
/* the connection is still alive, set back the association to enable nothing really useful to do with it anyway! */
the check below to trigger TRUE */ (void)Curl_done(&easy->easy_conn, easy->result, premature);
easy->easy_conn->data = easy->easy_handle;
if(easy->easy_conn)
/* the connection is still alive, set back the association to enable
the check below to trigger TRUE */
easy->easy_conn->data = easy->easy_handle;
}
else
/* Clear connection pipelines, if Curl_done above was not called */
Curl_getoff_all_pipelines(easy->easy_handle, easy->easy_conn);
} }
/* If this easy_handle was the last one in charge for one or more /* If this easy_handle was the last one in charge for one or more

View File

@@ -65,6 +65,7 @@
#include <certdb.h> #include <certdb.h>
#include "memory.h" #include "memory.h"
#include "rawstr.h"
#include "easyif.h" /* for Curl_convert_from_utf8 prototype */ #include "easyif.h" /* for Curl_convert_from_utf8 prototype */
/* The last #include file should be: */ /* The last #include file should be: */
@@ -263,7 +264,7 @@ nss_load_cert(const char *filename, PRBool cacert)
CK_BBOOL cktrue = CK_TRUE; CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL ckfalse = CK_FALSE; CK_BBOOL ckfalse = CK_FALSE;
CK_OBJECT_CLASS objClass = CKO_CERTIFICATE; CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
char *slotname = NULL; char slotname[SLOTSIZE];
#endif #endif
CERTCertificate *cert; CERTCertificate *cert;
char *nickname = NULL; char *nickname = NULL;
@@ -284,6 +285,8 @@ nss_load_cert(const char *filename, PRBool cacert)
if(cacert) if(cacert)
return 0; /* You can't specify an NSS CA nickname this way */ return 0; /* You can't specify an NSS CA nickname this way */
nickname = strdup(filename); nickname = strdup(filename);
if(!nickname)
return 0;
goto done; goto done;
} }
@@ -299,15 +302,15 @@ nss_load_cert(const char *filename, PRBool cacert)
else else
slotID = 1; slotID = 1;
slotname = malloc(SLOTSIZE);
nickname = malloc(PATH_MAX);
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID); snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
snprintf(nickname, PATH_MAX, "PEM Token #%ld:%s", slotID, n);
nickname = aprintf("PEM Token #%ld:%s", slotID, n);
if(!nickname)
return 0;
slot = PK11_FindSlotByName(slotname); slot = PK11_FindSlotByName(slotname);
if(!slot) { if(!slot) {
free(slotname);
free(nickname); free(nickname);
return 0; return 0;
} }
@@ -334,7 +337,6 @@ nss_load_cert(const char *filename, PRBool cacert)
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
free(slotname);
if(rv == NULL) { if(rv == NULL) {
free(nickname); free(nickname);
return 0; return 0;
@@ -452,8 +454,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
CK_BBOOL cktrue = CK_TRUE; CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY; CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
CK_SLOT_ID slotID; CK_SLOT_ID slotID;
char *slotname = NULL;
pphrase_arg_t *parg = NULL; pphrase_arg_t *parg = NULL;
char slotname[SLOTSIZE];
attrs = theTemplate; attrs = theTemplate;
@@ -461,11 +463,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
slotID = 1; /* hardcoded for now */ slotID = 1; /* hardcoded for now */
slotname = malloc(SLOTSIZE); snprintf(slotname, sizeof(slotname), "PEM Token #%ld", slotID);
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
slot = PK11_FindSlotByName(slotname); slot = PK11_FindSlotByName(slotname);
free(slotname);
if(!slot) if(!slot)
return 0; return 0;
@@ -487,6 +486,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
PK11_IsPresent(slot); PK11_IsPresent(slot);
parg = malloc(sizeof(pphrase_arg_t)); parg = malloc(sizeof(pphrase_arg_t));
if(!parg)
return 0;
parg->retryCount = 0; parg->retryCount = 0;
parg->data = conn->data; parg->data = conn->data;
/* parg is initialized in nss_Init_Tokens() */ /* parg is initialized in nss_Init_Tokens() */
@@ -583,6 +584,9 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
pphrase_arg_t *parg = NULL; pphrase_arg_t *parg = NULL;
parg = malloc(sizeof(pphrase_arg_t)); parg = malloc(sizeof(pphrase_arg_t));
if(!parg)
return SECFailure;
parg->retryCount = 0; parg->retryCount = 0;
parg->data = conn->data; parg->data = conn->data;
@@ -743,7 +747,7 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
* X509_check_issued function (in x509v3/v3_purp.c) * X509_check_issued function (in x509v3/v3_purp.c)
*/ */
static SECStatus check_issuer_cert(PRFileDesc *sock, static SECStatus check_issuer_cert(PRFileDesc *sock,
char* issuer_nickname) char *issuer_nickname)
{ {
CERTCertificate *cert,*cert_issuer,*issuer; CERTCertificate *cert,*cert_issuer,*issuer;
SECStatus res=SECSuccess; SECStatus res=SECSuccess;
@@ -801,12 +805,11 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
if(!strncmp(nickname, "PEM Token", 9)) { if(!strncmp(nickname, "PEM Token", 9)) {
CK_SLOT_ID slotID = 1; /* hardcoded for now */ CK_SLOT_ID slotID = 1; /* hardcoded for now */
char * slotname = malloc(SLOTSIZE); char slotname[SLOTSIZE];
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID); snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
slot = PK11_FindSlotByName(slotname); slot = PK11_FindSlotByName(slotname);
privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL); privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
free(slotname);
if(privKey) { if(privKey) {
secStatus = SECSuccess; secStatus = SECSuccess;
} }
@@ -973,12 +976,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
NSS_SetDomesticPolicy(); NSS_SetDomesticPolicy();
#ifdef HAVE_PK11_CREATEGENERICOBJECT #ifdef HAVE_PK11_CREATEGENERICOBJECT
configstring = malloc(PATH_MAX); configstring = aprintf("library=%s name=PEM", pem_library);
if(!configstring)
PR_snprintf(configstring, PATH_MAX, "library=%s name=PEM", pem_library); goto error;
mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE); mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
free(configstring); free(configstring);
if(!mod || !mod->loaded) { if(!mod || !mod->loaded) {
if(mod) { if(mod) {
SECMOD_DestroyModule(mod); SECMOD_DestroyModule(mod);
@@ -1108,41 +1111,48 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
if(data->set.str[STRING_CERT]) { if(data->set.str[STRING_CERT]) {
char *n; char *n;
char *nickname; char *nickname;
bool nickname_alloc = FALSE;
nickname = malloc(PATH_MAX);
if(is_file(data->set.str[STRING_CERT])) { if(is_file(data->set.str[STRING_CERT])) {
n = strrchr(data->set.str[STRING_CERT], '/'); n = strrchr(data->set.str[STRING_CERT], '/');
if(n) { if(n) {
n++; /* skip last slash */ n++; /* skip last slash */
snprintf(nickname, PATH_MAX, "PEM Token #%d:%s", 1, n); nickname = aprintf(nickname, "PEM Token #%d:%s", 1, n);
if(!nickname)
return CURLE_OUT_OF_MEMORY;
nickname_alloc = TRUE;
} }
} }
else { else {
strncpy(nickname, data->set.str[STRING_CERT], PATH_MAX); nickname = data->set.str[STRING_CERT];
nickname[PATH_MAX-1]=0; /* make sure this is zero terminated */
} }
if(nss_Init_Tokens(conn) != SECSuccess) { if(nss_Init_Tokens(conn) != SECSuccess) {
free(nickname); if(nickname_alloc)
free(nickname);
goto error; goto error;
} }
if(!cert_stuff(conn, data->set.str[STRING_CERT], if(!cert_stuff(conn, data->set.str[STRING_CERT],
data->set.str[STRING_KEY])) { data->set.str[STRING_KEY])) {
/* failf() is already done in cert_stuff() */ /* failf() is already done in cert_stuff() */
free(nickname); if(nickname_alloc)
free(nickname);
return CURLE_SSL_CERTPROBLEM; return CURLE_SSL_CERTPROBLEM;
} }
connssl->client_nickname = strdup(nickname); /* this "takes over" the pointer to the allocated name or makes a
dup of it */
connssl->client_nickname = nickname_alloc?nickname:strdup(nickname);
if(!connssl->client_nickname)
return CURLE_OUT_OF_MEMORY;
if(SSL_GetClientAuthDataHook(model, if(SSL_GetClientAuthDataHook(model,
(SSLGetClientAuthData) SelectClientCert, (SSLGetClientAuthData) SelectClientCert,
(void *)connssl) != (void *)connssl) != SECSuccess) {
SECSuccess) {
curlerr = CURLE_SSL_CERTPROBLEM; curlerr = CURLE_SSL_CERTPROBLEM;
goto error; goto error;
} }
free(nickname);
PK11_SetPasswordFunc(nss_no_password); PK11_SetPasswordFunc(nss_no_password);
} }
else else
@@ -1177,21 +1187,29 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
if (data->set.str[STRING_SSL_ISSUERCERT]) { if (data->set.str[STRING_SSL_ISSUERCERT]) {
char *n; char *n;
char *nickname; char *nickname;
nickname = malloc(PATH_MAX); bool nickname_alloc = FALSE;
SECStatus ret;
if(is_file(data->set.str[STRING_SSL_ISSUERCERT])) { if(is_file(data->set.str[STRING_SSL_ISSUERCERT])) {
n = strrchr(data->set.str[STRING_SSL_ISSUERCERT], '/'); n = strrchr(data->set.str[STRING_SSL_ISSUERCERT], '/');
if (n) { if (n) {
n++; /* skip last slash */ n++; /* skip last slash */
snprintf(nickname, PATH_MAX, "PEM Token #%d:%s", 1, n); nickname = aprintf("PEM Token #%d:%s", 1, n);
if(!nickname)
return CURLE_OUT_OF_MEMORY;
nickname_alloc = TRUE;
} }
} }
else { else
strncpy(nickname, data->set.str[STRING_SSL_ISSUERCERT], PATH_MAX); nickname = data->set.str[STRING_SSL_ISSUERCERT];
nickname[PATH_MAX-1]=0; /* make sure this is zero terminated */
} ret = check_issuer_cert(connssl->handle, nickname);
if (check_issuer_cert(connssl->handle, nickname) == SECFailure) {
infof(data,"SSL certificate issuer check failed\n"); if(nickname_alloc)
free(nickname); free(nickname);
if(SECFailure == ret) {
infof(data,"SSL certificate issuer check failed\n");
curlerr = CURLE_SSL_ISSUER_ERROR; curlerr = CURLE_SSL_ISSUER_ERROR;
goto error; goto error;
} }

View File

@@ -47,7 +47,8 @@
#define _MPRINTF_REPLACE /* use the internal *printf() functions */ #define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h> #include <curl/mprintf.h>
#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) /* the krb4 functions only exists for FTP and if krb4 or gssapi is defined */
#if !defined(CURL_DISABLE_FTP) && (defined(HAVE_KRB4) || defined(HAVE_GSSAPI))
#include "krb4.h" #include "krb4.h"
#else #else
#define Curl_sec_send(a,b,c,d) -1 #define Curl_sec_send(a,b,c,d) -1
@@ -425,7 +426,7 @@ static CURLcode pausewrite(struct SessionHandle *data,
} }
/* client_write() sends data to the write callback(s) /* Curl_client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header. The bit pattern defines to what "streams" to write to. Body and/or header.
The defines are in sendf.h of course. The defines are in sendf.h of course.
@@ -442,6 +443,9 @@ CURLcode Curl_client_write(struct connectdata *conn,
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
size_t wrote; size_t wrote;
if(0 == len)
len = strlen(ptr);
/* If reading is actually paused, we're forced to append this chunk of data /* If reading is actually paused, we're forced to append this chunk of data
to the already held data, but only if it is the same type as otherwise it to the already held data, but only if it is the same type as otherwise it
can't work and it'll return error instead. */ can't work and it'll return error instead. */
@@ -469,9 +473,6 @@ CURLcode Curl_client_write(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
if(0 == len)
len = strlen(ptr);
if(type & CLIENTWRITE_BODY) { if(type & CLIENTWRITE_BODY) {
if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') { if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
#ifdef CURL_DOES_CONVERSIONS #ifdef CURL_DOES_CONVERSIONS

View File

@@ -30,9 +30,6 @@
/* OS/400 netdb.h does not define NI_MAXSERV. */ /* OS/400 netdb.h does not define NI_MAXSERV. */
#define NI_MAXSERV 32 #define NI_MAXSERV 32
/* OS/400 does not define the ifr_dstaddr union member. */
#define ifr_dstaddr ifr_addr
/* No OS/400 header file defines u_int32_t. */ /* No OS/400 header file defines u_int32_t. */
typedef unsigned long u_int32_t; typedef unsigned long u_int32_t;

View File

@@ -355,7 +355,6 @@
# define sclose(x) close_s(x) # define sclose(x) close_s(x)
# define select(n,r,w,x,t) select_s(n,r,w,x,t) # define select(n,r,w,x,t) select_s(n,r,w,x,t)
# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) # define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
# define IOCTL_3_ARGS
# include <tcp.h> # include <tcp.h>
# ifdef word # ifdef word
# undef word # undef word
@@ -430,10 +429,6 @@
#endif #endif
#endif #endif
#ifdef mpeix
#define IOCTL_3_ARGS
#endif
#ifdef NETWARE #ifdef NETWARE
int netware_init(void); int netware_init(void);
#ifndef __NOVELL_LIBC__ #ifndef __NOVELL_LIBC__

View File

@@ -36,10 +36,6 @@
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
#error "this requires libssh2 0.16 or later"
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -103,6 +99,7 @@
#include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "strtoofft.h" #include "strtoofft.h"
#include "multiif.h" #include "multiif.h"
#include "select.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -421,7 +418,14 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
return CURLE_OK; return CURLE_OK;
} }
static CURLcode ssh_statemach_act(struct connectdata *conn) /*
* ssh_statemach_act() runs the SSH statemachine "one round" and returns. The
* data the pointer 'block' points to will be set to TRUE if the libssh2
* function returns LIBSSH2_ERROR_EAGAIN meaning it wants to be called again
* when the socket is ready
*/
static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@@ -432,8 +436,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
const char *fingerprint; const char *fingerprint;
#endif /* CURL_LIBSSH2_DEBUG */ #endif /* CURL_LIBSSH2_DEBUG */
const char *host_public_key_md5; const char *host_public_key_md5;
int rc,i; int rc = LIBSSH2_ERROR_NONE, i;
int err; int err;
*block = 0; /* we're not blocking by default */
switch(sshc->state) { switch(sshc->state) {
case SSH_S_STARTUP: case SSH_S_STARTUP:
@@ -519,6 +524,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->authlist) { if(!sshc->authlist) {
if((err = libssh2_session_last_errno(sshc->ssh_session)) == if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -729,6 +735,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->sftp_session) { if(!sshc->sftp_session) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -996,21 +1003,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
* This takes an extra protocol round trip. * This takes an extra protocol round trip.
*/ */
rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2, rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
&sshc->quote_attrs); &sshc->quote_attrs);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
break; break;
} }
else if(rc != 0) { /* get those attributes */ else if(rc != 0) { /* get those attributes */
err = libssh2_sftp_last_error(sshc->sftp_session); err = libssh2_sftp_last_error(sshc->sftp_session);
Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL; sshc->quote_path1 = NULL;
Curl_safefree(sshc->quote_path2); Curl_safefree(sshc->quote_path2);
sshc->quote_path2 = NULL; sshc->quote_path2 = NULL;
failf(data, "Attempt to get SFTP stats failed: %s", failf(data, "Attempt to get SFTP stats failed: %s",
sftp_libssh2_strerror(err)); sftp_libssh2_strerror(err));
state(conn, SSH_SFTP_CLOSE); state(conn, SSH_SFTP_CLOSE);
sshc->actualcode = CURLE_QUOTE_ERROR; sshc->actualcode = CURLE_QUOTE_ERROR;
break; break;
} }
} }
@@ -1233,6 +1240,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->sftp_handle) { if(!sshc->sftp_handle) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -1387,6 +1395,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->sftp_handle) { if(!sshc->sftp_handle) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -1421,6 +1430,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
PATH_MAX, PATH_MAX,
&sshc->readdir_attrs); &sshc->readdir_attrs);
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) { if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
if(sshc->readdir_len > 0) { if(sshc->readdir_len > 0) {
@@ -1521,6 +1531,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
sshc->readdir_filename, sshc->readdir_filename,
PATH_MAX); PATH_MAX);
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) { if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
Curl_safefree(sshc->readdir_linkPath); Curl_safefree(sshc->readdir_linkPath);
@@ -1578,6 +1589,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
case SSH_SFTP_READDIR_DONE: case SSH_SFTP_READDIR_DONE:
if(libssh2_sftp_closedir(sshc->sftp_handle) == if(libssh2_sftp_closedir(sshc->sftp_handle) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
sshc->sftp_handle = NULL; sshc->sftp_handle = NULL;
@@ -1601,6 +1613,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->sftp_handle) { if(!sshc->sftp_handle) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -1814,6 +1827,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->ssh_channel) { if(!sshc->ssh_channel) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -1860,6 +1874,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
if(!sshc->ssh_channel) { if(!sshc->ssh_channel) {
if(libssh2_session_last_errno(sshc->ssh_session) == if(libssh2_session_last_errno(sshc->ssh_session) ==
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
break; break;
} }
else { else {
@@ -2011,6 +2026,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
break; break;
} }
if(rc == LIBSSH2_ERROR_EAGAIN) {
/* we would block, we need to wait for the socket to be ready (in the
right direction too)! */
*block = TRUE;
}
return result; return result;
} }
@@ -2019,8 +2040,11 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
{ {
struct ssh_conn *sshc = &conn->proto.sshc; struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
bool block_we_ignore; /* we don't care about EAGAIN at this point, but TODO:
we _should_ store the status and use that to
provide a ssh_getsock() implementation */
result = ssh_statemach_act(conn); result = ssh_statemach_act(conn, &block_we_ignore);
*done = (bool)(sshc->state == SSH_STOP); *done = (bool)(sshc->state == SSH_STOP);
return result; return result;
@@ -2031,8 +2055,28 @@ static CURLcode ssh_easy_statemach(struct connectdata *conn)
struct ssh_conn *sshc = &conn->proto.sshc; struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
while((sshc->state != SSH_STOP) && !result) while((sshc->state != SSH_STOP) && !result) {
result = ssh_statemach_act(conn); bool block;
result = ssh_statemach_act(conn, &block);
#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTIONS
if((CURLE_OK == result) && block) {
int dir = libssh2_session_block_directions(sshc->ssh_session);
curl_socket_t sock = conn->sock[FIRSTSOCKET];
curl_socket_t fd_read = CURL_SOCKET_BAD;
curl_socket_t fd_write = CURL_SOCKET_BAD;
if (LIBSSH2_SESSION_BLOCK_INBOUND & dir) {
fd_read = sock;
}
if (LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) {
fd_write = sock;
}
/* wait for the socket to become ready */
Curl_socket_ready(fd_read, fd_write, 1000); /* ignore result */
}
#endif
}
return result; return result;
} }

View File

@@ -1,6 +1,5 @@
#ifndef __SSH_H #ifndef HEADER_CURL_SSH_H
#define __SSH_H #define HEADER_CURL_SSH_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
@@ -25,6 +24,17 @@
***************************************************************************/ ***************************************************************************/
#ifdef USE_LIBSSH2 #ifdef USE_LIBSSH2
#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
# error "SCP/SFTP protocols require libssh2 0.16 or later"
#endif
#if (LIBSSH2_VERSION_NUM >= 0x001300)
# define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTIONS 1
#else
# undef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTIONS
#endif
extern const struct Curl_handler Curl_handler_scp; extern const struct Curl_handler Curl_handler_scp;
extern const struct Curl_handler Curl_handler_sftp; extern const struct Curl_handler Curl_handler_sftp;
@@ -49,4 +59,4 @@ ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
#endif /* USE_LIBSSH2 */ #endif /* USE_LIBSSH2 */
#endif /* __SSH_H */ #endif /* HEADER_CURL_SSH_H */

View File

@@ -79,7 +79,6 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
#define Curl_ssl_init() 1 #define Curl_ssl_init() 1
#define Curl_ssl_cleanup() do { } while (0) #define Curl_ssl_cleanup() do { } while (0)
#define Curl_ssl_connect(x,y) CURLE_FAILED_INIT #define Curl_ssl_connect(x,y) CURLE_FAILED_INIT
#define Curl_ssl_connect_nonblocking(x,y,z) (z=z, CURLE_FAILED_INIT)
#define Curl_ssl_close_all(x) #define Curl_ssl_close_all(x)
#define Curl_ssl_close(x,y) #define Curl_ssl_close(x,y)
#define Curl_ssl_shutdown(x,y) CURLE_FAILED_INIT #define Curl_ssl_shutdown(x,y) CURLE_FAILED_INIT

View File

@@ -52,7 +52,9 @@
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>

View File

@@ -52,7 +52,9 @@
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>

View File

@@ -63,7 +63,9 @@
#ifdef HAVE_SYS_IOCTL_H #ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif #endif
#ifdef HAVE_SIGNAL_H
#include <signal.h> #include <signal.h>
#endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>

View File

@@ -1487,17 +1487,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break; break;
case CURLOPT_MAX_SEND_SPEED_LARGE: case CURLOPT_MAX_SEND_SPEED_LARGE:
/* /*
* The max speed limit that sends transfer more than * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
* CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is * bytes per second the transfer is throttled..
* throttled..
*/ */
data->set.max_send_speed=va_arg(param, curl_off_t); data->set.max_send_speed=va_arg(param, curl_off_t);
break; break;
case CURLOPT_MAX_RECV_SPEED_LARGE: case CURLOPT_MAX_RECV_SPEED_LARGE:
/* /*
* The max speed limit that sends transfer more than * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
* CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is * second the transfer is throttled..
* throttled..
*/ */
data->set.max_recv_speed=va_arg(param, curl_off_t); data->set.max_recv_speed=va_arg(param, curl_off_t);
break; break;
@@ -2361,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
return 0; return 0;
} }
/* remove the specified connection from all (possible) pipelines and related
queues */
void Curl_getoff_all_pipelines(struct SessionHandle *data,
struct connectdata *conn)
{
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
conn->readchannel_inuse)
conn->readchannel_inuse = FALSE;
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
conn->writechannel_inuse)
conn->writechannel_inuse = FALSE;
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
}
#if 0 /* this code is saved here as it is useful for debugging purposes */ #if 0 /* this code is saved here as it is useful for debugging purposes */
static void Curl_printPipeline(struct curl_llist *pipeline) static void Curl_printPipeline(struct curl_llist *pipeline)
{ {
@@ -2511,6 +2523,11 @@ ConnectionExists(struct SessionHandle *data,
/* don't do mixed proxy and non-proxy connections */ /* don't do mixed proxy and non-proxy connections */
continue; continue;
if(!canPipeline && check->inuse)
/* this request can't be pipelined but the checked connection is already
in use so we skip it */
continue;
if(!needle->bits.httpproxy || needle->protocol&PROT_SSL || if(!needle->bits.httpproxy || needle->protocol&PROT_SSL ||
(needle->bits.httpproxy && check->bits.httpproxy && (needle->bits.httpproxy && check->bits.httpproxy &&
needle->bits.tunnel_proxy && check->bits.tunnel_proxy && needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
@@ -4545,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp,
Curl_expire(data, 0); /* stop timer */ Curl_expire(data, 0); /* stop timer */
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && Curl_getoff_all_pipelines(data, conn);
conn->readchannel_inuse)
conn->readchannel_inuse = FALSE;
if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
conn->writechannel_inuse)
conn->writechannel_inuse = FALSE;
Curl_removeHandleFromPipeline(data, conn->pend_pipe);
if(conn->bits.done || if(conn->bits.done ||
(conn->send_pipe->size + conn->recv_pipe->size != 0 && (conn->send_pipe->size + conn->recv_pipe->size != 0 &&

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