Source cleanups. The major one being that we now _always_ use a Curl_addrinfo
linked list for name resolved data, even on hosts/systems with only IPv4 stacks as this simplifies a lot of code.
This commit is contained in:
parent
818aed35e2
commit
c39858aac0
@ -330,7 +330,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
Curl_resolv_unlock(data, h);
|
Curl_resolv_unlock(data, h);
|
||||||
/* we don't need it anymore after this function has returned */
|
/* we don't need it anymore after this function has returned */
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
if( bind(sockfd, addr->ai_addr, addr->ai_addrlen) >= 0) {
|
if( bind(sockfd, addr->ai_addr, addr->ai_addrlen) >= 0) {
|
||||||
/* we succeeded to bind */
|
/* we succeeded to bind */
|
||||||
struct sockaddr_in6 add;
|
struct sockaddr_in6 add;
|
||||||
@ -344,31 +343,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
{
|
|
||||||
struct sockaddr_in sa;
|
|
||||||
|
|
||||||
memset((char *)&sa, 0, sizeof(sa));
|
|
||||||
memcpy((char *)&sa.sin_addr, addr->h_addr, addr->h_length);
|
|
||||||
sa.sin_family = AF_INET;
|
|
||||||
sa.sin_addr.s_addr = in;
|
|
||||||
sa.sin_port = 0; /* get any port */
|
|
||||||
|
|
||||||
if( bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) >= 0) {
|
|
||||||
/* we succeeded to bind */
|
|
||||||
struct sockaddr_in add;
|
|
||||||
|
|
||||||
bindworked = TRUE;
|
|
||||||
|
|
||||||
size = sizeof(add);
|
|
||||||
if(getsockname(sockfd, (struct sockaddr *) &add,
|
|
||||||
(socklen_t *)&size)<0) {
|
|
||||||
failf(data, "getsockname() failed");
|
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(!bindworked) {
|
if(!bindworked) {
|
||||||
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
|
failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
@ -540,9 +515,8 @@ static void tcpnodelay(struct connectdata *conn,
|
|||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||||
struct Curl_dns_entry *remotehost, /* use this one */
|
struct Curl_dns_entry *remotehost, /* use this one */
|
||||||
int port, /* connect to this */
|
|
||||||
curl_socket_t *sockconn, /* the connected socket */
|
curl_socket_t *sockconn, /* the connected socket */
|
||||||
Curl_ipconnect **addr, /* the one we used */
|
Curl_addrinfo **addr, /* the one we used */
|
||||||
bool *connected) /* really connected? */
|
bool *connected) /* really connected? */
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
@ -552,8 +526,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
int num_addr;
|
int num_addr;
|
||||||
bool conected;
|
bool conected;
|
||||||
char addr_buf[256];
|
char addr_buf[256];
|
||||||
|
Curl_addrinfo *ai;
|
||||||
|
Curl_addrinfo *curr_addr;
|
||||||
|
|
||||||
Curl_ipconnect *curr_addr;
|
|
||||||
struct timeval after;
|
struct timeval after;
|
||||||
struct timeval before = Curl_tvnow();
|
struct timeval before = Curl_tvnow();
|
||||||
|
|
||||||
@ -601,17 +576,18 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
num_addr = Curl_num_addresses(remotehost->addr);
|
num_addr = Curl_num_addresses(remotehost->addr);
|
||||||
timeout_per_addr = timeout_ms / num_addr;
|
timeout_per_addr = timeout_ms / num_addr;
|
||||||
|
|
||||||
|
ai = remotehost->addr;
|
||||||
|
|
||||||
/* Below is the loop that attempts to connect to all IP-addresses we
|
/* Below is the loop that attempts to connect to all IP-addresses we
|
||||||
* know for the given host. One by one until one IP succeedes.
|
* know for the given host. One by one until one IP succeedes.
|
||||||
*/
|
*/
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
/*
|
/*
|
||||||
* Connecting with a getaddrinfo chain
|
* Connecting with a getaddrinfo chain
|
||||||
*/
|
*/
|
||||||
(void)port; /* the port number is already included in the getaddrinfo
|
for (curr_addr = ai, aliasindex=0; curr_addr;
|
||||||
struct */
|
|
||||||
for (curr_addr = remotehost->addr, aliasindex=0; curr_addr;
|
|
||||||
curr_addr = curr_addr->ai_next, aliasindex++) {
|
curr_addr = curr_addr->ai_next, aliasindex++) {
|
||||||
|
|
||||||
sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype,
|
sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype,
|
||||||
curr_addr->ai_protocol);
|
curr_addr->ai_protocol);
|
||||||
if (sockfd == CURL_SOCKET_BAD) {
|
if (sockfd == CURL_SOCKET_BAD) {
|
||||||
@ -619,31 +595,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Connecting with old style IPv4-only support
|
|
||||||
*/
|
|
||||||
curr_addr = (Curl_ipconnect*)remotehost->addr->h_addr_list[0];
|
|
||||||
for(aliasindex=0; curr_addr;
|
|
||||||
curr_addr=(Curl_ipconnect*)remotehost->addr->h_addr_list[++aliasindex]) {
|
|
||||||
struct sockaddr_in serv_addr;
|
|
||||||
|
|
||||||
/* create an IPv4 TCP socket */
|
|
||||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if(CURL_SOCKET_BAD == sockfd) {
|
|
||||||
failf(data, "couldn't create socket");
|
|
||||||
return CURLE_COULDNT_CONNECT; /* big time error */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nasty address work before connect can be made */
|
|
||||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
|
||||||
memcpy((char *)&(serv_addr.sin_addr), curr_addr,
|
|
||||||
sizeof(struct in_addr));
|
|
||||||
serv_addr.sin_family = remotehost->addr->h_addrtype;
|
|
||||||
serv_addr.sin_port = htons((unsigned short)port);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Curl_printable_address(curr_addr, addr_buf, sizeof(addr_buf));
|
Curl_printable_address(curr_addr, addr_buf, sizeof(addr_buf));
|
||||||
infof(data, " Trying %s... ", addr_buf);
|
infof(data, " Trying %s... ", addr_buf);
|
||||||
|
|
||||||
@ -664,11 +615,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
/* do not use #ifdef within the function arguments below, as connect() is
|
/* do not use #ifdef within the function arguments below, as connect() is
|
||||||
a defined macro on some platforms and some compilers don't like to mix
|
a defined macro on some platforms and some compilers don't like to mix
|
||||||
#ifdefs with macro usage! (AmigaOS is one such platform) */
|
#ifdefs with macro usage! (AmigaOS is one such platform) */
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
rc = connect(sockfd, curr_addr->ai_addr, curr_addr->ai_addrlen);
|
rc = connect(sockfd, curr_addr->ai_addr, curr_addr->ai_addrlen);
|
||||||
#else
|
|
||||||
rc = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
error = Curl_ourerrno();
|
error = Curl_ourerrno();
|
||||||
|
@ -32,9 +32,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||||
struct Curl_dns_entry *host, /* connect to this */
|
struct Curl_dns_entry *host, /* connect to this */
|
||||||
int port, /* connect to this port number */
|
|
||||||
curl_socket_t *sockconn, /* not set if error */
|
curl_socket_t *sockconn, /* not set if error */
|
||||||
Curl_ipconnect **addr, /* the one we used */
|
Curl_addrinfo **addr, /* the one we used */
|
||||||
bool *connected /* truly connected? */
|
bool *connected /* truly connected? */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
58
lib/easy.c
58
lib/easy.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -96,36 +96,36 @@ static void win32_cleanup(void)
|
|||||||
stack to allow networking */
|
stack to allow networking */
|
||||||
static CURLcode win32_init(void)
|
static CURLcode win32_init(void)
|
||||||
{
|
{
|
||||||
WORD wVersionRequested;
|
WORD wVersionRequested;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
wVersionRequested = MAKEWORD(2, 0);
|
wVersionRequested = MAKEWORD(2, 0);
|
||||||
#else
|
#else
|
||||||
wVersionRequested = MAKEWORD(1, 1);
|
wVersionRequested = MAKEWORD(1, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = WSAStartup(wVersionRequested, &wsaData);
|
err = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
/* Tell the user that we couldn't find a useable */
|
/* Tell the user that we couldn't find a useable */
|
||||||
/* winsock.dll. */
|
/* winsock.dll. */
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
/* Confirm that the Windows Sockets DLL supports what we need.*/
|
/* Confirm that the Windows Sockets DLL supports what we need.*/
|
||||||
/* Note that if the DLL supports versions greater */
|
/* Note that if the DLL supports versions greater */
|
||||||
/* than wVersionRequested, it will still return */
|
/* than wVersionRequested, it will still return */
|
||||||
/* wVersionRequested in wVersion. wHighVersion contains the */
|
/* wVersionRequested in wVersion. wHighVersion contains the */
|
||||||
/* highest supported version. */
|
/* highest supported version. */
|
||||||
|
|
||||||
if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
|
||||||
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
|
||||||
/* Tell the user that we couldn't find a useable */
|
/* Tell the user that we couldn't find a useable */
|
||||||
|
|
||||||
/* winsock.dll. */
|
/* winsock.dll. */
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@ -207,7 +207,7 @@ CURLcode curl_global_init(long flags)
|
|||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
init_flags = flags;
|
init_flags = flags;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ CURL *curl_easy_init(void)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* curl_easy_setopt() is the external interface for setting options on an
|
* curl_easy_setopt() is the external interface for setting options on an
|
||||||
* easy handle.
|
* easy handle.
|
||||||
*/
|
*/
|
||||||
@ -373,9 +373,9 @@ CURLcode curl_easy_perform(CURL *curl)
|
|||||||
screwed up and we should bail out! */
|
screwed up and we should bail out! */
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Curl_perform(data);
|
return Curl_perform(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,60 +1426,6 @@ int main()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _OLD_FORM_DEBUG
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
char *testargs[]={
|
|
||||||
"name1 = data in number one",
|
|
||||||
"name2 = number two data",
|
|
||||||
"test = @upload"
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
int i;
|
|
||||||
char *nextarg;
|
|
||||||
struct curl_httppost *httppost=NULL;
|
|
||||||
struct curl_httppost *last_post=NULL;
|
|
||||||
struct curl_httppost *post;
|
|
||||||
int size;
|
|
||||||
int nread;
|
|
||||||
char buffer[4096];
|
|
||||||
|
|
||||||
struct FormData *form;
|
|
||||||
struct Form formread;
|
|
||||||
|
|
||||||
for(i=1; i<argc; i++) {
|
|
||||||
|
|
||||||
if( FormParse( argv[i],
|
|
||||||
&httppost,
|
|
||||||
&last_post)) {
|
|
||||||
fprintf(stderr, "Illegally formatted input field: '%s'!\n",
|
|
||||||
argv[i]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
form=Curl_getFormData(httppost, &size);
|
|
||||||
|
|
||||||
Curl_FormInit(&formread, form);
|
|
||||||
|
|
||||||
do {
|
|
||||||
nread = Curl_FormReader(buffer, 1, sizeof(buffer),
|
|
||||||
(FILE *)&formread);
|
|
||||||
|
|
||||||
if(-1 == nread)
|
|
||||||
break;
|
|
||||||
fwrite(buffer, nread, 1, stderr);
|
|
||||||
} while(1);
|
|
||||||
|
|
||||||
fprintf(stderr, "size: %d\n", size);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* CURL_DISABLE_HTTP */
|
#else /* CURL_DISABLE_HTTP */
|
||||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||||
struct curl_httppost **last_post,
|
struct curl_httppost **last_post,
|
||||||
|
212
lib/ftp.c
212
lib/ftp.c
@ -93,6 +93,7 @@
|
|||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "inet_ntop.h"
|
||||||
|
|
||||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||||
#include "inet_ntoa_r.h"
|
#include "inet_ntoa_r.h"
|
||||||
@ -1022,121 +1023,13 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ftp_pasv_verbose(struct connectdata *conn,
|
ftp_pasv_verbose(struct connectdata *conn,
|
||||||
Curl_ipconnect *addr,
|
Curl_addrinfo *ai,
|
||||||
char *newhost, /* ascii version */
|
char *newhost, /* ascii version */
|
||||||
int port)
|
int port)
|
||||||
{
|
{
|
||||||
#ifndef ENABLE_IPV6
|
char buf[256];
|
||||||
/*****************************************************************
|
Curl_printable_address(ai, buf, sizeof(buf));
|
||||||
*
|
infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
|
||||||
* IPv4-only code section
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct in_addr in;
|
|
||||||
struct hostent * answer;
|
|
||||||
|
|
||||||
#ifdef HAVE_INET_NTOA_R
|
|
||||||
char ntoa_buf[64];
|
|
||||||
#endif
|
|
||||||
/* The array size trick below is to make this a large chunk of memory
|
|
||||||
suitably 8-byte aligned on 64-bit platforms. This was thoughtfully
|
|
||||||
suggested by Philip Gladstone. */
|
|
||||||
long bigbuf[9000 / sizeof(long)];
|
|
||||||
|
|
||||||
#if defined(HAVE_INET_ADDR)
|
|
||||||
in_addr_t address;
|
|
||||||
# if defined(HAVE_GETHOSTBYADDR_R)
|
|
||||||
int h_errnop;
|
|
||||||
# endif
|
|
||||||
char *hostent_buf = (char *)bigbuf; /* get a char * to the buffer */
|
|
||||||
|
|
||||||
address = inet_addr(newhost);
|
|
||||||
# ifdef HAVE_GETHOSTBYADDR_R
|
|
||||||
|
|
||||||
# ifdef HAVE_GETHOSTBYADDR_R_5
|
|
||||||
/* AIX, Digital Unix (OSF1, Tru64) style:
|
|
||||||
extern int gethostbyaddr_r(char *addr, size_t len, int type,
|
|
||||||
struct hostent *htent, struct hostent_data *ht_data); */
|
|
||||||
|
|
||||||
/* Fred Noz helped me try this out, now it at least compiles! */
|
|
||||||
|
|
||||||
/* Bjorn Reese (November 28 2001):
|
|
||||||
The Tru64 man page on gethostbyaddr_r() says that
|
|
||||||
the hostent struct must be filled with zeroes before the call to
|
|
||||||
gethostbyaddr_r().
|
|
||||||
|
|
||||||
... as must be struct hostent_data Craig Markwardt 19 Sep 2002. */
|
|
||||||
|
|
||||||
memset(hostent_buf, 0, sizeof(struct hostent)+sizeof(struct hostent_data));
|
|
||||||
|
|
||||||
if(gethostbyaddr_r((char *) &address,
|
|
||||||
sizeof(address), AF_INET,
|
|
||||||
(struct hostent *)hostent_buf,
|
|
||||||
(struct hostent_data *)(hostent_buf + sizeof(*answer))))
|
|
||||||
answer=NULL;
|
|
||||||
else
|
|
||||||
answer=(struct hostent *)hostent_buf;
|
|
||||||
|
|
||||||
# endif
|
|
||||||
# ifdef HAVE_GETHOSTBYADDR_R_7
|
|
||||||
/* Solaris and IRIX */
|
|
||||||
answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
|
|
||||||
(struct hostent *)bigbuf,
|
|
||||||
hostent_buf + sizeof(*answer),
|
|
||||||
sizeof(bigbuf) - sizeof(*answer),
|
|
||||||
&h_errnop);
|
|
||||||
# endif
|
|
||||||
# ifdef HAVE_GETHOSTBYADDR_R_8
|
|
||||||
/* Linux style */
|
|
||||||
if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
|
|
||||||
(struct hostent *)hostent_buf,
|
|
||||||
hostent_buf + sizeof(*answer),
|
|
||||||
sizeof(bigbuf) - sizeof(*answer),
|
|
||||||
&answer,
|
|
||||||
&h_errnop))
|
|
||||||
answer=NULL; /* error */
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# else
|
|
||||||
(void)hostent_buf; /* avoid compiler warning */
|
|
||||||
answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
answer = NULL;
|
|
||||||
#endif
|
|
||||||
(void) memcpy(&in.s_addr, addr, sizeof (Curl_ipconnect));
|
|
||||||
infof(conn->data, "Connecting to %s (%s) port %u\n",
|
|
||||||
answer?answer->h_name:newhost,
|
|
||||||
#if defined(HAVE_INET_NTOA_R)
|
|
||||||
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
|
|
||||||
#else
|
|
||||||
inet_ntoa(in),
|
|
||||||
#endif
|
|
||||||
port);
|
|
||||||
|
|
||||||
#else
|
|
||||||
/*****************************************************************
|
|
||||||
*
|
|
||||||
* IPv6-only code section
|
|
||||||
*/
|
|
||||||
char hbuf[NI_MAXHOST]; /* ~1KB */
|
|
||||||
char nbuf[NI_MAXHOST]; /* ~1KB */
|
|
||||||
char sbuf[NI_MAXSERV]; /* around 32 */
|
|
||||||
(void)port; /* prevent compiler warning */
|
|
||||||
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
|
||||||
nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), NIFLAGS)) {
|
|
||||||
snprintf(nbuf, sizeof(nbuf), "?");
|
|
||||||
snprintf(sbuf, sizeof(sbuf), "?");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
|
|
||||||
hbuf, sizeof(hbuf), NULL, 0, 0)) {
|
|
||||||
infof(conn->data, "Connecting to %s (%s) port %s\n", nbuf, newhost, sbuf);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
infof(conn->data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1381,36 +1274,44 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct Curl_dns_entry *h=NULL;
|
|
||||||
unsigned short porttouse;
|
unsigned short porttouse;
|
||||||
char myhost[256] = "";
|
char myhost[256] = "";
|
||||||
bool sa_filled_in = FALSE;
|
bool sa_filled_in = FALSE;
|
||||||
|
Curl_addrinfo *addr = NULL;
|
||||||
|
unsigned short ip[4];
|
||||||
|
|
||||||
if(data->set.ftpport) {
|
if(data->set.ftpport) {
|
||||||
in_addr_t in;
|
in_addr_t in;
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* First check if the given name is an IP address */
|
/* First check if the given name is an IP address */
|
||||||
in=inet_addr(data->set.ftpport);
|
in=inet_addr(data->set.ftpport);
|
||||||
|
|
||||||
if((in == CURL_INADDR_NONE) &&
|
if(in != CURL_INADDR_NONE)
|
||||||
Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
|
/* this is an IPv4 address */
|
||||||
rc = Curl_resolv(conn, myhost, 0, &h);
|
addr = Curl_ip2addr(in, data->set.ftpport, 0);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
|
||||||
rc = Curl_wait_for_resolv(conn, &h);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
size_t len = strlen(data->set.ftpport);
|
if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
|
||||||
if(len>1) {
|
/* The interface to IP conversion provided a dotted address */
|
||||||
rc = Curl_resolv(conn, data->set.ftpport, 0, &h);
|
in=inet_addr(myhost);
|
||||||
|
addr = Curl_ip2addr(in, myhost, 0);
|
||||||
|
}
|
||||||
|
else if(strlen(data->set.ftpport)> 1) {
|
||||||
|
/* might be a host name! */
|
||||||
|
struct Curl_dns_entry *h=NULL;
|
||||||
|
int rc = Curl_resolv(conn, myhost, 0, &h);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
rc = Curl_wait_for_resolv(conn, &h);
|
rc = Curl_wait_for_resolv(conn, &h);
|
||||||
}
|
if(h) {
|
||||||
if(h)
|
addr = h->addr;
|
||||||
strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
|
/* when we return from this function, we can forget about this entry
|
||||||
}
|
to we can unlock it now already */
|
||||||
}
|
Curl_resolv_unlock(data, h);
|
||||||
if(! *myhost) {
|
} /* (h) */
|
||||||
|
} /* strlen */
|
||||||
|
} /* CURL_INADDR_NONE */
|
||||||
|
} /* data->set.ftpport */
|
||||||
|
|
||||||
|
if(!addr) {
|
||||||
/* pick a suitable default here */
|
/* pick a suitable default here */
|
||||||
|
|
||||||
socklen_t sslen;
|
socklen_t sslen;
|
||||||
@ -1425,12 +1326,9 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
sa_filled_in = TRUE; /* the sa struct is filled in */
|
sa_filled_in = TRUE; /* the sa struct is filled in */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(h)
|
if (addr || sa_filled_in) {
|
||||||
/* when we return from here, we can forget about this */
|
portsock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
Curl_resolv_unlock(data, h);
|
if(CURL_SOCKET_BAD != portsock) {
|
||||||
|
|
||||||
if ( h || sa_filled_in) {
|
|
||||||
if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) != CURL_SOCKET_BAD ) {
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
/* we set the secondary socket variable to this for now, it
|
/* we set the secondary socket variable to this for now, it
|
||||||
@ -1439,11 +1337,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
conn->sock[SECONDARYSOCKET] = portsock;
|
conn->sock[SECONDARYSOCKET] = portsock;
|
||||||
|
|
||||||
if(!sa_filled_in) {
|
if(!sa_filled_in) {
|
||||||
memset((char *)&sa, 0, sizeof(sa));
|
memcpy(&sa, addr->ai_addr, sizeof(sa));
|
||||||
memcpy((char *)&sa.sin_addr,
|
|
||||||
h->addr->h_addr,
|
|
||||||
h->addr->h_length);
|
|
||||||
sa.sin_family = AF_INET;
|
|
||||||
sa.sin_addr.s_addr = INADDR_ANY;
|
sa.sin_addr.s_addr = INADDR_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1478,29 +1372,19 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "could't find my own IP address (%s)", myhost);
|
failf(data, "could't find IP address to use");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
#ifdef HAVE_INET_NTOA_R
|
|
||||||
char ntoa_buf[64];
|
|
||||||
#endif
|
|
||||||
struct in_addr in;
|
|
||||||
unsigned short ip[5];
|
|
||||||
(void) memcpy(&in.s_addr,
|
|
||||||
h?*h->addr->h_addr_list:(char *)&sa.sin_addr.s_addr,
|
|
||||||
sizeof (in.s_addr));
|
|
||||||
|
|
||||||
#ifdef HAVE_INET_NTOA_R
|
if(sa_filled_in)
|
||||||
/* ignore the return code from inet_ntoa_r() as it is int or
|
Curl_inet_ntop(AF_INET, &((struct sockaddr_in *)&sa)->sin_addr,
|
||||||
char * depending on system */
|
myhost, sizeof(myhost));
|
||||||
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf));
|
else
|
||||||
sscanf( ntoa_buf, "%hu.%hu.%hu.%hu",
|
Curl_printable_address(addr, myhost, sizeof(myhost));
|
||||||
&ip[0], &ip[1], &ip[2], &ip[3]);
|
|
||||||
#else
|
if(4 == sscanf(myhost, "%hu.%hu.%hu.%hu",
|
||||||
sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu",
|
&ip[0], &ip[1], &ip[2], &ip[3])) {
|
||||||
&ip[0], &ip[1], &ip[2], &ip[3]);
|
|
||||||
#endif
|
|
||||||
infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n",
|
infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n",
|
||||||
ip[0], ip[1], ip[2], ip[3], porttouse);
|
ip[0], ip[1], ip[2], ip[3], porttouse);
|
||||||
|
|
||||||
@ -1510,7 +1394,12 @@ CURLcode ftp_use_port(struct connectdata *conn)
|
|||||||
porttouse & 255);
|
porttouse & 255);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
Curl_freeaddrinfo(addr);
|
||||||
|
|
||||||
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
|
||||||
if(result)
|
if(result)
|
||||||
@ -1544,7 +1433,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
|
|||||||
int ftpcode; /* receive FTP response codes in this */
|
int ftpcode; /* receive FTP response codes in this */
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct Curl_dns_entry *addr=NULL;
|
struct Curl_dns_entry *addr=NULL;
|
||||||
Curl_ipconnect *conninfo;
|
Curl_addrinfo *conninfo;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1693,7 +1582,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
|
|||||||
|
|
||||||
result = Curl_connecthost(conn,
|
result = Curl_connecthost(conn,
|
||||||
addr,
|
addr,
|
||||||
connectport,
|
|
||||||
&conn->sock[SECONDARYSOCKET],
|
&conn->sock[SECONDARYSOCKET],
|
||||||
&conninfo,
|
&conninfo,
|
||||||
connected);
|
connected);
|
||||||
|
53
lib/hash.c
53
lib/hash.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -47,7 +47,7 @@ hash_str(const char *key, size_t key_length)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hash_element_dtor(void *user, void *element)
|
hash_element_dtor(void *user, void *element)
|
||||||
{
|
{
|
||||||
curl_hash *h = (curl_hash *) user;
|
curl_hash *h = (curl_hash *) user;
|
||||||
@ -70,7 +70,7 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
|
|||||||
|
|
||||||
h->dtor = dtor;
|
h->dtor = dtor;
|
||||||
h->size = 0;
|
h->size = 0;
|
||||||
h->slots = slots;
|
h->slots = slots;
|
||||||
|
|
||||||
h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
|
h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
|
||||||
if(h->table) {
|
if(h->table) {
|
||||||
@ -106,10 +106,10 @@ Curl_hash_alloc(int slots, curl_hash_dtor dtor)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len)
|
hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len)
|
||||||
{
|
{
|
||||||
if (key1_len == key2_len &&
|
if (key1_len == key2_len &&
|
||||||
*key1 == *key2 &&
|
*key1 == *key2 &&
|
||||||
memcmp(key1, key2, key1_len) == 0) {
|
memcmp(key1, key2, key1_len) == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -180,29 +180,6 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p)
|
|||||||
return NULL; /* failure */
|
return NULL; /* failure */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
int
|
|
||||||
Curl_hash_delete(curl_hash *h, char *key, size_t key_len)
|
|
||||||
{
|
|
||||||
curl_hash_element *he;
|
|
||||||
curl_llist_element *le;
|
|
||||||
curl_llist *l = FETCH_LIST(h, key, key_len);
|
|
||||||
|
|
||||||
for (le = l->head;
|
|
||||||
le;
|
|
||||||
le = le->next) {
|
|
||||||
he = le->ptr;
|
|
||||||
if (hash_key_compare(he->key, he->key_len, key, key_len)) {
|
|
||||||
Curl_llist_remove(l, le, (void *) h);
|
|
||||||
--h->size;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
|
Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
|
||||||
{
|
{
|
||||||
@ -223,7 +200,7 @@ Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||||
void
|
void
|
||||||
Curl_hash_apply(curl_hash *h, void *user,
|
Curl_hash_apply(curl_hash *h, void *user,
|
||||||
void (*cb)(void *user, void *ptr))
|
void (*cb)(void *user, void *ptr))
|
||||||
{
|
{
|
||||||
@ -278,15 +255,7 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void
|
||||||
int
|
|
||||||
Curl_hash_count(curl_hash *h)
|
|
||||||
{
|
|
||||||
return h->size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
Curl_hash_destroy(curl_hash *h)
|
Curl_hash_destroy(curl_hash *h)
|
||||||
{
|
{
|
||||||
if (!h)
|
if (!h)
|
||||||
|
10
lib/hash.h
10
lib/hash.h
@ -1,10 +1,10 @@
|
|||||||
#ifndef __HASH_H
|
#ifndef __HASH_H
|
||||||
#define __HASH_H
|
#define __HASH_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -204,7 +204,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
store.tv_sec = (int)timeout/1000;
|
store.tv_sec = (int)timeout/1000;
|
||||||
store.tv_usec = (timeout%1000)*1000;
|
store.tv_usec = (timeout%1000)*1000;
|
||||||
|
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_ZERO(&write_fds);
|
FD_ZERO(&write_fds);
|
||||||
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
|
||||||
@ -229,7 +229,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
|
|
||||||
/* Operation complete, if the lookup was successful we now have the entry
|
/* Operation complete, if the lookup was successful we now have the entry
|
||||||
in the cache. */
|
in the cache. */
|
||||||
|
|
||||||
if(entry)
|
if(entry)
|
||||||
*entry = conn->async.dns;
|
*entry = conn->async.dns;
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
|||||||
cleaning up this connection properly */
|
cleaning up this connection properly */
|
||||||
Curl_disconnect(conn);
|
Curl_disconnect(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,10 +273,11 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
in_addr_t in = inet_addr(hostname);
|
in_addr_t in = inet_addr(hostname);
|
||||||
|
|
||||||
*waitp = FALSE;
|
*waitp = FALSE;
|
||||||
|
|
||||||
if (in != CURL_INADDR_NONE)
|
if (in != CURL_INADDR_NONE) {
|
||||||
/* This is a dotted IP address 123.123.123.123-style */
|
/* This is a dotted IP address 123.123.123.123-style */
|
||||||
return Curl_ip2addr(in, hostname);
|
return Curl_ip2addr(in, hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
bufp = strdup(hostname);
|
bufp = strdup(hostname);
|
||||||
|
|
||||||
@ -290,8 +291,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
|
|
||||||
/* areschannel is already setup in the Curl_open() function */
|
/* areschannel is already setup in the Curl_open() function */
|
||||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
||||||
Curl_addrinfo_callback, conn);
|
Curl_addrinfo4_callback, conn);
|
||||||
|
|
||||||
*waitp = TRUE; /* please wait for the response */
|
*waitp = TRUE; /* please wait for the response */
|
||||||
}
|
}
|
||||||
return NULL; /* no struct yet */
|
return NULL; /* no struct yet */
|
||||||
|
@ -108,9 +108,9 @@
|
|||||||
*
|
*
|
||||||
* The storage operation locks and unlocks the DNS cache.
|
* The storage operation locks and unlocks the DNS cache.
|
||||||
*/
|
*/
|
||||||
void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */
|
static void addrinfo_callback(void *arg, /* "struct connectdata *" */
|
||||||
int status,
|
int status,
|
||||||
Curl_addrinfo *hostent)
|
void *addr)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = (struct connectdata *)arg;
|
struct connectdata *conn = (struct connectdata *)arg;
|
||||||
struct Curl_dns_entry *dns = NULL;
|
struct Curl_dns_entry *dns = NULL;
|
||||||
@ -126,19 +126,19 @@ void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */
|
|||||||
*
|
*
|
||||||
* IPv6: Curl_addrinfo_copy() returns the input pointer!
|
* IPv6: Curl_addrinfo_copy() returns the input pointer!
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *he = Curl_addrinfo_copy(hostent);
|
Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port);
|
||||||
if(he) {
|
if(ai) {
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
dns = Curl_cache_addr(data, he,
|
dns = Curl_cache_addr(data, ai,
|
||||||
conn->async.hostname,
|
conn->async.hostname,
|
||||||
conn->async.port);
|
conn->async.port);
|
||||||
if(!dns)
|
if(!dns)
|
||||||
/* failed to store, cleanup and return error */
|
/* failed to store, cleanup and return error */
|
||||||
Curl_freeaddrinfo(he);
|
Curl_freeaddrinfo(ai);
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
@ -151,4 +151,20 @@ void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */
|
|||||||
this function */
|
this function */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
|
||||||
|
int status,
|
||||||
|
struct hostent *hostent)
|
||||||
|
{
|
||||||
|
addrinfo_callback(arg, status, hostent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CURLRES_IPV6
|
||||||
|
void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
|
||||||
|
int status,
|
||||||
|
struct addrinfo *hostent)
|
||||||
|
{
|
||||||
|
addrinfo_callback(arg, status, hostent);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CURLRES_ASYNC */
|
#endif /* CURLRES_ASYNC */
|
||||||
|
141
lib/hostip.c
141
lib/hostip.c
@ -174,14 +174,8 @@ void Curl_global_host_cache_dtor(void)
|
|||||||
int Curl_num_addresses(const Curl_addrinfo *addr)
|
int Curl_num_addresses(const Curl_addrinfo *addr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
for (i = 0; addr; addr = addr->ai_next, i++);
|
||||||
#ifdef ENABLE_IPV6
|
return i;
|
||||||
for (i = 0; addr; addr = addr->ai_next, i++)
|
|
||||||
#else
|
|
||||||
for (i = 0; addr->h_addr_list[i]; i++)
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
return (i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -191,18 +185,18 @@ int Curl_num_addresses(const Curl_addrinfo *addr)
|
|||||||
*
|
*
|
||||||
* If the conversion fails, it returns NULL.
|
* If the conversion fails, it returns NULL.
|
||||||
*/
|
*/
|
||||||
const char *Curl_printable_address(const Curl_ipconnect *ip,
|
const char *Curl_printable_address(const Curl_addrinfo *ip,
|
||||||
char *buf, size_t bufsize)
|
char *buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
#ifdef CURLRES_IPV6
|
|
||||||
const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
|
const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
|
||||||
const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
|
|
||||||
int af = ip->ai_family;
|
int af = ip->ai_family;
|
||||||
|
#ifdef CURLRES_IPV6
|
||||||
return Curl_inet_ntop(af, af == AF_INET6 ? ip6 : ip4, buf, bufsize);
|
const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
|
||||||
#else
|
#else
|
||||||
return Curl_inet_ntop(AF_INET, ip, buf, bufsize);
|
const void *ip6 = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return Curl_inet_ntop(af, af == AF_INET ? ip4 : ip6, buf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -547,35 +541,6 @@ curl_hash *Curl_mk_dnscache(void)
|
|||||||
return Curl_hash_alloc(7, freednsentry);
|
return Curl_hash_alloc(7, freednsentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CURLRES_HOSTENT_RELOCATE
|
|
||||||
/*
|
|
||||||
* Curl_hostent_relocate() ajusts all pointers in the given hostent struct
|
|
||||||
* according to the offset. This is typically used when a hostent has been
|
|
||||||
* reallocated and needs to be setup properly on the new address.
|
|
||||||
*/
|
|
||||||
void Curl_hostent_relocate(struct hostent *h, long offset)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
h->h_name=(char *)((long)h->h_name+offset);
|
|
||||||
if(h->h_aliases) {
|
|
||||||
/* only relocate aliases if there are any! */
|
|
||||||
h->h_aliases=(char **)((long)h->h_aliases+offset);
|
|
||||||
while(h->h_aliases[i]) {
|
|
||||||
h->h_aliases[i]=(char *)((long)h->h_aliases[i]+offset);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h->h_addr_list=(char **)((long)h->h_addr_list+offset);
|
|
||||||
i=0;
|
|
||||||
while(h->h_addr_list[i]) {
|
|
||||||
h->h_addr_list[i]=(char *)((long)h->h_addr_list[i]+offset);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CURLRES_HOSTENT_RELOCATE */
|
|
||||||
|
|
||||||
#ifdef CURLRES_ADDRINFO_COPY
|
#ifdef CURLRES_ADDRINFO_COPY
|
||||||
|
|
||||||
/* align on even 64bit boundaries */
|
/* align on even 64bit boundaries */
|
||||||
@ -586,94 +551,10 @@ void Curl_hostent_relocate(struct hostent *h, long offset)
|
|||||||
* returns a pointer to the malloc()ed copy. You need to call free() on the
|
* returns a pointer to the malloc()ed copy. You need to call free() on the
|
||||||
* returned buffer when you're done with it.
|
* returned buffer when you're done with it.
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *orig)
|
Curl_addrinfo *Curl_addrinfo_copy(void *org, int port)
|
||||||
{
|
{
|
||||||
char *newbuf;
|
struct hostent *orig = org;
|
||||||
Curl_addrinfo *copy;
|
|
||||||
int i;
|
|
||||||
char *str;
|
|
||||||
size_t len;
|
|
||||||
char *aptr = (char *)malloc(CURL_HOSTENT_SIZE);
|
|
||||||
char *bufptr = aptr;
|
|
||||||
|
|
||||||
if(!bufptr)
|
return Curl_he2ai(orig, port);
|
||||||
return NULL; /* major bad */
|
|
||||||
|
|
||||||
copy = (Curl_addrinfo *)bufptr;
|
|
||||||
|
|
||||||
bufptr += sizeof(Curl_addrinfo);
|
|
||||||
copy->h_name = bufptr;
|
|
||||||
len = strlen(orig->h_name) + 1;
|
|
||||||
strncpy(bufptr, orig->h_name, len);
|
|
||||||
bufptr += len;
|
|
||||||
|
|
||||||
/* This must be aligned properly to work on many CPU architectures! */
|
|
||||||
bufptr = MEMALIGN(bufptr);
|
|
||||||
|
|
||||||
copy->h_aliases = (char**)bufptr;
|
|
||||||
|
|
||||||
/* Figure out how many aliases there are */
|
|
||||||
for (i = 0; orig->h_aliases && orig->h_aliases[i]; ++i);
|
|
||||||
|
|
||||||
/* Reserve room for the array */
|
|
||||||
bufptr += (i + 1) * sizeof(char*);
|
|
||||||
|
|
||||||
/* Clone all known aliases */
|
|
||||||
if(orig->h_aliases) {
|
|
||||||
for(i = 0; (str = orig->h_aliases[i]); i++) {
|
|
||||||
len = strlen(str) + 1;
|
|
||||||
strncpy(bufptr, str, len);
|
|
||||||
copy->h_aliases[i] = bufptr;
|
|
||||||
bufptr += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* if(!orig->h_aliases) i was already set to 0 */
|
|
||||||
|
|
||||||
/* Terminate the alias list with a NULL */
|
|
||||||
copy->h_aliases[i] = NULL;
|
|
||||||
|
|
||||||
copy->h_addrtype = orig->h_addrtype;
|
|
||||||
copy->h_length = orig->h_length;
|
|
||||||
|
|
||||||
/* align it for (at least) 32bit accesses */
|
|
||||||
bufptr = MEMALIGN(bufptr);
|
|
||||||
|
|
||||||
copy->h_addr_list = (char**)bufptr;
|
|
||||||
|
|
||||||
/* Figure out how many addresses there are */
|
|
||||||
for (i = 0; orig->h_addr_list[i] != NULL; ++i);
|
|
||||||
|
|
||||||
/* Reserve room for the array */
|
|
||||||
bufptr += (i + 1) * sizeof(char*);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
len = orig->h_length;
|
|
||||||
str = orig->h_addr_list[i];
|
|
||||||
while (str != NULL) {
|
|
||||||
memcpy(bufptr, str, len);
|
|
||||||
copy->h_addr_list[i] = bufptr;
|
|
||||||
bufptr += len;
|
|
||||||
str = orig->h_addr_list[++i];
|
|
||||||
}
|
|
||||||
copy->h_addr_list[i] = NULL;
|
|
||||||
|
|
||||||
/* now, shrink the allocated buffer to the size we actually need, which
|
|
||||||
most often is only a fraction of the original alloc */
|
|
||||||
newbuf=(char *)realloc(aptr, (long)(bufptr-aptr));
|
|
||||||
|
|
||||||
if(!newbuf) {
|
|
||||||
/* serious error, but since this is shrinking only requested, we can
|
|
||||||
still use the previous memory block */
|
|
||||||
newbuf = aptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the alloc moved, we need to adjust the hostent struct */
|
|
||||||
else if(newbuf != aptr)
|
|
||||||
Curl_hostent_relocate((struct hostent*)newbuf, (long)(newbuf-aptr));
|
|
||||||
|
|
||||||
/* setup the return */
|
|
||||||
copy = (Curl_addrinfo *)newbuf;
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
#endif /* CURLRES_ADDRINFO_COPY */
|
#endif /* CURLRES_ADDRINFO_COPY */
|
||||||
|
172
lib/hostip.h
172
lib/hostip.h
@ -26,6 +26,85 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup comfortable CURLRES_* defines to use in the host*.c sources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_ARES
|
||||||
|
#define CURLRES_ASYNCH
|
||||||
|
#define CURLRES_ARES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_THREADING_GETHOSTBYNAME
|
||||||
|
#define CURLRES_ASYNCH
|
||||||
|
#define CURLRES_THREADED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_THREADING_GETADDRINFO
|
||||||
|
#define CURLRES_ASYNCH
|
||||||
|
#define CURLRES_THREADED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
#define CURLRES_IPV6
|
||||||
|
#else
|
||||||
|
#define CURLRES_IPV4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CURLRES_IPV4
|
||||||
|
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
|
||||||
|
/* If built for ipv4 and missing gethostbyname_r(), or if using async name
|
||||||
|
resolve, we need the Curl_addrinfo_copy() function (which itself needs the
|
||||||
|
Curl_hostent_relocate() function)) */
|
||||||
|
#define CURLRES_ADDRINFO_COPY
|
||||||
|
#endif
|
||||||
|
#endif /* IPv4-only */
|
||||||
|
|
||||||
|
#ifndef CURLRES_ASYNCH
|
||||||
|
#define CURLRES_SYNCH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USE_LIBIDN
|
||||||
|
#define CURLRES_IDN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocate enough memory to hold the full name information structs and
|
||||||
|
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
||||||
|
* required for storing all possible aliases and IP numbers is according to
|
||||||
|
* Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
|
||||||
|
*/
|
||||||
|
#define CURL_HOSTENT_SIZE 9000
|
||||||
|
|
||||||
|
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
||||||
|
many seconds for a name resolve */
|
||||||
|
|
||||||
|
#ifdef CURLRES_ARES
|
||||||
|
#define CURL_ASYNC_SUCCESS ARES_SUCCESS
|
||||||
|
#else
|
||||||
|
#define CURL_ASYNC_SUCCESS CURLE_OK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_addrinfo MUST be used for all name resolved info.
|
||||||
|
*/
|
||||||
|
#ifdef CURLRES_IPV6
|
||||||
|
typedef struct addrinfo Curl_addrinfo;
|
||||||
|
#else
|
||||||
|
/* OK, so some ipv4-only include tree probably have the addrinfo struct, but
|
||||||
|
to work even on those that don't, we provide our own look-alike! */
|
||||||
|
struct Curl_addrinfo {
|
||||||
|
int ai_flags;
|
||||||
|
int ai_family;
|
||||||
|
int ai_socktype;
|
||||||
|
int ai_protocol;
|
||||||
|
size_t ai_addrlen;
|
||||||
|
struct sockaddr *ai_addr;
|
||||||
|
char *ai_canonname;
|
||||||
|
struct Curl_addrinfo *ai_next;
|
||||||
|
};
|
||||||
|
typedef struct Curl_addrinfo Curl_addrinfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
struct hostent;
|
struct hostent;
|
||||||
struct SessionHandle;
|
struct SessionHandle;
|
||||||
@ -119,28 +198,37 @@ int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the callback function that is used when we build with asynch
|
/* This is the callback function that is used when we build with asynch
|
||||||
resolve */
|
resolve, ipv4 */
|
||||||
void Curl_addrinfo_callback(void *arg,
|
void Curl_addrinfo4_callback(void *arg,
|
||||||
int status,
|
int status,
|
||||||
Curl_addrinfo *hostent);
|
struct hostent *hostent);
|
||||||
|
/* This is the callback function that is used when we build with asynch
|
||||||
|
resolve, ipv6 */
|
||||||
|
void Curl_addrinfo6_callback(void *arg,
|
||||||
|
int status,
|
||||||
|
struct hostent *hostent);
|
||||||
|
|
||||||
/* This is a utility-function for ipv4-builds to create a hostent struct
|
|
||||||
from a numerical-only IP address */
|
/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP
|
||||||
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname);
|
address */
|
||||||
|
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port);
|
||||||
|
|
||||||
|
/* [ipv4 only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain
|
||||||
|
and returns it */
|
||||||
|
Curl_addrinfo *Curl_he2ai(struct hostent *, unsigned short port);
|
||||||
|
|
||||||
/* relocate a hostent struct */
|
/* relocate a hostent struct */
|
||||||
void Curl_hostent_relocate(struct hostent *h, long offset);
|
void Curl_hostent_relocate(struct hostent *h, long offset);
|
||||||
|
|
||||||
/* copy a Curl_addrinfo struct, currently this only supports copying
|
/* Clone a Curl_addrinfo struct, works protocol independently */
|
||||||
a hostent (ipv4-style) struct */
|
Curl_addrinfo *Curl_addrinfo_copy(void *orig, int port);
|
||||||
Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *orig);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_printable_address() returns a printable version of the 1st address
|
* Curl_printable_address() returns a printable version of the 1st address
|
||||||
* given in the 'ip' argument. The result will be stored in the buf that is
|
* given in the 'ip' argument. The result will be stored in the buf that is
|
||||||
* bufsize bytes big.
|
* bufsize bytes big.
|
||||||
*/
|
*/
|
||||||
const char *Curl_printable_address(const Curl_ipconnect *ip,
|
const char *Curl_printable_address(const Curl_addrinfo *ip,
|
||||||
char *buf, size_t bufsize);
|
char *buf, size_t bufsize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -158,71 +246,7 @@ Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
|||||||
#define CURL_INADDR_NONE INADDR_NONE
|
#define CURL_INADDR_NONE INADDR_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup comfortable CURLRES_* defines to use in the host*.c sources.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef USE_ARES
|
|
||||||
#define CURLRES_ASYNCH
|
|
||||||
#define CURLRES_ARES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_THREADING_GETHOSTBYNAME
|
|
||||||
#define CURLRES_ASYNCH
|
|
||||||
#define CURLRES_THREADED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_THREADING_GETADDRINFO
|
|
||||||
#define CURLRES_ASYNCH
|
|
||||||
#define CURLRES_THREADED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
#define CURLRES_IPV6
|
|
||||||
#else
|
|
||||||
#define CURLRES_IPV4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CURLRES_IPV4
|
|
||||||
#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
|
|
||||||
/* If built for ipv4 and missing gethostbyname_r(), or if using async name
|
|
||||||
resolve, we need the Curl_addrinfo_copy() function (which itself needs the
|
|
||||||
Curl_hostent_relocate() function)) */
|
|
||||||
#define CURLRES_ADDRINFO_COPY
|
|
||||||
#define CURLRES_HOSTENT_RELOCATE
|
|
||||||
#endif
|
|
||||||
#endif /* IPv4-only */
|
|
||||||
|
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_6
|
|
||||||
#define CURLRES_HOSTENT_RELOCATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_5
|
|
||||||
#define CURLRES_HOSTENT_RELOCATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CURLRES_ASYNCH
|
|
||||||
#define CURLRES_SYNCH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_LIBIDN
|
|
||||||
#define CURLRES_IDN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allocate enough memory to hold the full name information structs and
|
|
||||||
* everything. OSF1 is known to require at least 8872 bytes. The buffer
|
|
||||||
* required for storing all possible aliases and IP numbers is according to
|
|
||||||
* Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
|
|
||||||
*/
|
|
||||||
#define CURL_HOSTENT_SIZE 9000
|
|
||||||
|
|
||||||
#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
|
|
||||||
many seconds for a name resolve */
|
|
||||||
|
|
||||||
#ifdef CURLRES_ARES
|
|
||||||
#define CURL_ASYNC_SUCCESS ARES_SUCCESS
|
|
||||||
#else
|
|
||||||
#define CURL_ASYNC_SUCCESS CURLE_OK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
278
lib/hostip4.c
278
lib/hostip4.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -97,13 +97,19 @@
|
|||||||
#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
|
#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a wrapper function for freeing name information in a protocol
|
* This is a function for freeing name information in a protocol independent
|
||||||
* independent way. This takes care of using the appropriate underlying
|
* way.
|
||||||
* function.
|
|
||||||
*/
|
*/
|
||||||
void Curl_freeaddrinfo(Curl_addrinfo *p)
|
void Curl_freeaddrinfo(Curl_addrinfo *ai)
|
||||||
{
|
{
|
||||||
free(p); /* works fine for the ARES case too */
|
Curl_addrinfo *next;
|
||||||
|
|
||||||
|
/* walk over the list and free all entries */
|
||||||
|
while(ai) {
|
||||||
|
next = ai->ai_next;
|
||||||
|
free(ai);
|
||||||
|
ai = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -119,28 +125,29 @@ bool Curl_ipvalid(struct SessionHandle *data)
|
|||||||
return TRUE; /* OK, proceed */
|
return TRUE; /* OK, proceed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct namebuf {
|
||||||
|
struct hostent hostentry;
|
||||||
|
char *h_addr_list[2];
|
||||||
|
struct in_addr addrentry;
|
||||||
|
char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
|
* Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
|
||||||
* together with a pointer to the string version of the address, and it
|
* together with a pointer to the string version of the address, and it
|
||||||
* retruns a malloc()ed version of a hostent struct filled in correctly with
|
* returns a Curl_addrinfo chain filled in correctly with information for this
|
||||||
* information for this address/host.
|
* address/host.
|
||||||
*
|
*
|
||||||
* The input parameters ARE NOT checked for validity but they are expected
|
* The input parameters ARE NOT checked for validity but they are expected
|
||||||
* to have been checked already when this is called.
|
* to have been checked already when this is called.
|
||||||
*/
|
*/
|
||||||
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname)
|
Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port)
|
||||||
{
|
{
|
||||||
|
Curl_addrinfo *ai;
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
struct in_addr *addrentry;
|
struct in_addr *addrentry;
|
||||||
struct namebuf {
|
struct namebuf buffer;
|
||||||
struct hostent hostentry;
|
struct namebuf *buf = &buffer;
|
||||||
char *h_addr_list[2];
|
|
||||||
struct in_addr addrentry;
|
|
||||||
char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
|
|
||||||
} *buf = (struct namebuf *)malloc(sizeof(struct namebuf));
|
|
||||||
|
|
||||||
if(!buf)
|
|
||||||
return NULL; /* major failure */
|
|
||||||
|
|
||||||
h = &buf->hostentry;
|
h = &buf->hostentry;
|
||||||
h->h_addr_list = &buf->h_addr_list[0];
|
h->h_addr_list = &buf->h_addr_list[0];
|
||||||
@ -156,7 +163,9 @@ Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname)
|
|||||||
/* Now store the dotted version of the address */
|
/* Now store the dotted version of the address */
|
||||||
snprintf(h->h_name, 16, "%s", hostname);
|
snprintf(h->h_name, 16, "%s", hostname);
|
||||||
|
|
||||||
return h;
|
ai = Curl_he2ai(h, port);
|
||||||
|
|
||||||
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */
|
#ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */
|
||||||
@ -183,6 +192,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
int port,
|
int port,
|
||||||
int *waitp)
|
int *waitp)
|
||||||
{
|
{
|
||||||
|
Curl_addrinfo *ai = NULL;
|
||||||
struct hostent *h = NULL;
|
struct hostent *h = NULL;
|
||||||
in_addr_t in;
|
in_addr_t in;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
@ -191,9 +201,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
*waitp = 0; /* don't wait, we act synchronously */
|
*waitp = 0; /* don't wait, we act synchronously */
|
||||||
|
|
||||||
in=inet_addr(hostname);
|
in=inet_addr(hostname);
|
||||||
if (in != CURL_INADDR_NONE)
|
if (in != CURL_INADDR_NONE) {
|
||||||
/* This is a dotted IP address 123.123.123.123-style */
|
/* This is a dotted IP address 123.123.123.123-style */
|
||||||
return Curl_ip2addr(in, hostname);
|
return Curl_ip2addr(in, hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_GETHOSTBYNAME_R)
|
#if defined(HAVE_GETHOSTBYNAME_R)
|
||||||
/*
|
/*
|
||||||
@ -204,7 +215,6 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
else {
|
else {
|
||||||
int h_errnop;
|
int h_errnop;
|
||||||
int res=ERANGE;
|
int res=ERANGE;
|
||||||
int step_size=200;
|
|
||||||
int *buf = (int *)calloc(CURL_HOSTENT_SIZE, 1);
|
int *buf = (int *)calloc(CURL_HOSTENT_SIZE, 1);
|
||||||
if(!buf)
|
if(!buf)
|
||||||
return NULL; /* major failure */
|
return NULL; /* major failure */
|
||||||
@ -217,99 +227,64 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
#ifdef HAVE_GETHOSTBYNAME_R_5
|
#ifdef HAVE_GETHOSTBYNAME_R_5
|
||||||
/* Solaris, IRIX and more */
|
/* Solaris, IRIX and more */
|
||||||
(void)res; /* prevent compiler warning */
|
(void)res; /* prevent compiler warning */
|
||||||
while(!h) {
|
h = gethostbyname_r(hostname,
|
||||||
h = gethostbyname_r(hostname,
|
(struct hostent *)buf,
|
||||||
(struct hostent *)buf,
|
(char *)buf + sizeof(struct hostent),
|
||||||
(char *)buf + sizeof(struct hostent),
|
CURL_HOSTENT_SIZE - sizeof(struct hostent),
|
||||||
step_size - sizeof(struct hostent),
|
&h_errnop);
|
||||||
&h_errnop);
|
|
||||||
|
|
||||||
/* If the buffer is too small, it returns NULL and sets errno to
|
/* If the buffer is too small, it returns NULL and sets errno to
|
||||||
* ERANGE. The errno is thread safe if this is compiled with
|
* ERANGE. The errno is thread safe if this is compiled with
|
||||||
* -D_REENTRANT as then the 'errno' variable is a macro defined to get
|
* -D_REENTRANT as then the 'errno' variable is a macro defined to get
|
||||||
* used properly for threads.
|
* used properly for threads.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(h || (errno != ERANGE))
|
|
||||||
break;
|
|
||||||
|
|
||||||
step_size+=200;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(h) {
|
if(h) {
|
||||||
int offset;
|
;
|
||||||
h=(struct hostent *)realloc(buf, step_size);
|
|
||||||
offset=(long)h-(long)buf;
|
|
||||||
Curl_hostent_relocate(h, offset);
|
|
||||||
buf=(int *)h;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* HAVE_GETHOSTBYNAME_R_5 */
|
#endif /* HAVE_GETHOSTBYNAME_R_5 */
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_6
|
#ifdef HAVE_GETHOSTBYNAME_R_6
|
||||||
/* Linux */
|
/* Linux */
|
||||||
do {
|
|
||||||
res=gethostbyname_r(hostname,
|
|
||||||
(struct hostent *)buf,
|
|
||||||
(char *)buf + sizeof(struct hostent),
|
|
||||||
step_size - sizeof(struct hostent),
|
|
||||||
&h, /* DIFFERENCE */
|
|
||||||
&h_errnop);
|
|
||||||
/* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
|
|
||||||
* sudden this function returns EAGAIN if the given buffer size is too
|
|
||||||
* small. Previous versions are known to return ERANGE for the same
|
|
||||||
* problem.
|
|
||||||
*
|
|
||||||
* This wouldn't be such a big problem if older versions wouldn't
|
|
||||||
* sometimes return EAGAIN on a common failure case. Alas, we can't
|
|
||||||
* assume that EAGAIN *or* ERANGE means ERANGE for any given version of
|
|
||||||
* glibc.
|
|
||||||
*
|
|
||||||
* For now, we do that and thus we may call the function repeatedly and
|
|
||||||
* fail for older glibc versions that return EAGAIN, until we run out of
|
|
||||||
* buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
|
|
||||||
*
|
|
||||||
* If anyone has a better fix, please tell us!
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* On October 23rd 2003, Dan C dug up more details on the mysteries of
|
|
||||||
* gethostbyname_r() in glibc:
|
|
||||||
*
|
|
||||||
* In glibc 2.2.5 the interface is different (this has also been
|
|
||||||
* discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
|
|
||||||
* explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
|
|
||||||
* (shipped/upgraded by Redhat 7.2) don't show this behavior!
|
|
||||||
*
|
|
||||||
* In this "buggy" version, the return code is -1 on error and 'errno'
|
|
||||||
* is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
|
|
||||||
* thread-safe variable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(((ERANGE == res) || (EAGAIN == res)) ||
|
res=gethostbyname_r(hostname,
|
||||||
((res<0) && ((ERANGE == errno) || (EAGAIN == errno))))
|
(struct hostent *)buf,
|
||||||
step_size+=200;
|
(char *)buf + sizeof(struct hostent),
|
||||||
else
|
CURL_HOSTENT_SIZE - sizeof(struct hostent),
|
||||||
break;
|
&h, /* DIFFERENCE */
|
||||||
} while(step_size <= CURL_HOSTENT_SIZE);
|
&h_errnop);
|
||||||
|
/* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
|
||||||
|
* sudden this function returns EAGAIN if the given buffer size is too
|
||||||
|
* small. Previous versions are known to return ERANGE for the same
|
||||||
|
* problem.
|
||||||
|
*
|
||||||
|
* This wouldn't be such a big problem if older versions wouldn't
|
||||||
|
* sometimes return EAGAIN on a common failure case. Alas, we can't
|
||||||
|
* assume that EAGAIN *or* ERANGE means ERANGE for any given version of
|
||||||
|
* glibc.
|
||||||
|
*
|
||||||
|
* For now, we do that and thus we may call the function repeatedly and
|
||||||
|
* fail for older glibc versions that return EAGAIN, until we run out of
|
||||||
|
* buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
|
||||||
|
*
|
||||||
|
* If anyone has a better fix, please tell us!
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* On October 23rd 2003, Dan C dug up more details on the mysteries of
|
||||||
|
* gethostbyname_r() in glibc:
|
||||||
|
*
|
||||||
|
* In glibc 2.2.5 the interface is different (this has also been
|
||||||
|
* discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
|
||||||
|
* explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
|
||||||
|
* (shipped/upgraded by Redhat 7.2) don't show this behavior!
|
||||||
|
*
|
||||||
|
* In this "buggy" version, the return code is -1 on error and 'errno'
|
||||||
|
* is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
|
||||||
|
* thread-safe variable.
|
||||||
|
*/
|
||||||
|
|
||||||
if(!h) /* failure */
|
if(!h) /* failure */
|
||||||
res=1;
|
|
||||||
|
|
||||||
#ifdef CURLDEBUG
|
|
||||||
infof(data, "gethostbyname_r() uses %d bytes\n", step_size);
|
|
||||||
#endif
|
|
||||||
if(!res) {
|
|
||||||
int offset;
|
|
||||||
h=(struct hostent *)realloc(buf, step_size);
|
|
||||||
offset=(long)h-(long)buf;
|
|
||||||
Curl_hostent_relocate(h, offset);
|
|
||||||
buf=(int *)h;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif/* HAVE_GETHOSTBYNAME_R_6 */
|
#endif/* HAVE_GETHOSTBYNAME_R_6 */
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_3
|
#ifdef HAVE_GETHOSTBYNAME_R_3
|
||||||
/* AIX, Digital Unix/Tru64, HPUX 10, more? */
|
/* AIX, Digital Unix/Tru64, HPUX 10, more? */
|
||||||
@ -361,7 +336,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
* calling Curl_addrinfo_copy() that subsequent realloc()s down the new
|
* calling Curl_addrinfo_copy() that subsequent realloc()s down the new
|
||||||
* memory area to the actually used amount.
|
* memory area to the actually used amount.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* HAVE_GETHOSTBYNAME_R_3 */
|
#endif /* HAVE_GETHOSTBYNAME_R_3 */
|
||||||
{
|
{
|
||||||
@ -386,14 +361,95 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
* between threads, which thus the copying here them allows the app to
|
* between threads, which thus the copying here them allows the app to
|
||||||
* do.
|
* do.
|
||||||
*/
|
*/
|
||||||
h = Curl_addrinfo_copy(h);
|
return Curl_addrinfo_copy(h);
|
||||||
}
|
}
|
||||||
#endif /*HAVE_GETHOSTBYNAME_R */
|
#endif /*HAVE_GETHOSTBYNAME_R */
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
if(h) {
|
||||||
|
ai = Curl_he2ai(h, port);
|
||||||
|
|
||||||
|
free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CURLRES_SYNCH */
|
#endif /* CURLRES_SYNCH */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_he2ai() translates from a hostent struct to a Curl_addrinfo struct.
|
||||||
|
* The Curl_addrinfo is meant to work like the addrinfo struct does for IPv6
|
||||||
|
* stacks, but for all hosts and environments.
|
||||||
|
|
||||||
|
struct Curl_addrinfo {
|
||||||
|
int ai_flags;
|
||||||
|
int ai_family;
|
||||||
|
int ai_socktype;
|
||||||
|
int ai_protocol;
|
||||||
|
size_t ai_addrlen;
|
||||||
|
struct sockaddr *ai_addr;
|
||||||
|
char *ai_canonname;
|
||||||
|
struct addrinfo *ai_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hostent {
|
||||||
|
char *h_name; * official name of host *
|
||||||
|
char **h_aliases; * alias list *
|
||||||
|
int h_addrtype; * host address type *
|
||||||
|
int h_length; * length of address *
|
||||||
|
char **h_addr_list; * list of addresses *
|
||||||
|
}
|
||||||
|
#define h_addr h_addr_list[0] * for backward compatibility *
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Curl_addrinfo *Curl_he2ai(struct hostent *he, unsigned short port)
|
||||||
|
{
|
||||||
|
Curl_addrinfo *ai;
|
||||||
|
Curl_addrinfo *prevai = NULL;
|
||||||
|
Curl_addrinfo *firstai = NULL;
|
||||||
|
struct sockaddr_in *addr;
|
||||||
|
int i;
|
||||||
|
struct in_addr *curr;
|
||||||
|
|
||||||
|
if(!he)
|
||||||
|
/* no input == no output! */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]); i++) {
|
||||||
|
|
||||||
|
ai = calloc(1, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
if(!ai)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(!firstai)
|
||||||
|
/* store the pointer we want to return from this function */
|
||||||
|
firstai = ai;
|
||||||
|
|
||||||
|
if(prevai)
|
||||||
|
/* make the previous entry point to this */
|
||||||
|
prevai->ai_next = ai;
|
||||||
|
|
||||||
|
ai->ai_family = AF_INET; /* we only support this */
|
||||||
|
ai->ai_socktype = SOCK_STREAM; /* we only support this */
|
||||||
|
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||||
|
/* make the ai_addr point to the address immediately following this struct
|
||||||
|
and use that area to store the address */
|
||||||
|
ai->ai_addr = (struct sockaddr *) ((char*)ai + sizeof(struct addrinfo));
|
||||||
|
|
||||||
|
/* leave the rest of the struct filled with zero */
|
||||||
|
|
||||||
|
addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
|
||||||
|
|
||||||
|
memcpy((char *)&(addr->sin_addr), curr, sizeof(struct in_addr));
|
||||||
|
addr->sin_family = he->h_addrtype;
|
||||||
|
addr->sin_port = htons((unsigned short)port);
|
||||||
|
|
||||||
|
prevai = ai;
|
||||||
|
}
|
||||||
|
return firstai;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CURLRES_IPV4 */
|
#endif /* CURLRES_IPV4 */
|
||||||
|
@ -469,7 +469,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
|||||||
hostname, port, Curl_strerror(conn,WSAGetLastError()));
|
hostname, port, Curl_strerror(conn,WSAGetLastError()));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return h;
|
return Curl_he2ai(h, port);
|
||||||
}
|
}
|
||||||
#endif /* CURLRES_IPV4 */
|
#endif /* CURLRES_IPV4 */
|
||||||
|
|
||||||
|
14
lib/if2ip.c
14
lib/if2ip.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -64,7 +64,7 @@
|
|||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
|
||||||
#include "inet_ntoa_r.h"
|
#include "inet_ntoa_r.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ char *Curl_if2ip(const char *interface, char *buf, int buf_size)
|
|||||||
{
|
{
|
||||||
int dummy;
|
int dummy;
|
||||||
char *ip=NULL;
|
char *ip=NULL;
|
||||||
|
|
||||||
if(!interface)
|
if(!interface)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
12
lib/if2ip.h
12
lib/if2ip.h
@ -1,10 +1,10 @@
|
|||||||
#ifndef __IF2IP_H
|
#ifndef __IF2IP_H
|
||||||
#define __IF2IP_H
|
#define __IF2IP_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -63,7 +63,7 @@ struct ifreq {
|
|||||||
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
||||||
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
||||||
|
|
||||||
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
|
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
|
||||||
#endif /* interix */
|
#endif /* interix */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
34
lib/krb4.c
34
lib/krb4.c
@ -10,22 +10,22 @@
|
|||||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
|
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
@ -70,7 +70,7 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define LOCAL_ADDR (&conn->local_addr)
|
#define LOCAL_ADDR (&conn->local_addr)
|
||||||
#define REMOTE_ADDR (&conn->serv_addr)
|
#define REMOTE_ADDR conn->ip_addr->ai_addr
|
||||||
#define myctladdr LOCAL_ADDR
|
#define myctladdr LOCAL_ADDR
|
||||||
#define hisctladdr REMOTE_ADDR
|
#define hisctladdr REMOTE_ADDR
|
||||||
|
|
||||||
@ -120,13 +120,13 @@ krb4_decode(void *app_data, void *buf, int len, int level,
|
|||||||
MSG_DAT m;
|
MSG_DAT m;
|
||||||
int e;
|
int e;
|
||||||
struct krb4_data *d = app_data;
|
struct krb4_data *d = app_data;
|
||||||
|
|
||||||
if(level == prot_safe)
|
if(level == prot_safe)
|
||||||
e = krb_rd_safe(buf, len, &d->key,
|
e = krb_rd_safe(buf, len, &d->key,
|
||||||
(struct sockaddr_in *)REMOTE_ADDR,
|
(struct sockaddr_in *)REMOTE_ADDR,
|
||||||
(struct sockaddr_in *)LOCAL_ADDR, &m);
|
(struct sockaddr_in *)LOCAL_ADDR, &m);
|
||||||
else
|
else
|
||||||
e = krb_rd_priv(buf, len, d->schedule, &d->key,
|
e = krb_rd_priv(buf, len, d->schedule, &d->key,
|
||||||
(struct sockaddr_in *)REMOTE_ADDR,
|
(struct sockaddr_in *)REMOTE_ADDR,
|
||||||
(struct sockaddr_in *)LOCAL_ADDR, &m);
|
(struct sockaddr_in *)LOCAL_ADDR, &m);
|
||||||
if(e) {
|
if(e) {
|
||||||
@ -155,11 +155,11 @@ krb4_encode(void *app_data, void *from, int length, int level, void **to,
|
|||||||
struct krb4_data *d = app_data;
|
struct krb4_data *d = app_data;
|
||||||
*to = malloc(length + 31);
|
*to = malloc(length + 31);
|
||||||
if(level == prot_safe)
|
if(level == prot_safe)
|
||||||
return krb_mk_safe(from, *to, length, &d->key,
|
return krb_mk_safe(from, *to, length, &d->key,
|
||||||
(struct sockaddr_in *)LOCAL_ADDR,
|
(struct sockaddr_in *)LOCAL_ADDR,
|
||||||
(struct sockaddr_in *)REMOTE_ADDR);
|
(struct sockaddr_in *)REMOTE_ADDR);
|
||||||
else if(level == prot_private)
|
else if(level == prot_private)
|
||||||
return krb_mk_priv(from, *to, length, d->schedule, &d->key,
|
return krb_mk_priv(from, *to, length, d->schedule, &d->key,
|
||||||
(struct sockaddr_in *)LOCAL_ADDR,
|
(struct sockaddr_in *)LOCAL_ADDR,
|
||||||
(struct sockaddr_in *)REMOTE_ADDR);
|
(struct sockaddr_in *)REMOTE_ADDR);
|
||||||
else
|
else
|
||||||
@ -167,7 +167,7 @@ krb4_encode(void *app_data, void *from, int length, int level, void **to,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mk_auth(struct krb4_data *d, KTEXT adat,
|
mk_auth(struct krb4_data *d, KTEXT adat,
|
||||||
const char *service, char *host, int checksum)
|
const char *service, char *host, int checksum)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -223,7 +223,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
Curl_infof(data, "%s\n", krb_get_err_text(ret));
|
Curl_infof(data, "%s\n", krb_get_err_text(ret));
|
||||||
return AUTH_CONTINUE;
|
return AUTH_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
|
||||||
if (krb_get_config_bool("nat_in_use")) {
|
if (krb_get_config_bool("nat_in_use")) {
|
||||||
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
|
||||||
@ -281,11 +281,11 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
return AUTH_ERROR;
|
return AUTH_ERROR;
|
||||||
}
|
}
|
||||||
adat.length = len;
|
adat.length = len;
|
||||||
ret = krb_rd_safe(adat.dat, adat.length, &d->key,
|
ret = krb_rd_safe(adat.dat, adat.length, &d->key,
|
||||||
(struct sockaddr_in *)hisctladdr,
|
(struct sockaddr_in *)hisctladdr,
|
||||||
(struct sockaddr_in *)myctladdr, &msg_data);
|
(struct sockaddr_in *)myctladdr, &msg_data);
|
||||||
if(ret) {
|
if(ret) {
|
||||||
Curl_failf(data, "Error reading reply from server: %s",
|
Curl_failf(data, "Error reading reply from server: %s",
|
||||||
krb_get_err_text(ret));
|
krb_get_err_text(ret));
|
||||||
return AUTH_ERROR;
|
return AUTH_ERROR;
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
tkt.length = tmp;
|
tkt.length = tmp;
|
||||||
tktcopy.length = tkt.length;
|
tktcopy.length = tkt.length;
|
||||||
|
|
||||||
p = strstr(conn->data->state.buffer, "P=");
|
p = strstr(conn->data->state.buffer, "P=");
|
||||||
if(!p) {
|
if(!p) {
|
||||||
Curl_failf(conn->data, "Bad reply from server");
|
Curl_failf(conn->data, "Bad reply from server");
|
||||||
@ -367,7 +367,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
|
|
||||||
des_string_to_key (conn->passwd, &key);
|
des_string_to_key (conn->passwd, &key);
|
||||||
des_key_sched(&key, schedule);
|
des_key_sched(&key, schedule);
|
||||||
|
|
||||||
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
|
||||||
tkt.length,
|
tkt.length,
|
||||||
schedule, &key, DES_DECRYPT);
|
schedule, &key, DES_DECRYPT);
|
||||||
|
65
lib/llist.c
65
lib/llist.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -32,7 +32,7 @@
|
|||||||
/* this must be the last include file */
|
/* this must be the last include file */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
|
Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
|
||||||
{
|
{
|
||||||
l->size = 0;
|
l->size = 0;
|
||||||
@ -90,36 +90,7 @@ Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
int
|
||||||
int
|
|
||||||
Curl_llist_insert_prev(curl_llist *list, curl_llist_element *e, const void *p)
|
|
||||||
{
|
|
||||||
curl_llist_element *ne;
|
|
||||||
|
|
||||||
ne = (curl_llist_element *) malloc(sizeof(curl_llist_element));
|
|
||||||
ne->ptr = (void *) p;
|
|
||||||
if (list->size == 0) {
|
|
||||||
list->head = ne;
|
|
||||||
list->head->prev = NULL;
|
|
||||||
list->head->next = NULL;
|
|
||||||
list->tail = ne;
|
|
||||||
} else {
|
|
||||||
ne->next = e;
|
|
||||||
ne->prev = e->prev;
|
|
||||||
if (e->prev)
|
|
||||||
e->prev->next = ne;
|
|
||||||
else
|
|
||||||
list->head = ne;
|
|
||||||
e->prev = ne;
|
|
||||||
}
|
|
||||||
|
|
||||||
++list->size;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
|
Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
|
||||||
{
|
{
|
||||||
if (e == NULL || list->size == 0)
|
if (e == NULL || list->size == 0)
|
||||||
@ -147,27 +118,7 @@ Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void
|
||||||
int
|
|
||||||
Curl_llist_remove_next(curl_llist *list, curl_llist_element *e, void *user)
|
|
||||||
{
|
|
||||||
return Curl_llist_remove(list, e->next, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Curl_llist_remove_prev(curl_llist *list, curl_llist_element *e, void *user)
|
|
||||||
{
|
|
||||||
return Curl_llist_remove(list, e->prev, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
Curl_llist_count(curl_llist *list)
|
|
||||||
{
|
|
||||||
return list->size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
Curl_llist_destroy(curl_llist *list, void *user)
|
Curl_llist_destroy(curl_llist *list, void *user)
|
||||||
{
|
{
|
||||||
if(list) {
|
if(list) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifdef CURLDEBUG
|
#ifdef CURLDEBUG
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -11,7 +11,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -99,12 +99,12 @@ static bool countcheck(const char *func, int line, const char *source)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
memsize--; /* countdown */
|
memsize--; /* countdown */
|
||||||
|
|
||||||
/* log the countdown */
|
/* log the countdown */
|
||||||
if(logfile && source)
|
if(logfile && source)
|
||||||
fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n",
|
fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n",
|
||||||
source, line, memsize);
|
source, line, memsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE; /* allow this */
|
return FALSE; /* allow this */
|
||||||
@ -166,7 +166,7 @@ char *curl_dostrdup(const char *str, int line, const char *source)
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
curlassert(str != NULL);
|
curlassert(str != NULL);
|
||||||
|
|
||||||
if(countcheck("strdup", line, source))
|
if(countcheck("strdup", line, source))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ void curl_dofree(void *ptr, int line, const char *source)
|
|||||||
|
|
||||||
/* destroy */
|
/* destroy */
|
||||||
memset(mem->mem, 0x13, mem->size);
|
memset(mem->mem, 0x13, mem->size);
|
||||||
|
|
||||||
/* free for real */
|
/* free for real */
|
||||||
(Curl_cfree)(mem);
|
(Curl_cfree)(mem);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ int curl_fclose(FILE *file, int line, const char *source)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
int VOID_VAR_MEMDEBUG;
|
int VOID_VAR_MEMDEBUG;
|
||||||
#else
|
#else
|
||||||
/* we provide a fake do-nothing function here to avoid compiler warnings */
|
/* we provide a fake do-nothing function here to avoid compiler warnings */
|
||||||
void curl_memdebug(void) {}
|
void curl_memdebug(void) {}
|
||||||
|
110
lib/mprintf.c
110
lib/mprintf.c
@ -142,9 +142,6 @@ typedef struct {
|
|||||||
LONG_LONG lnum;
|
LONG_LONG lnum;
|
||||||
#endif
|
#endif
|
||||||
double dnum;
|
double dnum;
|
||||||
#if 0 /*SIZEOF_LONG_DOUBLE */
|
|
||||||
long double ldnum;
|
|
||||||
#endif
|
|
||||||
} data;
|
} data;
|
||||||
} va_stack_t;
|
} va_stack_t;
|
||||||
|
|
||||||
@ -227,7 +224,7 @@ int dprintf_Pass1Report(va_stack_t *vto, int max)
|
|||||||
break;
|
break;
|
||||||
case FORMAT_LONGDOUBLE:
|
case FORMAT_LONGDOUBLE:
|
||||||
type = "long double";
|
type = "long double";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -317,7 +314,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
/* Handle the positional case (N$) */
|
/* Handle the positional case (N$) */
|
||||||
|
|
||||||
param_num++;
|
param_num++;
|
||||||
|
|
||||||
this_param = dprintf_DollarString(fmt, &fmt);
|
this_param = dprintf_DollarString(fmt, &fmt);
|
||||||
if (0 == this_param)
|
if (0 == this_param)
|
||||||
/* we got no positional, get the next counter */
|
/* we got no positional, get the next counter */
|
||||||
@ -418,7 +415,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
case '*': /* Special case */
|
case '*': /* Special case */
|
||||||
flags |= FLAGS_WIDTHPARAM;
|
flags |= FLAGS_WIDTHPARAM;
|
||||||
param_num++;
|
param_num++;
|
||||||
|
|
||||||
i = dprintf_DollarString(fmt, &fmt);
|
i = dprintf_DollarString(fmt, &fmt);
|
||||||
if(i)
|
if(i)
|
||||||
width = i;
|
width = i;
|
||||||
@ -471,7 +468,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
case 'c':
|
case 'c':
|
||||||
vto[i].type = FORMAT_INT;
|
vto[i].type = FORMAT_INT;
|
||||||
flags |= FLAGS_CHAR;
|
flags |= FLAGS_CHAR;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
vto[i].type = FORMAT_DOUBLE;
|
vto[i].type = FORMAT_DOUBLE;
|
||||||
break;
|
break;
|
||||||
@ -486,11 +483,11 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
case 'g':
|
case 'g':
|
||||||
vto[i].type = FORMAT_DOUBLE;
|
vto[i].type = FORMAT_DOUBLE;
|
||||||
flags |= FLAGS_FLOATG;
|
flags |= FLAGS_FLOATG;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
vto[i].type = FORMAT_DOUBLE;
|
vto[i].type = FORMAT_DOUBLE;
|
||||||
flags |= FLAGS_FLOATG|FLAGS_UPPER;
|
flags |= FLAGS_FLOATG|FLAGS_UPPER;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vto[i].type = FORMAT_UNKNOWN;
|
vto[i].type = FORMAT_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
@ -499,7 +496,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
vto[i].flags = flags;
|
vto[i].flags = flags;
|
||||||
vto[i].width = width;
|
vto[i].width = width;
|
||||||
vto[i].precision = precision;
|
vto[i].precision = precision;
|
||||||
|
|
||||||
if (flags & FLAGS_WIDTHPARAM) {
|
if (flags & FLAGS_WIDTHPARAM) {
|
||||||
/* we have the width specified from a parameter, so we make that
|
/* we have the width specified from a parameter, so we make that
|
||||||
parameter's info setup properly */
|
parameter's info setup properly */
|
||||||
@ -508,7 +505,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
vto[i].type = FORMAT_WIDTH;
|
vto[i].type = FORMAT_WIDTH;
|
||||||
vto[i].flags = FLAGS_NEW;
|
vto[i].flags = FLAGS_NEW;
|
||||||
vto[i].precision = vto[i].width = 0; /* can't use width or precision
|
vto[i].precision = vto[i].width = 0; /* can't use width or precision
|
||||||
of width! */
|
of width! */
|
||||||
}
|
}
|
||||||
if (flags & FLAGS_PRECPARAM) {
|
if (flags & FLAGS_PRECPARAM) {
|
||||||
/* we have the precision specified from a parameter, so we make that
|
/* we have the precision specified from a parameter, so we make that
|
||||||
@ -543,13 +540,13 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
case FORMAT_STRING:
|
case FORMAT_STRING:
|
||||||
vto[i].data.str = va_arg(arglist, char *);
|
vto[i].data.str = va_arg(arglist, char *);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_INTPTR:
|
case FORMAT_INTPTR:
|
||||||
case FORMAT_UNKNOWN:
|
case FORMAT_UNKNOWN:
|
||||||
case FORMAT_PTR:
|
case FORMAT_PTR:
|
||||||
vto[i].data.ptr = va_arg(arglist, void *);
|
vto[i].data.ptr = va_arg(arglist, void *);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_INT:
|
case FORMAT_INT:
|
||||||
#ifdef ENABLE_64BIT
|
#ifdef ENABLE_64BIT
|
||||||
if(vto[i].flags & FLAGS_LONGLONG)
|
if(vto[i].flags & FLAGS_LONGLONG)
|
||||||
@ -561,23 +558,18 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
|
|||||||
else
|
else
|
||||||
vto[i].data.num = va_arg(arglist, int);
|
vto[i].data.num = va_arg(arglist, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_DOUBLE:
|
case FORMAT_DOUBLE:
|
||||||
#if 0 /*SIZEOF_LONG_DOUBLE */
|
vto[i].data.dnum = va_arg(arglist, double);
|
||||||
if(vto[i].flags & FLAGS_LONG)
|
|
||||||
vto[i].data.ldnum = va_arg(arglist, long double);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
vto[i].data.dnum = va_arg(arglist, double);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_WIDTH:
|
case FORMAT_WIDTH:
|
||||||
/* Argument has been read. Silently convert it into an integer
|
/* Argument has been read. Silently convert it into an integer
|
||||||
* for later use
|
* for later use
|
||||||
*/
|
*/
|
||||||
vto[i].type = FORMAT_INT;
|
vto[i].type = FORMAT_INT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -620,21 +612,21 @@ static int dprintf_formatf(
|
|||||||
|
|
||||||
end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
|
end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
|
||||||
created for us */
|
created for us */
|
||||||
|
|
||||||
f = (char *)format;
|
f = (char *)format;
|
||||||
while (*f != '\0') {
|
while (*f != '\0') {
|
||||||
/* Format spec modifiers. */
|
/* Format spec modifiers. */
|
||||||
char alt;
|
char alt;
|
||||||
|
|
||||||
/* Width of a field. */
|
/* Width of a field. */
|
||||||
long width;
|
long width;
|
||||||
|
|
||||||
/* Precision of a field. */
|
/* Precision of a field. */
|
||||||
long prec;
|
long prec;
|
||||||
|
|
||||||
/* Decimal integer is negative. */
|
/* Decimal integer is negative. */
|
||||||
char is_neg;
|
char is_neg;
|
||||||
|
|
||||||
/* Base of a number to be written. */
|
/* Base of a number to be written. */
|
||||||
long base;
|
long base;
|
||||||
|
|
||||||
@ -645,7 +637,7 @@ static int dprintf_formatf(
|
|||||||
unsigned long num;
|
unsigned long num;
|
||||||
#endif
|
#endif
|
||||||
long signed_num;
|
long signed_num;
|
||||||
|
|
||||||
if (*f != '%') {
|
if (*f != '%') {
|
||||||
/* This isn't a format spec, so write everything out until the next one
|
/* This isn't a format spec, so write everything out until the next one
|
||||||
OR end of string is reached. */
|
OR end of string is reached. */
|
||||||
@ -654,9 +646,9 @@ static int dprintf_formatf(
|
|||||||
} while(*++f && ('%' != *f));
|
} while(*++f && ('%' != *f));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
++f;
|
++f;
|
||||||
|
|
||||||
/* Check for "%%". Note that although the ANSI standard lists
|
/* Check for "%%". Note that although the ANSI standard lists
|
||||||
'%' as a conversion specifier, it says "The complete format
|
'%' as a conversion specifier, it says "The complete format
|
||||||
specification shall be `%%'," so we can avoid all the width
|
specification shall be `%%'," so we can avoid all the width
|
||||||
@ -675,7 +667,7 @@ static int dprintf_formatf(
|
|||||||
param = param_num;
|
param = param_num;
|
||||||
else
|
else
|
||||||
--param;
|
--param;
|
||||||
|
|
||||||
param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
|
param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
|
||||||
third %s will pick the 3rd argument */
|
third %s will pick the 3rd argument */
|
||||||
|
|
||||||
@ -696,7 +688,7 @@ static int dprintf_formatf(
|
|||||||
prec = -1;
|
prec = -1;
|
||||||
|
|
||||||
alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
|
alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
|
||||||
|
|
||||||
switch (p->type) {
|
switch (p->type) {
|
||||||
case FORMAT_INT:
|
case FORMAT_INT:
|
||||||
num = p->data.num;
|
num = p->data.num;
|
||||||
@ -742,26 +734,26 @@ static int dprintf_formatf(
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
signed_num = (long) num;
|
signed_num = (long) num;
|
||||||
|
|
||||||
is_neg = signed_num < 0;
|
is_neg = signed_num < 0;
|
||||||
num = is_neg ? (- signed_num) : signed_num;
|
num = is_neg ? (- signed_num) : signed_num;
|
||||||
}
|
}
|
||||||
goto number;
|
goto number;
|
||||||
|
|
||||||
unsigned_number:;
|
unsigned_number:;
|
||||||
/* Unsigned number of base BASE. */
|
/* Unsigned number of base BASE. */
|
||||||
is_neg = 0;
|
is_neg = 0;
|
||||||
|
|
||||||
number:;
|
number:;
|
||||||
/* Number of base BASE. */
|
/* Number of base BASE. */
|
||||||
{
|
{
|
||||||
char *workend = &work[sizeof(work) - 1];
|
char *workend = &work[sizeof(work) - 1];
|
||||||
char *w;
|
char *w;
|
||||||
|
|
||||||
/* Supply a default precision if none was given. */
|
/* Supply a default precision if none was given. */
|
||||||
if (prec == -1)
|
if (prec == -1)
|
||||||
prec = 1;
|
prec = 1;
|
||||||
|
|
||||||
/* Put the number in WORK. */
|
/* Put the number in WORK. */
|
||||||
w = workend;
|
w = workend;
|
||||||
while (num > 0) {
|
while (num > 0) {
|
||||||
@ -770,35 +762,35 @@ static int dprintf_formatf(
|
|||||||
}
|
}
|
||||||
width -= workend - w;
|
width -= workend - w;
|
||||||
prec -= workend - w;
|
prec -= workend - w;
|
||||||
|
|
||||||
if (alt && base == 8 && prec <= 0) {
|
if (alt && base == 8 && prec <= 0) {
|
||||||
*w-- = '0';
|
*w-- = '0';
|
||||||
--width;
|
--width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prec > 0) {
|
if (prec > 0) {
|
||||||
width -= prec;
|
width -= prec;
|
||||||
while (prec-- > 0)
|
while (prec-- > 0)
|
||||||
*w-- = '0';
|
*w-- = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alt && base == 16)
|
if (alt && base == 16)
|
||||||
width -= 2;
|
width -= 2;
|
||||||
|
|
||||||
if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
|
if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
|
||||||
--width;
|
--width;
|
||||||
|
|
||||||
if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
|
if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
|
||||||
while (width-- > 0)
|
while (width-- > 0)
|
||||||
OUTCHAR(' ');
|
OUTCHAR(' ');
|
||||||
|
|
||||||
if (is_neg)
|
if (is_neg)
|
||||||
OUTCHAR('-');
|
OUTCHAR('-');
|
||||||
else if (p->flags & FLAGS_SHOWSIGN)
|
else if (p->flags & FLAGS_SHOWSIGN)
|
||||||
OUTCHAR('+');
|
OUTCHAR('+');
|
||||||
else if (p->flags & FLAGS_SPACE)
|
else if (p->flags & FLAGS_SPACE)
|
||||||
OUTCHAR(' ');
|
OUTCHAR(' ');
|
||||||
|
|
||||||
if (alt && base == 16) {
|
if (alt && base == 16) {
|
||||||
OUTCHAR('0');
|
OUTCHAR('0');
|
||||||
if(p->flags & FLAGS_UPPER)
|
if(p->flags & FLAGS_UPPER)
|
||||||
@ -810,25 +802,25 @@ static int dprintf_formatf(
|
|||||||
if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
|
if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
|
||||||
while (width-- > 0)
|
while (width-- > 0)
|
||||||
OUTCHAR('0');
|
OUTCHAR('0');
|
||||||
|
|
||||||
/* Write the number. */
|
/* Write the number. */
|
||||||
while (++w <= workend) {
|
while (++w <= workend) {
|
||||||
OUTCHAR(*w);
|
OUTCHAR(*w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->flags & FLAGS_LEFT)
|
if (p->flags & FLAGS_LEFT)
|
||||||
while (width-- > 0)
|
while (width-- > 0)
|
||||||
OUTCHAR(' ');
|
OUTCHAR(' ');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_STRING:
|
case FORMAT_STRING:
|
||||||
/* String. */
|
/* String. */
|
||||||
{
|
{
|
||||||
static char null[] = "(nil)";
|
static char null[] = "(nil)";
|
||||||
char *str;
|
char *str;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
str = (char *) p->data.str;
|
str = (char *) p->data.str;
|
||||||
if ( str == NULL) {
|
if ( str == NULL) {
|
||||||
/* Write null[] if there's space. */
|
/* Write null[] if there's space. */
|
||||||
@ -845,7 +837,7 @@ static int dprintf_formatf(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
|
|
||||||
if (prec != -1 && (size_t) prec < len)
|
if (prec != -1 && (size_t) prec < len)
|
||||||
len = prec;
|
len = prec;
|
||||||
width -= len;
|
width -= len;
|
||||||
@ -856,7 +848,7 @@ static int dprintf_formatf(
|
|||||||
if (!(p->flags&FLAGS_LEFT))
|
if (!(p->flags&FLAGS_LEFT))
|
||||||
while (width-- > 0)
|
while (width-- > 0)
|
||||||
OUTCHAR(' ');
|
OUTCHAR(' ');
|
||||||
|
|
||||||
while (len-- > 0)
|
while (len-- > 0)
|
||||||
OUTCHAR(*str++);
|
OUTCHAR(*str++);
|
||||||
if (p->flags&FLAGS_LEFT)
|
if (p->flags&FLAGS_LEFT)
|
||||||
@ -867,7 +859,7 @@ static int dprintf_formatf(
|
|||||||
OUTCHAR('"');
|
OUTCHAR('"');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMAT_PTR:
|
case FORMAT_PTR:
|
||||||
/* Generic pointer. */
|
/* Generic pointer. */
|
||||||
{
|
{
|
||||||
@ -886,7 +878,7 @@ static int dprintf_formatf(
|
|||||||
/* Write "(nil)" for a nil pointer. */
|
/* Write "(nil)" for a nil pointer. */
|
||||||
static char strnil[] = "(nil)";
|
static char strnil[] = "(nil)";
|
||||||
char *point;
|
char *point;
|
||||||
|
|
||||||
width -= sizeof(strnil) - 1;
|
width -= sizeof(strnil) - 1;
|
||||||
if (p->flags & FLAGS_LEFT)
|
if (p->flags & FLAGS_LEFT)
|
||||||
while (width-- > 0)
|
while (width-- > 0)
|
||||||
@ -904,7 +896,7 @@ static int dprintf_formatf(
|
|||||||
{
|
{
|
||||||
char formatbuf[32]="%";
|
char formatbuf[32]="%";
|
||||||
char *fptr;
|
char *fptr;
|
||||||
|
|
||||||
width = -1;
|
width = -1;
|
||||||
if (p->flags & FLAGS_WIDTH)
|
if (p->flags & FLAGS_WIDTH)
|
||||||
width = p->width;
|
width = p->width;
|
||||||
@ -948,13 +940,7 @@ static int dprintf_formatf(
|
|||||||
|
|
||||||
/* NOTE NOTE NOTE!! Not all sprintf() implementations returns number
|
/* NOTE NOTE NOTE!! Not all sprintf() implementations returns number
|
||||||
of output characters */
|
of output characters */
|
||||||
#if 0 /*SIZEOF_LONG_DOUBLE*/
|
(sprintf)(work, formatbuf, p->data.dnum);
|
||||||
if (p->flags & FLAGS_LONG)
|
|
||||||
/* This is for support of the 'long double' type */
|
|
||||||
(sprintf)(work, formatbuf, p->data.ldnum);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
(sprintf)(work, formatbuf, p->data.dnum);
|
|
||||||
|
|
||||||
for(fptr=work; *fptr; fptr++)
|
for(fptr=work; *fptr; fptr++)
|
||||||
OUTCHAR(*fptr);
|
OUTCHAR(*fptr);
|
||||||
@ -990,7 +976,7 @@ static int addbyter(int output, FILE *data)
|
|||||||
{
|
{
|
||||||
struct nsprintf *infop=(struct nsprintf *)data;
|
struct nsprintf *infop=(struct nsprintf *)data;
|
||||||
unsigned char outc = (unsigned char)output;
|
unsigned char outc = (unsigned char)output;
|
||||||
|
|
||||||
if(infop->length < infop->max) {
|
if(infop->length < infop->max) {
|
||||||
/* only do this if we haven't reached max length yet */
|
/* only do this if we haven't reached max length yet */
|
||||||
infop->buffer[0] = outc; /* store */
|
infop->buffer[0] = outc; /* store */
|
||||||
@ -1038,7 +1024,7 @@ static int alloc_addbyter(int output, FILE *data)
|
|||||||
{
|
{
|
||||||
struct asprintf *infop=(struct asprintf *)data;
|
struct asprintf *infop=(struct asprintf *)data;
|
||||||
unsigned char outc = (unsigned char)output;
|
unsigned char outc = (unsigned char)output;
|
||||||
|
|
||||||
if(!infop->buffer) {
|
if(!infop->buffer) {
|
||||||
infop->buffer=(char *)malloc(32);
|
infop->buffer=(char *)malloc(32);
|
||||||
if(!infop->buffer) {
|
if(!infop->buffer) {
|
||||||
@ -1195,7 +1181,7 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
curl_mprintf("%3d %5d\n", 10, 1998);
|
curl_mprintf("%3d %5d\n", 10, 1998);
|
||||||
|
|
||||||
ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a hit in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
|
ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a hit in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
|
||||||
|
|
||||||
puts(ptr);
|
puts(ptr);
|
||||||
|
13
lib/setup.h
13
lib/setup.h
@ -270,19 +270,6 @@ typedef int curl_socket_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Curl_addrinfo MUST be used for name resolving information.
|
|
||||||
* Information regarding a single IP witin a Curl_addrinfo MUST be stored in
|
|
||||||
* a Curl_ipconnect struct.
|
|
||||||
*/
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
typedef struct addrinfo Curl_addrinfo;
|
|
||||||
typedef struct addrinfo Curl_ipconnect;
|
|
||||||
#else
|
|
||||||
typedef struct hostent Curl_addrinfo;
|
|
||||||
typedef struct in_addr Curl_ipconnect;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef mpeix
|
#ifdef mpeix
|
||||||
#define IOCTL_3_ARGS
|
#define IOCTL_3_ARGS
|
||||||
#endif
|
#endif
|
||||||
|
180
lib/telnet.c
180
lib/telnet.c
@ -1,8 +1,8 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
* / __| | | | |_) | |
|
* / __| | | | |_) | |
|
||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
*
|
*
|
||||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
* copies of the Software, and permit persons to whom the Software is
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
* furnished to do so, under the terms of the COPYING file.
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
@ -151,12 +151,12 @@ typedef enum
|
|||||||
struct TELNET {
|
struct TELNET {
|
||||||
int please_negotiate;
|
int please_negotiate;
|
||||||
int already_negotiated;
|
int already_negotiated;
|
||||||
int us[256];
|
int us[256];
|
||||||
int usq[256];
|
int usq[256];
|
||||||
int us_preferred[256];
|
int us_preferred[256];
|
||||||
int him[256];
|
int him[256];
|
||||||
int himq[256];
|
int himq[256];
|
||||||
int him_preferred[256];
|
int him_preferred[256];
|
||||||
char subopt_ttype[32]; /* Set with suboption TTYPE */
|
char subopt_ttype[32]; /* Set with suboption TTYPE */
|
||||||
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
|
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
|
||||||
struct curl_slist *telnet_vars; /* Environment variables */
|
struct curl_slist *telnet_vars; /* Environment variables */
|
||||||
@ -164,7 +164,7 @@ struct TELNET {
|
|||||||
/* suboptions */
|
/* suboptions */
|
||||||
char subbuffer[SUBBUFSIZE];
|
char subbuffer[SUBBUFSIZE];
|
||||||
char *subpointer, *subend; /* buffer for sub-options */
|
char *subpointer, *subend; /* buffer for sub-options */
|
||||||
|
|
||||||
TelnetReceive telrcv_state;
|
TelnetReceive telrcv_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -172,22 +172,22 @@ struct TELNET {
|
|||||||
static CURLcode
|
static CURLcode
|
||||||
check_wsock2 ( struct SessionHandle *data )
|
check_wsock2 ( struct SessionHandle *data )
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
WORD wVersionRequested;
|
WORD wVersionRequested;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
|
||||||
curlassert(data);
|
curlassert(data);
|
||||||
|
|
||||||
/* telnet requires at least WinSock 2.0 so ask for it. */
|
/* telnet requires at least WinSock 2.0 so ask for it. */
|
||||||
wVersionRequested = MAKEWORD(2, 0);
|
wVersionRequested = MAKEWORD(2, 0);
|
||||||
|
|
||||||
err = WSAStartup(wVersionRequested, &wsaData);
|
err = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
|
||||||
/* We must've called this once already, so this call */
|
/* We must've called this once already, so this call */
|
||||||
/* should always succeed. But, just in case... */
|
/* should always succeed. But, just in case... */
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
failf(data,"WSAStartup failed (%d)",err);
|
failf(data,"WSAStartup failed (%d)",err);
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have to have a WSACleanup call for every successful */
|
/* We have to have a WSACleanup call for every successful */
|
||||||
@ -212,29 +212,17 @@ CURLcode init_telnet(struct connectdata *conn)
|
|||||||
{
|
{
|
||||||
struct TELNET *tn;
|
struct TELNET *tn;
|
||||||
|
|
||||||
tn = (struct TELNET *)malloc(sizeof(struct TELNET));
|
tn = (struct TELNET *)calloc(1, sizeof(struct TELNET));
|
||||||
if(!tn)
|
if(!tn)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
conn->proto.telnet = (void *)tn; /* make us known */
|
|
||||||
|
|
||||||
memset(tn, 0, sizeof(struct TELNET));
|
conn->proto.telnet = (void *)tn; /* make us known */
|
||||||
|
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
|
|
||||||
/* Init suboptions */
|
/* Init suboptions */
|
||||||
CURL_SB_CLEAR(tn);
|
CURL_SB_CLEAR(tn);
|
||||||
|
|
||||||
/* Set all options to NO */
|
|
||||||
#if 0
|
|
||||||
/* NO is zero => default fill pattern */
|
|
||||||
memset(tn->us, CURL_NO, 256);
|
|
||||||
memset(tn->usq, CURL_NO, 256);
|
|
||||||
memset(tn->us_preferred, CURL_NO, 256);
|
|
||||||
memset(tn->him, CURL_NO, 256);
|
|
||||||
memset(tn->himq, CURL_NO, 256);
|
|
||||||
memset(tn->him_preferred, CURL_NO, 256);
|
|
||||||
#endif
|
|
||||||
/* Set the options we want by default */
|
/* Set the options we want by default */
|
||||||
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
|
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
|
||||||
tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
|
tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
|
||||||
@ -248,12 +236,12 @@ static void negotiate(struct connectdata *conn)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
|
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
|
||||||
|
|
||||||
for(i = 0;i < CURL_NTELOPTS;i++)
|
for(i = 0;i < CURL_NTELOPTS;i++)
|
||||||
{
|
{
|
||||||
if(tn->us_preferred[i] == CURL_YES)
|
if(tn->us_preferred[i] == CURL_YES)
|
||||||
set_local_option(conn, i, CURL_YES);
|
set_local_option(conn, i, CURL_YES);
|
||||||
|
|
||||||
if(tn->him_preferred[i] == CURL_YES)
|
if(tn->him_preferred[i] == CURL_YES)
|
||||||
set_remote_option(conn, i, CURL_YES);
|
set_remote_option(conn, i, CURL_YES);
|
||||||
}
|
}
|
||||||
@ -264,7 +252,7 @@ static void printoption(struct SessionHandle *data,
|
|||||||
{
|
{
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
const char *opt;
|
const char *opt;
|
||||||
|
|
||||||
if (data->set.verbose)
|
if (data->set.verbose)
|
||||||
{
|
{
|
||||||
if (cmd == CURL_IAC)
|
if (cmd == CURL_IAC)
|
||||||
@ -305,9 +293,9 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
|
|||||||
buf[0] = CURL_IAC;
|
buf[0] = CURL_IAC;
|
||||||
buf[1] = cmd;
|
buf[1] = cmd;
|
||||||
buf[2] = option;
|
buf[2] = option;
|
||||||
|
|
||||||
(void)swrite(conn->sock[FIRSTSOCKET], buf, 3);
|
(void)swrite(conn->sock[FIRSTSOCKET], buf, 3);
|
||||||
|
|
||||||
printoption(conn->data, "SENT", cmd, option);
|
printoption(conn->data, "SENT", cmd, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,11 +311,11 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
|
|||||||
tn->him[option] = CURL_WANTYES;
|
tn->him[option] = CURL_WANTYES;
|
||||||
send_negotiation(conn, CURL_DO, option);
|
send_negotiation(conn, CURL_DO, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
/* Already enabled */
|
/* Already enabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -340,7 +328,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -361,12 +349,12 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
|
|||||||
case CURL_NO:
|
case CURL_NO:
|
||||||
/* Already disabled */
|
/* Already disabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
tn->him[option] = CURL_WANTNO;
|
tn->him[option] = CURL_WANTNO;
|
||||||
send_negotiation(conn, CURL_DONT, option);
|
send_negotiation(conn, CURL_DONT, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -378,7 +366,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -410,11 +398,11 @@ void rec_will(struct connectdata *conn, int option)
|
|||||||
send_negotiation(conn, CURL_DONT, option);
|
send_negotiation(conn, CURL_DONT, option);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
/* Already enabled */
|
/* Already enabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -429,7 +417,7 @@ void rec_will(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -445,7 +433,7 @@ void rec_will(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void rec_wont(struct connectdata *conn, int option)
|
void rec_wont(struct connectdata *conn, int option)
|
||||||
{
|
{
|
||||||
@ -455,19 +443,19 @@ void rec_wont(struct connectdata *conn, int option)
|
|||||||
case CURL_NO:
|
case CURL_NO:
|
||||||
/* Already disabled */
|
/* Already disabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
tn->him[option] = CURL_NO;
|
tn->him[option] = CURL_NO;
|
||||||
send_negotiation(conn, CURL_DONT, option);
|
send_negotiation(conn, CURL_DONT, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
case CURL_EMPTY:
|
case CURL_EMPTY:
|
||||||
tn->him[option] = CURL_NO;
|
tn->him[option] = CURL_NO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_OPPOSITE:
|
case CURL_OPPOSITE:
|
||||||
tn->him[option] = CURL_WANTYES;
|
tn->him[option] = CURL_WANTYES;
|
||||||
tn->himq[option] = CURL_EMPTY;
|
tn->himq[option] = CURL_EMPTY;
|
||||||
@ -475,7 +463,7 @@ void rec_wont(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->himq[option])
|
switch(tn->himq[option])
|
||||||
{
|
{
|
||||||
@ -490,7 +478,7 @@ void rec_wont(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_local_option(struct connectdata *conn, int option, int newstate)
|
set_local_option(struct connectdata *conn, int option, int newstate)
|
||||||
{
|
{
|
||||||
@ -503,11 +491,11 @@ set_local_option(struct connectdata *conn, int option, int newstate)
|
|||||||
tn->us[option] = CURL_WANTYES;
|
tn->us[option] = CURL_WANTYES;
|
||||||
send_negotiation(conn, CURL_WILL, option);
|
send_negotiation(conn, CURL_WILL, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
/* Already enabled */
|
/* Already enabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -520,7 +508,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -541,12 +529,12 @@ set_local_option(struct connectdata *conn, int option, int newstate)
|
|||||||
case CURL_NO:
|
case CURL_NO:
|
||||||
/* Already disabled */
|
/* Already disabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
tn->us[option] = CURL_WANTNO;
|
tn->us[option] = CURL_WANTNO;
|
||||||
send_negotiation(conn, CURL_WONT, option);
|
send_negotiation(conn, CURL_WONT, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -558,7 +546,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -590,11 +578,11 @@ void rec_do(struct connectdata *conn, int option)
|
|||||||
send_negotiation(conn, CURL_WONT, option);
|
send_negotiation(conn, CURL_WONT, option);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
/* Already enabled */
|
/* Already enabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -609,7 +597,7 @@ void rec_do(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -626,7 +614,7 @@ void rec_do(struct connectdata *conn, int option)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void rec_dont(struct connectdata *conn, int option)
|
void rec_dont(struct connectdata *conn, int option)
|
||||||
{
|
{
|
||||||
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
|
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
|
||||||
@ -635,19 +623,19 @@ void rec_dont(struct connectdata *conn, int option)
|
|||||||
case CURL_NO:
|
case CURL_NO:
|
||||||
/* Already disabled */
|
/* Already disabled */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_YES:
|
case CURL_YES:
|
||||||
tn->us[option] = CURL_NO;
|
tn->us[option] = CURL_NO;
|
||||||
send_negotiation(conn, CURL_WONT, option);
|
send_negotiation(conn, CURL_WONT, option);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTNO:
|
case CURL_WANTNO:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
case CURL_EMPTY:
|
case CURL_EMPTY:
|
||||||
tn->us[option] = CURL_NO;
|
tn->us[option] = CURL_NO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_OPPOSITE:
|
case CURL_OPPOSITE:
|
||||||
tn->us[option] = CURL_WANTYES;
|
tn->us[option] = CURL_WANTYES;
|
||||||
tn->usq[option] = CURL_EMPTY;
|
tn->usq[option] = CURL_EMPTY;
|
||||||
@ -655,7 +643,7 @@ void rec_dont(struct connectdata *conn, int option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_WANTYES:
|
case CURL_WANTYES:
|
||||||
switch(tn->usq[option])
|
switch(tn->usq[option])
|
||||||
{
|
{
|
||||||
@ -746,7 +734,7 @@ static void printsub(struct SessionHandle *data,
|
|||||||
Curl_infof(data, " NAME");
|
Curl_infof(data, " NAME");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(pointer[0]) {
|
switch(pointer[0]) {
|
||||||
case CURL_TELOPT_TTYPE:
|
case CURL_TELOPT_TTYPE:
|
||||||
case CURL_TELOPT_XDISPLOC:
|
case CURL_TELOPT_XDISPLOC:
|
||||||
@ -776,7 +764,7 @@ static void printsub(struct SessionHandle *data,
|
|||||||
Curl_infof(data, " %.2x", pointer[i]);
|
Curl_infof(data, " %.2x", pointer[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction)
|
if (direction)
|
||||||
{
|
{
|
||||||
Curl_infof(data, "\n");
|
Curl_infof(data, "\n");
|
||||||
@ -986,21 +974,21 @@ void telrcv(struct connectdata *conn,
|
|||||||
rec_will(conn, c);
|
rec_will(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case CURL_TS_WONT:
|
case CURL_TS_WONT:
|
||||||
printoption(data, "RCVD", CURL_WONT, c);
|
printoption(data, "RCVD", CURL_WONT, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_wont(conn, c);
|
rec_wont(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case CURL_TS_DO:
|
case CURL_TS_DO:
|
||||||
printoption(data, "RCVD", CURL_DO, c);
|
printoption(data, "RCVD", CURL_DO, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
rec_do(conn, c);
|
rec_do(conn, c);
|
||||||
tn->telrcv_state = CURL_TS_DATA;
|
tn->telrcv_state = CURL_TS_DATA;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case CURL_TS_DONT:
|
case CURL_TS_DONT:
|
||||||
printoption(data, "RCVD", CURL_DONT, c);
|
printoption(data, "RCVD", CURL_DONT, c);
|
||||||
tn->please_negotiate = 1;
|
tn->please_negotiate = 1;
|
||||||
@ -1040,7 +1028,7 @@ void telrcv(struct connectdata *conn,
|
|||||||
CURL_SB_ACCUM(tn, c);
|
CURL_SB_ACCUM(tn, c);
|
||||||
tn->subpointer -= 2;
|
tn->subpointer -= 2;
|
||||||
CURL_SB_TERM(tn);
|
CURL_SB_TERM(tn);
|
||||||
|
|
||||||
printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
|
printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
|
||||||
suboption(conn); /* handle sub-option */
|
suboption(conn); /* handle sub-option */
|
||||||
tn->telrcv_state = CURL_TS_IAC;
|
tn->telrcv_state = CURL_TS_IAC;
|
||||||
@ -1090,7 +1078,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
WSAEVENT event_handle;
|
WSAEVENT event_handle;
|
||||||
WSANETWORKEVENTS events;
|
WSANETWORKEVENTS events;
|
||||||
HANDLE stdin_handle;
|
HANDLE stdin_handle;
|
||||||
HANDLE objs[2];
|
HANDLE objs[2];
|
||||||
DWORD obj_count;
|
DWORD obj_count;
|
||||||
DWORD wait_timeout;
|
DWORD wait_timeout;
|
||||||
DWORD waitret;
|
DWORD waitret;
|
||||||
@ -1099,7 +1087,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
fd_set readfd;
|
fd_set readfd;
|
||||||
fd_set keepfd;
|
fd_set keepfd;
|
||||||
#endif
|
#endif
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
bool keepon = TRUE;
|
bool keepon = TRUE;
|
||||||
char *buf = data->state.buffer;
|
char *buf = data->state.buffer;
|
||||||
struct TELNET *tn;
|
struct TELNET *tn;
|
||||||
@ -1193,19 +1181,19 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
FreeLibrary(wsock2);
|
FreeLibrary(wsock2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
|
/* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
|
||||||
else use the old WaitForMultipleObjects() way */
|
else use the old WaitForMultipleObjects() way */
|
||||||
if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) {
|
if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) {
|
||||||
/* Don't wait for stdin_handle, just wait for event_handle */
|
/* Don't wait for stdin_handle, just wait for event_handle */
|
||||||
obj_count = 1;
|
obj_count = 1;
|
||||||
/* Check stdin_handle per 100 milliseconds */
|
/* Check stdin_handle per 100 milliseconds */
|
||||||
wait_timeout = 100;
|
wait_timeout = 100;
|
||||||
} else {
|
} else {
|
||||||
obj_count = 2;
|
obj_count = 2;
|
||||||
wait_timeout = INFINITE;
|
wait_timeout = INFINITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep on listening and act on events */
|
/* Keep on listening and act on events */
|
||||||
while(keepon) {
|
while(keepon) {
|
||||||
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
|
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
|
||||||
@ -1222,67 +1210,67 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!nread)
|
if(!nread)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||||
&readfile_read, NULL)) {
|
&readfile_read, NULL)) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nread = readfile_read;
|
nread = readfile_read;
|
||||||
|
|
||||||
while(nread--) {
|
while(nread--) {
|
||||||
outbuf[0] = *buffer++;
|
outbuf[0] = *buffer++;
|
||||||
out_count = 1;
|
out_count = 1;
|
||||||
if(outbuf[0] == CURL_IAC)
|
if(outbuf[0] == CURL_IAC)
|
||||||
outbuf[out_count++] = CURL_IAC;
|
outbuf[out_count++] = CURL_IAC;
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
||||||
out_count, &bytes_written);
|
out_count, &bytes_written);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
{
|
{
|
||||||
unsigned char outbuf[2];
|
unsigned char outbuf[2];
|
||||||
int out_count = 0;
|
int out_count = 0;
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
char *buffer = buf;
|
char *buffer = buf;
|
||||||
|
|
||||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||||
&readfile_read, NULL)) {
|
&readfile_read, NULL)) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nread = readfile_read;
|
nread = readfile_read;
|
||||||
|
|
||||||
while(nread--) {
|
while(nread--) {
|
||||||
outbuf[0] = *buffer++;
|
outbuf[0] = *buffer++;
|
||||||
out_count = 1;
|
out_count = 1;
|
||||||
if(outbuf[0] == CURL_IAC)
|
if(outbuf[0] == CURL_IAC)
|
||||||
outbuf[out_count++] = CURL_IAC;
|
outbuf[out_count++] = CURL_IAC;
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
||||||
out_count, &bytes_written);
|
out_count, &bytes_written);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
if(enum_netevents_func(sockfd, event_handle, &events)
|
if(enum_netevents_func(sockfd, event_handle, &events)
|
||||||
!= SOCKET_ERROR) {
|
!= SOCKET_ERROR) {
|
||||||
if(events.lNetworkEvents & FD_READ) {
|
if(events.lNetworkEvents & FD_READ) {
|
||||||
/* This reallu OUGHT to check its return code. */
|
/* This reallu OUGHT to check its return code. */
|
||||||
(void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
|
(void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
|
||||||
|
|
||||||
telrcv(conn, (unsigned char *)buf, nread);
|
telrcv(conn, (unsigned char *)buf, nread);
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
/* Negotiate if the peer has started negotiating,
|
/* Negotiate if the peer has started negotiating,
|
||||||
otherwise don't. We don't want to speak telnet with
|
otherwise don't. We don't want to speak telnet with
|
||||||
non-telnet servers, like POP or SMTP. */
|
non-telnet servers, like POP or SMTP. */
|
||||||
@ -1291,7 +1279,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
tn->already_negotiated = 1;
|
tn->already_negotiated = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(events.lNetworkEvents & FD_CLOSE) {
|
if(events.lNetworkEvents & FD_CLOSE) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
@ -1340,7 +1328,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
int out_count = 0;
|
int out_count = 0;
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
char *buffer = buf;
|
char *buffer = buf;
|
||||||
|
|
||||||
nread = read(0, buf, 255);
|
nread = read(0, buf, 255);
|
||||||
|
|
||||||
while(nread--) {
|
while(nread--) {
|
||||||
@ -1348,7 +1336,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
|
|||||||
out_count = 1;
|
out_count = 1;
|
||||||
if(outbuf[0] == CURL_IAC)
|
if(outbuf[0] == CURL_IAC)
|
||||||
outbuf[out_count++] = CURL_IAC;
|
outbuf[out_count++] = CURL_IAC;
|
||||||
|
|
||||||
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
|
||||||
out_count, &bytes_written);
|
out_count, &bytes_written);
|
||||||
}
|
}
|
||||||
|
@ -870,13 +870,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0 /* for consideration */
|
|
||||||
else {
|
|
||||||
/* This is a Location: but we have not been instructed to
|
|
||||||
follow it */
|
|
||||||
infof(data, "We ignore this location header as instructed\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* CURL_DISABLE_HTTP */
|
#endif /* CURL_DISABLE_HTTP */
|
||||||
|
|
||||||
|
68
lib/url.c
68
lib/url.c
@ -273,13 +273,11 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
|||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
struct SessionHandle *data;
|
struct SessionHandle *data;
|
||||||
/* Very simple start-up: alloc the struct, init it with zeroes and return */
|
/* Very simple start-up: alloc the struct, init it with zeroes and return */
|
||||||
data = (struct SessionHandle *)malloc(sizeof(struct SessionHandle));
|
data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
|
||||||
if(!data)
|
if(!data)
|
||||||
/* this is a very serious error */
|
/* this is a very serious error */
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
memset(data, 0, sizeof(struct SessionHandle));
|
|
||||||
|
|
||||||
#ifdef USE_ARES
|
#ifdef USE_ARES
|
||||||
if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
|
if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
|
||||||
free(data);
|
free(data);
|
||||||
@ -1859,7 +1857,6 @@ static int handleSock5Proxy(const char *proxy_name,
|
|||||||
socksreq[3] = 1; /* IPv4 = 1 */
|
socksreq[3] = 1; /* IPv4 = 1 */
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifndef ENABLE_IPV6
|
|
||||||
struct Curl_dns_entry *dns;
|
struct Curl_dns_entry *dns;
|
||||||
Curl_addrinfo *hp=NULL;
|
Curl_addrinfo *hp=NULL;
|
||||||
int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns);
|
int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns);
|
||||||
@ -1877,24 +1874,28 @@ static int handleSock5Proxy(const char *proxy_name,
|
|||||||
*/
|
*/
|
||||||
if(dns)
|
if(dns)
|
||||||
hp=dns->addr;
|
hp=dns->addr;
|
||||||
if (hp && hp->h_addr_list[0]) {
|
if (hp) {
|
||||||
socksreq[4] = ((char*)hp->h_addr_list[0])[0];
|
char buf[64];
|
||||||
socksreq[5] = ((char*)hp->h_addr_list[0])[1];
|
unsigned short ip[4];
|
||||||
socksreq[6] = ((char*)hp->h_addr_list[0])[2];
|
Curl_printable_address(hp, buf, sizeof(buf));
|
||||||
socksreq[7] = ((char*)hp->h_addr_list[0])[3];
|
|
||||||
|
if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
|
||||||
|
&ip[0], &ip[1], &ip[2], &ip[3])) {
|
||||||
|
socksreq[4] = ip[0];
|
||||||
|
socksreq[5] = ip[1];
|
||||||
|
socksreq[6] = ip[2];
|
||||||
|
socksreq[7] = ip[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hp = NULL; /* fail! */
|
||||||
|
|
||||||
Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
|
Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
|
||||||
}
|
}
|
||||||
else {
|
if(!hp) {
|
||||||
failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
|
failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
|
||||||
conn->host.name);
|
conn->host.name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
failf(conn->data,
|
|
||||||
"%s:%d has an internal error and needs to be fixed to work",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
|
*((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
|
||||||
@ -1939,7 +1940,7 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
|||||||
bool *connected)
|
bool *connected)
|
||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
Curl_ipconnect *addr;
|
Curl_addrinfo *addr;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
|
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
|
||||||
|
|
||||||
@ -1951,25 +1952,13 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
result= Curl_connecthost(conn,
|
result= Curl_connecthost(conn,
|
||||||
hostaddr,
|
hostaddr,
|
||||||
conn->port,
|
|
||||||
&conn->sock[FIRSTSOCKET],
|
&conn->sock[FIRSTSOCKET],
|
||||||
&addr,
|
&addr,
|
||||||
connected);
|
connected);
|
||||||
if(CURLE_OK == result) {
|
if(CURLE_OK == result) {
|
||||||
/* All is cool, then we store the current information from the hostaddr
|
/* All is cool, then we store the current information */
|
||||||
struct to the serv_addr, as it might be needed later. The address
|
conn->dns_entry = hostaddr;
|
||||||
returned from the function above is crucial here. */
|
conn->ip_addr = addr;
|
||||||
conn->connect_addr = hostaddr;
|
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
conn->serv_addr = addr;
|
|
||||||
#else
|
|
||||||
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
|
||||||
memcpy((char *)&(conn->serv_addr.sin_addr),
|
|
||||||
(struct in_addr *)addr, sizeof(struct in_addr));
|
|
||||||
conn->serv_addr.sin_family = hostaddr->addr->h_addrtype;
|
|
||||||
conn->serv_addr.sin_port = htons((unsigned short)conn->port);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
|
||||||
return handleSock5Proxy(conn->proxyuser,
|
return handleSock5Proxy(conn->proxyuser,
|
||||||
@ -1995,15 +1984,10 @@ static CURLcode ConnectPlease(struct connectdata *conn,
|
|||||||
static void verboseconnect(struct connectdata *conn)
|
static void verboseconnect(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char addrbuf[256] = "";
|
char addrbuf[256];
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
const Curl_ipconnect *addr = conn->serv_addr;
|
|
||||||
#else
|
|
||||||
const Curl_ipconnect *addr = &conn->serv_addr.sin_addr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get a printable version of the network address. */
|
/* Get a printable version of the network address. */
|
||||||
Curl_printable_address(addr, addrbuf, sizeof(addrbuf));
|
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
|
||||||
infof(data, "Connected to %s (%s) port %d\n",
|
infof(data, "Connected to %s (%s) port %d\n",
|
||||||
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
|
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
|
||||||
addrbuf[0] ? addrbuf : "??", conn->port);
|
addrbuf[0] ? addrbuf : "??", conn->port);
|
||||||
@ -3221,8 +3205,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
if(conn->bits.reuse) {
|
if(conn->bits.reuse) {
|
||||||
/* re-used connection, no resolving is necessary */
|
/* re-used connection, no resolving is necessary */
|
||||||
hostaddr = NULL;
|
hostaddr = NULL;
|
||||||
conn->connect_addr = NULL; /* we don't connect now so we don't have any
|
conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh
|
||||||
fresh connect_addr struct to point to */
|
dns entry struct to point to */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* this is a fresh connect */
|
/* this is a fresh connect */
|
||||||
@ -3476,8 +3460,8 @@ CURLcode Curl_done(struct connectdata **connp,
|
|||||||
conn->newurl = NULL;
|
conn->newurl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->connect_addr)
|
if(conn->dns_entry)
|
||||||
Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */
|
Curl_resolv_unlock(conn->data, conn->dns_entry); /* done with this */
|
||||||
|
|
||||||
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
|
||||||
/* scan for DNS cache entries still marked as in use */
|
/* scan for DNS cache entries still marked as in use */
|
||||||
|
@ -446,13 +446,9 @@ struct connectdata {
|
|||||||
#define PROT_SSL (1<<10) /* protocol requires SSL */
|
#define PROT_SSL (1<<10) /* protocol requires SSL */
|
||||||
|
|
||||||
/* the particular host we use, in two different ways */
|
/* the particular host we use, in two different ways */
|
||||||
struct Curl_dns_entry *connect_addr;
|
struct Curl_dns_entry *dns_entry;
|
||||||
|
Curl_addrinfo *ip_addr; /* the particular IP we connected to */
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
|
||||||
struct addrinfo *serv_addr;
|
|
||||||
#else
|
|
||||||
struct sockaddr_in serv_addr;
|
|
||||||
#endif
|
|
||||||
char protostr[16]; /* store the protocol string in this buffer */
|
char protostr[16]; /* store the protocol string in this buffer */
|
||||||
|
|
||||||
struct hostname host;
|
struct hostname host;
|
||||||
@ -574,10 +570,6 @@ struct connectdata {
|
|||||||
struct FTP *ftp;
|
struct FTP *ftp;
|
||||||
struct FILEPROTO *file;
|
struct FILEPROTO *file;
|
||||||
void *telnet; /* private for telnet.c-eyes only */
|
void *telnet; /* private for telnet.c-eyes only */
|
||||||
#if 0 /* no need for special ones for these: */
|
|
||||||
struct LDAP *ldap;
|
|
||||||
struct DICT *dict;
|
|
||||||
#endif
|
|
||||||
void *generic;
|
void *generic;
|
||||||
} proto;
|
} proto;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user