mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-01-13 13:17:36 +03:00
Applying IPv6 patch from Archana Shah <archana.shah@wipro.com>
closing bug #114837 * configure.in: Added checks for IPv6 support and getaddrinfo(). * acconfig.h: Defined HAVE_GETADDRINFO and SUPPORT_IP6. * config.h.in: Defined HAVE_GETADDRINFO and SUPPORT_IP6. * nanoftp.c: Structure xmlNanoFTPCtxt contains either sockaddr_storage field or sockaddr_in field, depending upon the availability of IPv6 support. have_ipv6(): Added to check for run-time IPv6 support. (xmlNanoFTPScanURL), (xmlNanoFTPUpdateURL), (xmlNanoFTPScanProxy): Modified to parse a URI with IPv6 address given in []. (xmlNanoFTPConnect): Changed to use getaddrinfo for address resolution, if it is available on the system, as gethostbyname does not return IPv6 addresses on some platforms. (xmlNanoFTPGetConnection): Modified type of dataAddr variable to sockaddr_storage or sockaddr_in depending upon the IPv6 support. Sending EPSV, EPRT or PASV, PORT depending upon the type of address we are dealing with. * nanohttp.c: (have_ipv6): Added to check for run-time IPv6 support. (xmlNanoHTTPScanURL), (xmlNanoHTTPScanProxy): Modified to parse a URI with IPv6 address given in []. (xmlNanoHTTPConnectHost): Modified to use getaddrinfo if it is available on the system. Also IPv6 addresses will be resolved by gethostbyname only if IPv6 run-time support is available. (xmlNanoHTTPConnectAttempt): Modified to deal with IPv6 address. Daniel
This commit is contained in:
parent
e8b5b0f148
commit
de2a67b430
33
ChangeLog
33
ChangeLog
@ -1,3 +1,36 @@
|
||||
Sat Jun 21 16:10:24 CEST 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
Applying IPv6 patch from Archana Shah <archana.shah@wipro.com>
|
||||
closing bug #114837
|
||||
|
||||
* configure.in: Added checks for IPv6 support and getaddrinfo().
|
||||
|
||||
* acconfig.h: Defined HAVE_GETADDRINFO and SUPPORT_IP6.
|
||||
|
||||
* config.h.in: Defined HAVE_GETADDRINFO and SUPPORT_IP6.
|
||||
|
||||
* nanoftp.c: Structure xmlNanoFTPCtxt contains either sockaddr_storage
|
||||
field or sockaddr_in field, depending upon the availability of IPv6
|
||||
support.
|
||||
have_ipv6(): Added to check for run-time IPv6 support.
|
||||
(xmlNanoFTPScanURL), (xmlNanoFTPUpdateURL), (xmlNanoFTPScanProxy):
|
||||
Modified to parse a URI with IPv6 address given in [].
|
||||
(xmlNanoFTPConnect): Changed to use getaddrinfo for address
|
||||
resolution, if it is available on the system, as gethostbyname
|
||||
does not return IPv6 addresses on some platforms.
|
||||
(xmlNanoFTPGetConnection): Modified type of dataAddr variable to
|
||||
sockaddr_storage or sockaddr_in depending upon the IPv6 support.
|
||||
Sending EPSV, EPRT or PASV, PORT depending upon the type of address
|
||||
we are dealing with.
|
||||
|
||||
* nanohttp.c: (have_ipv6): Added to check for run-time IPv6 support.
|
||||
(xmlNanoHTTPScanURL), (xmlNanoHTTPScanProxy): Modified to parse
|
||||
a URI with IPv6 address given in [].
|
||||
(xmlNanoHTTPConnectHost): Modified to use getaddrinfo if it is
|
||||
available on the system. Also IPv6 addresses will be resolved by
|
||||
gethostbyname only if IPv6 run-time support is available.
|
||||
(xmlNanoHTTPConnectAttempt): Modified to deal with IPv6 address.
|
||||
|
||||
Sat Jun 14 18:46:51 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
|
||||
|
||||
* win32/configure.js include/win32config.h
|
||||
|
@ -9,3 +9,9 @@
|
||||
#undef SOCKLEN_T
|
||||
#undef HAVE_LIBPTHREAD
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define if IPV6 support is there */
|
||||
#undef SUPPORT_IP6
|
||||
|
||||
/* Define if getaddrinfo is there */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
@ -11,6 +11,12 @@
|
||||
#undef HAVE_LIBPTHREAD
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define if IPv6 support is there. */
|
||||
#undef SUPPORT_IP6
|
||||
|
||||
/* Define if you have the getaddrinfo function. */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the <ansidecl.h> header file. */
|
||||
#undef HAVE_ANSIDECL_H
|
||||
|
||||
|
36
configure.in
36
configure.in
@ -192,6 +192,42 @@ AC_TRY_COMPILE2([
|
||||
AC_MSG_WARN(could not determine)])])])
|
||||
AC_DEFINE_UNQUOTED(SOCKLEN_T, $SOCKLEN_T)
|
||||
|
||||
dnl ***********************Checking for availability of IPv6*******************
|
||||
|
||||
AC_MSG_CHECKING([whether to enable IPv6])
|
||||
AC_ARG_ENABLE(ipv6, [ --enable-ipv6=[yes/no] enables compilation of IPv6 code],, enable_ipv6=yes)
|
||||
if test $enable_ipv6 = yes; then
|
||||
have_ipv6=no
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>], [
|
||||
struct sockaddr_storage ss;
|
||||
socket(AF_INET6, SOCK_STREAM, 0)
|
||||
],
|
||||
have_ipv6=yes,
|
||||
have_ipv6=no
|
||||
)
|
||||
AC_MSG_RESULT($have_ipv6)
|
||||
|
||||
if test $have_ipv6=yes; then
|
||||
AC_DEFINE(SUPPORT_IP6)
|
||||
|
||||
have_getaddrinfo=no
|
||||
AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes)
|
||||
if test $have_getaddrinfo != yes; then
|
||||
for lib in bsd socket inet; do
|
||||
AC_CHECK_LIB($lib, getaddrinfo, [LIBS="$LIBS -l$lib";have_getaddrinfo=yes;break])
|
||||
done
|
||||
fi
|
||||
|
||||
if test $have_getaddrinfo=yes; then
|
||||
AC_DEFINE(HAVE_GETADDRINFO)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ******************************End IPv6 checks******************************
|
||||
|
||||
dnl Checks for isnan in libm if not in libc
|
||||
AC_CHECK_FUNC(isnan, , AC_CHECK_LIB(m, isnan,
|
||||
[AC_DEFINE(HAVE_ISNAN)]))
|
||||
|
415
nanoftp.c
415
nanoftp.c
@ -62,6 +62,7 @@
|
||||
#include <libxml/uri.h>
|
||||
#include <libxml/nanoftp.h>
|
||||
#include <libxml/globals.h>
|
||||
#include <config.h>
|
||||
|
||||
/* #define DEBUG_FTP 1 */
|
||||
#ifdef STANDALONE
|
||||
@ -93,7 +94,11 @@ typedef struct xmlNanoFTPCtxt {
|
||||
char *path; /* the path within the URL */
|
||||
char *user; /* user string */
|
||||
char *passwd; /* passwd string */
|
||||
#ifdef SUPPORT_IP6
|
||||
struct sockaddr_storage ftpAddr; /* this is large enough to hold IPv6 address*/
|
||||
#else
|
||||
struct sockaddr_in ftpAddr; /* the socket address struct */
|
||||
#endif
|
||||
int passive; /* currently we support only passive !!! */
|
||||
SOCKET controlFd; /* the file descriptor for the control socket */
|
||||
SOCKET dataFd; /* the file descriptor for the data socket */
|
||||
@ -113,6 +118,19 @@ static char *proxyUser = NULL; /* user for proxy authentication */
|
||||
static char *proxyPasswd = NULL;/* passwd for proxy authentication */
|
||||
static int proxyType = 0; /* uses TYPE or a@b ? */
|
||||
|
||||
#ifdef SUPPORT_IP6
|
||||
static int have_ipv6() {
|
||||
int s;
|
||||
|
||||
s = socket (AF_INET6, SOCK_STREAM, 0);
|
||||
if (s != -1) {
|
||||
close (s);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xmlNanoFTPInit:
|
||||
*
|
||||
@ -289,26 +307,64 @@ xmlNanoFTPScanURL(void *ctx, const char *URL) {
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (cur[0] == ':') {
|
||||
if ((strchr (cur, '[') && !strchr (cur, ']')) ||
|
||||
(!strchr (cur, '[') && strchr (cur, ']'))) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanURL: %s",
|
||||
"Syntax Error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cur[0] == '[') {
|
||||
cur++;
|
||||
while (cur[0] != ']')
|
||||
buf[indx++] = *cur++;
|
||||
|
||||
if (!strchr (buf, ':')) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanURL: %s",
|
||||
"Use [IPv6]/IPv4 format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup(buf);
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
if (cur[0] == ':') {
|
||||
cur++;
|
||||
while (*cur >= '0' && *cur <= '9') {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup(buf);
|
||||
indx = 0;
|
||||
break;
|
||||
else { /* address is an IPv4 one*/
|
||||
if (cur[0] == ':') {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[indx++] = *cur++;
|
||||
}
|
||||
@ -371,29 +427,69 @@ xmlNanoFTPUpdateURL(void *ctx, const char *URL) {
|
||||
|
||||
buf[indx] = 0;
|
||||
while (1) {
|
||||
if (cur[0] == ':') {
|
||||
if ((strchr (cur, '[') && !strchr (cur, ']')) ||
|
||||
(!strchr (cur, '[') && strchr (cur, ']'))) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPUpdateURL: %s",
|
||||
"Syntax Error\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (cur[0] == '[') {
|
||||
cur++;
|
||||
while (cur[0] != ']')
|
||||
buf[indx++] = *cur++;
|
||||
|
||||
if (!strchr (buf, ':')) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPUpdateURL: %s",
|
||||
"Use [IPv6]/IPv4 format\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
buf[indx] = 0;
|
||||
if (strcmp(ctxt->hostname, buf))
|
||||
return(-1);
|
||||
if (strcmp (ctxt->hostname, buf))
|
||||
return (-1);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
if (cur[0] == ':') {
|
||||
cur++;
|
||||
while (*cur >= '0' && *cur <= '9') {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (port != ctxt->port)
|
||||
return (-1);
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
}
|
||||
if (port != ctxt->port)
|
||||
return(-1);
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
if (strcmp(ctxt->hostname, buf))
|
||||
return(-1);
|
||||
indx = 0;
|
||||
break;
|
||||
else {
|
||||
if (cur[0] == ':') {
|
||||
buf[indx] = 0;
|
||||
if (strcmp (ctxt->hostname, buf))
|
||||
return (-1);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != ctxt->port)
|
||||
return (-1);
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
if (strcmp (ctxt->hostname, buf))
|
||||
return (-1);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[indx++] = *cur++;
|
||||
}
|
||||
@ -460,26 +556,63 @@ xmlNanoFTPScanProxy(const char *URL) {
|
||||
|
||||
buf[indx] = 0;
|
||||
while (1) {
|
||||
if (cur[0] == ':') {
|
||||
if ((strchr (cur, '[') && !strchr (cur, ']')) ||
|
||||
(!strchr (cur, '[') && strchr (cur, ']'))) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanProxy: %s",
|
||||
"Syntax error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cur[0] == '[') {
|
||||
cur++;
|
||||
while (cur[0] != ']')
|
||||
buf[indx++] = *cur++;
|
||||
if (!strchr (buf, ':')) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanProxy: %s",
|
||||
"Use [IPv6]/IPv4 format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup(buf);
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
if (cur[0] == ':') {
|
||||
cur++;
|
||||
while (*cur >= '0' && *cur <= '9') {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup(buf);
|
||||
indx = 0;
|
||||
break;
|
||||
else {
|
||||
if (cur[0] == ':') {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[indx++] = *cur++;
|
||||
}
|
||||
@ -865,6 +998,7 @@ xmlNanoFTPConnect(void *ctx) {
|
||||
struct hostent *hp;
|
||||
int port;
|
||||
int res;
|
||||
int addrlen;
|
||||
|
||||
if (ctxt == NULL)
|
||||
return(-1);
|
||||
@ -874,19 +1008,6 @@ xmlNanoFTPConnect(void *ctx) {
|
||||
/*
|
||||
* do the blocking DNS query.
|
||||
*/
|
||||
if (proxy)
|
||||
hp = gethostbyname(proxy);
|
||||
else
|
||||
hp = gethostbyname(ctxt->hostname);
|
||||
if (hp == NULL)
|
||||
return(-1);
|
||||
|
||||
/*
|
||||
* Prepare the socket
|
||||
*/
|
||||
memset(&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
|
||||
ctxt->ftpAddr.sin_family = AF_INET;
|
||||
memcpy(&ctxt->ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
|
||||
if (proxy) {
|
||||
port = proxyPort;
|
||||
} else {
|
||||
@ -894,8 +1015,65 @@ xmlNanoFTPConnect(void *ctx) {
|
||||
}
|
||||
if (port == 0)
|
||||
port = 21;
|
||||
ctxt->ftpAddr.sin_port = htons(port);
|
||||
ctxt->controlFd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
memset (&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
|
||||
|
||||
#ifdef SUPPORT_IP6
|
||||
if (have_ipv6 ()) {
|
||||
struct addrinfo hints, *res, *result;
|
||||
|
||||
result = NULL;
|
||||
memset (&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (proxy) {
|
||||
if (getaddrinfo (proxy, NULL, &hints, &result) != 0)
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
if (getaddrinfo (ctxt->hostname, NULL, &hints, &result) != 0)
|
||||
return (-1);
|
||||
|
||||
for (res = result; res; res = res->ai_next)
|
||||
if (res->ai_family == AF_INET || res->ai_family == AF_INET6)
|
||||
break;
|
||||
|
||||
if (res) {
|
||||
if (res->ai_family == AF_INET6) {
|
||||
memcpy (&ctxt->ftpAddr, res->ai_addr, res->ai_addrlen);
|
||||
((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port);
|
||||
ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0);
|
||||
}
|
||||
else {
|
||||
memcpy (&ctxt->ftpAddr, res->ai_addr, res->ai_addrlen);
|
||||
((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port);
|
||||
ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
addrlen = res->ai_addrlen;
|
||||
freeaddrinfo (result);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (proxy)
|
||||
hp = gethostbyname (proxy);
|
||||
else
|
||||
hp = gethostbyname (ctxt->hostname);
|
||||
if (hp == NULL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Prepare the socket
|
||||
*/
|
||||
((struct sockaddr_in *)&ctxt->ftpAddr)->sin_family = AF_INET;
|
||||
memcpy (&((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr,
|
||||
hp->h_addr_list[0], hp->h_length);
|
||||
((struct sockaddr_in *)&ctxt->ftpAddr)->sin_port = htons (port);
|
||||
ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
if (ctxt->controlFd < 0)
|
||||
return(-1);
|
||||
|
||||
@ -903,7 +1081,7 @@ xmlNanoFTPConnect(void *ctx) {
|
||||
* Do the connect.
|
||||
*/
|
||||
if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
|
||||
sizeof(struct sockaddr_in)) < 0) {
|
||||
addrlen) < 0) {
|
||||
closesocket(ctxt->controlFd); ctxt->controlFd = -1;
|
||||
ctxt->controlFd = -1;
|
||||
return(-1);
|
||||
@ -1293,22 +1471,41 @@ xmlNanoFTPGetConnection(void *ctx) {
|
||||
int res;
|
||||
unsigned char ad[6], *adp, *portp;
|
||||
unsigned int temp[6];
|
||||
#ifdef SUPPORT_IP6
|
||||
struct sockaddr_storage dataAddr;
|
||||
#else
|
||||
struct sockaddr_in dataAddr;
|
||||
#endif
|
||||
SOCKLEN_T dataAddrLen;
|
||||
|
||||
ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (ctxt->dataFd < 0) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlNanoFTPGetConnection: failed to create socket\n");
|
||||
return(-1);
|
||||
memset (&dataAddr, 0, sizeof(dataAddr));
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6) {
|
||||
ctxt->dataFd = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
((struct sockaddr_in6 *)&dataAddr)->sin6_family = AF_INET6;
|
||||
dataAddrLen = sizeof(struct sockaddr_in6);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
((struct sockaddr_in *)&dataAddr)->sin_family = AF_INET;
|
||||
dataAddrLen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
if (ctxt->dataFd < 0) {
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"xmlNanoFTPGetConnection: failed to create socket\n");
|
||||
return (-1);
|
||||
}
|
||||
dataAddrLen = sizeof(dataAddr);
|
||||
memset(&dataAddr, 0, dataAddrLen);
|
||||
dataAddr.sin_family = AF_INET;
|
||||
|
||||
if (ctxt->passive) {
|
||||
snprintf(buf, sizeof(buf), "PASV\r\n");
|
||||
len = strlen(buf);
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6)
|
||||
snprintf (buf, sizeof(buf), "EPSV\r\n");
|
||||
else
|
||||
#endif
|
||||
snprintf (buf, sizeof(buf), "PASV\r\n");
|
||||
len = strlen (buf);
|
||||
#ifdef DEBUG_FTP
|
||||
xmlGenericError(xmlGenericErrorContext, "%s", buf);
|
||||
#endif
|
||||
@ -1332,18 +1529,36 @@ xmlNanoFTPGetConnection(void *ctx) {
|
||||
}
|
||||
cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
|
||||
while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
|
||||
if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
|
||||
&temp[3], &temp[4], &temp[5]) != 6) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"Invalid answer to PASV\n");
|
||||
if (ctxt->dataFd != -1) {
|
||||
closesocket(ctxt->dataFd); ctxt->dataFd = -1;
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6) {
|
||||
if (sscanf (cur, "%u", &temp[0]) != 1) {
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"Invalid answer to EPSV\n");
|
||||
if (ctxt->dataFd != -1) {
|
||||
closesocket (ctxt->dataFd); ctxt->dataFd = -1;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
return(-1);
|
||||
memcpy (&((struct sockaddr_in6 *)&dataAddr)->sin6_addr, &((struct sockaddr_in6 *)&ctxt->ftpAddr)->sin6_addr, sizeof(struct in6_addr));
|
||||
((struct sockaddr_in6 *)&dataAddr)->sin6_port = htons (temp[0]);
|
||||
}
|
||||
for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
|
||||
memcpy(&dataAddr.sin_addr, &ad[0], 4);
|
||||
memcpy(&dataAddr.sin_port, &ad[4], 2);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (sscanf (cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
|
||||
&temp[3], &temp[4], &temp[5]) != 6) {
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"Invalid answer to PASV\n");
|
||||
if (ctxt->dataFd != -1) {
|
||||
closesocket (ctxt->dataFd); ctxt->dataFd = -1;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
|
||||
memcpy (&((struct sockaddr_in *)&dataAddr)->sin_addr, &ad[0], 4);
|
||||
memcpy (&((struct sockaddr_in *)&dataAddr)->sin_port, &ad[4], 2);
|
||||
}
|
||||
|
||||
if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"Failed to create a data connection\n");
|
||||
@ -1352,7 +1567,13 @@ xmlNanoFTPGetConnection(void *ctx) {
|
||||
}
|
||||
} else {
|
||||
getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
|
||||
dataAddr.sin_port = 0;
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6)
|
||||
((struct sockaddr_in6 *)&dataAddr)->sin6_port = 0;
|
||||
else
|
||||
#endif
|
||||
((struct sockaddr_in *)&dataAddr)->sin_port = 0;
|
||||
|
||||
if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"Failed to bind a port\n");
|
||||
@ -1362,17 +1583,37 @@ xmlNanoFTPGetConnection(void *ctx) {
|
||||
getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
|
||||
|
||||
if (listen(ctxt->dataFd, 1) < 0) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"Could not listen on port %d\n",
|
||||
ntohs(dataAddr.sin_port));
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6)
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"Could not listen on port %d\n",
|
||||
ntohs (((struct sockaddr_in6 *)&dataAddr)->sin6_port));
|
||||
else
|
||||
#endif
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"Could not listen on port %d\n",
|
||||
ntohs (((struct sockaddr_in *)&dataAddr)->sin_port));
|
||||
closesocket(ctxt->dataFd); ctxt->dataFd = -1;
|
||||
return (-1);
|
||||
}
|
||||
adp = (unsigned char *) &dataAddr.sin_addr;
|
||||
portp = (unsigned char *) &dataAddr.sin_port;
|
||||
snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||
adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
|
||||
portp[0] & 0xff, portp[1] & 0xff);
|
||||
#ifdef SUPPORT_IP6
|
||||
if ((ctxt->ftpAddr).ss_family == AF_INET6) {
|
||||
char buf6[INET6_ADDRSTRLEN];
|
||||
inet_ntop (AF_INET6, &((struct sockaddr_in6 *)&dataAddr)->sin6_addr,
|
||||
buf6, INET6_ADDRSTRLEN);
|
||||
adp = buf6;
|
||||
portp = (unsigned char *) &((struct sockaddr_in6 *)&dataAddr)->sin6_port;
|
||||
snprintf (buf, sizeof(buf), "EPRT |2|%s|%s|\r\n", adp, portp);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
adp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_addr;
|
||||
portp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_port;
|
||||
snprintf (buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||
adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
|
||||
portp[0] & 0xff, portp[1] & 0xff);
|
||||
}
|
||||
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
len = strlen(buf);
|
||||
#ifdef DEBUG_FTP
|
||||
|
325
nanohttp.c
325
nanohttp.c
@ -77,6 +77,7 @@
|
||||
#include <libxml/nanohttp.h>
|
||||
#include <libxml/globals.h>
|
||||
#include <libxml/uri.h>
|
||||
#include <config.h>
|
||||
|
||||
/**
|
||||
* A couple portability macros
|
||||
@ -149,6 +150,19 @@ static int socket_errno(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_IP6
|
||||
static int have_ipv6() {
|
||||
int s;
|
||||
|
||||
s = socket (AF_INET6, SOCK_STREAM, 0);
|
||||
if (s != -1) {
|
||||
close (s);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xmlNanoHTTPInit:
|
||||
*
|
||||
@ -253,26 +267,64 @@ xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {
|
||||
|
||||
buf[indx] = 0;
|
||||
while (1) {
|
||||
if (cur[0] == ':') {
|
||||
if ((strchr (cur, '[') && !strchr (cur, ']')) ||
|
||||
(!strchr (cur, '[') && strchr (cur, ']'))) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoHTTPScanURL: %s",
|
||||
"Syntax Error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cur[0] == '[') {
|
||||
cur++;
|
||||
while (cur[0] != ']')
|
||||
buf[indx++] = *cur++;
|
||||
|
||||
if (!strchr (buf, ':')) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoHTTPScanURL: %s",
|
||||
"Use [IPv6]/IPv4 format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup(buf);
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
if (cur[0] == ':') {
|
||||
cur++;
|
||||
while (*cur >= '0' && *cur <= '9') {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup(buf);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (cur[0] == ':') {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) ctxt->port = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
ctxt->hostname = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[indx++] = *cur++;
|
||||
}
|
||||
@ -335,26 +387,64 @@ xmlNanoHTTPScanProxy(const char *URL) {
|
||||
|
||||
buf[indx] = 0;
|
||||
while (1) {
|
||||
if (cur[0] == ':') {
|
||||
if ((strchr (cur, '[') && !strchr (cur, ']')) ||
|
||||
(!strchr (cur, '[') && strchr (cur, ']'))) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoHTTPScanProxy: %s",
|
||||
"Syntax error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cur[0] == '[') {
|
||||
cur++;
|
||||
while (cur[0] != ']')
|
||||
buf[indx++] = *cur++;
|
||||
|
||||
if (!strchr (buf, ':')) {
|
||||
xmlGenericError (xmlGenericErrorContext, "\nxmlNanoHTTPScanProxy: %s",
|
||||
"Use [IPv6]/IPv4 format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup(buf);
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
if (cur[0] == ':') {
|
||||
cur++;
|
||||
while (*cur >= '0' && *cur <= '9') {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur ++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup(buf);
|
||||
indx = 0;
|
||||
break;
|
||||
else {
|
||||
if (cur[0] == ':') {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
cur += 1;
|
||||
while ((*cur >= '0') && (*cur <= '9')) {
|
||||
port *= 10;
|
||||
port += *cur - '0';
|
||||
cur++;
|
||||
}
|
||||
if (port != 0) proxyPort = port;
|
||||
while ((cur[0] != '/') && (*cur != 0))
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if ((*cur == '/') || (*cur == 0)) {
|
||||
buf[indx] = 0;
|
||||
proxy = xmlMemStrdup (buf);
|
||||
indx = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[indx++] = *cur++;
|
||||
}
|
||||
@ -711,11 +801,23 @@ xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {
|
||||
static int
|
||||
xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
|
||||
{
|
||||
SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
fd_set wfd;
|
||||
struct timeval tv;
|
||||
int status;
|
||||
int addrlen;
|
||||
SOCKET s;
|
||||
|
||||
#ifdef SUPPORT_IP6
|
||||
if (addr->sa_family == AF_INET6) {
|
||||
s = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
addrlen = sizeof (struct sockaddr_in6);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
addrlen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
if (s==-1) {
|
||||
#ifdef DEBUG_HTTP
|
||||
perror("socket");
|
||||
@ -764,7 +866,7 @@ xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
|
||||
#endif /* !VMS */
|
||||
#endif /* !_WINSOCKAPI_ */
|
||||
|
||||
if ((connect(s, addr, sizeof(*addr))==-1)) {
|
||||
if (connect (s, addr, addrlen) == -1) {
|
||||
switch (socket_errno()) {
|
||||
case EINPROGRESS:
|
||||
case EWOULDBLOCK:
|
||||
@ -862,13 +964,64 @@ xmlNanoHTTPConnectHost(const char *host, int port)
|
||||
int i;
|
||||
int s;
|
||||
|
||||
#if defined(SUPPORT_IP6) && defined(RES_USE_INET6)
|
||||
if (!(_res.options & RES_INIT))
|
||||
res_init();
|
||||
_res.options |= RES_USE_INET6;
|
||||
memset (&sockin, 0, sizeof(sockin));
|
||||
#ifdef SUPPORT_IP6
|
||||
memset (&sockin6, 0, sizeof(sockin6));
|
||||
if (have_ipv6 ())
|
||||
{
|
||||
#if !defined(HAVE_GETADDRINFO) && defined(RES_USE_INET6)
|
||||
if (!(_res.options & RES_INIT))
|
||||
res_init();
|
||||
_res.options |= RES_USE_INET6;
|
||||
}
|
||||
#elif defined(HAVE_GETADDRINFO)
|
||||
int status;
|
||||
struct addrinfo hints, *res, *result;
|
||||
|
||||
result = NULL;
|
||||
memset (&hints, 0,sizeof(hints));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
status = getaddrinfo (host, NULL, &hints, &result);
|
||||
if (status) {
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: %s '%s' - %s",
|
||||
"Failed to resolve host", host, gai_strerror (status));
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (res = result; res; res = res->ai_next) {
|
||||
if (res) {
|
||||
if (res->ai_family == AF_INET6) {
|
||||
memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
|
||||
sockin6.sin6_port = htons (port);
|
||||
addr = (struct sockaddr *)&sockin6;
|
||||
}
|
||||
|
||||
if (res->ai_family == AF_INET) {
|
||||
memcpy (&sockin, res->ai_addr, res->ai_addrlen);
|
||||
sockin.sin_port = htons (port);
|
||||
addr = (struct sockaddr *)&sockin;
|
||||
}
|
||||
|
||||
s = xmlNanoHTTPConnectAttempt (addr);
|
||||
if (s != -1) {
|
||||
freeaddrinfo (result);
|
||||
return (s);
|
||||
}
|
||||
}
|
||||
else {
|
||||
freeaddrinfo (result);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
h = gethostbyname(host);
|
||||
if (h == NULL) {
|
||||
#endif
|
||||
{
|
||||
h = gethostbyname (host);
|
||||
if (h == NULL) {
|
||||
|
||||
/*
|
||||
* Okay, I got fed up by the non-portability of this error message
|
||||
@ -876,68 +1029,68 @@ xmlNanoHTTPConnectHost(const char *host, int port)
|
||||
* and one want to enable it, send me the defined(foobar) needed
|
||||
*/
|
||||
#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)
|
||||
const char *h_err_txt = "";
|
||||
const char *h_err_txt = "";
|
||||
|
||||
switch (h_errno) {
|
||||
case HOST_NOT_FOUND:
|
||||
h_err_txt = "Authoritive host not found";
|
||||
break;
|
||||
switch (h_errno) {
|
||||
case HOST_NOT_FOUND:
|
||||
h_err_txt = "Authoritive host not found";
|
||||
break;
|
||||
|
||||
case TRY_AGAIN:
|
||||
h_err_txt =
|
||||
"Non-authoritive host not found or server failure.";
|
||||
break;
|
||||
case TRY_AGAIN:
|
||||
h_err_txt =
|
||||
"Non-authoritive host not found or server failure.";
|
||||
break;
|
||||
|
||||
case NO_RECOVERY:
|
||||
h_err_txt =
|
||||
"Non-recoverable errors: FORMERR, REFUSED, or NOTIMP.";
|
||||
break;
|
||||
case NO_RECOVERY:
|
||||
h_err_txt =
|
||||
"Non-recoverable errors: FORMERR, REFUSED, or NOTIMP.";
|
||||
break;
|
||||
|
||||
case NO_ADDRESS:
|
||||
h_err_txt =
|
||||
"Valid name, no data record of requested type.";
|
||||
break;
|
||||
case NO_ADDRESS:
|
||||
h_err_txt =
|
||||
"Valid name, no data record of requested type.";
|
||||
break;
|
||||
|
||||
default:
|
||||
h_err_txt = "No error text defined.";
|
||||
break;
|
||||
}
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: %s '%s' - %s",
|
||||
"Failed to resolve host", host, h_err_txt);
|
||||
default:
|
||||
h_err_txt = "No error text defined.";
|
||||
break;
|
||||
}
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: %s '%s' - %s",
|
||||
"Failed to resolve host", host, h_err_txt);
|
||||
#else
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: %s '%s'",
|
||||
"Failed to resolve host", host);
|
||||
xmlGenericError (xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: %s '%s'",
|
||||
"Failed to resolve host", host);
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i = 0; h->h_addr_list[i]; i++) {
|
||||
if (h->h_addrtype == AF_INET) {
|
||||
/* A records (IPv4) */
|
||||
memcpy(&ia, h->h_addr_list[i], h->h_length);
|
||||
sockin.sin_family = h->h_addrtype;
|
||||
sockin.sin_addr = ia;
|
||||
sockin.sin_port = htons(port);
|
||||
addr = (struct sockaddr *) &sockin;
|
||||
for (i = 0; h->h_addr_list[i]; i++) {
|
||||
if (h->h_addrtype == AF_INET) {
|
||||
/* A records (IPv4) */
|
||||
memcpy (&ia, h->h_addr_list[i], h->h_length);
|
||||
sockin.sin_family = h->h_addrtype;
|
||||
sockin.sin_addr = ia;
|
||||
sockin.sin_port = htons (port);
|
||||
addr = (struct sockaddr *) &sockin;
|
||||
#ifdef SUPPORT_IP6
|
||||
} else if (h->h_addrtype == AF_INET6) {
|
||||
/* AAAA records (IPv6) */
|
||||
memcpy(&ia6, h->h_addr_list[i], h->h_length);
|
||||
sockin6.sin_family = h->h_addrtype;
|
||||
sockin6.sin_addr = ia6;
|
||||
sockin6.sin_port = htons(port);
|
||||
addr = (struct sockaddr *) &sockin6;
|
||||
} else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) {
|
||||
/* AAAA records (IPv6) */
|
||||
memcpy (&ia6, h->h_addr_list[i], h->h_length);
|
||||
sockin6.sin6_family = h->h_addrtype;
|
||||
sockin6.sin6_addr = ia6;
|
||||
sockin6.sin6_port = htons (port);
|
||||
addr = (struct sockaddr *) &sockin6;
|
||||
#endif
|
||||
} else
|
||||
break; /* for */
|
||||
} else
|
||||
break; /* for */
|
||||
|
||||
s = xmlNanoHTTPConnectAttempt(addr);
|
||||
if (s != -1)
|
||||
return (s);
|
||||
s = xmlNanoHTTPConnectAttempt (addr);
|
||||
if (s != -1)
|
||||
return (s);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HTTP
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"xmlNanoHTTPConnectHost: unable to connect to '%s'.\n",
|
||||
|
Loading…
Reference in New Issue
Block a user