Compare commits
136 Commits
curl-7_19_
...
cares-1_6_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b962ef3154 | ||
|
|
32f78136b2 | ||
|
|
01d6133bd7 | ||
|
|
4b62cd3616 | ||
|
|
df7b1d8e64 | ||
|
|
2449e1f5a5 | ||
|
|
66c0e4ad5f | ||
|
|
18371aaff9 | ||
|
|
f36eab2608 | ||
|
|
66d38261f7 | ||
|
|
553b4cfd0b | ||
|
|
edd63a7920 | ||
|
|
5ce03efc3e | ||
|
|
4645e8b6b1 | ||
|
|
42365aa7ef | ||
|
|
dff4ce92ad | ||
|
|
e5b0533dab | ||
|
|
a2a315a6e8 | ||
|
|
7abdc4b218 | ||
|
|
479ddb1fee | ||
|
|
4ee27b4594 | ||
|
|
58ebde9502 | ||
|
|
04ee89493e | ||
|
|
dd3594c6b3 | ||
|
|
f7ea431516 | ||
|
|
16a153468d | ||
|
|
b062212e55 | ||
|
|
39eb96e9ff | ||
|
|
4c84f6b423 | ||
|
|
0b2ae71f8b | ||
|
|
39d0b57ebf | ||
|
|
c036f6ae2d | ||
|
|
e35e2ea6ec | ||
|
|
f33f8eee26 | ||
|
|
31a3f064c0 | ||
|
|
232518a219 | ||
|
|
bc165078a2 | ||
|
|
e4dabef0c7 | ||
|
|
00142d8443 | ||
|
|
1b0b7fa0e1 | ||
|
|
67fb731ec4 | ||
|
|
a30a6f2f20 | ||
|
|
baeebb2b57 | ||
|
|
ecc6f550eb | ||
|
|
640974fb28 | ||
|
|
3b0c5ae467 | ||
|
|
0fa14c8662 | ||
|
|
d17be0df52 | ||
|
|
53a8a6e5a6 | ||
|
|
dd2fc45c27 | ||
|
|
ba9f8c674c | ||
|
|
c4f4fa4089 | ||
|
|
32634b0771 | ||
|
|
c97b66287c | ||
|
|
cd6fc8a8ef | ||
|
|
3308781376 | ||
|
|
40e8b4e527 | ||
|
|
4741e64c89 | ||
|
|
0b489c7e61 | ||
|
|
22d4db1cf2 | ||
|
|
7383225271 | ||
|
|
4b3ae5e157 | ||
|
|
797bc8504c | ||
|
|
305f4d92ef | ||
|
|
c36f0e71b6 | ||
|
|
a028c69f48 | ||
|
|
4e4b6de5ce | ||
|
|
9aac2328c6 | ||
|
|
e5084c1eca | ||
|
|
9b12f09600 | ||
|
|
a71762e405 | ||
|
|
b8f3e5675a | ||
|
|
820011dedc | ||
|
|
cdd6054e08 | ||
|
|
a15b6a6f86 | ||
|
|
20d3e2b967 | ||
|
|
608fdce0a0 | ||
|
|
ecd3251542 | ||
|
|
999c7126b3 | ||
|
|
3c50ea961f | ||
|
|
acc29ff1d9 | ||
|
|
886bba55ac | ||
|
|
cd440215a5 | ||
|
|
73060b4523 | ||
|
|
c76d939563 | ||
|
|
3c4b69f95d | ||
|
|
3f01d9a043 | ||
|
|
dbc6fe3e84 | ||
|
|
da6c15163b | ||
|
|
9818bf7026 | ||
|
|
73c7acb159 | ||
|
|
ea8fbb5233 | ||
|
|
9b033e1b8a | ||
|
|
a65ce7b107 | ||
|
|
2249c12a3c | ||
|
|
b4ac9cd02c | ||
|
|
3517eba632 | ||
|
|
2cd44abafc | ||
|
|
4b486ebbc1 | ||
|
|
f9f211d2c6 | ||
|
|
77b30f69e4 | ||
|
|
17d2a464ad | ||
|
|
ae6530ee82 | ||
|
|
a6ba9e5ccd | ||
|
|
c4cdab969b | ||
|
|
c331c73ec6 | ||
|
|
d1f063c62d | ||
|
|
b686dc4911 | ||
|
|
78936b2f2a | ||
|
|
b2ed1e2607 | ||
|
|
fb8870297d | ||
|
|
4cbc0f6c2e | ||
|
|
1b9eff64fa | ||
|
|
d07d1a6ef8 | ||
|
|
8bdd60fa71 | ||
|
|
b872086c74 | ||
|
|
e0af4a15d0 | ||
|
|
d31802ed98 | ||
|
|
87c4136bd4 | ||
|
|
09e027bc9d | ||
|
|
707828b71a | ||
|
|
8f44037133 | ||
|
|
9717ccb786 | ||
|
|
6354cbf9d6 | ||
|
|
95a849efc2 | ||
|
|
fe083a94b9 | ||
|
|
6fdcdfa5ea | ||
|
|
4a4885eead | ||
|
|
a0ef686c54 | ||
|
|
2903a5c050 | ||
|
|
4d50b9f1f1 | ||
|
|
5e3c2af236 | ||
|
|
5d791838d2 | ||
|
|
b80c5cff49 | ||
|
|
47b5740bdf | ||
|
|
b8092857d9 |
170
CHANGES
170
CHANGES
@@ -6,6 +6,176 @@
|
||||
|
||||
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)
|
||||
|
||||
Daniel Stenberg (4 Nov 2008)
|
||||
|
||||
@@ -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
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 672
|
||||
Contributors: 683
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o pkg-config can now show supported_protocols and supported_features
|
||||
o Added CURLOPT_CERTINFO and CURLINFO_CERTINFO
|
||||
o Added CURLOPT_POSTREDIR
|
||||
o Better detect HTTP 1.0 servers and don't do HTTP 1.1 requests on them
|
||||
o configure --disable-proxy disables proxy support
|
||||
o Added CURLOPT_USERNAME and CURLOPT_PASSWORD
|
||||
o --interface now works with IPv6 connections on glibc systems
|
||||
o Added CURLOPT_PROXYUSERNAME and CURLOPT_PROXYPASSWORD
|
||||
o
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o MingW32 non-configure builds are now largefile feature enabled by default
|
||||
o NetWare LIBC builds are now largefile feature enabled by default
|
||||
o curl_easy_pause() could behave wrongly on unpause
|
||||
o cookies with invalid expire dates are now considered expired
|
||||
o HTTP pipelining over proxy
|
||||
o fix regression in configure script which affected OpenSSL builds on MSYS
|
||||
o GnuTLS-based multi interface doing HTTPS over proxy failed
|
||||
o recv() failures cause CURLE_RECV_ERROR
|
||||
o SFTP over SOCKS crash fixed
|
||||
o thread-safety issues addressed for NSS-powered libcurls
|
||||
o removed the use of mktime() and gmtime(_r)() in date parsing and conversions
|
||||
o HTTP Digest with a blank realm did wrong
|
||||
o CURLINFO_REDIRECT_URL didn't work with the multi interface
|
||||
o CURLOPT_RANGE now works for SFTP downloads
|
||||
o FTP SIZE response 550 now causes CURLE_REMOTE_FILE_NOT_FOUND
|
||||
o CURLINFO_PRIMARY_IP fixed for persistent connection re-use cases
|
||||
o remove_handle/add_handle multi interface timer callback flaw
|
||||
o CURLINFO_REDIRECT_URL memory leak and wrong-doing
|
||||
o case insensitive string matching works in Turkish too
|
||||
o Solaris builds get _REENTRANT defined properly and work again
|
||||
o Garbage sent on chunky upload after curl_easy_pause()
|
||||
o ipv4 name resolves when libcurl is built with ipv6-enabled c-ares
|
||||
o undersized IPv6 address internal buffer truncated long IPv6 addresses
|
||||
o CURLINFO_FILETIME works for file:// transfers as well
|
||||
o build failure when disabling FTP but enabling GSS
|
||||
o fixed several calls to memory functions that didn't check return codes
|
||||
o memory leak for SSL connects with libcurl/NSS when CURLOPT_ISSUERCERT was
|
||||
used
|
||||
o re-use of connections with the multi interface when multiple handles used
|
||||
the same server
|
||||
o memory leak with HTTP GSS/kerberos authentication
|
||||
o removed the default use of "Pragma: no-cache"
|
||||
o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
|
||||
o bad fclose() after a fatal error in cookie code
|
||||
o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
|
||||
o GSS authentication infinite loop problem
|
||||
o 550 response from SIZE no longer treated as missing file
|
||||
o ftps:// control connections now use explicit protection level
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
o see docs/KNOWN_BUGS (http://curl.haxx.se/docs/knownbugs.html)
|
||||
|
||||
Other curl-related news:
|
||||
|
||||
o
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev,
|
||||
Linus Nielsen Feltzing, Martin Drasar, Stefan Krause, Dmitry Kurochkin,
|
||||
Mike Revi, Andres Garcia, Michael Goffioul, Markus Moeller, Rob Crittenden,
|
||||
Jamie Lokier, Emanuele Bovisio, Maxim Ivanov, Ian Lynagh, Daniel Egger,
|
||||
Igor Novoseltsev, John Wilkinson, Pascal Terjan, Steve Roskowski,
|
||||
Daniel Johnson
|
||||
|
||||
Yang Tse, Daniel Fandrich, Jim Meyering, Christian Krause, Andreas Wurf,
|
||||
Markus Koetter, Josef Wolf, Vlad Grachov, Pawel Kierski, Igor Novoseltsev,
|
||||
Fred Machado, Ken Hirsch
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
26
TODO-RELEASE
26
TODO-RELEASE
@@ -1,18 +1,24 @@
|
||||
To be addressed before 7.19.1 (planned release: November 2008)
|
||||
=============================
|
||||
|
||||
To be addressed in 7.19.2 (planned release: January 2009)
|
||||
To be addressed in 7.19.3 (planned release: January 2009)
|
||||
=========================
|
||||
|
||||
188 - "Curl keep special character in filename when saving" bug #2192220
|
||||
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"
|
||||
http://curl.haxx.se/mail/archive-2008-10/0000.html
|
||||
199 - "Bug 2351645" adjustment of the patch Daniel S applied
|
||||
- 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 -
|
||||
150
acinclude.m4
150
acinclude.m4
@@ -1965,154 +1965,6 @@ AC_DEFUN([TYPE_SIG_ATOMIC_T], [
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||
dnl four known different ways, with the one used almost everywhere being POSIX
|
||||
dnl and XPG3, while the other different ways for different systems (old BSD,
|
||||
dnl Windows and Amiga).
|
||||
dnl
|
||||
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
|
||||
dnl O_NONBLOCK define is found but does not work. This condition is attempted
|
||||
dnl to get caught in this script by using an excessive number of #ifdefs...
|
||||
|
||||
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
|
||||
AC_MSG_CHECKING([non-blocking sockets style])
|
||||
nonblock="unknown"
|
||||
#
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for O_NONBLOCK test */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
/* */
|
||||
#if defined(sun) || defined(__sun__) || \
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
/* */
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
]],[[
|
||||
/* O_NONBLOCK source test */
|
||||
int socket;
|
||||
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
|
||||
]])
|
||||
],[
|
||||
dnl the O_NONBLOCK test was fine
|
||||
nonblock="O_NONBLOCK"
|
||||
AC_DEFINE(HAVE_O_NONBLOCK, 1,
|
||||
[use O_NONBLOCK for non-blocking sockets])
|
||||
])
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for FIONBIO test */
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
]],[[
|
||||
/* FIONBIO source test (old-style unix) */
|
||||
int socket;
|
||||
int flags = ioctl(socket, FIONBIO, &flags);
|
||||
]])
|
||||
],[
|
||||
dnl FIONBIO test was good
|
||||
nonblock="FIONBIO"
|
||||
AC_DEFINE(HAVE_FIONBIO, 1,
|
||||
[use FIONBIO for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for ioctlsocket test (Windows) */
|
||||
#undef inline
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
]],[[
|
||||
/* ioctlsocket source code (Windows) */
|
||||
SOCKET sd;
|
||||
unsigned long flags = 0;
|
||||
sd = socket(0, 0, 0);
|
||||
ioctlsocket(sd, FIONBIO, &flags);
|
||||
]])
|
||||
],[
|
||||
dnl ioctlsocket test was good
|
||||
nonblock="ioctlsocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET, 1,
|
||||
[use ioctlsocket() for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for IoctlSocket test (Amiga?) */
|
||||
#include <sys/ioctl.h>
|
||||
]],[[
|
||||
/* IoctlSocket source code (Amiga?) */
|
||||
int socket;
|
||||
int flags = IoctlSocket(socket, FIONBIO, (long)1);
|
||||
]])
|
||||
],[
|
||||
dnl Ioctlsocket test was good
|
||||
nonblock="IoctlSocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1,
|
||||
[use Ioctlsocket() for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for SO_NONBLOCK test (BeOS) */
|
||||
#include <socket.h>
|
||||
]],[[
|
||||
/* SO_NONBLOCK source code (BeOS) */
|
||||
long b = 1;
|
||||
int socket;
|
||||
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
]])
|
||||
],[
|
||||
dnl the SO_NONBLOCK test was good
|
||||
nonblock="SO_NONBLOCK"
|
||||
AC_DEFINE(HAVE_SO_NONBLOCK, 1,
|
||||
[use SO_NONBLOCK for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
AC_MSG_RESULT($nonblock)
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
|
||||
[disabled non-blocking sockets])
|
||||
AC_MSG_WARN([non-block sockets disabled])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl TYPE_IN_ADDR_T
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||
@@ -2689,6 +2541,7 @@ dnl /etc/ssl/certs/ca-certificates.crt Debian systems
|
||||
dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva
|
||||
dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat
|
||||
dnl /usr/local/share/certs/ca-root.crt FreeBSD
|
||||
dnl /etc/ssl/cert.pem OpenBSD
|
||||
dnl /etc/ssl/certs/ (ca path) SUSE
|
||||
|
||||
AC_DEFUN([CURL_CHECK_CA_BUNDLE], [
|
||||
@@ -2751,6 +2604,7 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
|
||||
/etc/pki/tls/certs/ca-bundle.crt \
|
||||
/usr/share/ssl/certs/ca-bundle.crt \
|
||||
/usr/local/share/certs/ca-root.crt \
|
||||
/etc/ssl/cert.pem \
|
||||
"$cac"; do
|
||||
if test -f "$a"; then
|
||||
ca="$a"
|
||||
|
||||
58
ares/CHANGES
58
ares/CHANGES
@@ -1,5 +1,63 @@
|
||||
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)
|
||||
- Carlo Contavalli added support for the glibc "rotate" option, as documented
|
||||
in man resolv.conf:
|
||||
|
||||
@@ -11,10 +11,10 @@ include ../packages/DOS/common.dj
|
||||
include Makefile.inc
|
||||
|
||||
CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \
|
||||
-DHAVE_STRUCT_IN6_ADDR -DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID \
|
||||
-DHAVE_SYS_TIME_H -DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
||||
-DHAVE_SIGNAL_H -DHAVE_SIG_ATOMIC_T -DRETSIGTYPE='void' \
|
||||
-DHAVE_PROCESS_H -DHAVE_ARPA_NAMESER_H -DHAVE_SYS_SOCKET_H \
|
||||
-DHAVE_IOCTLSOCKET_FIONBIO -DHAVE_STRUCT_IN6_ADDR \
|
||||
-DHAVE_SOCKADDR_IN6_SIN6_SCOPE_ID -DHAVE_SYS_TIME_H \
|
||||
-DHAVE_STRUCT_SOCKADDR_IN6 -DHAVE_STRUCT_ADDRINFO \
|
||||
-DHAVE_ARPA_NAMESER_H -DHAVE_ARPA_INET_H -DHAVE_SYS_SOCKET_H \
|
||||
-DHAVE_SYS_UIO_H -DHAVE_NETINET_IN_H -DHAVE_NETINET_TCP_H \
|
||||
-DNS_INADDRSZ=4 -DHAVE_RECV -DHAVE_SEND -DHAVE_GETTIMEOFDAY \
|
||||
-DSEND_TYPE_ARG1='int' -DSEND_QUAL_ARG2='const' \
|
||||
@@ -29,7 +29,7 @@ CFLAGS += -DWATT32 -DHAVE_AF_INET6 -DHAVE_PF_INET6 -DHAVE_IOCTLSOCKET \
|
||||
-DRECVFROM_TYPE_ARG6='int' -DRECVFROM_TYPE_RETV='int' \
|
||||
-DRECVFROM_TYPE_ARG5='struct sockaddr' -DHAVE_RECVFROM \
|
||||
-DRECVFROM_TYPE_ARG2_IS_VOID -DHAVE_STRDUP -DHAVE_NETDB_H \
|
||||
-DHAVE_ARPA_INET_H -DHAVE_STRCASECMP -DHAVE_STRNCASECMP
|
||||
-DHAVE_STRCASECMP -DHAVE_STRNCASECMP -DHAVE_GETHOSTNAME
|
||||
|
||||
LDFLAGS = -s
|
||||
|
||||
|
||||
@@ -18,5 +18,6 @@ MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \
|
||||
ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \
|
||||
ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \
|
||||
ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 \
|
||||
ares_getsock.3 ares_parse_ns_reply.3 \
|
||||
ares_destroy_options.3 ares_save_options.3
|
||||
ares_getsock.3 ares_parse_ns_reply.3 ares_dup.3 \
|
||||
ares_destroy_options.3 ares_save_options.3 ares_gethostbyname_file.3 \
|
||||
ares_set_socket_callback.3
|
||||
|
||||
@@ -350,12 +350,14 @@ endif
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@
|
||||
|
||||
@@ -26,7 +26,7 @@ OBJ_DIR = VC6_obj
|
||||
DEF_FILE = cares.def
|
||||
|
||||
!if "$(USE_WATT32)" == "1"
|
||||
CFLAGS = $(CFLAGS) -UWIN32 -DWATT32 -I$(WATT_ROOT)\inc
|
||||
CFLAGS = $(CFLAGS) -UWIN32 -DWATT32 -D_USE_32BIT_TIME_T -I$(WATT_ROOT)\inc
|
||||
EX_LIBS = $(WATT_ROOT)\lib\wattcpvc_imp.lib
|
||||
|
||||
!else
|
||||
@@ -124,9 +124,11 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6
|
||||
@echo ares_inet_net_pton >> $@
|
||||
@echo ares_inet_ntop >> $@
|
||||
@echo ares_inet_pton >> $@
|
||||
@echo ares_writev >> $@
|
||||
@echo ares_getnameinfo >> $@
|
||||
@echo ares_parse_aaaa_reply >> $@
|
||||
!if "$(USE_WATT32)" == "0"
|
||||
@echo ares_writev >> $@
|
||||
!endif
|
||||
|
||||
ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib
|
||||
link $(LDFLAGS) -out:$@ $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib $(EX_LIBS)
|
||||
|
||||
@@ -11,7 +11,7 @@ c-ares is not API compatible with ares: a new name makes that more obvious to
|
||||
the public.
|
||||
|
||||
The full source code is available in the 'c-ares' release archives, and in the
|
||||
'ares' subdir of the curl CVS source repostitory.
|
||||
'ares' subdir of the curl CVS source repository.
|
||||
|
||||
If you find bugs, correct flaws, have questions or have comments in general in
|
||||
regard to c-ares (or by all means the original ares too), get in touch with us
|
||||
|
||||
@@ -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 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:
|
||||
|
||||
|
||||
and obviously Daniel Stenberg
|
||||
Yang Tse, Charles Hardin, Carlo Contavalli, Brad Spencer, Gerald Combs,
|
||||
Gregor Jasny
|
||||
|
||||
Have fun!
|
||||
|
||||
@@ -1433,154 +1433,6 @@ AC_DEFUN([TYPE_SIG_ATOMIC_T], [
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_CHECK_NONBLOCKING_SOCKET
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket to non-blocking state. There seems to exist
|
||||
dnl four known different ways, with the one used almost everywhere being POSIX
|
||||
dnl and XPG3, while the other different ways for different systems (old BSD,
|
||||
dnl Windows and Amiga).
|
||||
dnl
|
||||
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
|
||||
dnl O_NONBLOCK define is found but does not work. This condition is attempted
|
||||
dnl to get caught in this script by using an excessive number of #ifdefs...
|
||||
|
||||
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
|
||||
AC_MSG_CHECKING([non-blocking sockets style])
|
||||
nonblock="unknown"
|
||||
#
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for O_NONBLOCK test */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
/* */
|
||||
#if defined(sun) || defined(__sun__) || \
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
/* */
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error "O_NONBLOCK does not work on this platform"
|
||||
#endif
|
||||
]],[[
|
||||
/* O_NONBLOCK source test */
|
||||
int socket;
|
||||
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
|
||||
]])
|
||||
],[
|
||||
dnl the O_NONBLOCK test was fine
|
||||
nonblock="O_NONBLOCK"
|
||||
AC_DEFINE(HAVE_O_NONBLOCK, 1,
|
||||
[use O_NONBLOCK for non-blocking sockets])
|
||||
])
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for FIONBIO test */
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
]],[[
|
||||
/* FIONBIO source test (old-style unix) */
|
||||
int socket;
|
||||
int flags = ioctl(socket, FIONBIO, &flags);
|
||||
]])
|
||||
],[
|
||||
dnl FIONBIO test was good
|
||||
nonblock="FIONBIO"
|
||||
AC_DEFINE(HAVE_FIONBIO, 1,
|
||||
[use FIONBIO for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for ioctlsocket test (Windows) */
|
||||
#undef inline
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#ifdef HAVE_WINSOCK_H
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
]],[[
|
||||
/* ioctlsocket source code (Windows) */
|
||||
SOCKET sd;
|
||||
unsigned long flags = 0;
|
||||
sd = socket(0, 0, 0);
|
||||
ioctlsocket(sd, FIONBIO, &flags);
|
||||
]])
|
||||
],[
|
||||
dnl ioctlsocket test was good
|
||||
nonblock="ioctlsocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET, 1,
|
||||
[use ioctlsocket() for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_LINK_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for IoctlSocket test (Amiga?) */
|
||||
#include <sys/ioctl.h>
|
||||
]],[[
|
||||
/* IoctlSocket source code (Amiga?) */
|
||||
int socket;
|
||||
int flags = IoctlSocket(socket, FIONBIO, (long)1);
|
||||
]])
|
||||
],[
|
||||
dnl Ioctlsocket test was good
|
||||
nonblock="IoctlSocket"
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1,
|
||||
[use Ioctlsocket() for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
/* headers for SO_NONBLOCK test (BeOS) */
|
||||
#include <socket.h>
|
||||
]],[[
|
||||
/* SO_NONBLOCK source code (BeOS) */
|
||||
long b = 1;
|
||||
int socket;
|
||||
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
]])
|
||||
],[
|
||||
dnl the SO_NONBLOCK test was good
|
||||
nonblock="SO_NONBLOCK"
|
||||
AC_DEFINE(HAVE_SO_NONBLOCK, 1,
|
||||
[use SO_NONBLOCK for non-blocking sockets])
|
||||
])
|
||||
fi
|
||||
#
|
||||
AC_MSG_RESULT($nonblock)
|
||||
#
|
||||
if test "$nonblock" = "unknown"; then
|
||||
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
|
||||
[disabled non-blocking sockets])
|
||||
AC_MSG_WARN([non-block sockets disabled])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl TYPE_IN_ADDR_T
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for in_addr_t: it is used to receive the return code of inet_addr()
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#if defined(WIN32) && !defined(WATT32)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
36
ares/ares.h
36
ares/ares.h
@@ -1,7 +1,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* 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
|
||||
* software and its documentation for any purpose and without
|
||||
@@ -29,10 +29,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(_AIX) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
|
||||
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||
libc5-based Linux systems. Only include it on system that are known to
|
||||
require it! */
|
||||
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
||||
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
|
||||
@@ -51,8 +52,8 @@
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -180,12 +181,28 @@ typedef void (*ares_sock_state_cb)(void *data,
|
||||
|
||||
struct apattern;
|
||||
|
||||
/* NOTE about the ares_options struct to users and developers.
|
||||
|
||||
This struct will remain looking like this. It will not be extended nor
|
||||
shrunk in future releases, but all new options will be set by ares_set_*()
|
||||
options instead of with the ares_init_options() function.
|
||||
|
||||
Eventually (in a galaxy far far away), all options will be settable by
|
||||
ares_set_*() options and the ares_init_options() function will become
|
||||
deprecated.
|
||||
|
||||
When new options are added to c-ares, they are not added to this
|
||||
struct. And they are not "saved" with the ares_save_options() function but
|
||||
instead we encourage the use of the ares_dup() function. Needless to say,
|
||||
if you add config options to c-ares you need to make sure ares_dup()
|
||||
duplicates this new option.
|
||||
|
||||
*/
|
||||
struct ares_options {
|
||||
int flags;
|
||||
int timeout; /* in seconds or milliseconds, depending on options */
|
||||
int tries;
|
||||
int ndots;
|
||||
int rotate;
|
||||
unsigned short udp_port;
|
||||
unsigned short tcp_port;
|
||||
int socket_send_buffer_size;
|
||||
@@ -212,14 +229,21 @@ typedef void (*ares_host_callback)(void *arg, int status, int timeouts,
|
||||
struct hostent *hostent);
|
||||
typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
|
||||
char *node, char *service);
|
||||
typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
|
||||
int type, void *data);
|
||||
|
||||
int ares_init(ares_channel *channelptr);
|
||||
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
int optmask);
|
||||
int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask);
|
||||
int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||
int *optmask);
|
||||
void ares_destroy_options(struct ares_options *options);
|
||||
int ares_dup(ares_channel *dest, ares_channel src);
|
||||
void ares_destroy(ares_channel channel);
|
||||
void ares_cancel(ares_channel channel);
|
||||
void ares_set_socket_callback(ares_channel channel,
|
||||
ares_sock_create_callback callback,
|
||||
void *user_data);
|
||||
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
|
||||
ares_callback callback, void *arg);
|
||||
void ares_query(ares_channel channel, const char *name, int dnsclass,
|
||||
@@ -228,6 +252,8 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
|
||||
int type, ares_callback callback, void *arg);
|
||||
void ares_gethostbyname(ares_channel channel, const char *name, int family,
|
||||
ares_host_callback callback, void *arg);
|
||||
int ares_gethostbyname_file(ares_channel channel, const char *name,
|
||||
int family, struct hostent **host);
|
||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
int family, ares_host_callback callback, void *arg);
|
||||
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
|
||||
|
||||
43
ares/ares_dup.3
Normal file
43
ares/ares_dup.3
Normal 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
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
struct addr_query {
|
||||
/* Arguments passed to ares_gethostbyaddr() */
|
||||
ares_channel channel;
|
||||
union ares_addr addr;
|
||||
int family;
|
||||
struct ares_addr addr;
|
||||
ares_host_callback callback;
|
||||
void *arg;
|
||||
|
||||
@@ -66,8 +65,8 @@ static void addr_callback(void *arg, int status, int timeouts,
|
||||
unsigned char *abuf, int alen);
|
||||
static void end_aquery(struct addr_query *aquery, int status,
|
||||
struct hostent *host);
|
||||
static int file_lookup(union ares_addr *addr, int family, struct hostent **host);
|
||||
static void ptr_rr_name(char *name, int family, union ares_addr *addr);
|
||||
static int file_lookup(struct ares_addr *addr, struct hostent **host);
|
||||
static void ptr_rr_name(char *name, struct ares_addr *addr);
|
||||
|
||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
int family, ares_host_callback callback, void *arg)
|
||||
@@ -95,10 +94,10 @@ void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
|
||||
}
|
||||
aquery->channel = channel;
|
||||
if (family == AF_INET)
|
||||
memcpy(&aquery->addr.addr4, addr, sizeof(struct in_addr));
|
||||
memcpy(&aquery->addr.addrV4, addr, sizeof(struct in_addr));
|
||||
else
|
||||
memcpy(&aquery->addr.addr6, addr, sizeof(struct in6_addr));
|
||||
aquery->family = family;
|
||||
memcpy(&aquery->addr.addrV6, addr, sizeof(struct in6_addr));
|
||||
aquery->addr.family = family;
|
||||
aquery->callback = callback;
|
||||
aquery->arg = arg;
|
||||
aquery->remaining_lookups = channel->lookups;
|
||||
@@ -119,13 +118,13 @@ static void next_lookup(struct addr_query *aquery)
|
||||
switch (*p)
|
||||
{
|
||||
case 'b':
|
||||
ptr_rr_name(name, aquery->family, &aquery->addr);
|
||||
ptr_rr_name(name, &aquery->addr);
|
||||
aquery->remaining_lookups = p + 1;
|
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
|
||||
aquery);
|
||||
return;
|
||||
case 'f':
|
||||
status = file_lookup(&aquery->addr, aquery->family, &host);
|
||||
status = file_lookup(&aquery->addr, &host);
|
||||
|
||||
/* this status check below previously checked for !ARES_ENOTFOUND,
|
||||
but we should not assume that this single error code is the one
|
||||
@@ -150,11 +149,11 @@ static void addr_callback(void *arg, int status, int timeouts,
|
||||
aquery->timeouts += timeouts;
|
||||
if (status == ARES_SUCCESS)
|
||||
{
|
||||
if (aquery->family == AF_INET)
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr4,
|
||||
if (aquery->addr.family == AF_INET)
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4,
|
||||
sizeof(struct in_addr), AF_INET, &host);
|
||||
else
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addr6,
|
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV6,
|
||||
sizeof(struct in6_addr), AF_INET6, &host);
|
||||
end_aquery(aquery, status, host);
|
||||
}
|
||||
@@ -173,7 +172,7 @@ static void end_aquery(struct addr_query *aquery, int status,
|
||||
free(aquery);
|
||||
}
|
||||
|
||||
static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
||||
static int file_lookup(struct ares_addr *addr, struct hostent **host)
|
||||
{
|
||||
FILE *fp;
|
||||
int status;
|
||||
@@ -226,21 +225,21 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
||||
return ARES_EFILE;
|
||||
}
|
||||
}
|
||||
while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS)
|
||||
while ((status = ares__get_hostent(fp, addr->family, host)) == ARES_SUCCESS)
|
||||
{
|
||||
if (family != (*host)->h_addrtype)
|
||||
if (addr->family != (*host)->h_addrtype)
|
||||
{
|
||||
ares_free_hostent(*host);
|
||||
continue;
|
||||
}
|
||||
if (family == AF_INET)
|
||||
if (addr->family == AF_INET)
|
||||
{
|
||||
if (memcmp((*host)->h_addr, &addr->addr4, sizeof(struct in_addr)) == 0)
|
||||
if (memcmp((*host)->h_addr, &addr->addrV4, sizeof(struct in_addr)) == 0)
|
||||
break;
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
else if (addr->family == AF_INET6)
|
||||
{
|
||||
if (memcmp((*host)->h_addr, &addr->addr6, sizeof(struct in6_addr)) == 0)
|
||||
if (memcmp((*host)->h_addr, &addr->addrV6, sizeof(struct in6_addr)) == 0)
|
||||
break;
|
||||
}
|
||||
ares_free_hostent(*host);
|
||||
@@ -253,11 +252,11 @@ static int file_lookup(union ares_addr *addr, int family, struct hostent **host)
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ptr_rr_name(char *name, int family, union ares_addr *addr)
|
||||
static void ptr_rr_name(char *name, struct ares_addr *addr)
|
||||
{
|
||||
if (family == AF_INET)
|
||||
if (addr->family == AF_INET)
|
||||
{
|
||||
unsigned long laddr = ntohl(addr->addr4.s_addr);
|
||||
unsigned long laddr = ntohl(addr->addrV4.s_addr);
|
||||
int a1 = (int)((laddr >> 24) & 0xff);
|
||||
int a2 = (int)((laddr >> 16) & 0xff);
|
||||
int a3 = (int)((laddr >> 8) & 0xff);
|
||||
@@ -266,14 +265,17 @@ static void ptr_rr_name(char *name, int family, union ares_addr *addr)
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *bytes = (unsigned char *)&addr->addr6.s6_addr;
|
||||
unsigned char *bytes = (unsigned char *)&addr->addrV6.s6_addr;
|
||||
/* There are too many arguments to do this in one line using
|
||||
* minimally C89-compliant compilers */
|
||||
sprintf(name,
|
||||
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
|
||||
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
||||
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.",
|
||||
bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4,
|
||||
bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4,
|
||||
bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4,
|
||||
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4,
|
||||
bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4);
|
||||
sprintf(name+strlen(name),
|
||||
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
|
||||
bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4,
|
||||
bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4,
|
||||
bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4,
|
||||
|
||||
@@ -289,6 +289,33 @@ static int fake_hostent(const char *name, int family, ares_host_callback callbac
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This is an API method */
|
||||
int ares_gethostbyname_file(ares_channel channel, const char *name,
|
||||
int family, struct hostent **host)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* We only take the channel to ensure that ares_init() been called. */
|
||||
if(channel == NULL)
|
||||
{
|
||||
/* Anything will do, really. This seems fine, and is consistent with
|
||||
other error cases. */
|
||||
*host = NULL;
|
||||
return ARES_ENOTFOUND;
|
||||
}
|
||||
|
||||
/* Just chain to the internal implementation we use here; it's exactly
|
||||
* what we want.
|
||||
*/
|
||||
result = file_lookup(name, family, host);
|
||||
if(result != ARES_SUCCESS)
|
||||
{
|
||||
/* We guarantee a NULL hostent on failure. */
|
||||
*host = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int file_lookup(const char *name, int family, struct hostent **host)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -405,13 +432,13 @@ static int get_address_index(struct in_addr *addr, struct apattern *sortlist,
|
||||
continue;
|
||||
if (sortlist[i].type == PATTERN_MASK)
|
||||
{
|
||||
if ((addr->s_addr & sortlist[i].mask.addr.addr4.s_addr)
|
||||
== sortlist[i].addr.addr4.s_addr)
|
||||
if ((addr->s_addr & sortlist[i].mask.addr4.s_addr)
|
||||
== sortlist[i].addrV4.s_addr)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addr.addr4.s_addr,
|
||||
if (!ares_bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr,
|
||||
sortlist[i].mask.bits))
|
||||
break;
|
||||
}
|
||||
@@ -458,7 +485,7 @@ static int get6_address_index(struct in6_addr *addr, struct apattern *sortlist,
|
||||
{
|
||||
if (sortlist[i].family != AF_INET6)
|
||||
continue;
|
||||
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addr.addr6.s6_addr, sortlist[i].mask.bits))
|
||||
if (!ares_bitncmp(&addr->s6_addr, &sortlist[i].addrV6.s6_addr, sortlist[i].mask.bits))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
|
||||
84
ares/ares_gethostbyname_file.3
Normal file
84
ares/ares_gethostbyname_file.3
Normal 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.
|
||||
@@ -225,6 +225,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, struct hosten
|
||||
We do this by determining our own domain name, then searching the string
|
||||
for this domain name and removing it.
|
||||
*/
|
||||
#ifdef HAVE_GETHOSTNAME
|
||||
if (niquery->flags & ARES_NI_NOFQDN)
|
||||
{
|
||||
char buf[255];
|
||||
@@ -237,6 +238,7 @@ static void nameinfo_callback(void *arg, int status, int timeouts, struct hosten
|
||||
*end = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name),
|
||||
service);
|
||||
return;
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
|
||||
int ares_getopt(int nargc, char * const nargv[], const char *ostr);
|
||||
|
||||
#if defined(WATT32)
|
||||
#undef optarg
|
||||
#undef optind
|
||||
#undef opterr
|
||||
#endif
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
|
||||
@@ -154,7 +154,7 @@ recursion for you. Recursion must be handled by the application calling ares
|
||||
if \fIARES_FLAG_NORECURSE\fP is set.
|
||||
.TP 23
|
||||
.B ARES_FLAG_STAYOPEN
|
||||
Do not close communciations sockets when the number of active queries
|
||||
Do not close communications sockets when the number of active queries
|
||||
drops to zero.
|
||||
.TP 23
|
||||
.B ARES_FLAG_NOSEARCH
|
||||
@@ -185,7 +185,8 @@ A configuration file could not be read.
|
||||
.B ARES_ENOMEM
|
||||
The process's available memory was exhausted.
|
||||
.SH SEE ALSO
|
||||
.BR ares_destroy (3)
|
||||
.BR ares_destroy(3),
|
||||
.BR ares_dup(3)
|
||||
.SH AUTHOR
|
||||
Greg Hudson, MIT Information Systems
|
||||
.br
|
||||
|
||||
@@ -159,6 +159,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
channel->servers = NULL;
|
||||
channel->sock_state_cb = NULL;
|
||||
channel->sock_state_cb_data = NULL;
|
||||
channel->sock_create_cb = NULL;
|
||||
channel->sock_create_cb_data = NULL;
|
||||
|
||||
channel->last_server = 0;
|
||||
channel->last_timeout_processed = (time_t)now.tv_sec;
|
||||
@@ -179,7 +181,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
*/
|
||||
|
||||
if (status == ARES_SUCCESS) {
|
||||
status = init_by_options(channel, options, optmask);
|
||||
status = init_by_options(channel, options, optmask);
|
||||
if (status != ARES_SUCCESS)
|
||||
DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
|
||||
ares_strerror(status)));
|
||||
@@ -257,6 +259,40 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
/* ares_dup() duplicates a channel handle with all its options and returns a
|
||||
new channel handle */
|
||||
int ares_dup(ares_channel *dest, ares_channel src)
|
||||
{
|
||||
struct ares_options opts;
|
||||
int rc;
|
||||
int optmask;
|
||||
|
||||
*dest = NULL; /* in case of failure return NULL explicitly */
|
||||
|
||||
/* First get the options supported by the old ares_save_options() function,
|
||||
which is most of them */
|
||||
rc = ares_save_options(src, &opts, &optmask);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
/* Then create the new channel with those options */
|
||||
rc = ares_init_options(dest, &opts, optmask);
|
||||
|
||||
/* destroy the options copy to not leak any memory */
|
||||
ares_destroy_options(&opts);
|
||||
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
/* Now clone the options that ares_save_options() doesn't support. */
|
||||
(*dest)->sock_create_cb = src->sock_create_cb;
|
||||
(*dest)->sock_create_cb_data = src->sock_create_cb_data;
|
||||
|
||||
|
||||
return ARES_SUCCESS; /* everything went fine */
|
||||
|
||||
}
|
||||
|
||||
/* Save options from initialized channel */
|
||||
int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||
int *optmask)
|
||||
@@ -269,10 +305,14 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||
if (!ARES_CONFIG_CHECK(channel))
|
||||
return ARES_ENODATA;
|
||||
|
||||
/* Traditionally the optmask wasn't saved in the channel struct so it was
|
||||
recreated here. ROTATE is the first option that has no struct field of
|
||||
its own in the public config struct */
|
||||
(*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
|
||||
ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
|
||||
ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
|
||||
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
|
||||
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
|
||||
(channel->optmask & ARES_OPT_ROTATE);
|
||||
|
||||
/* Copy easy stuff */
|
||||
options->flags = channel->flags;
|
||||
@@ -355,7 +395,7 @@ static int init_by_options(ares_channel channel,
|
||||
if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
|
||||
channel->ndots = options->ndots;
|
||||
if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
|
||||
channel->rotate = options->rotate;
|
||||
channel->rotate = 1;
|
||||
if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
|
||||
channel->udp_port = options->udp_port;
|
||||
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
|
||||
@@ -426,11 +466,14 @@ static int init_by_options(ares_channel channel,
|
||||
return ARES_ENOMEM;
|
||||
for (i = 0; i < options->nsort; i++)
|
||||
{
|
||||
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]), sizeof(struct apattern));
|
||||
memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
|
||||
sizeof(struct apattern));
|
||||
}
|
||||
channel->nsort = options->nsort;
|
||||
}
|
||||
|
||||
channel->optmask = optmask;
|
||||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -966,7 +1009,9 @@ static int init_by_defaults(ares_channel channel)
|
||||
*/
|
||||
size_t len = 64;
|
||||
int res;
|
||||
channel->ndomains = 0; /* default to none */
|
||||
|
||||
#ifdef HAVE_GETHOSTNAME
|
||||
hostname = malloc(len);
|
||||
if(!hostname) {
|
||||
rc = ARES_ENOMEM;
|
||||
@@ -994,7 +1039,6 @@ static int init_by_defaults(ares_channel channel)
|
||||
|
||||
} while(0);
|
||||
|
||||
channel->ndomains = 0; /* default to none */
|
||||
if (strchr(hostname, '.')) {
|
||||
/* a dot was found */
|
||||
|
||||
@@ -1010,6 +1054,7 @@ static int init_by_defaults(ares_channel channel)
|
||||
}
|
||||
channel->ndomains = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (channel->nsort == -1) {
|
||||
@@ -1179,8 +1224,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
/* Lets see if it is CIDR */
|
||||
/* First we'll try IPv6 */
|
||||
if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
|
||||
&pat.addr.addr6,
|
||||
sizeof(pat.addr.addr6))) > 0)
|
||||
&pat.addrV6,
|
||||
sizeof(pat.addrV6))) > 0)
|
||||
{
|
||||
pat.type = PATTERN_CIDR;
|
||||
pat.mask.bits = (unsigned short)bits;
|
||||
@@ -1189,8 +1234,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
if (ipbufpfx[0] &&
|
||||
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addr.addr4,
|
||||
sizeof(pat.addr.addr4))) > 0)
|
||||
(bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
|
||||
sizeof(pat.addrV4))) > 0)
|
||||
{
|
||||
pat.type = PATTERN_CIDR;
|
||||
pat.mask.bits = (unsigned short)bits;
|
||||
@@ -1199,13 +1244,13 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
return ARES_ENOMEM;
|
||||
}
|
||||
/* See if it is just a regular IP */
|
||||
else if (ip_addr(ipbuf, (int)(q-str), &pat.addr.addr4) == 0)
|
||||
else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
|
||||
{
|
||||
if (ipbufpfx[0])
|
||||
{
|
||||
memcpy(ipbuf, str, (int)(q-str));
|
||||
ipbuf[(int)(q-str)] = '\0';
|
||||
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr.addr4) != 0)
|
||||
if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
|
||||
natural_mask(&pat);
|
||||
}
|
||||
else
|
||||
@@ -1420,17 +1465,17 @@ static void natural_mask(struct apattern *pat)
|
||||
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
|
||||
* but portable.
|
||||
*/
|
||||
addr.s_addr = ntohl(pat->addr.addr4.s_addr);
|
||||
addr.s_addr = ntohl(pat->addrV4.s_addr);
|
||||
|
||||
/* This is out of date in the CIDR world, but some people might
|
||||
* still rely on it.
|
||||
*/
|
||||
if (IN_CLASSA(addr.s_addr))
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSA_NET);
|
||||
pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
|
||||
else if (IN_CLASSB(addr.s_addr))
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSB_NET);
|
||||
pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
|
||||
else
|
||||
pat->mask.addr.addr4.s_addr = htonl(IN_CLASSC_NET);
|
||||
pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
|
||||
}
|
||||
#endif
|
||||
/* initialize an rc4 key. If possible a cryptographically secure random key
|
||||
@@ -1503,9 +1548,17 @@ static int init_id_key(rc4_key* key,int key_data_len)
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
short ares__generate_new_id(rc4_key* key)
|
||||
unsigned short ares__generate_new_id(rc4_key* key)
|
||||
{
|
||||
short r=0;
|
||||
unsigned short r=0;
|
||||
ares__rc4(key, (unsigned char *)&r, sizeof(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
void ares_set_socket_callback(ares_channel channel,
|
||||
ares_sock_create_callback cb,
|
||||
void *data)
|
||||
{
|
||||
channel->sock_create_cb = cb;
|
||||
channel->sock_create_cb_data = data;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
@@ -55,6 +55,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
||||
char *ptrname, *hostname, *rr_name, *rr_data;
|
||||
struct hostent *hostent;
|
||||
int aliascnt = 0;
|
||||
int alias_alloc = 8;
|
||||
char ** aliases;
|
||||
|
||||
/* Set *host to NULL for all failure cases. */
|
||||
@@ -84,7 +85,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
|
||||
|
||||
/* Examine each answer resource record (RR) in turn. */
|
||||
hostname = NULL;
|
||||
aliases = malloc(8 * sizeof(char *));
|
||||
aliases = malloc(alias_alloc * sizeof(char *));
|
||||
if (!aliases)
|
||||
{
|
||||
free(ptrname);
|
||||
@@ -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);
|
||||
aliascnt++;
|
||||
if ((aliascnt%8)==0)
|
||||
aliases = realloc(aliases, (aliascnt/16+1) * sizeof(char *));
|
||||
if (aliascnt >= alias_alloc) {
|
||||
char **ptr;
|
||||
alias_alloc *= 2;
|
||||
ptr = realloc(aliases, alias_alloc * sizeof(char *));
|
||||
if(!ptr) {
|
||||
status = ARES_ENOMEM;
|
||||
break;
|
||||
}
|
||||
aliases = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (rr_class == C_IN && rr_type == T_CNAME)
|
||||
|
||||
@@ -115,6 +115,16 @@
|
||||
# define writev(s,ptr,cnt) ares_writev(s,ptr,cnt)
|
||||
#endif
|
||||
|
||||
struct ares_addr {
|
||||
int family;
|
||||
union {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
} addr;
|
||||
};
|
||||
#define addrV4 addr.addr4
|
||||
#define addrV6 addr.addr6
|
||||
|
||||
struct query;
|
||||
|
||||
struct send_request {
|
||||
@@ -213,17 +223,17 @@ struct query_server_info {
|
||||
#define PATTERN_MASK 0x1
|
||||
#define PATTERN_CIDR 0x2
|
||||
|
||||
union ares_addr {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
};
|
||||
|
||||
struct apattern {
|
||||
union ares_addr addr;
|
||||
union
|
||||
{
|
||||
union ares_addr addr;
|
||||
unsigned short bits;
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
} addr;
|
||||
union
|
||||
{
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
unsigned short bits;
|
||||
} mask;
|
||||
int family;
|
||||
unsigned short type;
|
||||
@@ -253,6 +263,8 @@ struct ares_channeldata {
|
||||
int nsort;
|
||||
char *lookups;
|
||||
|
||||
int optmask; /* the option bitfield passed in at init time */
|
||||
|
||||
/* Server addresses and communications state */
|
||||
struct server_state *servers;
|
||||
int nservers;
|
||||
@@ -284,6 +296,9 @@ struct ares_channeldata {
|
||||
|
||||
ares_sock_state_cb sock_state_cb;
|
||||
void *sock_state_cb_data;
|
||||
|
||||
ares_sock_create_callback sock_create_cb;
|
||||
void *sock_create_cb_data;
|
||||
};
|
||||
|
||||
/* return true if now is exactly check time or later */
|
||||
@@ -302,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__read_line(FILE *fp, char **buf, int *bufsize);
|
||||
void ares__free_query(struct query *query);
|
||||
short ares__generate_new_id(rc4_key* key);
|
||||
unsigned short ares__generate_new_id(rc4_key* key);
|
||||
struct timeval ares__tvnow(void);
|
||||
#if 0 /* Not used */
|
||||
long ares__tvdiff(struct timeval t1, struct timeval t2);
|
||||
|
||||
@@ -805,68 +805,51 @@ void ares__send_query(ares_channel channel, struct query *query,
|
||||
static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
#if defined(USE_BLOCKING_SOCKETS)
|
||||
|
||||
return 0; /* returns success */
|
||||
|
||||
#elif defined(HAVE_FCNTL_O_NONBLOCK)
|
||||
|
||||
/* most recent unix versions */
|
||||
int flags;
|
||||
|
||||
flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if (FALSE != nonblock)
|
||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 1
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||
#elif defined(HAVE_IOCTL_FIONBIO)
|
||||
|
||||
/* older unix versions */
|
||||
int flags;
|
||||
|
||||
flags = nonblock;
|
||||
return ioctl(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 2
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||
#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
|
||||
|
||||
#ifdef WATT32
|
||||
char flags;
|
||||
#else
|
||||
/* Windows? */
|
||||
/* Windows */
|
||||
unsigned long flags;
|
||||
#endif
|
||||
flags = nonblock;
|
||||
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 3
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||
/* presumably for Amiga */
|
||||
#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
|
||||
|
||||
/* Amiga */
|
||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 4
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
|
||||
|
||||
/* BeOS */
|
||||
long b = nonblock ? 1 : 0;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 5
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||
return 0; /* returns success */
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 6
|
||||
#endif
|
||||
|
||||
#if (SETBLOCK == 0)
|
||||
#error "no non-blocking method was found/used/set"
|
||||
#else
|
||||
# error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -914,6 +897,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef TCP_NODELAY
|
||||
/*
|
||||
* Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in
|
||||
* configure_socket). In general, in DNS lookups we're pretty much interested
|
||||
@@ -927,6 +911,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server)
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Connect to the server. */
|
||||
memset(&sockin, 0, sizeof(sockin));
|
||||
@@ -944,6 +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);
|
||||
server->tcp_buffer_pos = 0;
|
||||
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);
|
||||
|
||||
server->udp_socket = s;
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
@@ -67,7 +70,7 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
|
||||
key->y = y;
|
||||
}
|
||||
|
||||
static struct query* find_query_by_id(ares_channel channel, int id)
|
||||
static struct query* find_query_by_id(ares_channel channel, unsigned short id)
|
||||
{
|
||||
unsigned short qid;
|
||||
struct list_node* list_head;
|
||||
@@ -92,15 +95,15 @@ static struct query* find_query_by_id(ares_channel channel, int id)
|
||||
performed per id generation. In practice this search should happen only
|
||||
once per newly generated id
|
||||
*/
|
||||
static int generate_unique_id(ares_channel channel)
|
||||
static unsigned short generate_unique_id(ares_channel channel)
|
||||
{
|
||||
int id;
|
||||
unsigned short id;
|
||||
|
||||
do {
|
||||
id = ares__generate_new_id(&channel->id_key);
|
||||
} while (find_query_by_id(channel,id));
|
||||
id = ares__generate_new_id(&channel->id_key);
|
||||
} while (find_query_by_id(channel, id));
|
||||
|
||||
return id;
|
||||
return (unsigned short)id;
|
||||
}
|
||||
|
||||
void ares_query(ares_channel channel, const char *name, int dnsclass,
|
||||
|
||||
@@ -24,9 +24,7 @@ ares_save_options \- Save configuration values obtained from initialized ares_ch
|
||||
.B void ares_save_options(ares_channel \fIchannel\fP, struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B ares_save_options
|
||||
function saves the channel data identified by
|
||||
The \fBares_save_options(3)\fP function saves the channel data identified by
|
||||
.IR channel ,
|
||||
into the options struct identified by
|
||||
.IR options ,
|
||||
@@ -38,11 +36,18 @@ The resultant options and optmask are then able to be
|
||||
passed directly to ares_init_options. When the options
|
||||
are no longer needed, ares_destroy_options should be called
|
||||
to free any associated memory.
|
||||
|
||||
|
||||
.SH NOTE
|
||||
Since c-ares 1.6.0 the ares_options struct has been "locked" meaning that it
|
||||
won't be extended to cover new funtions. This function will remain
|
||||
functioning, but it can only return config data that can be represented in
|
||||
this config struct, which may no longer be the complete set of config
|
||||
options. \fBares_dup(3)\fP will not have that restriction.
|
||||
.SH SEE ALSO
|
||||
.BR ares_destroy_options (3),
|
||||
.BR ares_init_options (3)
|
||||
.BR ares_init_options (3),
|
||||
.BR ares_dup (3)
|
||||
.SH AVAILABILITY
|
||||
ares_save_options(3) was added in c-ares 1.4.0
|
||||
.SH AUTHOR
|
||||
Brad House
|
||||
.br
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
24
ares/ares_set_socket_callback.3
Normal file
24
ares/ares_set_socket_callback.3
Normal 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
|
||||
|
||||
@@ -1,6 +1,44 @@
|
||||
#!/bin/sh
|
||||
|
||||
${LIBTOOLIZE:-libtoolize} --copy --automake --force
|
||||
# The logic for finding the right libtoolize is taken from libcurl's buildconf
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# findtool works as 'which' but we use a different name to make it more
|
||||
# obvious we aren't using 'which'! ;-)
|
||||
#
|
||||
findtool(){
|
||||
file="$1"
|
||||
|
||||
old_IFS=$IFS; IFS=':'
|
||||
for path in $PATH
|
||||
do
|
||||
IFS=$old_IFS
|
||||
# echo "checks for $file in $path" >&2
|
||||
if test -f "$path/$file"; then
|
||||
echo "$path/$file"
|
||||
return
|
||||
fi
|
||||
done
|
||||
IFS=$old_IFS
|
||||
}
|
||||
|
||||
# this approach that tries 'glibtool' first is some kind of work-around for
|
||||
# some BSD-systems I believe that use to provide the GNU libtool named
|
||||
# glibtool, with 'libtool' being something completely different.
|
||||
libtool=`findtool glibtool 2>/dev/null`
|
||||
if test ! -x "$libtool"; then
|
||||
libtool=`findtool ${LIBTOOL:-libtool}`
|
||||
fi
|
||||
|
||||
if test -z "$LIBTOOLIZE"; then
|
||||
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
|
||||
# $libtool is already the full path
|
||||
libtoolize="${libtool}ize"
|
||||
else
|
||||
libtoolize=`findtool $LIBTOOLIZE`
|
||||
fi
|
||||
|
||||
${libtoolize} --copy --automake --force
|
||||
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
|
||||
${AUTOHEADER:-autoheader}
|
||||
${AUTOCONF:-autoconf}
|
||||
|
||||
@@ -76,9 +76,12 @@
|
||||
/* FUNCTIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/* #define HAVE_STRCASECMP 1 */
|
||||
|
||||
@@ -94,6 +97,9 @@
|
||||
/* Define if you have the strnicmp function. */
|
||||
#define HAVE_STRNICMP 1
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
@@ -162,6 +168,15 @@
|
||||
#define SOCKET int
|
||||
#define NS_INADDRSZ 4
|
||||
#define HAVE_ARPA_NAMESER_H 1
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_NETDB_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
#define HAVE_AF_INET6 1
|
||||
#define HAVE_PF_INET6 1
|
||||
#define HAVE_STRUCT_IN6_ADDR 1
|
||||
#define HAVE_STRUCT_SOCKADDR_IN6 1
|
||||
#undef HAVE_WINSOCK_H
|
||||
#undef HAVE_WINSOCK2_H
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
@@ -4,6 +4,8 @@ dnl Version not hardcoded here. Fetched later from ares_version.h
|
||||
AC_INIT([c-ares], [-],
|
||||
[c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares])
|
||||
|
||||
CARES_OVERRIDE_AUTOCONF
|
||||
|
||||
AC_CONFIG_SRCDIR([ares_ipv6.h])
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
@@ -12,6 +14,8 @@ CARES_CHECK_OPTION_DEBUG
|
||||
CARES_CHECK_OPTION_OPTIMIZE
|
||||
CARES_CHECK_OPTION_WARNINGS
|
||||
|
||||
CARES_CHECK_PATH_SEPARATOR
|
||||
|
||||
dnl SED is mandatory for configure process and libtool.
|
||||
dnl Set it now, allowing it to be changed later.
|
||||
AC_PATH_PROG([SED], [sed], [not_found],
|
||||
@@ -95,22 +99,6 @@ CARES_PROCESS_DEBUG_BUILD_OPTS
|
||||
AM_CONDITIONAL(DEBUGBUILD, test x$want_debug = xyes)
|
||||
AM_CONDITIONAL(CURLDEBUG, test x$want_debug = xyes)
|
||||
|
||||
dnl skip libtool C++ and Fortran compiler checks
|
||||
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
|
||||
m4_defun([AC_PROG_CXX],[])
|
||||
m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])])
|
||||
m4_defun([AC_PROG_CXXCPP],[true])
|
||||
m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])])
|
||||
m4_defun([AC_PROG_F77],[])
|
||||
|
||||
dnl skip libtool C++ and Fortran linker checks
|
||||
m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])])
|
||||
m4_defun([AC_LIBTOOL_CXX],[])
|
||||
m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])])
|
||||
m4_defun([AC_LIBTOOL_CXXCPP],[true])
|
||||
m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])])
|
||||
m4_defun([AC_LIBTOOL_F77],[])
|
||||
|
||||
dnl force libtool to build static libraries with PIC on AMD64-Linux & FreeBSD
|
||||
AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
|
||||
case $host in
|
||||
@@ -342,9 +330,7 @@ then
|
||||
fi
|
||||
|
||||
|
||||
if test "$HAVE_GETHOSTBYNAME" = "1"; then
|
||||
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
|
||||
else
|
||||
if test "$HAVE_GETHOSTBYNAME" != "1"; then
|
||||
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
|
||||
fi
|
||||
|
||||
@@ -553,12 +539,19 @@ CURL_CHECK_FUNC_RECVFROM
|
||||
CURL_CHECK_FUNC_SEND
|
||||
CURL_CHECK_MSG_NOSIGNAL
|
||||
|
||||
CARES_CHECK_FUNC_FCNTL
|
||||
CARES_CHECK_FUNC_FREEADDRINFO
|
||||
CARES_CHECK_FUNC_GETADDRINFO
|
||||
CARES_CHECK_FUNC_GETHOSTBYADDR
|
||||
CARES_CHECK_FUNC_GETHOSTBYNAME
|
||||
CARES_CHECK_FUNC_GETHOSTNAME
|
||||
CARES_CHECK_FUNC_GETSERVBYPORT_R
|
||||
CARES_CHECK_FUNC_INET_NTOP
|
||||
CARES_CHECK_FUNC_INET_PTON
|
||||
CARES_CHECK_FUNC_IOCTL
|
||||
CARES_CHECK_FUNC_IOCTLSOCKET
|
||||
CARES_CHECK_FUNC_IOCTLSOCKET_CAMEL
|
||||
CARES_CHECK_FUNC_SETSOCKOPT
|
||||
CARES_CHECK_FUNC_STRCASECMP
|
||||
CARES_CHECK_FUNC_STRCMPI
|
||||
CARES_CHECK_FUNC_STRDUP
|
||||
@@ -851,8 +844,6 @@ dnl and get the types of five of its arguments.
|
||||
CURL_CHECK_FUNC_GETNAMEINFO
|
||||
|
||||
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
AC_C_BIGENDIAN(
|
||||
[AC_DEFINE(ARES_BIG_ENDIAN, 1,
|
||||
[define this if ares is built for a big endian system])],
|
||||
@@ -883,6 +874,9 @@ if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then
|
||||
[a suitable file/device to read random data from])
|
||||
fi
|
||||
|
||||
CARES_CHECK_OPTION_NONBLOCKING
|
||||
CARES_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
CARES_PRIVATE_LIBS="$LIBS"
|
||||
AC_SUBST(CARES_PRIVATE_LIBS)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#***************************************************************************
|
||||
|
||||
# File version for 'aclocal' use. Keep it a single number.
|
||||
# serial 45
|
||||
# serial 46
|
||||
|
||||
|
||||
dnl CARES_CHECK_COMPILER
|
||||
@@ -875,6 +875,13 @@ AC_DEFUN([CARES_SET_COMPILER_WARNING_OPTS], [
|
||||
tmp_CFLAGS="$tmp_CFLAGS -Wdeclaration-after-statement"
|
||||
fi
|
||||
#
|
||||
dnl Only gcc 4.3 or later
|
||||
if test "$compiler_num" -ge "403"; then
|
||||
tmp_CFLAGS="$tmp_CFLAGS -Wtype-limits -Wold-style-declaration"
|
||||
tmp_CFLAGS="$tmp_CFLAGS -Wmissing-parameter-type -Wempty-body"
|
||||
tmp_CFLAGS="$tmp_CFLAGS -Wclobbered -Wignored-qualifiers"
|
||||
fi
|
||||
#
|
||||
fi
|
||||
#
|
||||
dnl Do not issue warnings for code in system include paths.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#***************************************************************************
|
||||
|
||||
# File version for 'aclocal' use. Keep it a single number.
|
||||
# serial 2
|
||||
# serial 3
|
||||
|
||||
|
||||
dnl CARES_CHECK_OPTION_DEBUG
|
||||
@@ -52,6 +52,38 @@ AC_HELP_STRING([--disable-debug],[Disable debug build options]),
|
||||
])
|
||||
|
||||
|
||||
dnl CARES_CHECK_OPTION_NONBLOCKING
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify if configure has been invoked with option
|
||||
dnl --enable-nonblocking or --disable-nonblocking, and
|
||||
dnl set shell variable want_nonblocking as appropriate.
|
||||
|
||||
AC_DEFUN([CARES_CHECK_OPTION_NONBLOCKING], [
|
||||
AC_BEFORE([$0],[CARES_CHECK_NONBLOCKING_SOCKET])dnl
|
||||
AC_MSG_CHECKING([whether to enable non-blocking communications])
|
||||
OPT_NONBLOCKING="default"
|
||||
AC_ARG_ENABLE(nonblocking,
|
||||
AC_HELP_STRING([--enable-nonblocking],[Enable non-blocking communications])
|
||||
AC_HELP_STRING([--disable-nonblocking],[Disable non-blocking communications]),
|
||||
OPT_NONBLOCKING=$enableval)
|
||||
case "$OPT_NONBLOCKING" in
|
||||
no)
|
||||
dnl --disable-nonblocking option used
|
||||
want_nonblocking="no"
|
||||
;;
|
||||
default)
|
||||
dnl configure option not specified
|
||||
want_nonblocking="yes"
|
||||
;;
|
||||
*)
|
||||
dnl --enable-nonblocking option used
|
||||
want_nonblocking="yes"
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$want_nonblocking])
|
||||
])
|
||||
|
||||
|
||||
dnl CARES_CHECK_OPTION_OPTIMIZE
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify if configure has been invoked with option
|
||||
@@ -140,3 +172,43 @@ AC_HELP_STRING([--disable-warnings],[Disable strict compiler warnings]),
|
||||
esac
|
||||
AC_MSG_RESULT([$want_warnings])
|
||||
])
|
||||
|
||||
|
||||
dnl CARES_CHECK_NONBLOCKING_SOCKET
|
||||
dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket into non-blocking state.
|
||||
|
||||
AC_DEFUN([CARES_CHECK_NONBLOCKING_SOCKET], [
|
||||
AC_REQUIRE([CARES_CHECK_OPTION_NONBLOCKING])dnl
|
||||
AC_REQUIRE([CARES_CHECK_FUNC_FCNTL])dnl
|
||||
AC_REQUIRE([CARES_CHECK_FUNC_IOCTL])dnl
|
||||
AC_REQUIRE([CARES_CHECK_FUNC_IOCTLSOCKET])dnl
|
||||
AC_REQUIRE([CARES_CHECK_FUNC_IOCTLSOCKET_CAMEL])dnl
|
||||
AC_REQUIRE([CARES_CHECK_FUNC_SETSOCKOPT])dnl
|
||||
#
|
||||
tst_method="unknown"
|
||||
if test "$want_nonblocking" = "yes"; then
|
||||
AC_MSG_CHECKING([how to set a socket into non-blocking mode])
|
||||
if test "x$ac_cv_func_fcntl_o_nonblock" = "xyes"; then
|
||||
tst_method="fcntl O_NONBLOCK"
|
||||
elif test "x$ac_cv_func_ioctl_fionbio" = "xyes"; then
|
||||
tst_method="ioctl FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_fionbio" = "xyes"; then
|
||||
tst_method="ioctlsocket FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_camel_fionbio" = "xyes"; then
|
||||
tst_method="IoctlSocket FIONBIO"
|
||||
elif test "x$ac_cv_func_setsockopt_so_nonblock" = "xyes"; then
|
||||
tst_method="setsockopt SO_NONBLOCK"
|
||||
fi
|
||||
AC_MSG_RESULT([$tst_method])
|
||||
if test "$tst_method" = "unknown"; then
|
||||
AC_MSG_WARN([cannot determine non-blocking socket method.])
|
||||
fi
|
||||
fi
|
||||
if test "$tst_method" = "unknown"; then
|
||||
AC_DEFINE_UNQUOTED(USE_BLOCKING_SOCKETS, 1,
|
||||
[Define to disable non-blocking sockets.])
|
||||
AC_MSG_WARN([non-blocking sockets disabled.])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
103
ares/m4/cares-override.m4
Normal file
103
ares/m4/cares-override.m4
Normal 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
74
ares/m4/cares-system.m4
Normal 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])
|
||||
])
|
||||
|
||||
|
||||
28
ares/setup.h
28
ares/setup.h
@@ -107,6 +107,18 @@
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
|
||||
#define HAVE_SYS_TIME_H
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
|
||||
#define HAVE_SYS_UIO_H
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/*
|
||||
@@ -123,22 +135,6 @@
|
||||
#undef VERSION
|
||||
#undef PACKAGE
|
||||
|
||||
/*
|
||||
* Assume a few thing unless they're set by configure
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
|
||||
#define HAVE_SYS_TIME_H
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
|
||||
#define HAVE_SYS_UIO_H
|
||||
#endif
|
||||
|
||||
/* IPv6 compatibility */
|
||||
#if !defined(HAVE_AF_INET6)
|
||||
#if defined(HAVE_PF_INET6)
|
||||
|
||||
63
configure.ac
63
configure.ac
@@ -27,6 +27,8 @@ AC_PREREQ(2.57)
|
||||
dnl We don't know the version number "statically" so we use a dash here
|
||||
AC_INIT([curl], [-], [a suitable curl mailing list => http://curl.haxx.se/mail/])
|
||||
|
||||
CURL_OVERRIDE_AUTOCONF
|
||||
|
||||
dnl configure script copyright
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2008 Daniel Stenberg, <daniel@haxx.se>
|
||||
This configure script may be copied, distributed and modified under the
|
||||
@@ -40,6 +42,8 @@ CURL_CHECK_OPTION_DEBUG
|
||||
CURL_CHECK_OPTION_OPTIMIZE
|
||||
CURL_CHECK_OPTION_WARNINGS
|
||||
|
||||
CURL_CHECK_PATH_SEPARATOR
|
||||
|
||||
dnl SED is mandatory for configure process and libtool.
|
||||
dnl Set it now, allowing it to be changed later.
|
||||
AC_PATH_PROG([SED], [sed], [not_found],
|
||||
@@ -153,22 +157,6 @@ AC_LIBTOOL_WIN32_DLL
|
||||
|
||||
CURL_PROCESS_DEBUG_BUILD_OPTS
|
||||
|
||||
dnl skip libtool C++ and Fortran compiler checks
|
||||
m4_ifdef([AC_PROG_CXX], [m4_undefine([AC_PROG_CXX])])
|
||||
m4_defun([AC_PROG_CXX],[])
|
||||
m4_ifdef([AC_PROG_CXXCPP], [m4_undefine([AC_PROG_CXXCPP])])
|
||||
m4_defun([AC_PROG_CXXCPP],[true])
|
||||
m4_ifdef([AC_PROG_F77], [m4_undefine([AC_PROG_F77])])
|
||||
m4_defun([AC_PROG_F77],[])
|
||||
|
||||
dnl skip libtool C++ and Fortran linker checks
|
||||
m4_ifdef([AC_LIBTOOL_CXX], [m4_undefine([AC_LIBTOOL_CXX])])
|
||||
m4_defun([AC_LIBTOOL_CXX],[])
|
||||
m4_ifdef([AC_LIBTOOL_CXXCPP], [m4_undefine([AC_LIBTOOL_CXXCPP])])
|
||||
m4_defun([AC_LIBTOOL_CXXCPP],[true])
|
||||
m4_ifdef([AC_LIBTOOL_F77], [m4_undefine([AC_LIBTOOL_F77])])
|
||||
m4_defun([AC_LIBTOOL_F77],[])
|
||||
|
||||
dnl force libtool to build static libraries with PIC on AMD64-Linux & FreeBSD
|
||||
AC_MSG_CHECKING([if arch-OS host is AMD64-Linux/FreeBSD (to build static libraries with PIC)])
|
||||
case $host in
|
||||
@@ -658,9 +646,7 @@ then
|
||||
fi
|
||||
|
||||
|
||||
if test "$HAVE_GETHOSTBYNAME" = "1"; then
|
||||
AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [If you have gethostbyname])
|
||||
else
|
||||
if test "$HAVE_GETHOSTBYNAME" != "1"; then
|
||||
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
|
||||
fi
|
||||
|
||||
@@ -832,25 +818,6 @@ if test "$ipv6" = "yes"; then
|
||||
curl_ipv6_msg="enabled"
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check how non-blocking sockets are set
|
||||
dnl **********************************************************************
|
||||
AC_ARG_ENABLE(nonblocking,
|
||||
AC_HELP_STRING([--enable-nonblocking],[Enable detecting how to do it])
|
||||
AC_HELP_STRING([--disable-nonblocking],[Disable non-blocking socket detection]),
|
||||
[
|
||||
if test "$enableval" = "no" ; then
|
||||
AC_MSG_WARN([non-blocking sockets disabled])
|
||||
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1,
|
||||
[to disable NON-BLOCKING connections])
|
||||
else
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
fi
|
||||
],
|
||||
[
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
])
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check if the operating system allows programs to write to their own argv[]
|
||||
dnl **********************************************************************
|
||||
@@ -2014,19 +1981,28 @@ CURL_CHECK_FUNC_SEND
|
||||
CURL_CHECK_MSG_NOSIGNAL
|
||||
|
||||
CURL_CHECK_FUNC_ALARM
|
||||
CURL_CHECK_FUNC_FCNTL
|
||||
CURL_CHECK_FUNC_FDOPEN
|
||||
CURL_CHECK_FUNC_FREEADDRINFO
|
||||
CURL_CHECK_FUNC_FREEIFADDRS
|
||||
CURL_CHECK_FUNC_FTRUNCATE
|
||||
CURL_CHECK_FUNC_GETADDRINFO
|
||||
CURL_CHECK_FUNC_GETHOSTBYADDR
|
||||
CURL_CHECK_FUNC_GETHOSTBYADDR_R
|
||||
CURL_CHECK_FUNC_GETHOSTBYNAME
|
||||
CURL_CHECK_FUNC_GETHOSTBYNAME_R
|
||||
CURL_CHECK_FUNC_GETHOSTNAME
|
||||
CURL_CHECK_FUNC_GETIFADDRS
|
||||
CURL_CHECK_FUNC_GETSERVBYPORT_R
|
||||
CURL_CHECK_FUNC_GMTIME_R
|
||||
CURL_CHECK_FUNC_INET_NTOA_R
|
||||
CURL_CHECK_FUNC_INET_NTOP
|
||||
CURL_CHECK_FUNC_INET_PTON
|
||||
CURL_CHECK_FUNC_IOCTL
|
||||
CURL_CHECK_FUNC_IOCTLSOCKET
|
||||
CURL_CHECK_FUNC_IOCTLSOCKET_CAMEL
|
||||
CURL_CHECK_FUNC_LOCALTIME_R
|
||||
CURL_CHECK_FUNC_SETSOCKOPT
|
||||
CURL_CHECK_FUNC_SIGACTION
|
||||
CURL_CHECK_FUNC_SIGINTERRUPT
|
||||
CURL_CHECK_FUNC_SIGNAL
|
||||
@@ -2062,8 +2038,6 @@ AC_CHECK_FUNCS([basename \
|
||||
closesocket \
|
||||
fork \
|
||||
geteuid \
|
||||
gethostbyaddr \
|
||||
getifaddrs \
|
||||
getpass_r \
|
||||
getppid \
|
||||
getprotobyname \
|
||||
@@ -2169,6 +2143,15 @@ if test "$disable_poll" = "no"; then
|
||||
fi dnl poll() was found
|
||||
fi dnl poll()-check is not disabled
|
||||
|
||||
dnl ************************************************************
|
||||
dnl enable non-blocking communications
|
||||
dnl
|
||||
CURL_CHECK_OPTION_NONBLOCKING
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
dnl ************************************************************
|
||||
dnl nroff tool stuff
|
||||
dnl
|
||||
|
||||
AC_PATH_PROG( PERL, perl, ,
|
||||
$PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )
|
||||
|
||||
45
docs/HISTORY
45
docs/HISTORY
@@ -77,7 +77,7 @@ different bindings exist at the time of this writing.
|
||||
September 2000, kerberos4 support was added.
|
||||
|
||||
In November 2000 started the work on a test suite for curl. It was later
|
||||
re-written from scratch again.
|
||||
re-written from scratch again. The libcurl major SONAME number was set to 1.
|
||||
|
||||
January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or
|
||||
MPL). The MIT license is extremely liberal and can be used combined with GPL
|
||||
@@ -88,7 +88,7 @@ deemed "GPL incompatible".)
|
||||
|
||||
curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
|
||||
also introduced libcurl's ability to do persistent connections. 24000 lines of
|
||||
code.
|
||||
code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
|
||||
|
||||
The first experimental ftps:// support was added in March 2001.
|
||||
|
||||
@@ -129,7 +129,12 @@ December 2003, full-fledged SSL for FTP is supported.
|
||||
|
||||
January 2004: curl 7.11.0 introduced large file support.
|
||||
|
||||
June 2004: curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
June 2004:
|
||||
|
||||
curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
|
||||
This release bumped the major SONAME to 3 due to the removal of the
|
||||
curl_formparse() function
|
||||
|
||||
August 2004:
|
||||
Curl and libcurl 7.12.1
|
||||
@@ -144,10 +149,38 @@ August 2004:
|
||||
|
||||
April 2005:
|
||||
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
|
||||
September 2005:
|
||||
|
||||
TFTP support was added.
|
||||
TFTP support was added.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
||||
April 2006:
|
||||
|
||||
Added the multi_socket() API
|
||||
|
||||
September 2006:
|
||||
|
||||
The major SONAME number for libcurl was bumped to 4 due to the removal of
|
||||
ftp third party transfer support.
|
||||
|
||||
November 2006:
|
||||
|
||||
Added SCP and SFTP support
|
||||
|
||||
February 2007:
|
||||
|
||||
Added support for the Mozilla NSS library to do the SSL/TLS stuff
|
||||
|
||||
November 2008:
|
||||
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 683
|
||||
|
||||
145,000 unique visitors. >100 GB downloaded.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
||||
17
docs/INSTALL
17
docs/INSTALL
@@ -782,9 +782,13 @@ REDUCING SIZE
|
||||
--without-ssl (disables support for SSL/TLS)
|
||||
--without-zlib (disables support for on-the-fly decompression)
|
||||
|
||||
The GNU linker has a number of options to reduce the size of the libcurl
|
||||
dynamic libraries on some platforms even further. Specify them by giving
|
||||
the options -Wl,-Bsymbolic and -Wl,-s on the gcc command-line.
|
||||
The GNU compiler and linker have a number of options that can reduce the
|
||||
size of the libcurl dynamic libraries on some platforms even further.
|
||||
Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
|
||||
configure command-line:
|
||||
CFLAGS="-ffunction-sections -fdata-sections" \
|
||||
LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
|
||||
|
||||
Be sure also to strip debugging symbols from your binaries after
|
||||
compiling using 'strip' (or the appropriate variant if cross-compiling).
|
||||
If space is really tight, you may be able to remove some unneeded
|
||||
@@ -826,9 +830,14 @@ PORTS
|
||||
- Alpha OpenVMS V7.1-1H2
|
||||
- Alpha Tru64 v5.0 5.1
|
||||
- AVR32 Linux
|
||||
- ARM INTEGRITY
|
||||
- ARM iPhone OS
|
||||
- Cell Linux
|
||||
- Cell Cell OS
|
||||
- HP-PA HP-UX 9.X 10.X 11.X
|
||||
- HP-PA Linux
|
||||
- HP3000 MPE/iX
|
||||
- MicroBlaze uClinux
|
||||
- MIPS IRIX 6.2, 6.5
|
||||
- MIPS Linux
|
||||
- OS/400
|
||||
@@ -848,7 +857,6 @@ PORTS
|
||||
- StrongARM (and other ARM) RISC OS 3.1, 4.02
|
||||
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6
|
||||
- StrongARM NetBSD 1.4.1
|
||||
- ARM INTEGRITY
|
||||
- Symbian OS (P.I.P.S.) 9.x
|
||||
- TPF
|
||||
- Ultrix 4.3a
|
||||
@@ -878,6 +886,7 @@ PORTS
|
||||
- m68k OpenBSD
|
||||
- m88k dg-dgux5.4R3.00
|
||||
- s390 Linux
|
||||
- x86_64 Linux
|
||||
- XScale/PXA250 Linux 2.4
|
||||
- Nios II uClinux
|
||||
|
||||
|
||||
11
docs/THANKS
11
docs/THANKS
@@ -182,6 +182,7 @@ Edin Kadribasic
|
||||
Eduard Bloch
|
||||
Eetu Ojanen
|
||||
Ellis Pritchard
|
||||
Emanuele Bovisio
|
||||
Emil Romanus
|
||||
Emiliano Ida
|
||||
Enrico Scholz
|
||||
@@ -257,10 +258,12 @@ Henrik Storner
|
||||
Hzhijun
|
||||
Ian Ford
|
||||
Ian Gulliver
|
||||
Ian Lynagh
|
||||
Ian Turner
|
||||
Ian Wilkes
|
||||
Ignacio Vazquez-Abrams
|
||||
Igor Franchuk
|
||||
Igor Novoseltsev
|
||||
Igor Polyakov
|
||||
Ilguiz Latypov
|
||||
Ilja van Sprundel
|
||||
@@ -317,6 +320,7 @@ John Kelly
|
||||
John Lask
|
||||
John Lightsey
|
||||
John McGowan
|
||||
John Wilkinson
|
||||
Johnny Luong
|
||||
Jon Grubbs
|
||||
Jon Travis
|
||||
@@ -348,6 +352,7 @@ Katie Wang
|
||||
Kees Cook
|
||||
Keith MacDonald
|
||||
Keith McGuigan
|
||||
Keith Mok
|
||||
Ken Hirsch
|
||||
Ken Rastatter
|
||||
Kent Boortz
|
||||
@@ -407,6 +412,7 @@ Markus Moeller
|
||||
Markus Oberhumer
|
||||
Martijn Koster
|
||||
Martin C. Martin
|
||||
Martin Drasar
|
||||
Martin Hedenfalk
|
||||
Martin Skinner
|
||||
Marty Kuhrt
|
||||
@@ -422,12 +428,14 @@ Matthew Blain
|
||||
Matthew Clarke
|
||||
Maurice Barnum
|
||||
Max Katsev
|
||||
Maxim Ivanov
|
||||
Maxim Perenesenko
|
||||
Mekonikum
|
||||
Mettgut Jamalla
|
||||
Michael Benedict
|
||||
Michael Calmer
|
||||
Michael Curtis
|
||||
Michael Goffioul
|
||||
Michael Jahn
|
||||
Michael Jerris
|
||||
Michael Mealling
|
||||
@@ -441,6 +449,7 @@ Mike Bytnar
|
||||
Mike Dobbs
|
||||
Mike Hommey
|
||||
Mike Protts
|
||||
Mike Revi
|
||||
Miklos Nemeth
|
||||
Mitz Wark
|
||||
Mohamed Lrhazi
|
||||
@@ -475,6 +484,7 @@ Olaf Stueben
|
||||
Olaf St<53>ben
|
||||
Oren Tirosh
|
||||
P R Schaffner
|
||||
Pascal Terjan
|
||||
Patrick Bihan-Faou
|
||||
Patrick Monnerat
|
||||
Patrick Smith
|
||||
@@ -606,6 +616,7 @@ Steve Lhomme
|
||||
Steve Little
|
||||
Steve Marx
|
||||
Steve Oliphant
|
||||
Steve Roskowski
|
||||
Steven Bazyl
|
||||
Steven G. Johnson
|
||||
Stoned Elipot
|
||||
|
||||
113
docs/TODO
113
docs/TODO
@@ -15,16 +15,13 @@
|
||||
1.1 Zero-copy interface
|
||||
1.2 More data sharing
|
||||
1.3 struct lifreq
|
||||
1.4 Get IP address
|
||||
1.5 c-ares ipv6
|
||||
1.6 configure-based info in public headers
|
||||
1.7 signal-based resolver timeouts
|
||||
1.4 signal-based resolver timeouts
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
2.2 Pause transfers
|
||||
2.3 Remove easy interface internally
|
||||
2.4 Avoid having to remove/readd handles
|
||||
2.2 Remove easy interface internally
|
||||
2.3 Avoid having to remove/readd handles
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
3. Documentation
|
||||
3.1 More and better
|
||||
@@ -39,9 +36,8 @@
|
||||
4.7 ASCII support
|
||||
|
||||
5. HTTP
|
||||
5.1 Other HTTP versions with CONNECT
|
||||
5.2 Better persistency for HTTP 1.0
|
||||
5.3 support FF3 sqlite cookie files
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
5.2 support FF3 sqlite cookie files
|
||||
|
||||
6. TELNET
|
||||
6.1 ditch stdin
|
||||
@@ -52,14 +48,13 @@
|
||||
7. SSL
|
||||
7.1 Disable specific versions
|
||||
7.2 Provide mutex locking API
|
||||
7.3 dumpcert
|
||||
7.4 Evaluate SSL patches
|
||||
7.5 Cache OpenSSL contexts
|
||||
7.6 Export session ids
|
||||
7.7 Provide callback for cert verification
|
||||
7.8 Support other SSL libraries
|
||||
7.9 Support SRP on the TLS layer
|
||||
7.10 improve configure --with-ssl
|
||||
7.3 Evaluate SSL patches
|
||||
7.4 Cache OpenSSL contexts
|
||||
7.5 Export session ids
|
||||
7.6 Provide callback for cert verification
|
||||
7.7 Support other SSL libraries
|
||||
7.8 Support SRP on the TLS layer
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
8. GnuTLS
|
||||
8.1 Make NTLM work without OpenSSL functions
|
||||
@@ -132,37 +127,7 @@
|
||||
SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
|
||||
To support ipv6 interface addresses for network interfaces properly.
|
||||
|
||||
1.4 Get IP address
|
||||
|
||||
Add the following to curl_easy_getinfo(): GET_HTTP_IP, GET_FTP_IP and
|
||||
GET_FTP_DATA_IP. Return a string with the used IP.
|
||||
|
||||
1.5 c-ares ipv6
|
||||
|
||||
Make libcurl built with c-ares use c-ares' IPv6 abilities. They weren't
|
||||
present when we first added c-ares support but they have been added since!
|
||||
When this is done and works, we can actually start considering making c-ares
|
||||
powered libcurl the default build (which of course would require that we'd
|
||||
bundle the c-ares source code in the libcurl source code releases).
|
||||
|
||||
1.6 configure-based info in public headers
|
||||
|
||||
Make the public headers include the proper system includes based on what was
|
||||
present at the time when configure was run. Currently, the sys/select.h
|
||||
header is for example included by curl/multi.h only on specific platforms we
|
||||
know MUST have it. This is error-prone. We therefore want the header files to
|
||||
adapt to configure results. Those results must be stored in a new header and
|
||||
they must use a curl name space, i.e not be HAVE_* prefix (as that would risk
|
||||
a collision with other apps that use libcurl and that runs configure).
|
||||
|
||||
Work on this has been started but hasn't been finished, and the initial patch
|
||||
and some details are found here:
|
||||
http://curl.haxx.se/mail/lib-2006-12/0084.html
|
||||
|
||||
The remaining problems to solve involve the platforms that can't run
|
||||
configure.
|
||||
|
||||
1.7 signal-based resolver timeouts
|
||||
1.4 signal-based resolver timeouts
|
||||
|
||||
libcurl built without an asynchronous resolver library uses alarm() to time
|
||||
out DNS lookups. When a timeout occurs, this causes libcurl to jump from the
|
||||
@@ -181,17 +146,7 @@
|
||||
Make sure we don't ever loop because of non-blocking sockets returning
|
||||
EWOULDBLOCK or similar. The GnuTLS connection etc.
|
||||
|
||||
2.2 Pause transfers
|
||||
|
||||
Make transfers treated more carefully. We need a way to tell libcurl we have
|
||||
data to write, as the current system expects us to upload data each time the
|
||||
socket is writable and there is no way to say that we want to upload data
|
||||
soon just not right now, without that aborting the upload. The opposite
|
||||
situation should be possible as well, that we tell libcurl we're ready to
|
||||
accept read data. Today libcurl feeds the data as soon as it is available for
|
||||
reading, no matter what.
|
||||
|
||||
2.3 Remove easy interface internally
|
||||
2.2 Remove easy interface internally
|
||||
|
||||
Make curl_easy_perform() a wrapper-function that simply creates a multi
|
||||
handle, adds the easy handle to it, runs curl_multi_perform() until the
|
||||
@@ -200,7 +155,7 @@
|
||||
internally use and assume the multi interface. The select()-loop should use
|
||||
curl_multi_socket().
|
||||
|
||||
2.4 Avoid having to remove/readd handles
|
||||
2.3 Avoid having to remove/readd handles
|
||||
|
||||
curl_multi_handle_control() - this can control the easy handle (while) added
|
||||
to a multi handle in various ways:
|
||||
@@ -217,6 +172,13 @@
|
||||
|
||||
o RESUME?
|
||||
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
HTTP Pipelining can be a way to greatly enhance performance for multiple
|
||||
serial requests and currently libcurl only supports that for HEAD and GET
|
||||
requests but it should also be possible for PUT.
|
||||
|
||||
|
||||
3. Documentation
|
||||
|
||||
3.1 More and better
|
||||
@@ -269,18 +231,12 @@
|
||||
|
||||
5. HTTP
|
||||
|
||||
5.1 Other HTTP versions with CONNECT
|
||||
|
||||
When doing CONNECT to a HTTP proxy, libcurl always uses HTTP/1.0. This has
|
||||
never been reported as causing trouble to anyone, but should be considered to
|
||||
use the HTTP version the user has chosen.
|
||||
|
||||
5.2 Better persistency for HTTP 1.0
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
|
||||
"Better" support for persistent connections over HTTP 1.0
|
||||
http://curl.haxx.se/bug/feature.cgi?id=1089001
|
||||
|
||||
5.3 support FF3 sqlite cookie files
|
||||
5.2 support FF3 sqlite cookie files
|
||||
|
||||
Firefox 3 is changing from its former format to a a sqlite database instead.
|
||||
We should consider how (lib)curl can/should support this.
|
||||
@@ -323,17 +279,12 @@ to provide the data to send.
|
||||
library, so that the same application code can use mutex-locking
|
||||
independently of OpenSSL or GnutTLS being used.
|
||||
|
||||
7.3 dumpcert
|
||||
|
||||
Anton Fedorov's "dumpcert" patch:
|
||||
http://curl.haxx.se/mail/lib-2004-03/0088.html
|
||||
|
||||
7.4 Evaluate SSL patches
|
||||
7.3 Evaluate SSL patches
|
||||
|
||||
Evaluate/apply Gertjan van Wingerde's SSL patches:
|
||||
http://curl.haxx.se/mail/lib-2004-03/0087.html
|
||||
|
||||
7.5 Cache OpenSSL contexts
|
||||
7.4 Cache OpenSSL contexts
|
||||
|
||||
"Look at SSL cafile - quick traces look to me like these are done on every
|
||||
request as well, when they should only be necessary once per ssl context (or
|
||||
@@ -343,7 +294,7 @@ to provide the data to send.
|
||||
style connections are re-used. It will make us use slightly more memory but
|
||||
it will libcurl do less creations and deletions of SSL contexts.
|
||||
|
||||
7.6 Export session ids
|
||||
7.5 Export session ids
|
||||
|
||||
Add an interface to libcurl that enables "session IDs" to get
|
||||
exported/imported. Cris Bailiff said: "OpenSSL has functions which can
|
||||
@@ -351,24 +302,24 @@ to provide the data to send.
|
||||
the state from such a buffer at a later date - this is used by mod_ssl for
|
||||
apache to implement and SSL session ID cache".
|
||||
|
||||
7.7 Provide callback for cert verification
|
||||
7.6 Provide callback for cert verification
|
||||
|
||||
OpenSSL supports a callback for customised verification of the peer
|
||||
certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
|
||||
it be? There's so much that could be done if it were!
|
||||
|
||||
7.8 Support other SSL libraries
|
||||
7.7 Support other SSL libraries
|
||||
|
||||
Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||
MatrixSSL (http://www.matrixssl.org/).
|
||||
|
||||
7.9 Support SRP on the TLS layer
|
||||
7.8 Support SRP on the TLS layer
|
||||
|
||||
Peter Sylvester's patch for SRP on the TLS layer. Awaits OpenSSL support for
|
||||
this, no need to support this in libcurl before there's an OpenSSL release
|
||||
that does it.
|
||||
|
||||
7.10 improve configure --with-ssl
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||
then NSS...
|
||||
|
||||
@@ -12,5 +12,5 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface \
|
||||
COMPLICATED_EXAMPLES = \
|
||||
curlgtk.c curlx.c htmltitle.cc cacertinmem.c ftpuploadresume.c \
|
||||
ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c
|
||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c
|
||||
|
||||
|
||||
460
docs/examples/evhiperfifo.c
Normal file
460
docs/examples/evhiperfifo.c
Normal 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;
|
||||
}
|
||||
@@ -180,12 +180,17 @@ static void event_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) userp;
|
||||
CURLMcode rc;
|
||||
(void)kind; /* unused */
|
||||
|
||||
int action =
|
||||
(kind&EV_READ?CURL_CSELECT_IN:0)|
|
||||
(kind&EV_WRITE?CURL_CSELECT_OUT:0);
|
||||
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, fd, &g->still_running);
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("event_cb: curl_multi_socket", rc);
|
||||
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_run_count(g);
|
||||
if ( g->still_running <= 0 ) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
@@ -206,9 +211,10 @@ static void timer_cb(int fd, short kind, void *userp)
|
||||
(void)kind;
|
||||
|
||||
do {
|
||||
rc = curl_multi_socket(g->multi, CURL_SOCKET_TIMEOUT, &g->still_running);
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
} while (rc == CURLM_CALL_MULTI_PERFORM);
|
||||
mcode_or_die("timer_cb: curl_multi_socket", rc);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_run_count(g);
|
||||
}
|
||||
|
||||
@@ -337,11 +343,9 @@ static void new_conn(char *url, GlobalInfo *g )
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc =curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
do {
|
||||
rc = curl_multi_socket_all(g->multi, &g->still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
mcode_or_die("new_conn: curl_multi_socket_all", rc);
|
||||
check_run_count(g);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
@@ -400,7 +404,6 @@ static int init_fifo (GlobalInfo *g)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
CURLMcode rc;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
@@ -409,13 +412,16 @@ int main(int argc, char **argv)
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
evtimer_set(&g.timer_event, timer_cb, &g);
|
||||
|
||||
/* setup the generic multi interface options we want */
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
do {
|
||||
rc = curl_multi_socket_all(g.multi, &g.still_running);
|
||||
} while (CURLM_CALL_MULTI_PERFORM == rc);
|
||||
|
||||
/* we don't call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
event_dispatch();
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
|
||||
@@ -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
|
||||
it too slow and abort.
|
||||
.IP CURLOPT_MAX_SEND_SPEED_LARGE
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed on cumulative
|
||||
average during the transfer, the transfer will pause to keep the average rate
|
||||
less than or equal to the parameter value. Defaults to unlimited
|
||||
speed. (Added in 7.15.5)
|
||||
Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in
|
||||
bytes per second) on cumulative average during the transfer, the transfer will
|
||||
pause to keep the average rate less than or equal to the parameter value.
|
||||
Defaults to unlimited speed. (Added in 7.15.5)
|
||||
.IP CURLOPT_MAX_RECV_SPEED_LARGE
|
||||
Pass a curl_off_t as parameter. If a download exceeds this speed on
|
||||
cumulative average during the transfer, the transfer will pause to keep the
|
||||
average rate less than or equal to the parameter value. Defaults to unlimited
|
||||
speed. (Added in 7.15.5)
|
||||
Pass a curl_off_t as parameter. If a download exceeds this speed (counted in
|
||||
bytes per second) on cumulative average during the transfer, the transfer will
|
||||
pause to keep the average rate less than or equal to the parameter
|
||||
value. Defaults to unlimited speed. (Added in 7.15.5)
|
||||
.IP CURLOPT_MAXCONNECTS
|
||||
Pass a long. The set number will be the persistent connection cache size. The
|
||||
set amount will be the maximum amount of simultaneously open connections that
|
||||
@@ -1388,6 +1388,7 @@ Resolve to ipv6 addresses.
|
||||
.IP CURLOPT_CONNECT_ONLY
|
||||
Pass a long. If the parameter equals 1, it tells the library to perform all
|
||||
the required proxy authentication and connection setup, but no data transfer.
|
||||
This option is useful only on HTTP URLs.
|
||||
|
||||
This option is useful with the \fICURLINFO_LASTSOCKET\fP option to
|
||||
\fIcurl_easy_getinfo(3)\fP. The library can set up the connection and then the
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
.\" * $Id$
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH libcurl-tutorial 3 "27 Feb 2007" "libcurl" "libcurl programming"
|
||||
.TH libcurl-tutorial 3 "17 Nov 2008" "libcurl" "libcurl programming"
|
||||
.SH NAME
|
||||
libcurl-tutorial \- libcurl programming tutorial
|
||||
.SH "Objective"
|
||||
@@ -41,7 +41,7 @@ refer to their respective man pages.
|
||||
|
||||
.SH "Building"
|
||||
There are many different ways to build C programs. This chapter will assume a
|
||||
unix-style build process. If you use a different build system, you can still
|
||||
UNIX-style build process. If you use a different build system, you can still
|
||||
read this to get general information that may apply to your environment as
|
||||
well.
|
||||
.IP "Compiling the Program"
|
||||
@@ -167,11 +167,9 @@ something different. Alas, multiple requests using the same handle will use
|
||||
the same options.
|
||||
|
||||
Many of the options you set in libcurl are "strings", pointers to data
|
||||
terminated with a zero byte. Keep in mind that when you set strings with
|
||||
\fIcurl_easy_setopt(3)\fP, libcurl will not copy the data. It will merely
|
||||
point to the data. You MUST make sure that the data remains available for
|
||||
libcurl to use until finished or until you use the same option again to point
|
||||
to something else.
|
||||
terminated with a zero byte. When you set strings with
|
||||
\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't
|
||||
need to be kept around in your application after being set[4].
|
||||
|
||||
One of the most basic properties to set in the handle is the URL. You set
|
||||
your preferred URL to transfer with CURLOPT_URL in a manner similar to:
|
||||
@@ -245,14 +243,20 @@ again. Mind you, it is even preferred that you re-use an existing handle if
|
||||
you intend to make another transfer. libcurl will then attempt to re-use the
|
||||
previous connection.
|
||||
|
||||
For some protocols, downloading a file can involve a complicated process of
|
||||
logging in, setting the transfer mode, changing the current directory and
|
||||
finally transferring the file data. libcurl takes care of all that
|
||||
complication for you. Given simply the URL to a file, libcurl will take care
|
||||
of all the details needed to get the file moved from one machine to another.
|
||||
|
||||
.SH "Multi-threading Issues"
|
||||
The first basic rule is that you must \fBnever\fP share a libcurl handle (be
|
||||
it easy or multi or whatever) between multiple threads. Only use one handle in
|
||||
one thread at a time.
|
||||
|
||||
libcurl is completely thread safe, except for two issues: signals and SSL/TLS
|
||||
handlers. Signals are used timeouting name resolves (during DNS lookup) - when
|
||||
built without c-ares support and not on Windows..
|
||||
handlers. Signals are used for timing out name resolves (during DNS lookup) -
|
||||
when built without c-ares support and not on Windows..
|
||||
|
||||
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
|
||||
then of course using the underlying SSL library multi-threaded and those libs
|
||||
@@ -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]:
|
||||
|
||||
.nf
|
||||
/* in this example, file_size must be an off_t variable */
|
||||
/* in this example, file_size must be an curl_off_t variable */
|
||||
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
|
||||
.fi
|
||||
|
||||
@@ -389,7 +393,7 @@ to the CURLOPT_USERPWD option like this:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret");
|
||||
|
||||
There's a long time unix "standard" way of storing ftp user names and
|
||||
There's a long time UNIX "standard" way of storing ftp user names and
|
||||
passwords, namely in the $HOME/.netrc file. The file should be made private
|
||||
so that only the user may read it (see also the "Security Considerations"
|
||||
chapter), as it might contain the password in plain text. libcurl has the
|
||||
@@ -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
|
||||
library.
|
||||
.IP "[3]"
|
||||
The curl-config tool is generated at build-time (on unix-like systems) and
|
||||
The curl-config tool is generated at build-time (on UNIX-like systems) and
|
||||
should be installed with the 'make install' or similar instruction that
|
||||
installs the library, header files, man pages etc.
|
||||
.IP "[4]"
|
||||
This behavior was different in versions before 7.17.0, where strings had to
|
||||
remain valid past the end of the \fIcurl_easy_setopt(3)\fP call.
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.19.1-CVS"
|
||||
#define LIBCURL_VERSION "7.19.3-CVS"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 19
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
#define LIBCURL_VERSION_PATCH 3
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -54,7 +54,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x071301
|
||||
#define LIBCURL_VERSION_NUM 0x071303
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
## and optionally OpenSSL (0.9.8), libssh2 (0.18), zlib (1.2.3)
|
||||
##
|
||||
## Usage:
|
||||
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [SSPI=1] [IPV6=1] [DYN=1]
|
||||
## mingw32-make -f Makefile.m32 [SSL=1] [SSH2=1] [ZLIB=1] [IDN=1] [SSPI=1] [IPV6=1] [LDAPS=1] [DYN=1]
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.3
|
||||
@@ -21,12 +21,16 @@ ZLIB_PATH = ../../zlib-1.2.3
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8g
|
||||
OPENSSL_PATH = ../../openssl-0.9.8i
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-0.18
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.11
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
@@ -72,6 +76,11 @@ ifdef ZLIB
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
DLL_LIBS += -L$(ZLIB_PATH) -lz
|
||||
endif
|
||||
ifdef IDN
|
||||
INCLUDES += -I"$(LIBIDN_PATH)/include"
|
||||
CFLAGS += -DUSE_LIBIDN
|
||||
DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
|
||||
@@ -20,7 +20,7 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8h
|
||||
OPENSSL_PATH = ../../openssl-0.9.8i
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
@@ -28,6 +28,11 @@ ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-0.18
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.11
|
||||
endif
|
||||
|
||||
ifndef INSTDIR
|
||||
INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
|
||||
endif
|
||||
@@ -183,6 +188,10 @@ else
|
||||
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
INCLUDES += -I$(LIBIDN_PATH)/include
|
||||
LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
|
||||
endif
|
||||
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
INCLUDES += -I$(SDK_LIBC)/include
|
||||
@@ -452,12 +461,13 @@ endif
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
|
||||
@@ -536,6 +546,10 @@ endif
|
||||
ifdef WITH_SSH2
|
||||
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef WITH_IDN
|
||||
@echo $(DL)#define HAVE_LIBIDN 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TLD_H 1$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)#ifdef __GNUC__$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@
|
||||
|
||||
@@ -7,13 +7,13 @@ objs = o.base64 o.connect o.cookie o.dict \
|
||||
o.dllinit o.easy o.escape o.file \
|
||||
o.formdata o.ftp o.getenv \
|
||||
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.memdebug o.mprintf o.netrc o.parsedate o.progress \
|
||||
o.security o.select o.sendf o.speedcheck o.ssluse \
|
||||
o.strequal o.strtok o.telnet o.timeval \
|
||||
o.transfer o.url o.version o.strtoofft o.sslgen o.gtls \
|
||||
o.rawstr
|
||||
o.rawstr o.curl_addrinfo
|
||||
|
||||
# Compile options:
|
||||
linkopts = -o libcurl
|
||||
@@ -33,6 +33,9 @@ o.connect: c.connect
|
||||
o.cookie: 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
|
||||
gcc $(compileropts) -c -o dict.o c.dict
|
||||
|
||||
|
||||
@@ -426,62 +426,63 @@ clean:
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\formdata.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)\getinfo.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hostares.obj \
|
||||
$(DIROBJ)\hostthre.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\netrc.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)\hostsyn.obj \
|
||||
$(DIROBJ)\hostthre.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_negotiate.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)\memdebug.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\progress.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)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
127
lib/base64.c
127
lib/base64.c
@@ -239,130 +239,3 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
return strlen(base64data); /* return the length of the new data */
|
||||
}
|
||||
/* ---- 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
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
#define HAVE_INET_ADDR 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_LIBSSL 1
|
||||
#define HAVE_LIBZ 1
|
||||
|
||||
@@ -54,7 +54,8 @@
|
||||
#define HAVE_RAND_STATUS 1
|
||||
#define HAVE_RAND_EGD 1
|
||||
|
||||
#define HAVE_FIONBIO 1
|
||||
#define HAVE_IOCTL 1
|
||||
#define HAVE_IOCTL_FIONBIO 1
|
||||
|
||||
#define RETSIGTYPE void
|
||||
|
||||
|
||||
@@ -283,6 +283,9 @@
|
||||
/* Define if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define if you have the <stropts.h> header file. */
|
||||
#define HAVE_STROPTS_H
|
||||
|
||||
/* Define if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR
|
||||
|
||||
@@ -392,9 +395,14 @@
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#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 */
|
||||
#undef CURL_DISABLE_LDAP
|
||||
|
||||
@@ -378,12 +378,11 @@
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* this is a quick hack. I hope it's correct. */
|
||||
#define ifr_dstaddr ifr_addr
|
||||
/* Define if you have the ioctl function. */
|
||||
#define HAVE_IOCTL
|
||||
|
||||
#define IOCTL_3_ARGS
|
||||
|
||||
#define HAVE_FIONBIO
|
||||
/* Define if you have a working ioctl FIONBIO function. */
|
||||
#define HAVE_IOCTL_FIONBIO
|
||||
|
||||
/* to disable LDAP */
|
||||
#define CURL_DISABLE_LDAP
|
||||
|
||||
@@ -111,9 +111,6 @@
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
/* #undef HAVE_DES_H */
|
||||
|
||||
/* disabled non-blocking sockets */
|
||||
/* #undef HAVE_DISABLED_NONBLOCKING */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
@@ -129,8 +126,11 @@
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* use FIONBIO for non-blocking sockets */
|
||||
#define HAVE_FIONBIO 1
|
||||
/* Define to 1 if you have the fcntl function. */
|
||||
#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 HAVE_FORK 1*/
|
||||
@@ -231,11 +231,23 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#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 */
|
||||
|
||||
/* use Ioctlsocket() for non-blocking sockets */
|
||||
/* #undef HAVE_IOCTLSOCKET_CASE */
|
||||
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
|
||||
/* #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. */
|
||||
/* #undef HAVE_IO_H */
|
||||
@@ -361,9 +373,6 @@
|
||||
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||
/*#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. */
|
||||
/* #undef HAVE_PEM_H */
|
||||
|
||||
@@ -427,6 +436,12 @@
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
/*#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 HAVE_SGTTY_H 1*/
|
||||
|
||||
@@ -454,9 +469,6 @@
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* use SO_NONBLOCK for non-blocking sockets */
|
||||
/* #undef HAVE_SO_NONBLOCK */
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
/* #undef HAVE_SPNEGO */
|
||||
|
||||
@@ -715,6 +727,9 @@
|
||||
/* Define if you want to enable c-ares support */
|
||||
/* #undef USE_ARES */
|
||||
|
||||
/* Define to disable non-blocking sockets */
|
||||
/* #undef USE_BLOCKING_SOCKETS */
|
||||
|
||||
/* if GnuTLS is enabled */
|
||||
/* #undef USE_GNUTLS */
|
||||
|
||||
|
||||
@@ -104,9 +104,6 @@
|
||||
/* #undef HAVE_DES_H */
|
||||
#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. */
|
||||
/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
|
||||
#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
|
||||
@@ -121,9 +118,11 @@
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* use FIONBIO for non-blocking sockets */
|
||||
/* #undef HAVE_FIONBIO */
|
||||
#define HAVE_FIONBIO 1
|
||||
/* Define to 1 if you have the fcntl function. */
|
||||
#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. */
|
||||
/* #undef HAVE_FORK */
|
||||
@@ -217,11 +216,23 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#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 */
|
||||
|
||||
/* use Ioctlsocket() for non-blocking sockets */
|
||||
/* #undef HAVE_IOCTLSOCKET_CASE */
|
||||
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
|
||||
/* #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. */
|
||||
/* #undef HAVE_IO_H */
|
||||
@@ -328,9 +339,6 @@
|
||||
/* #undef HAVE_OPENSSL_X509_H */
|
||||
#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. */
|
||||
/* #undef HAVE_PEM_H */
|
||||
#define HAVE_PEM_H 1
|
||||
@@ -380,6 +388,12 @@
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#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. */
|
||||
/* #undef HAVE_SGTTY_H 1 */
|
||||
|
||||
@@ -407,9 +421,6 @@
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* use SO_NONBLOCK for non-blocking sockets */
|
||||
/* #undef HAVE_SO_NONBLOCK */
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
/* #undef HAVE_SPNEGO */
|
||||
|
||||
@@ -602,6 +613,9 @@
|
||||
/* Define if you want to enable ares support */
|
||||
/* #undef USE_ARES */
|
||||
|
||||
/* Define to disable non-blocking sockets */
|
||||
/* #undef USE_BLOCKING_SOCKETS */
|
||||
|
||||
/* if GnuTLS is enabled */
|
||||
/* #undef USE_GNUTLS */
|
||||
|
||||
|
||||
@@ -157,9 +157,12 @@
|
||||
/* Define if you have the inet_addr function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the perror function. */
|
||||
#define HAVE_PERROR 1
|
||||
|
||||
|
||||
@@ -145,9 +145,12 @@
|
||||
/* Define if you have the inet_addr function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the perror function. */
|
||||
#define HAVE_PERROR 1
|
||||
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FIONBIO 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
#define HAVE_GETPROTOBYNAME 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_IO_H 1
|
||||
#define HAVE_IOCTL 1
|
||||
#define HAVE_IOCTL_FIONBIO 1
|
||||
#define HAVE_IOCTLSOCKET 1
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
#define HAVE_LOCALE_H 1
|
||||
#define HAVE_LONGLONG 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#include <stdlib.h> /* required for free() prototype, without it, this crashes */
|
||||
#endif /* on macos 68K */
|
||||
|
||||
#if (defined(HAVE_FIONBIO) && defined(NETWARE))
|
||||
#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#ifdef NETWARE
|
||||
@@ -91,7 +91,6 @@
|
||||
#include "multiif.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "inet_ntop.h"
|
||||
#include "inet_pton.h"
|
||||
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
|
||||
|
||||
/* 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 nonblock /* TRUE or FALSE */)
|
||||
{
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
#if defined(USE_BLOCKING_SOCKETS)
|
||||
|
||||
return 0; /* returns success */
|
||||
|
||||
#elif defined(HAVE_FCNTL_O_NONBLOCK)
|
||||
|
||||
/* most recent unix versions */
|
||||
int flags;
|
||||
|
||||
flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if(FALSE != nonblock)
|
||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 1
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||
#elif defined(HAVE_IOCTL_FIONBIO)
|
||||
|
||||
/* older unix versions */
|
||||
int flags;
|
||||
|
||||
flags = nonblock;
|
||||
return ioctl(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 2
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||
/* Windows? */
|
||||
#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
|
||||
|
||||
/* Windows */
|
||||
unsigned long flags;
|
||||
flags = nonblock;
|
||||
|
||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 3
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||
/* presumably for Amiga */
|
||||
#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
|
||||
|
||||
/* Amiga */
|
||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 4
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
|
||||
|
||||
/* BeOS */
|
||||
long b = nonblock ? 1 : 0;
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 5
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||
return 0; /* returns success */
|
||||
#undef SETBLOCK
|
||||
#define SETBLOCK 6
|
||||
#endif
|
||||
|
||||
#if(SETBLOCK == 0)
|
||||
#error "no non-blocking method was found/used/set"
|
||||
#else
|
||||
# error "no non-blocking method was found/used/set"
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -866,12 +848,14 @@ singleipconnect(struct connectdata *conn,
|
||||
switch (error) {
|
||||
case EINPROGRESS:
|
||||
case EWOULDBLOCK:
|
||||
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
|
||||
#if defined(EAGAIN)
|
||||
#if (EAGAIN) != (EWOULDBLOCK)
|
||||
/* On some platforms EAGAIN and EWOULDBLOCK are the
|
||||
* same value, and on others they are different, hence
|
||||
* the odd #if
|
||||
*/
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#endif
|
||||
rc = waitconnect(sockfd, timeout_ms);
|
||||
break;
|
||||
|
||||
@@ -1003,7 +1003,8 @@ int Curl_cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
format_ptr = get_netscape_format(co);
|
||||
if(format_ptr == NULL) {
|
||||
fprintf(out, "#\n# Fatal libcurl error\n");
|
||||
fclose(out);
|
||||
if(!use_stdout)
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
|
||||
@@ -190,7 +190,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
|
||||
*result = cafirst;
|
||||
|
||||
return error; /* This is not a CURLcode */
|
||||
/* This is not a CURLcode */
|
||||
return error;
|
||||
}
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
@@ -254,6 +255,8 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
/* no input == no output! */
|
||||
return NULL;
|
||||
|
||||
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
|
||||
|
||||
for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
int ss_size;
|
||||
@@ -300,7 +303,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
|
||||
switch (ai->ai_family) {
|
||||
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));
|
||||
addr->sin_family = (unsigned short)(he->h_addrtype);
|
||||
@@ -309,7 +312,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
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));
|
||||
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)
|
||||
/*
|
||||
* curl_dofreeaddrinfo()
|
||||
|
||||
@@ -78,6 +78,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
Curl_addrinfo *
|
||||
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)
|
||||
void
|
||||
|
||||
@@ -53,7 +53,9 @@
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -57,7 +57,9 @@
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -267,7 +267,7 @@ static const char * ContentTypeForFilename (const char *filename,
|
||||
* extensions and pick the first we match!
|
||||
*/
|
||||
struct ContentType {
|
||||
const char *extension;
|
||||
char extension[6];
|
||||
const char *type;
|
||||
};
|
||||
static const struct ContentType ctts[]={
|
||||
@@ -275,7 +275,8 @@ static const char * ContentTypeForFilename (const char *filename,
|
||||
{".jpg", "image/jpeg"},
|
||||
{".jpeg", "image/jpeg"},
|
||||
{".txt", "text/plain"},
|
||||
{".html", "text/html"}
|
||||
{".html", "text/html"},
|
||||
{".xml", "application/xml"}
|
||||
};
|
||||
|
||||
if(prevtype)
|
||||
@@ -1100,7 +1101,7 @@ static char *strippath(const char *fullfile)
|
||||
|
||||
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 multiple-file */
|
||||
char *filebasename=
|
||||
(!file->showfilename)?strippath(file->contents):NULL;
|
||||
char *filebasename= NULL;
|
||||
if(!file->showfilename) {
|
||||
filebasename = strippath(file->contents);
|
||||
if(!filebasename) {
|
||||
Curl_formclean(&firstform);
|
||||
free(boundary);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
result = AddFormDataf(&form, &size,
|
||||
"\r\n--%s\r\nContent-Disposition: "
|
||||
@@ -1729,7 +1737,7 @@ char *Curl_FormBoundary(void)
|
||||
the same form won't be identical */
|
||||
size_t i;
|
||||
|
||||
static const char table16[]="abcdef0123456789";
|
||||
static const char table16[]="0123456789abcdef";
|
||||
|
||||
retstring = malloc(BOUNDARY_LENGTH+1);
|
||||
|
||||
|
||||
104
lib/ftp.c
104
lib/ftp.c
@@ -85,6 +85,7 @@
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "inet_ntop.h"
|
||||
#include "inet_pton.h"
|
||||
#include "select.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#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,
|
||||
bool *dophase_done);
|
||||
static CURLcode ftp_setup_connection(struct connectdata * conn);
|
||||
#ifdef USE_SSL
|
||||
static CURLcode ftps_setup_connection(struct connectdata * conn);
|
||||
#endif
|
||||
|
||||
/* easy-to-use macro: */
|
||||
#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 = {
|
||||
"FTPS", /* scheme */
|
||||
ftps_setup_connection, /* setup_connection */
|
||||
ftp_setup_connection, /* setup_connection */
|
||||
ftp_do, /* do_it */
|
||||
ftp_done, /* done */
|
||||
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 */
|
||||
if(ftpportstr) {
|
||||
in_addr_t in;
|
||||
struct in_addr in;
|
||||
|
||||
/* First check if the given name is an IP address */
|
||||
in=inet_addr(ftpportstr);
|
||||
|
||||
if(in != CURL_INADDR_NONE)
|
||||
/* First check if the given string is an IP address */
|
||||
if(Curl_inet_pton(AF_INET, ftpportstr, &in) > 0) {
|
||||
/* this is an IPv4 address */
|
||||
addr = Curl_ip2addr(in, ftpportstr, 0);
|
||||
else {
|
||||
if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) {
|
||||
/* The interface to IP conversion provided a dotted address */
|
||||
in=inet_addr(myhost);
|
||||
addr = Curl_ip2addr(in, myhost, 0);
|
||||
}
|
||||
else if(strlen(ftpportstr)> 1) {
|
||||
/* might be a host name! */
|
||||
struct Curl_dns_entry *h=NULL;
|
||||
int rc = Curl_resolv(conn, ftpportstr, 0, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING */
|
||||
rc = Curl_wait_for_resolv(conn, &h);
|
||||
if(h) {
|
||||
addr = h->addr;
|
||||
/* when we return from this function, we can forget about this entry
|
||||
so we can unlock it now already */
|
||||
Curl_resolv_unlock(data, h);
|
||||
addr = Curl_ip2addr(AF_INET, &in, ftpportstr, 0);
|
||||
}
|
||||
/* otherwise check if the given string is an interface */
|
||||
else if(Curl_if2ip(AF_INET, ftpportstr, myhost, sizeof(myhost))) {
|
||||
/* The interface to IP conversion provided a dotted address */
|
||||
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! */
|
||||
struct Curl_dns_entry *h=NULL;
|
||||
int rc = Curl_resolv(conn, ftpportstr, 0, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING */
|
||||
rc = Curl_wait_for_resolv(conn, &h);
|
||||
if(h) {
|
||||
addr = h->addr;
|
||||
/* when we return from this function, we can forget about this entry
|
||||
so we can unlock it now already */
|
||||
Curl_resolv_unlock(data, h);
|
||||
|
||||
freeaddr = FALSE; /* make sure we don't free 'addr' in this function
|
||||
since it points to a DNS cache entry! */
|
||||
} /* (h) */
|
||||
else {
|
||||
infof(data, "Failed to resolve host name %s\n", ftpportstr);
|
||||
}
|
||||
} /* strlen */
|
||||
} /* CURL_INADDR_NONE */
|
||||
freeaddr = FALSE; /* make sure we don't free 'addr' in this function
|
||||
since it points to a DNS cache entry! */
|
||||
} /* (h) */
|
||||
else {
|
||||
infof(data, "Failed to resolve host name %s\n", ftpportstr);
|
||||
}
|
||||
} /* strlen */
|
||||
} /* ftpportstr */
|
||||
|
||||
if(!addr) {
|
||||
@@ -2191,10 +2187,6 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||||
curl_off_t filesize;
|
||||
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: */
|
||||
filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
|
||||
|
||||
@@ -2688,24 +2680,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
|
||||
case FTP_PBSZ:
|
||||
/* FIX: check response code */
|
||||
|
||||
/* For TLS, the data connection can have one of two security levels.
|
||||
|
||||
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;
|
||||
}
|
||||
NBFTPSENDF(conn, "PROT %c",
|
||||
data->set.ftp_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
|
||||
state(conn, FTP_PROT);
|
||||
|
||||
break;
|
||||
|
||||
@@ -3170,7 +3147,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
case CURLE_UPLOAD_FAILED:
|
||||
case CURLE_REMOTE_ACCESS_DENIED:
|
||||
case CURLE_FILESIZE_EXCEEDED:
|
||||
case CURLE_REMOTE_FILE_NOT_FOUND:
|
||||
/* the connection stays alive fine even though this happened */
|
||||
/* fall-through */
|
||||
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;
|
||||
}
|
||||
|
||||
#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 */
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "memory.h"
|
||||
@@ -263,6 +265,11 @@ Curl_gtls_connect(struct connectdata *conn,
|
||||
struct in_addr addr;
|
||||
#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)
|
||||
_Curl_gtls_init();
|
||||
|
||||
@@ -338,7 +345,7 @@ Curl_gtls_connect(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
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);
|
||||
if(rc < 0)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
@@ -289,80 +289,6 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
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
|
||||
@@ -379,22 +305,24 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
{
|
||||
char *bufp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
in_addr_t in = inet_addr(hostname);
|
||||
struct in_addr in;
|
||||
int family = PF_INET;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
struct in6_addr in6;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
*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 */
|
||||
return Curl_ip2addr(in, hostname, port);
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
/* Otherwise, check if this is an IPv6 address string */
|
||||
if (Curl_inet_pton (AF_INET6, hostname, &in6) > 0) {
|
||||
/* 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) {
|
||||
|
||||
85
lib/hostip.c
85
lib/hostip.c
@@ -724,88 +724,3 @@ Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
|
||||
return Curl_he2ai(orig, port);
|
||||
}
|
||||
#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 */
|
||||
|
||||
@@ -104,11 +104,6 @@
|
||||
#define ares_destroy(x) do {} while(0)
|
||||
#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 hostent;
|
||||
struct SessionHandle;
|
||||
@@ -224,10 +219,6 @@ CURLcode Curl_addrinfo6_callback(void *arg,
|
||||
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 */
|
||||
Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
|
||||
|
||||
|
||||
@@ -118,20 +118,18 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
#endif
|
||||
Curl_addrinfo *ai = NULL;
|
||||
struct hostent *h = NULL;
|
||||
in_addr_t in;
|
||||
struct in_addr in;
|
||||
struct hostent *buf = NULL;
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)conn;
|
||||
#endif
|
||||
|
||||
(void)port; /* unused in IPv4 code */
|
||||
|
||||
*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 */
|
||||
return Curl_ip2addr(in, hostname, port);
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
|
||||
#if defined(HAVE_GETHOSTBYNAME_R)
|
||||
/*
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -665,14 +666,13 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
{
|
||||
struct hostent *h = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
in_addr_t in;
|
||||
struct in_addr in;
|
||||
|
||||
*waitp = 0; /* don't wait, we act synchronously */
|
||||
|
||||
in = inet_addr(hostname);
|
||||
if(in != CURL_INADDR_NONE)
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* 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! */
|
||||
if(init_resolve_thread(conn, hostname, port, NULL)) {
|
||||
|
||||
269
lib/http.c
269
lib/http.c
@@ -114,11 +114,13 @@
|
||||
static int http_getsock_do(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
#else
|
||||
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -246,8 +248,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
char *authorization;
|
||||
struct SessionHandle *data=conn->data;
|
||||
char **userp;
|
||||
char *user;
|
||||
char *pwd;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
@@ -456,6 +458,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
}
|
||||
|
||||
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 */
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -493,6 +499,90 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
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
|
||||
* host/proxy and the correct authentication
|
||||
@@ -516,7 +606,6 @@ http_output_auth(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *auth=NULL;
|
||||
struct auth *authhost;
|
||||
struct auth *authproxy;
|
||||
|
||||
@@ -550,66 +639,12 @@ http_output_auth(struct connectdata *conn,
|
||||
/* Send proxy authentication header if needed */
|
||||
if(conn->bits.httpproxy &&
|
||||
(conn->bits.tunnel_proxy == proxytunnel)) {
|
||||
#ifdef HAVE_GSSAPI
|
||||
if((authproxy->picked == CURLAUTH_GSSNEGOTIATE) &&
|
||||
data->state.negotiate.context &&
|
||||
!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;
|
||||
}
|
||||
result = output_auth_headers(conn, authproxy, request, path, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#else
|
||||
(void)request;
|
||||
(void)path;
|
||||
(void)proxytunnel;
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
/* 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 ||
|
||||
conn->bits.netrc ||
|
||||
!data->state.first_host ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name) ||
|
||||
data->set.http_disable_hostname_check_before_authentication) {
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
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
|
||||
* types (using &), we OR this authentication type to the authavail
|
||||
* 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
|
||||
if(checkprefix("GSS-Negotiate", start) ||
|
||||
checkprefix("Negotiate", start)) {
|
||||
int neg;
|
||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
|
||||
/* if exactly this is wanted, go */
|
||||
int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
|
||||
|
||||
if(data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* 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) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
data->state.authproblem = (data->req.newurl == NULL);
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received GSS auth info and we dealt with it fine */
|
||||
data->state.negotiate.state = GSS_AUTHRECV;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1822,18 +1815,12 @@ static int http_getsock_do(struct connectdata *conn,
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
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 */
|
||||
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
|
||||
if(result)
|
||||
@@ -1841,6 +1828,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
to prevent (bad) re-use or similar */
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/* 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";
|
||||
|
||||
if(( (HTTPREQ_POST == httpreq) ||
|
||||
@@ -2468,7 +2451,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
"%s" /* range */
|
||||
"%s" /* user agent */
|
||||
"%s" /* host */
|
||||
"%s" /* pragma */
|
||||
"%s" /* accept */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
@@ -2488,7 +2470,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
*data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
|
||||
conn->allocptr.uagent:"",
|
||||
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
|
||||
http->p_pragma?http->p_pragma:"",
|
||||
http->p_accept?http->p_accept:"",
|
||||
(data->set.str[STRING_ENCODING] &&
|
||||
*data->set.str[STRING_ENCODING] &&
|
||||
|
||||
@@ -105,8 +105,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
(2 == sscanf(header, "%255[^=]=%1023[^\r\n,]",
|
||||
value, content)) ) {
|
||||
if(!strcmp("\"\"", content)) {
|
||||
/* for the name="" case where we get only the "" in the content variable,
|
||||
* simply clear the content then
|
||||
/* for the name="" case where we get only the "" in the content
|
||||
* variable, simply clear the content then
|
||||
*/
|
||||
content[0]=0;
|
||||
}
|
||||
|
||||
118
lib/if2ip.c
118
lib/if2ip.c
@@ -23,46 +23,43 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
# include <unistd.h>
|
||||
#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
|
||||
#include <sys/socket.h>
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#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
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "strequal.h"
|
||||
#include "if2ip.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -71,6 +68,10 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
#if defined(HAVE_GETIFADDRS)
|
||||
|
||||
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
|
||||
{
|
||||
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) {
|
||||
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)) {
|
||||
void *addr;
|
||||
char scope[12]="";
|
||||
#ifdef ENABLE_IPV6
|
||||
if (af == AF_INET6) {
|
||||
unsigned int scopeid;
|
||||
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);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
|
||||
ip = (char *) Curl_inet_ntop(af, addr, buf, 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;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#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"
|
||||
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
|
||||
|
||||
#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);
|
||||
req.ifr_addr.sa_family = AF_INET;
|
||||
#ifdef IOCTL_3_ARGS
|
||||
if(SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) {
|
||||
#else
|
||||
if(SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) {
|
||||
#endif
|
||||
sclose(dummy);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
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));
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- end of if2ip() -- */
|
||||
#else
|
||||
|
||||
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
|
||||
{
|
||||
(void) af;
|
||||
@@ -201,4 +158,5 @@ char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
|
||||
(void) buf_size;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,6 @@ struct ifreq {
|
||||
|
||||
/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
|
||||
C code. */
|
||||
#define ifr_dstaddr ifr_addr
|
||||
|
||||
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
|
||||
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||
|
||||
@@ -74,9 +74,6 @@ Curl_inet_pton(int af, const char *src, void *dst)
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, (unsigned char *)dst));
|
||||
#ifdef ENABLE_IPV6
|
||||
#ifndef AF_INET6
|
||||
#define AF_INET6 (AF_MAX+1) /* just to let this compile */
|
||||
#endif
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, (unsigned char *)dst));
|
||||
#endif
|
||||
@@ -114,6 +111,8 @@ inet_pton4(const char *src, unsigned char *dst)
|
||||
if((pch = strchr(digits, ch)) != NULL) {
|
||||
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
|
||||
|
||||
if(saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if(val > 255)
|
||||
return (0);
|
||||
*tp = (unsigned char)val;
|
||||
@@ -134,7 +133,6 @@ inet_pton4(const char *src, unsigned char *dst)
|
||||
}
|
||||
if(octets < 4)
|
||||
return (0);
|
||||
/* bcopy(tmp, dst, INADDRSZ); */
|
||||
memcpy(dst, tmp, INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
@@ -181,9 +179,8 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
if(pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if(val > 0xffff)
|
||||
if(++saw_xdigit > 4)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if(ch == ':') {
|
||||
@@ -224,6 +221,8 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
const long n = tp - colonp;
|
||||
long i;
|
||||
|
||||
if(tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
@@ -232,7 +231,6 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
}
|
||||
if(tp != endp)
|
||||
return (0);
|
||||
/* bcopy(tmp, dst, IN6ADDRSZ); */
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -153,6 +153,8 @@ krb4_encode(void *app_data, const void *from, int length, int level, void **to,
|
||||
{
|
||||
struct krb4_data *d = app_data;
|
||||
*to = malloc(length + 31);
|
||||
if(!*to)
|
||||
return -1;
|
||||
if(level == prot_safe)
|
||||
/* NOTE that the void* cast is safe, krb_mk_safe/priv don't modify the
|
||||
* input buffer
|
||||
|
||||
@@ -48,6 +48,7 @@ OBJECTS = $(TMP_DIR)/base64.o \
|
||||
$(TMP_DIR)/connect.o \
|
||||
$(TMP_DIR)/content_encoding.o \
|
||||
$(TMP_DIR)/cookie.o \
|
||||
$(TMP_DIR)/curl_addrinfo.o \
|
||||
$(TMP_DIR)/dict.o \
|
||||
$(TMP_DIR)/easy.o \
|
||||
$(TMP_DIR)/escape.o \
|
||||
|
||||
@@ -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 \
|
||||
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 \
|
||||
sslgen.c gtls.c strerror.c rawstr.c
|
||||
sslgen.c gtls.c strerror.c rawstr.c curl_addrinfo.c
|
||||
|
||||
all: $(OBJS:.c=.o)
|
||||
ar cru libcurl.a $(OBJS:.c=.o)
|
||||
|
||||
31
lib/multi.c
31
lib/multi.c
@@ -620,22 +620,27 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
|
||||
}
|
||||
|
||||
/* we must call Curl_done() here (if we still "own it") so that we don't
|
||||
leave a half-baked one around */
|
||||
if(easy->easy_conn &&
|
||||
(easy->easy_conn->data == easy->easy_handle)) {
|
||||
if(easy->easy_conn) {
|
||||
|
||||
/* Curl_done() clears the conn->data field to lose the association
|
||||
between the easy handle and the connection
|
||||
/* we must call Curl_done() here (if we still "own it") so that we don't
|
||||
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
|
||||
really useful to do with it anyway! */
|
||||
(void)Curl_done(&easy->easy_conn, easy->result, premature);
|
||||
/* Curl_done() clears the conn->data field to lose the association
|
||||
between the easy handle and the connection
|
||||
|
||||
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;
|
||||
Note that this ignores the return code simply because there's
|
||||
nothing really useful to do with it anyway! */
|
||||
(void)Curl_done(&easy->easy_conn, easy->result, premature);
|
||||
|
||||
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
|
||||
|
||||
92
lib/nss.c
92
lib/nss.c
@@ -65,6 +65,7 @@
|
||||
#include <certdb.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "rawstr.h"
|
||||
#include "easyif.h" /* for Curl_convert_from_utf8 prototype */
|
||||
|
||||
/* 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 ckfalse = CK_FALSE;
|
||||
CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
|
||||
char *slotname = NULL;
|
||||
char slotname[SLOTSIZE];
|
||||
#endif
|
||||
CERTCertificate *cert;
|
||||
char *nickname = NULL;
|
||||
@@ -284,6 +285,8 @@ nss_load_cert(const char *filename, PRBool cacert)
|
||||
if(cacert)
|
||||
return 0; /* You can't specify an NSS CA nickname this way */
|
||||
nickname = strdup(filename);
|
||||
if(!nickname)
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -299,15 +302,15 @@ nss_load_cert(const char *filename, PRBool cacert)
|
||||
else
|
||||
slotID = 1;
|
||||
|
||||
slotname = malloc(SLOTSIZE);
|
||||
nickname = malloc(PATH_MAX);
|
||||
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);
|
||||
|
||||
if(!slot) {
|
||||
free(slotname);
|
||||
free(nickname);
|
||||
return 0;
|
||||
}
|
||||
@@ -334,7 +337,6 @@ nss_load_cert(const char *filename, PRBool cacert)
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
free(slotname);
|
||||
if(rv == NULL) {
|
||||
free(nickname);
|
||||
return 0;
|
||||
@@ -452,8 +454,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
|
||||
CK_SLOT_ID slotID;
|
||||
char *slotname = NULL;
|
||||
pphrase_arg_t *parg = NULL;
|
||||
char slotname[SLOTSIZE];
|
||||
|
||||
attrs = theTemplate;
|
||||
|
||||
@@ -461,11 +463,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
|
||||
|
||||
slotID = 1; /* hardcoded for now */
|
||||
|
||||
slotname = malloc(SLOTSIZE);
|
||||
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
|
||||
|
||||
snprintf(slotname, sizeof(slotname), "PEM Token #%ld", slotID);
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
free(slotname);
|
||||
|
||||
if(!slot)
|
||||
return 0;
|
||||
@@ -487,6 +486,8 @@ static int nss_load_key(struct connectdata *conn, char *key_file)
|
||||
PK11_IsPresent(slot);
|
||||
|
||||
parg = malloc(sizeof(pphrase_arg_t));
|
||||
if(!parg)
|
||||
return 0;
|
||||
parg->retryCount = 0;
|
||||
parg->data = conn->data;
|
||||
/* parg is initialized in nss_Init_Tokens() */
|
||||
@@ -583,6 +584,9 @@ static SECStatus nss_Init_Tokens(struct connectdata * conn)
|
||||
pphrase_arg_t *parg = NULL;
|
||||
|
||||
parg = malloc(sizeof(pphrase_arg_t));
|
||||
if(!parg)
|
||||
return SECFailure;
|
||||
|
||||
parg->retryCount = 0;
|
||||
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)
|
||||
*/
|
||||
static SECStatus check_issuer_cert(PRFileDesc *sock,
|
||||
char* issuer_nickname)
|
||||
char *issuer_nickname)
|
||||
{
|
||||
CERTCertificate *cert,*cert_issuer,*issuer;
|
||||
SECStatus res=SECSuccess;
|
||||
@@ -801,12 +805,11 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
|
||||
if(!strncmp(nickname, "PEM Token", 9)) {
|
||||
CK_SLOT_ID slotID = 1; /* hardcoded for now */
|
||||
char * slotname = malloc(SLOTSIZE);
|
||||
char slotname[SLOTSIZE];
|
||||
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
|
||||
PK11_FreeSlot(slot);
|
||||
free(slotname);
|
||||
if(privKey) {
|
||||
secStatus = SECSuccess;
|
||||
}
|
||||
@@ -973,12 +976,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
NSS_SetDomesticPolicy();
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
configstring = malloc(PATH_MAX);
|
||||
|
||||
PR_snprintf(configstring, PATH_MAX, "library=%s name=PEM", pem_library);
|
||||
|
||||
configstring = aprintf("library=%s name=PEM", pem_library);
|
||||
if(!configstring)
|
||||
goto error;
|
||||
mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
|
||||
free(configstring);
|
||||
|
||||
if(!mod || !mod->loaded) {
|
||||
if(mod) {
|
||||
SECMOD_DestroyModule(mod);
|
||||
@@ -1108,41 +1111,48 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
char *n;
|
||||
char *nickname;
|
||||
bool nickname_alloc = FALSE;
|
||||
|
||||
nickname = malloc(PATH_MAX);
|
||||
if(is_file(data->set.str[STRING_CERT])) {
|
||||
n = strrchr(data->set.str[STRING_CERT], '/');
|
||||
if(n) {
|
||||
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 {
|
||||
strncpy(nickname, data->set.str[STRING_CERT], PATH_MAX);
|
||||
nickname[PATH_MAX-1]=0; /* make sure this is zero terminated */
|
||||
nickname = data->set.str[STRING_CERT];
|
||||
}
|
||||
if(nss_Init_Tokens(conn) != SECSuccess) {
|
||||
free(nickname);
|
||||
if(nickname_alloc)
|
||||
free(nickname);
|
||||
goto error;
|
||||
}
|
||||
if(!cert_stuff(conn, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY])) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
free(nickname);
|
||||
if(nickname_alloc)
|
||||
free(nickname);
|
||||
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,
|
||||
(SSLGetClientAuthData) SelectClientCert,
|
||||
(void *)connssl) !=
|
||||
SECSuccess) {
|
||||
(void *)connssl) != SECSuccess) {
|
||||
curlerr = CURLE_SSL_CERTPROBLEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
free(nickname);
|
||||
|
||||
PK11_SetPasswordFunc(nss_no_password);
|
||||
}
|
||||
else
|
||||
@@ -1177,21 +1187,29 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
if (data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||
char *n;
|
||||
char *nickname;
|
||||
nickname = malloc(PATH_MAX);
|
||||
bool nickname_alloc = FALSE;
|
||||
SECStatus ret;
|
||||
|
||||
if(is_file(data->set.str[STRING_SSL_ISSUERCERT])) {
|
||||
n = strrchr(data->set.str[STRING_SSL_ISSUERCERT], '/');
|
||||
if (n) {
|
||||
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 {
|
||||
strncpy(nickname, data->set.str[STRING_SSL_ISSUERCERT], PATH_MAX);
|
||||
nickname[PATH_MAX-1]=0; /* make sure this is zero terminated */
|
||||
}
|
||||
if (check_issuer_cert(connssl->handle, nickname) == SECFailure) {
|
||||
infof(data,"SSL certificate issuer check failed\n");
|
||||
else
|
||||
nickname = data->set.str[STRING_SSL_ISSUERCERT];
|
||||
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
|
||||
if(nickname_alloc)
|
||||
free(nickname);
|
||||
|
||||
if(SECFailure == ret) {
|
||||
infof(data,"SSL certificate issuer check failed\n");
|
||||
curlerr = CURLE_SSL_ISSUER_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
11
lib/sendf.c
11
lib/sendf.c
@@ -47,7 +47,8 @@
|
||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||
#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"
|
||||
#else
|
||||
#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 defines are in sendf.h of course.
|
||||
@@ -442,6 +443,9 @@ CURLcode Curl_client_write(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
size_t wrote;
|
||||
|
||||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
/* 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
|
||||
can't work and it'll return error instead. */
|
||||
@@ -469,9 +473,6 @@ CURLcode Curl_client_write(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
if(type & CLIENTWRITE_BODY) {
|
||||
if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
/* OS/400 netdb.h does not define NI_MAXSERV. */
|
||||
#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. */
|
||||
typedef unsigned long u_int32_t;
|
||||
|
||||
|
||||
@@ -355,7 +355,6 @@
|
||||
# define sclose(x) close_s(x)
|
||||
# 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_3_ARGS
|
||||
# include <tcp.h>
|
||||
# ifdef word
|
||||
# undef word
|
||||
@@ -430,10 +429,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef mpeix
|
||||
#define IOCTL_3_ARGS
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
int netware_init(void);
|
||||
#ifndef __NOVELL_LIBC__
|
||||
|
||||
86
lib/ssh.c
86
lib/ssh.c
@@ -36,10 +36,6 @@
|
||||
#include <libssh2.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
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -103,6 +99,7 @@
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "strtoofft.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -421,7 +418,14 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
|
||||
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;
|
||||
struct SessionHandle *data = conn->data;
|
||||
@@ -432,8 +436,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
const char *fingerprint;
|
||||
#endif /* CURL_LIBSSH2_DEBUG */
|
||||
const char *host_public_key_md5;
|
||||
int rc,i;
|
||||
int rc = LIBSSH2_ERROR_NONE, i;
|
||||
int err;
|
||||
*block = 0; /* we're not blocking by default */
|
||||
|
||||
switch(sshc->state) {
|
||||
case SSH_S_STARTUP:
|
||||
@@ -519,6 +524,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->authlist) {
|
||||
if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -729,6 +735,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->sftp_session) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -996,21 +1003,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
* This takes an extra protocol round trip.
|
||||
*/
|
||||
rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
|
||||
&sshc->quote_attrs);
|
||||
&sshc->quote_attrs);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else if(rc != 0) { /* get those attributes */
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
sshc->quote_path2 = NULL;
|
||||
failf(data, "Attempt to get SFTP stats failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
break;
|
||||
err = libssh2_sftp_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
sshc->quote_path1 = NULL;
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
sshc->quote_path2 = NULL;
|
||||
failf(data, "Attempt to get SFTP stats failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,6 +1240,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1387,6 +1395,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1421,6 +1430,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
PATH_MAX,
|
||||
&sshc->readdir_attrs);
|
||||
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
if(sshc->readdir_len > 0) {
|
||||
@@ -1521,6 +1531,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
sshc->readdir_filename,
|
||||
PATH_MAX);
|
||||
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
Curl_safefree(sshc->readdir_linkPath);
|
||||
@@ -1578,6 +1589,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
case SSH_SFTP_READDIR_DONE:
|
||||
if(libssh2_sftp_closedir(sshc->sftp_handle) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
sshc->sftp_handle = NULL;
|
||||
@@ -1601,6 +1613,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->sftp_handle) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1814,6 +1827,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->ssh_channel) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1860,6 +1874,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
if(!sshc->ssh_channel) {
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -2011,6 +2026,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2019,8 +2040,11 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
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);
|
||||
|
||||
return result;
|
||||
@@ -2031,8 +2055,28 @@ static CURLcode ssh_easy_statemach(struct connectdata *conn)
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
while((sshc->state != SSH_STOP) && !result)
|
||||
result = ssh_statemach_act(conn);
|
||||
while((sshc->state != SSH_STOP) && !result) {
|
||||
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;
|
||||
}
|
||||
|
||||
18
lib/ssh.h
18
lib/ssh.h
@@ -1,6 +1,5 @@
|
||||
#ifndef __SSH_H
|
||||
#define __SSH_H
|
||||
|
||||
#ifndef HEADER_CURL_SSH_H
|
||||
#define HEADER_CURL_SSH_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -25,6 +24,17 @@
|
||||
***************************************************************************/
|
||||
|
||||
#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_sftp;
|
||||
|
||||
@@ -49,4 +59,4 @@ ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
#endif /* USE_LIBSSH2 */
|
||||
|
||||
#endif /* __SSH_H */
|
||||
#endif /* HEADER_CURL_SSH_H */
|
||||
|
||||
@@ -79,7 +79,6 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
#define Curl_ssl_init() 1
|
||||
#define Curl_ssl_cleanup() do { } while (0)
|
||||
#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(x,y)
|
||||
#define Curl_ssl_shutdown(x,y) CURLE_FAILED_INIT
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
|
||||
37
lib/url.c
37
lib/url.c
@@ -1487,17 +1487,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
break;
|
||||
case CURLOPT_MAX_SEND_SPEED_LARGE:
|
||||
/*
|
||||
* The max speed limit that sends transfer more than
|
||||
* CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is
|
||||
* throttled..
|
||||
* When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
|
||||
* bytes per second the transfer is throttled..
|
||||
*/
|
||||
data->set.max_send_speed=va_arg(param, curl_off_t);
|
||||
break;
|
||||
case CURLOPT_MAX_RECV_SPEED_LARGE:
|
||||
/*
|
||||
* The max speed limit that sends transfer more than
|
||||
* CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is
|
||||
* throttled..
|
||||
* When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
|
||||
* second the transfer is throttled..
|
||||
*/
|
||||
data->set.max_recv_speed=va_arg(param, curl_off_t);
|
||||
break;
|
||||
@@ -2361,6 +2359,20 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
|
||||
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 */
|
||||
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 */
|
||||
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 ||
|
||||
(needle->bits.httpproxy && check->bits.httpproxy &&
|
||||
needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
|
||||
@@ -4545,13 +4562,7 @@ CURLcode Curl_done(struct connectdata **connp,
|
||||
|
||||
Curl_expire(data, 0); /* stop timer */
|
||||
|
||||
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);
|
||||
Curl_getoff_all_pipelines(data, conn);
|
||||
|
||||
if(conn->bits.done ||
|
||||
(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
Reference in New Issue
Block a user