diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/connect.c | 72 | ||||
| -rw-r--r-- | lib/connect.h | 3 | ||||
| -rw-r--r-- | lib/easy.c | 58 | ||||
| -rw-r--r-- | lib/formdata.c | 54 | ||||
| -rw-r--r-- | lib/ftp.c | 214 | ||||
| -rw-r--r-- | lib/hash.c | 53 | ||||
| -rw-r--r-- | lib/hash.h | 10 | ||||
| -rw-r--r-- | lib/hostares.c | 27 | ||||
| -rw-r--r-- | lib/hostasyn.c | 30 | ||||
| -rw-r--r-- | lib/hostip.c | 141 | ||||
| -rw-r--r-- | lib/hostip.h | 172 | ||||
| -rw-r--r-- | lib/hostip4.c | 280 | ||||
| -rw-r--r-- | lib/hostthre.c | 2 | ||||
| -rw-r--r-- | lib/if2ip.c | 14 | ||||
| -rw-r--r-- | lib/if2ip.h | 12 | ||||
| -rw-r--r-- | lib/krb4.c | 34 | ||||
| -rw-r--r-- | lib/llist.c | 65 | ||||
| -rw-r--r-- | lib/memdebug.c | 20 | ||||
| -rw-r--r-- | lib/mprintf.c | 110 | ||||
| -rw-r--r-- | lib/setup.h | 13 | ||||
| -rw-r--r-- | lib/telnet.c | 180 | ||||
| -rw-r--r-- | lib/transfer.c | 7 | ||||
| -rw-r--r-- | lib/url.c | 68 | ||||
| -rw-r--r-- | lib/urldata.h | 12 | 
24 files changed, 630 insertions, 1021 deletions
| diff --git a/lib/connect.c b/lib/connect.c index 5da4ac996..cd024edde 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -330,7 +330,6 @@ static CURLcode bindlocal(struct connectdata *conn,          Curl_resolv_unlock(data, h);          /* we don't need it anymore after this function has returned */ -#ifdef ENABLE_IPV6          if( bind(sockfd, addr->ai_addr, addr->ai_addrlen) >= 0) {            /* we succeeded to bind */            struct sockaddr_in6 add; @@ -344,31 +343,7 @@ static CURLcode bindlocal(struct connectdata *conn,              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) {            failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));            return CURLE_HTTP_PORT_FAILED; @@ -540,9 +515,8 @@ static void tcpnodelay(struct connectdata *conn,  CURLcode Curl_connecthost(struct connectdata *conn,  /* context */                            struct Curl_dns_entry *remotehost, /* use this one */ -                          int port,                  /* connect to this */                            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? */  {    struct SessionHandle *data = conn->data; @@ -552,8 +526,9 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */    int num_addr;    bool conected;    char addr_buf[256]; +  Curl_addrinfo *ai; +  Curl_addrinfo *curr_addr; -  Curl_ipconnect *curr_addr;    struct timeval after;    struct timeval before = Curl_tvnow(); @@ -601,17 +576,18 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */    num_addr = Curl_num_addresses(remotehost->addr);    timeout_per_addr = timeout_ms / num_addr; +  ai = remotehost->addr; +    /* 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.     */ -#ifdef ENABLE_IPV6 +    /*     * Connecting with a getaddrinfo chain     */ -  (void)port; /* the port number is already included in the getaddrinfo -                 struct */ -  for (curr_addr = remotehost->addr, aliasindex=0; curr_addr; +  for (curr_addr = ai, aliasindex=0; curr_addr;         curr_addr = curr_addr->ai_next, aliasindex++) { +      sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype,                      curr_addr->ai_protocol);      if (sockfd == CURL_SOCKET_BAD) { @@ -619,31 +595,6 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */        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));      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         a defined macro on some platforms and some compilers don't like to mix         #ifdefs with macro usage! (AmigaOS is one such platform) */ -#ifdef ENABLE_IPV6 +      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) {        error = Curl_ourerrno(); diff --git a/lib/connect.h b/lib/connect.h index bccb84387..bf46ed348 100644 --- a/lib/connect.h +++ b/lib/connect.h @@ -32,9 +32,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,  CURLcode Curl_connecthost(struct connectdata *conn,                            struct Curl_dns_entry *host, /* connect to this */ -                          int port,       /* connect to this port number */                            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? */                            ); diff --git a/lib/easy.c b/lib/easy.c index b007b97ed..8371afbae 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. @@ -96,36 +96,36 @@ static void win32_cleanup(void)     stack to allow networking */  static CURLcode win32_init(void)  { -  WORD wVersionRequested;   -  WSADATA wsaData;  -  int err;  +  WORD wVersionRequested; +  WSADATA wsaData; +  int err;  #ifdef ENABLE_IPV6    wVersionRequested = MAKEWORD(2, 0);  #else    wVersionRequested = MAKEWORD(1, 1);  #endif -     -  err = WSAStartup(wVersionRequested, &wsaData);  -     -  if (err != 0)  -    /* Tell the user that we couldn't find a useable */  -    /* winsock.dll.     */  -    return CURLE_FAILED_INIT;  -     -  /* Confirm that the Windows Sockets DLL supports what we need.*/  -  /* Note that if the DLL supports versions greater */  -  /* than wVersionRequested, it will still return */  + +  err = WSAStartup(wVersionRequested, &wsaData); + +  if (err != 0) +    /* Tell the user that we couldn't find a useable */ +    /* winsock.dll.     */ +    return CURLE_FAILED_INIT; + +  /* Confirm that the Windows Sockets DLL supports what we need.*/ +  /* Note that if the DLL supports versions greater */ +  /* than wVersionRequested, it will still return */    /* wVersionRequested in wVersion. wHighVersion contains the */    /* highest supported version. */ -  if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||  -       HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {  -    /* Tell the user that we couldn't find a useable */  +  if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) || +       HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) { +    /* Tell the user that we couldn't find a useable */ -    /* winsock.dll. */  -    WSACleanup();  -    return CURLE_FAILED_INIT;  +    /* winsock.dll. */ +    WSACleanup(); +    return CURLE_FAILED_INIT;    }    /* The Windows Sockets DLL is acceptable. Proceed. */    return CURLE_OK; @@ -207,7 +207,7 @@ CURLcode curl_global_init(long flags)    initialized = 1;    init_flags  = flags; -   +    return CURLE_OK;  } @@ -292,7 +292,7 @@ CURL *curl_easy_init(void)    return data;  } -/*  +/*   * curl_easy_setopt() is the external interface for setting options on an   * easy handle.   */ @@ -373,9 +373,9 @@ CURLcode curl_easy_perform(CURL *curl)             screwed up and we should bail out! */          return CURLE_OUT_OF_MEMORY;      } -     +    } -   +    return Curl_perform(data);  } diff --git a/lib/formdata.c b/lib/formdata.c index ea5c4acd8..c338052da 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -1426,60 +1426,6 @@ int main()  #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 */  CURLFORMcode curl_formadd(struct curl_httppost **httppost,                            struct curl_httppost **last_post, @@ -93,6 +93,7 @@  #include "connect.h"  #include "strerror.h"  #include "memory.h" +#include "inet_ntop.h"  #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)  #include "inet_ntoa_r.h" @@ -1022,121 +1023,13 @@ CURLcode ftp_getsize(struct connectdata *conn, char *file,   */  static void  ftp_pasv_verbose(struct connectdata *conn, -                 Curl_ipconnect *addr, +                 Curl_addrinfo *ai,                   char *newhost, /* ascii version */                   int port)  { -#ifndef ENABLE_IPV6 -  /***************************************************************** -   * -   * 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 +  char buf[256]; +  Curl_printable_address(ai, buf, sizeof(buf)); +  infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);  }  /*********************************************************************** @@ -1381,36 +1274,44 @@ CURLcode ftp_use_port(struct connectdata *conn)     *     */    struct sockaddr_in sa; -  struct Curl_dns_entry *h=NULL;    unsigned short porttouse;    char myhost[256] = "";    bool sa_filled_in = FALSE; +  Curl_addrinfo *addr = NULL; +  unsigned short ip[4];    if(data->set.ftpport) {      in_addr_t in; -    int rc;      /* First check if the given name is an IP address */      in=inet_addr(data->set.ftpport); -    if((in == CURL_INADDR_NONE) && -       Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { -      rc = Curl_resolv(conn, myhost, 0, &h); -      if(rc == CURLRESOLV_PENDING) -        rc = Curl_wait_for_resolv(conn, &h); -    } +    if(in != CURL_INADDR_NONE) +      /* this is an IPv4 address */ +      addr = Curl_ip2addr(in, data->set.ftpport, 0);      else { -      size_t len = strlen(data->set.ftpport); -      if(len>1) { -        rc = Curl_resolv(conn, data->set.ftpport, 0, &h); +      if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) { +        /* The interface to IP conversion provided a dotted address */ +        in=inet_addr(myhost); +        addr = Curl_ip2addr(in, myhost, 0); +      } +      else if(strlen(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)            rc = Curl_wait_for_resolv(conn, &h); -      } -      if(h) -        strcpy(myhost, data->set.ftpport); /* buffer overflow risk */ -    } -  } -  if(! *myhost) { +        if(h) { +          addr = h->addr; +          /* when we return from this function, we can forget about this entry +             to we can unlock it now already */ +          Curl_resolv_unlock(data, h); +        } /* (h) */ +      } /* strlen */ +    } /* CURL_INADDR_NONE */ +  } /* data->set.ftpport */ + +  if(!addr) {      /* pick a suitable default here */      socklen_t sslen; @@ -1425,12 +1326,9 @@ CURLcode ftp_use_port(struct connectdata *conn)      sa_filled_in = TRUE; /* the sa struct is filled in */    } -  if(h) -    /* when we return from here, we can forget about this */ -    Curl_resolv_unlock(data, h); - -  if ( h || sa_filled_in) { -    if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) != CURL_SOCKET_BAD ) { +  if (addr || sa_filled_in) { +    portsock = socket(AF_INET, SOCK_STREAM, 0); +    if(CURL_SOCKET_BAD != portsock) {        int size;        /* 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;        if(!sa_filled_in) { -        memset((char *)&sa, 0, sizeof(sa)); -        memcpy((char *)&sa.sin_addr, -               h->addr->h_addr, -               h->addr->h_length); -        sa.sin_family = AF_INET; +        memcpy(&sa, addr->ai_addr, sizeof(sa));          sa.sin_addr.s_addr = INADDR_ANY;        } @@ -1478,29 +1372,19 @@ CURLcode ftp_use_port(struct connectdata *conn)      }    }    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;    } -  { -#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 -    /* ignore the return code from inet_ntoa_r() as it is int or -       char * depending on system */ -    inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)); -    sscanf( ntoa_buf, "%hu.%hu.%hu.%hu", -            &ip[0], &ip[1], &ip[2], &ip[3]); -#else -    sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu", -            &ip[0], &ip[1], &ip[2], &ip[3]); -#endif + +  if(sa_filled_in) +    Curl_inet_ntop(AF_INET, &((struct sockaddr_in *)&sa)->sin_addr, +                   myhost, sizeof(myhost)); +  else +    Curl_printable_address(addr, myhost, sizeof(myhost)); + +  if(4 == sscanf(myhost, "%hu.%hu.%hu.%hu", +                 &ip[0], &ip[1], &ip[2], &ip[3])) { +      infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n",            ip[0], ip[1], ip[2], ip[3], porttouse); @@ -1510,7 +1394,12 @@ CURLcode ftp_use_port(struct connectdata *conn)                           porttouse & 255);      if(result)        return result; +    } +  else +    return CURLE_FTP_PORT_FAILED; + +  Curl_freeaddrinfo(addr);    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);    if(result) @@ -1544,7 +1433,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,    int ftpcode; /* receive FTP response codes in this */    CURLcode result;    struct Curl_dns_entry *addr=NULL; -  Curl_ipconnect *conninfo; +  Curl_addrinfo *conninfo;    int rc;    /* @@ -1693,7 +1582,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn,    result = Curl_connecthost(conn,                              addr, -                            connectport,                              &conn->sock[SECONDARYSOCKET],                              &conninfo,                              connected); diff --git a/lib/hash.c b/lib/hash.c index f33d91dc8..be841b3fe 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * 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;  } -static void  +static void  hash_element_dtor(void *user, void *element)  {    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->size = 0; -  h->slots = slots;   +  h->slots = slots;    h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));    if(h->table) { @@ -106,10 +106,10 @@ Curl_hash_alloc(int slots, curl_hash_dtor dtor)    return h;  } -static int  +static int  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 &&        memcmp(key1, key2, key1_len) == 0) {      return 1; @@ -180,29 +180,6 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p)    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 *  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) -void  +void  Curl_hash_apply(curl_hash *h, void *user,                  void (*cb)(void *user, void *ptr))  { @@ -278,15 +255,7 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user,    }  } -#if 0 -int -Curl_hash_count(curl_hash *h) -{ -  return h->size; -} -#endif - -void  +void  Curl_hash_destroy(curl_hash *h)  {    if (!h) diff --git a/lib/hash.h b/lib/hash.h index 60fd84d52..7814674fd 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -1,10 +1,10 @@  #ifndef __HASH_H  #define __HASH_H  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. diff --git a/lib/hostares.c b/lib/hostares.c index 07a79fd96..80d1ecd6c 100644 --- a/lib/hostares.c +++ b/lib/hostares.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * 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_usec = (timeout%1000)*1000; -     +      FD_ZERO(&read_fds);      FD_ZERO(&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       in the cache. */ -     +    if(entry)      *entry = conn->async.dns; @@ -251,7 +251,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,         cleaning up this connection properly */      Curl_disconnect(conn);    } -   +    return rc;  } @@ -273,10 +273,11 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,    in_addr_t in = inet_addr(hostname);    *waitp = FALSE; -   -  if (in != CURL_INADDR_NONE) + +  if (in != CURL_INADDR_NONE) {      /* 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); @@ -290,8 +291,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,      /* areschannel is already setup in the Curl_open() function */      ares_gethostbyname(data->state.areschannel, hostname, PF_INET, -                       Curl_addrinfo_callback, conn); -       +                       Curl_addrinfo4_callback, conn); +      *waitp = TRUE; /* please wait for the response */    }    return NULL; /* no struct yet */ diff --git a/lib/hostasyn.c b/lib/hostasyn.c index d308cd17d..da072a043 100644 --- a/lib/hostasyn.c +++ b/lib/hostasyn.c @@ -108,9 +108,9 @@   *   * The storage operation locks and unlocks the DNS cache.   */ -void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */ -                            int status, -                            Curl_addrinfo *hostent) +static void addrinfo_callback(void *arg, /* "struct connectdata *" */ +                              int status, +                              void *addr)  {    struct connectdata *conn = (struct connectdata *)arg;    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!       */ -    Curl_addrinfo *he = Curl_addrinfo_copy(hostent); -    if(he) { +    Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port); +    if(ai) {        struct SessionHandle *data = conn->data;        if(data->share)          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.port);        if(!dns)          /* failed to store, cleanup and return error */ -        Curl_freeaddrinfo(he); +        Curl_freeaddrinfo(ai);        if(data->share)          Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -151,4 +151,20 @@ void Curl_addrinfo_callback(void *arg, /* "struct connectdata *" */       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 */ diff --git a/lib/hostip.c b/lib/hostip.c index b5c710339..7a32d1728 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -174,14 +174,8 @@ void Curl_global_host_cache_dtor(void)  int Curl_num_addresses(const Curl_addrinfo *addr)  {    int i; - -#ifdef ENABLE_IPV6 -  for (i = 0; addr; addr = addr->ai_next, i++) -#else -  for (i = 0; addr->h_addr_list[i]; i++) -#endif -      ; -  return (i); +  for (i = 0; addr; addr = addr->ai_next, i++); +  return i;  }  /* @@ -191,18 +185,18 @@ int Curl_num_addresses(const Curl_addrinfo *addr)   *   * 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)  { -#ifdef CURLRES_IPV6    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; - -  return Curl_inet_ntop(af, af == AF_INET6 ? ip6 : ip4, buf, bufsize); +#ifdef CURLRES_IPV6 +  const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;  #else -  return Curl_inet_ntop(AF_INET, ip, buf, bufsize); +  const void *ip6 = NULL;  #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);  } -#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  /* 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   * 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; -  Curl_addrinfo *copy; -  int i; -  char *str; -  size_t len; -  char *aptr = (char *)malloc(CURL_HOSTENT_SIZE); -  char *bufptr = aptr; - -  if(!bufptr) -    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; +  struct hostent *orig = org; -  return copy; +  return Curl_he2ai(orig, port);  }  #endif /* CURLRES_ADDRINFO_COPY */ diff --git a/lib/hostip.h b/lib/hostip.h index 24d6fcfe1..aa3aba05f 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -26,6 +26,85 @@  #include "setup.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 hostent;  struct SessionHandle; @@ -119,28 +198,37 @@ int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,  #endif  /* This is the callback function that is used when we build with asynch -   resolve */ -void Curl_addrinfo_callback(void *arg, +   resolve, ipv4 */ +void Curl_addrinfo4_callback(void *arg,                              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); + + +/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP +   address */ +Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port); -/* This is a utility-function for ipv4-builds to create a hostent struct -   from a numerical-only IP address */ -Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname); +/* [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 */  void Curl_hostent_relocate(struct hostent *h, long offset); -/* copy a Curl_addrinfo struct, currently this only supports copying -   a hostent (ipv4-style) struct */ -Curl_addrinfo *Curl_addrinfo_copy(Curl_addrinfo *orig); +/* Clone a Curl_addrinfo struct, works protocol independently */ +Curl_addrinfo *Curl_addrinfo_copy(void *orig, int port);  /*   * 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   * 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);  /* @@ -158,71 +246,7 @@ Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,  #define CURL_INADDR_NONE INADDR_NONE  #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 diff --git a/lib/hostip4.c b/lib/hostip4.c index eef1f1ab6..4dfa31b80 100644 --- a/lib/hostip4.c +++ b/lib/hostip4.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. @@ -97,13 +97,19 @@  #ifdef CURLRES_IPV4 /* plain ipv4 code coming up */  /* - * This is a wrapper function for freeing name information in a protocol - * independent way. This takes care of using the appropriate underlying - * function. + * This is a function for freeing name information in a protocol independent + * way.   */ -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 */  } +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   * 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 - * information for this address/host. + * returns a Curl_addrinfo chain filled in correctly with information for this + * address/host.   *   * The input parameters ARE NOT checked for validity but they are expected   * to have been checked already when this is called.   */ -Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname) +Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port)  { +  Curl_addrinfo *ai;    struct hostent *h;    struct in_addr *addrentry; -  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 */ -  } *buf = (struct namebuf *)malloc(sizeof(struct namebuf)); - -  if(!buf) -    return NULL; /* major failure */ +  struct namebuf buffer; +  struct namebuf *buf = &buffer;    h = &buf->hostentry;    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 */    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 */ @@ -183,6 +192,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,                                  int port,                                  int *waitp)  { +  Curl_addrinfo *ai = NULL;    struct hostent *h = NULL;    in_addr_t in;    struct SessionHandle *data = conn->data; @@ -191,9 +201,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,    *waitp = 0; /* don't wait, we act synchronously */    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 */ -    return Curl_ip2addr(in, hostname); +    return Curl_ip2addr(in, hostname, port); +  }  #if defined(HAVE_GETHOSTBYNAME_R)    /* @@ -204,7 +215,6 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,    else {      int h_errnop;      int res=ERANGE; -    int step_size=200;      int *buf = (int *)calloc(CURL_HOSTENT_SIZE, 1);      if(!buf)        return NULL; /* major failure */ @@ -217,99 +227,64 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,  #ifdef HAVE_GETHOSTBYNAME_R_5      /* Solaris, IRIX and more */      (void)res; /* prevent compiler warning */ -    while(!h) { -      h = gethostbyname_r(hostname, -                          (struct hostent *)buf, -                          (char *)buf + sizeof(struct hostent), -                          step_size - sizeof(struct hostent), -                          &h_errnop); - -      /* If the buffer is too small, it returns NULL and sets errno to -       * ERANGE. The errno is thread safe if this is compiled with -       * -D_REENTRANT as then the 'errno' variable is a macro defined to get -       * 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 +    h = gethostbyname_r(hostname, +                        (struct hostent *)buf, +                        (char *)buf + sizeof(struct hostent), +                        CURL_HOSTENT_SIZE - sizeof(struct hostent), +                        &h_errnop); + +    /* If the buffer is too small, it returns NULL and sets errno to +     * ERANGE. The errno is thread safe if this is compiled with +     * -D_REENTRANT as then the 'errno' variable is a macro defined to get +     * used properly for threads. +     */      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  #endif /* HAVE_GETHOSTBYNAME_R_5 */  #ifdef HAVE_GETHOSTBYNAME_R_6      /* 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<0) && ((ERANGE == errno) || (EAGAIN == errno)))) -	step_size+=200; -      else -        break; -    } while(step_size <= CURL_HOSTENT_SIZE); +    res=gethostbyname_r(hostname, +                        (struct hostent *)buf, +                        (char *)buf + sizeof(struct hostent), +                        CURL_HOSTENT_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(!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 */  #ifdef HAVE_GETHOSTBYNAME_R_3      /* 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         * memory area to the actually used amount.         */ -    }     +    }      else  #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         * do.         */ -      h = Curl_addrinfo_copy(h); +      return Curl_addrinfo_copy(h);      }  #endif /*HAVE_GETHOSTBYNAME_R */    } -  return h; +  if(h) { +    ai = Curl_he2ai(h, port); + +    free(h); +  } + +  return ai;  }  #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 */ diff --git a/lib/hostthre.c b/lib/hostthre.c index 9014b02c9..29b6ab387 100644 --- a/lib/hostthre.c +++ b/lib/hostthre.c @@ -469,7 +469,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,            hostname, port, Curl_strerror(conn,WSAGetLastError()));      return NULL;    } -  return h; +  return Curl_he2ai(h, port);  }  #endif /* CURLRES_IPV4 */ diff --git a/lib/if2ip.c b/lib/if2ip.c index b816d246f..237d1f758 100644 --- a/lib/if2ip.c +++ b/lib/if2ip.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. @@ -64,7 +64,7 @@  #include <sys/sockio.h>  #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"  #endif @@ -84,7 +84,7 @@ char *Curl_if2ip(const char *interface, char *buf, int buf_size)  {    int dummy;    char *ip=NULL; -   +    if(!interface)      return NULL; diff --git a/lib/if2ip.h b/lib/if2ip.h index 30a6540a4..45a180531 100644 --- a/lib/if2ip.h +++ b/lib/if2ip.h @@ -1,10 +1,10 @@  #ifndef __IF2IP_H  #define __IF2IP_H  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * 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_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 diff --git a/lib/krb4.c b/lib/krb4.c index 994e6111f..743f3f121 100644 --- a/lib/krb4.c +++ b/lib/krb4.c @@ -10,22 +10,22 @@   * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan   * (Royal Institute of Technology, Stockholm, Sweden).   * All rights reserved. - *  + *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions   * are met: - *  + *   * 1. Redistributions of source code must retain the above copyright   *    notice, this list of conditions and the following disclaimer. - *  + *   * 2. Redistributions in binary form must reproduce the above copyright   *    notice, this list of conditions and the following disclaimer in the   *    documentation and/or other materials provided with the distribution. - *  + *   * 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   *    without specific prior written permission. - *  + *   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -70,7 +70,7 @@  #include "memdebug.h"  #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 hisctladdr REMOTE_ADDR @@ -120,13 +120,13 @@ krb4_decode(void *app_data, void *buf, int len, int level,    MSG_DAT m;    int e;    struct krb4_data *d = app_data; -   +    if(level == prot_safe)      e = krb_rd_safe(buf, len, &d->key,                      (struct sockaddr_in *)REMOTE_ADDR,                      (struct sockaddr_in *)LOCAL_ADDR, &m);    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 *)LOCAL_ADDR, &m);    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;    *to = malloc(length + 31);    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 *)REMOTE_ADDR);    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 *)REMOTE_ADDR);    else @@ -167,7 +167,7 @@ krb4_encode(void *app_data, void *from, int length, int level, void **to,  }  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)  {    int ret; @@ -223,7 +223,7 @@ krb4_auth(void *app_data, struct connectdata *conn)      Curl_infof(data, "%s\n", krb_get_err_text(ret));      return AUTH_CONTINUE;    } -   +  #ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM    if (krb_get_config_bool("nat_in_use")) {      struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; @@ -281,11 +281,11 @@ krb4_auth(void *app_data, struct connectdata *conn)      return AUTH_ERROR;    }    adat.length = len; -  ret = krb_rd_safe(adat.dat, adat.length, &d->key,  -                    (struct sockaddr_in *)hisctladdr,  +  ret = krb_rd_safe(adat.dat, adat.length, &d->key, +                    (struct sockaddr_in *)hisctladdr,                      (struct sockaddr_in *)myctladdr, &msg_data);    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));      return AUTH_ERROR;    } @@ -354,7 +354,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)    }    tkt.length = tmp;    tktcopy.length = tkt.length; -     +    p = strstr(conn->data->state.buffer, "P=");    if(!p) {      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_key_sched(&key, schedule); -     +    des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,                     tkt.length,                     schedule, &key, DES_DECRYPT); diff --git a/lib/llist.c b/lib/llist.c index 2f059991d..961848692 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. @@ -32,7 +32,7 @@  /* this must be the last include file */  #include "memdebug.h" -void  +void  Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)  {    l->size = 0; @@ -90,36 +90,7 @@ Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)    return 1;  } -#if 0 -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  +int  Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)  {    if (e == NULL || list->size == 0) @@ -147,27 +118,7 @@ Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)    return 1;  } -#if 0 -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  +void  Curl_llist_destroy(curl_llist *list, void *user)  {    if(list) { diff --git a/lib/memdebug.c b/lib/memdebug.c index 718391cdb..f5ef34d44 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -1,9 +1,9 @@  #ifdef CURLDEBUG  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * 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        memsize--; /* countdown */ -     +      /* log the countdown */      if(logfile && source)        fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n",                source, line, memsize); -     +    }    return FALSE; /* allow this */ @@ -166,7 +166,7 @@ char *curl_dostrdup(const char *str, int line, const char *source)    size_t len;    curlassert(str != NULL); -   +    if(countcheck("strdup", line, source))      return NULL; @@ -221,7 +221,7 @@ void curl_dofree(void *ptr, int line, const char *source)    /* destroy  */    memset(mem->mem, 0x13, mem->size); -   +    /* free for real */    (Curl_cfree)(mem); @@ -285,7 +285,7 @@ int curl_fclose(FILE *file, int line, const char *source)  }  #else  #ifdef VMS -int VOID_VAR_MEMDEBUG;	 +int VOID_VAR_MEMDEBUG;  #else  /* we provide a fake do-nothing function here to avoid compiler warnings */  void curl_memdebug(void) {} diff --git a/lib/mprintf.c b/lib/mprintf.c index cd096c599..6e77075c2 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -142,9 +142,6 @@ typedef struct {      LONG_LONG lnum;  #endif      double dnum; -#if 0 /*SIZEOF_LONG_DOUBLE */ -    long double ldnum; -#endif    } data;  } va_stack_t; @@ -227,7 +224,7 @@ int dprintf_Pass1Report(va_stack_t *vto, int max)        break;      case FORMAT_LONGDOUBLE:        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$) */        param_num++; -       +        this_param = dprintf_DollarString(fmt, &fmt);        if (0 == this_param)  	/* 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 */  	  flags |= FLAGS_WIDTHPARAM;  	  param_num++; -	   +  	  i = dprintf_DollarString(fmt, &fmt);  	  if(i)  	    width = i; @@ -471,7 +468,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,        case 'c':  	vto[i].type = FORMAT_INT;  	flags |= FLAGS_CHAR; -	break;	 +	break;        case 'f':  	vto[i].type = FORMAT_DOUBLE;  	break; @@ -486,11 +483,11 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,        case 'g':  	vto[i].type = FORMAT_DOUBLE;  	flags |= FLAGS_FLOATG; -	break;	 +	break;        case 'G':  	vto[i].type = FORMAT_DOUBLE;  	flags |= FLAGS_FLOATG|FLAGS_UPPER; -	break;	 +	break;        default:  	vto[i].type = FORMAT_UNKNOWN;  	break; @@ -499,7 +496,7 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,        vto[i].flags = flags;        vto[i].width = width;        vto[i].precision = precision; -       +        if (flags & FLAGS_WIDTHPARAM) {  	/* we have the width specified from a parameter, so we make that  	   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].flags = FLAGS_NEW;  	vto[i].precision = vto[i].width = 0; /* can't use width or precision -						of width! */	 +						of width! */        }        if (flags & FLAGS_PRECPARAM) {  	/* 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:  	vto[i].data.str = va_arg(arglist, char *);  	break; -	 +        case FORMAT_INTPTR:        case FORMAT_UNKNOWN:        case FORMAT_PTR:  	vto[i].data.ptr = va_arg(arglist, void *);  	break; -	 +        case FORMAT_INT:  #ifdef ENABLE_64BIT  	if(vto[i].flags & FLAGS_LONGLONG) @@ -561,23 +558,18 @@ static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,  	else  	  vto[i].data.num = va_arg(arglist, int);  	break; -	 +        case FORMAT_DOUBLE: -#if 0 /*SIZEOF_LONG_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); +        vto[i].data.dnum = va_arg(arglist, double);  	break; -	 +        case FORMAT_WIDTH:  	/* Argument has been read. Silently convert it into an integer  	 * for later use  	 */  	vto[i].type = FORMAT_INT;  	break; -	 +        default:  	break;        } @@ -620,21 +612,21 @@ static int dprintf_formatf(    end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()                         created for us */ -   +    f = (char *)format;    while (*f != '\0') {      /* Format spec modifiers.  */      char alt; -     +      /* Width of a field.  */      long width;      /* Precision of a field.  */      long prec; -     +      /* Decimal integer is negative.  */      char is_neg; -     +      /* Base of a number to be written.  */      long base; @@ -645,7 +637,7 @@ static int dprintf_formatf(      unsigned long num;  #endif      long signed_num; -     +      if (*f != '%') {        /* This isn't a format spec, so write everything out until the next one  	 OR end of string is reached.  */ @@ -654,9 +646,9 @@ static int dprintf_formatf(        } while(*++f && ('%' != *f));        continue;      } -     +      ++f; -     +      /* Check for "%%".  Note that although the ANSI standard lists         '%' as a conversion specifier, it says "The complete format         specification shall be `%%'," so we can avoid all the width @@ -675,7 +667,7 @@ static int dprintf_formatf(        param = param_num;      else        --param; -     +      param_num++; /* increase this always to allow "%2$s %1$s %s" and then the  		    third %s will pick the 3rd argument */ @@ -696,7 +688,7 @@ static int dprintf_formatf(        prec = -1;      alt = (p->flags & FLAGS_ALT)?TRUE:FALSE; -     +      switch (p->type) {      case FORMAT_INT:        num = p->data.num; @@ -742,26 +734,26 @@ static int dprintf_formatf(  #endif        {  	signed_num = (long) num; -       +  	is_neg = signed_num < 0;  	num = is_neg ? (- signed_num) : signed_num;        }        goto number; -       +      unsigned_number:;        /* Unsigned number of base BASE.  */        is_neg = 0; -       +      number:;        /* Number of base BASE.  */        {  	char *workend = &work[sizeof(work) - 1];  	char *w; -	 +  	/* Supply a default precision if none was given.  */  	if (prec == -1)  	  prec = 1; -	 +  	/* Put the number in WORK.  */  	w = workend;  	while (num > 0) { @@ -770,35 +762,35 @@ static int dprintf_formatf(  	}  	width -= workend - w;  	prec -= workend - w; -	 +  	if (alt && base == 8 && prec <= 0) {  	  *w-- = '0';  	  --width;  	} -	 +  	if (prec > 0) {  	  width -= prec;  	  while (prec-- > 0)  	    *w-- = '0';  	} -	 +  	if (alt && base == 16)  	  width -= 2; -	 +  	if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))  	  --width; -	 +  	if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))  	  while (width-- > 0)  	    OUTCHAR(' '); -	 +  	if (is_neg)  	  OUTCHAR('-');  	else if (p->flags & FLAGS_SHOWSIGN)  	  OUTCHAR('+');  	else if (p->flags & FLAGS_SPACE)  	  OUTCHAR(' '); -	 +  	if (alt && base == 16) {  	  OUTCHAR('0');  	  if(p->flags & FLAGS_UPPER) @@ -810,25 +802,25 @@ static int dprintf_formatf(  	if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))  	  while (width-- > 0)  	    OUTCHAR('0'); -	 +  	/* Write the number.  */  	while (++w <= workend) {  	  OUTCHAR(*w);  	} -	 +  	if (p->flags & FLAGS_LEFT)  	  while (width-- > 0)  	    OUTCHAR(' ');        }        break; -       +      case FORMAT_STRING:  	    /* String.  */        {  	static char null[] = "(nil)";  	char *str;  	size_t len; -	 +  	str = (char *) p->data.str;  	if ( str == NULL) {  	  /* Write null[] if there's space.  */ @@ -845,7 +837,7 @@ static int dprintf_formatf(  	}  	else  	  len = strlen(str); -	 +  	if (prec != -1 && (size_t) prec < len)  	  len = prec;  	width -= len; @@ -856,7 +848,7 @@ static int dprintf_formatf(  	if (!(p->flags&FLAGS_LEFT))  	  while (width-- > 0)  	    OUTCHAR(' '); -	 +  	while (len-- > 0)  	  OUTCHAR(*str++);  	if (p->flags&FLAGS_LEFT) @@ -867,7 +859,7 @@ static int dprintf_formatf(  	  OUTCHAR('"');        }        break; -       +      case FORMAT_PTR:        /* Generic pointer.  */        { @@ -886,7 +878,7 @@ static int dprintf_formatf(  	  /* Write "(nil)" for a nil pointer.  */  	  static char strnil[] = "(nil)";  	  char *point; -	   +  	  width -= sizeof(strnil) - 1;  	  if (p->flags & FLAGS_LEFT)  	    while (width-- > 0) @@ -904,7 +896,7 @@ static int dprintf_formatf(        {  	char formatbuf[32]="%";  	char *fptr; -	 +  	width = -1;  	if (p->flags & FLAGS_WIDTH)  	  width = p->width; @@ -948,13 +940,7 @@ static int dprintf_formatf(  	/* NOTE NOTE NOTE!! Not all sprintf() implementations returns number  	   of output characters */ -#if 0 /*SIZEOF_LONG_DOUBLE*/ -	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); +        (sprintf)(work, formatbuf, p->data.dnum);  	for(fptr=work; *fptr; fptr++)  	  OUTCHAR(*fptr); @@ -990,7 +976,7 @@ static int addbyter(int output, FILE *data)  {    struct nsprintf *infop=(struct nsprintf *)data;    unsigned char outc = (unsigned char)output; -  +    if(infop->length < infop->max) {      /* only do this if we haven't reached max length yet */      infop->buffer[0] = outc; /* store */ @@ -1038,7 +1024,7 @@ static int alloc_addbyter(int output, FILE *data)  {    struct asprintf *infop=(struct asprintf *)data;    unsigned char outc = (unsigned char)output; -  +    if(!infop->buffer) {      infop->buffer=(char *)malloc(32);      if(!infop->buffer) { @@ -1195,7 +1181,7 @@ int main()  #endif    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);    puts(ptr); diff --git a/lib/setup.h b/lib/setup.h index 936199138..2ee7ee267 100644 --- a/lib/setup.h +++ b/lib/setup.h @@ -270,19 +270,6 @@ typedef int curl_socket_t;  #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  #define IOCTL_3_ARGS  #endif diff --git a/lib/telnet.c b/lib/telnet.c index fb4ba5e00..6915e601d 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -1,8 +1,8 @@  /*************************************************************************** - *                                  _   _ ____  _      - *  Project                     ___| | | |  _ \| |     - *                             / __| | | | |_) | |     - *                            | (__| |_| |  _ <| |___  + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___   *                             \___|\___/|_| \_\_____|   *   * 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   * you should have received as part of this distribution. The terms   * are also available at http://curl.haxx.se/docs/copyright.html. - *  + *   * 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   * furnished to do so, under the terms of the COPYING file. @@ -151,12 +151,12 @@ typedef enum  struct TELNET {    int please_negotiate;    int already_negotiated; -  int us[256];  -  int usq[256];  -  int us_preferred[256];  -  int him[256];  -  int himq[256];  -  int him_preferred[256];  +  int us[256]; +  int usq[256]; +  int us_preferred[256]; +  int him[256]; +  int himq[256]; +  int him_preferred[256];    char subopt_ttype[32];             /* Set with suboption TTYPE */    char subopt_xdisploc[128];          /* Set with suboption XDISPLOC */    struct curl_slist *telnet_vars; /* Environment variables */ @@ -164,7 +164,7 @@ struct TELNET {    /* suboptions */    char subbuffer[SUBBUFSIZE];    char *subpointer, *subend;      /* buffer for sub-options */ -   +    TelnetReceive telrcv_state;  }; @@ -172,22 +172,22 @@ struct TELNET {  static CURLcode  check_wsock2 ( struct SessionHandle *data )  { -  int err;  -  WORD wVersionRequested;   -  WSADATA wsaData;  +  int err; +  WORD wVersionRequested; +  WSADATA wsaData;    curlassert(data);    /* telnet requires at least WinSock 2.0 so ask for it. */    wVersionRequested = MAKEWORD(2, 0); -  err = WSAStartup(wVersionRequested, &wsaData);  -   +  err = WSAStartup(wVersionRequested, &wsaData); +    /* We must've called this once already, so this call */    /* should always succeed.  But, just in case... */    if (err != 0) {      failf(data,"WSAStartup failed (%d)",err); -    return CURLE_FAILED_INIT;  +    return CURLE_FAILED_INIT;    }    /* We have to have a WSACleanup call for every successful */ @@ -212,29 +212,17 @@ CURLcode init_telnet(struct connectdata *conn)  {    struct TELNET *tn; -  tn = (struct TELNET *)malloc(sizeof(struct TELNET)); +  tn = (struct TELNET *)calloc(1, sizeof(struct TELNET));    if(!tn)      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;    /* Init suboptions */    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 */    tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;    tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES; @@ -248,12 +236,12 @@ static void negotiate(struct connectdata *conn)  {    int i;    struct TELNET *tn = (struct TELNET *)conn->proto.telnet; -    +    for(i = 0;i < CURL_NTELOPTS;i++)    {      if(tn->us_preferred[i] == CURL_YES)        set_local_option(conn, i, CURL_YES); -       +      if(tn->him_preferred[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 *opt; -    +    if (data->set.verbose)    {      if (cmd == CURL_IAC) @@ -305,9 +293,9 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)     buf[0] = CURL_IAC;     buf[1] = cmd;     buf[2] = option; -    +     (void)swrite(conn->sock[FIRSTSOCKET], buf, 3); -    +     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;          send_negotiation(conn, CURL_DO, option);          break; -	  +        case CURL_YES:          /* Already enabled */          break; -	  +        case CURL_WANTNO:          switch(tn->himq[option])          { @@ -340,7 +328,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)              break;          }          break; -	  +        case CURL_WANTYES:          switch(tn->himq[option])          { @@ -361,12 +349,12 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)        case CURL_NO:          /* Already disabled */          break; -	  +        case CURL_YES:          tn->him[option] = CURL_WANTNO;          send_negotiation(conn, CURL_DONT, option);          break; -	  +        case CURL_WANTNO:          switch(tn->himq[option])          { @@ -378,7 +366,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)              break;          }          break; -	  +        case CURL_WANTYES:          switch(tn->himq[option])          { @@ -410,11 +398,11 @@ void rec_will(struct connectdata *conn, int option)          send_negotiation(conn, CURL_DONT, option);        }        break; -	  +      case CURL_YES:        /* Already enabled */        break; -	  +      case CURL_WANTNO:        switch(tn->himq[option])        { @@ -429,7 +417,7 @@ void rec_will(struct connectdata *conn, int option)            break;        }        break; -	  +      case CURL_WANTYES:        switch(tn->himq[option])        { @@ -445,7 +433,7 @@ void rec_will(struct connectdata *conn, int option)        break;    }  } -    +  static  void rec_wont(struct connectdata *conn, int option)  { @@ -455,19 +443,19 @@ void rec_wont(struct connectdata *conn, int option)      case CURL_NO:        /* Already disabled */        break; -	  +      case CURL_YES:        tn->him[option] = CURL_NO;        send_negotiation(conn, CURL_DONT, option);        break; -	  +      case CURL_WANTNO:        switch(tn->himq[option])        {          case CURL_EMPTY:            tn->him[option] = CURL_NO;            break; -	  +          case CURL_OPPOSITE:            tn->him[option] = CURL_WANTYES;            tn->himq[option] = CURL_EMPTY; @@ -475,7 +463,7 @@ void rec_wont(struct connectdata *conn, int option)            break;        }        break; -	  +      case CURL_WANTYES:        switch(tn->himq[option])        { @@ -490,7 +478,7 @@ void rec_wont(struct connectdata *conn, int option)        break;    }  } -    +  static void  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;          send_negotiation(conn, CURL_WILL, option);          break; -	  +        case CURL_YES:          /* Already enabled */          break; -	  +        case CURL_WANTNO:          switch(tn->usq[option])          { @@ -520,7 +508,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)              break;          }          break; -	  +        case CURL_WANTYES:          switch(tn->usq[option])          { @@ -541,12 +529,12 @@ set_local_option(struct connectdata *conn, int option, int newstate)        case CURL_NO:          /* Already disabled */          break; -	  +        case CURL_YES:          tn->us[option] = CURL_WANTNO;          send_negotiation(conn, CURL_WONT, option);          break; -	  +        case CURL_WANTNO:          switch(tn->usq[option])          { @@ -558,7 +546,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)              break;          }          break; -	  +        case CURL_WANTYES:          switch(tn->usq[option])          { @@ -590,11 +578,11 @@ void rec_do(struct connectdata *conn, int option)          send_negotiation(conn, CURL_WONT, option);        }        break; -	  +      case CURL_YES:        /* Already enabled */        break; -	  +      case CURL_WANTNO:        switch(tn->usq[option])        { @@ -609,7 +597,7 @@ void rec_do(struct connectdata *conn, int option)            break;        }        break; -	  +      case CURL_WANTYES:        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)  {    struct TELNET *tn = (struct TELNET *)conn->proto.telnet; @@ -635,19 +623,19 @@ void rec_dont(struct connectdata *conn, int option)      case CURL_NO:        /* Already disabled */        break; -	  +      case CURL_YES:        tn->us[option] = CURL_NO;        send_negotiation(conn, CURL_WONT, option);        break; -	  +      case CURL_WANTNO:        switch(tn->usq[option])        {          case CURL_EMPTY:            tn->us[option] = CURL_NO;            break; -	  +          case CURL_OPPOSITE:            tn->us[option] = CURL_WANTYES;            tn->usq[option] = CURL_EMPTY; @@ -655,7 +643,7 @@ void rec_dont(struct connectdata *conn, int option)            break;        }        break; -	  +      case CURL_WANTYES:        switch(tn->usq[option])        { @@ -746,7 +734,7 @@ static void printsub(struct SessionHandle *data,          Curl_infof(data, " NAME");          break;      } -       +      switch(pointer[0]) {        case CURL_TELOPT_TTYPE:        case CURL_TELOPT_XDISPLOC: @@ -776,7 +764,7 @@ static void printsub(struct SessionHandle *data,            Curl_infof(data, " %.2x", pointer[i]);          break;      } -       +      if (direction)      {        Curl_infof(data, "\n"); @@ -986,21 +974,21 @@ void telrcv(struct connectdata *conn,          rec_will(conn, c);          tn->telrcv_state = CURL_TS_DATA;          continue; -       +        case CURL_TS_WONT:          printoption(data, "RCVD", CURL_WONT, c);          tn->please_negotiate = 1;          rec_wont(conn, c);          tn->telrcv_state = CURL_TS_DATA;          continue; -       +        case CURL_TS_DO:          printoption(data, "RCVD", CURL_DO, c);          tn->please_negotiate = 1;          rec_do(conn, c);          tn->telrcv_state = CURL_TS_DATA;          continue; -       +        case CURL_TS_DONT:          printoption(data, "RCVD", CURL_DONT, c);          tn->please_negotiate = 1; @@ -1040,7 +1028,7 @@ void telrcv(struct connectdata *conn,              CURL_SB_ACCUM(tn, c);              tn->subpointer -= 2;              CURL_SB_TERM(tn); -	     +              printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);              suboption(conn);   /* handle sub-option */              tn->telrcv_state = CURL_TS_IAC; @@ -1090,7 +1078,7 @@ CURLcode Curl_telnet(struct connectdata *conn)    WSAEVENT event_handle;    WSANETWORKEVENTS events;    HANDLE stdin_handle; -  HANDLE objs[2];          +  HANDLE objs[2];    DWORD  obj_count;    DWORD  wait_timeout;    DWORD waitret; @@ -1099,7 +1087,7 @@ CURLcode Curl_telnet(struct connectdata *conn)    fd_set readfd;    fd_set keepfd;  #endif -  ssize_t nread;   +  ssize_t nread;    bool keepon = TRUE;    char *buf = data->state.buffer;    struct TELNET *tn; @@ -1193,19 +1181,19 @@ CURLcode Curl_telnet(struct connectdata *conn)      FreeLibrary(wsock2);      return 0;    } -                                    -  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,  -     else use the old WaitForMultipleObjects() way */          + +  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, +     else use the old WaitForMultipleObjects() way */    if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) {      /* Don't wait for stdin_handle, just wait for event_handle */ -    obj_count = 1;       +    obj_count = 1;      /* Check stdin_handle per 100 milliseconds */ -    wait_timeout = 100;   +    wait_timeout = 100;    } else {      obj_count = 2;      wait_timeout = INFINITE;    } -   +    /* Keep on listening and act on events */    while(keepon) {      waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); @@ -1222,67 +1210,67 @@ CURLcode Curl_telnet(struct connectdata *conn)            keepon = FALSE;            break;          } -         +          if(!nread)            break; -           +          if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),                       &readfile_read, NULL)) {            keepon = FALSE;            break;          }          nread = readfile_read; -         +          while(nread--) {            outbuf[0] = *buffer++;            out_count = 1;            if(outbuf[0] == CURL_IAC)              outbuf[out_count++] = CURL_IAC; -             +            Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,                       out_count, &bytes_written);          }        } -    }       +    }      break; -     +      case WAIT_OBJECT_0 + 1:      {        unsigned char outbuf[2];        int out_count = 0;        ssize_t bytes_written;        char *buffer = buf; -               +        if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),                     &readfile_read, NULL)) {          keepon = FALSE;          break;        }        nread = readfile_read; -         +        while(nread--) {          outbuf[0] = *buffer++;          out_count = 1;          if(outbuf[0] == CURL_IAC)            outbuf[out_count++] = CURL_IAC; -           +          Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,                     out_count, &bytes_written);        }      }      break; -       +      case WAIT_OBJECT_0:        if(enum_netevents_func(sockfd, event_handle, &events)           != SOCKET_ERROR) {          if(events.lNetworkEvents & FD_READ) {            /* This reallu OUGHT to check its return code. */            (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); -             +            telrcv(conn, (unsigned char *)buf, nread); -           +            fflush(stdout); -             +            /* Negotiate if the peer has started negotiating,               otherwise don't. We don't want to speak telnet with               non-telnet servers, like POP or SMTP. */ @@ -1291,7 +1279,7 @@ CURLcode Curl_telnet(struct connectdata *conn)              tn->already_negotiated = 1;            }          } -           +          if(events.lNetworkEvents & FD_CLOSE) {            keepon = FALSE;          } @@ -1340,7 +1328,7 @@ CURLcode Curl_telnet(struct connectdata *conn)          int out_count = 0;          ssize_t bytes_written;          char *buffer = buf; -         +          nread = read(0, buf, 255);          while(nread--) { @@ -1348,7 +1336,7 @@ CURLcode Curl_telnet(struct connectdata *conn)            out_count = 1;            if(outbuf[0] == CURL_IAC)              outbuf[out_count++] = CURL_IAC; -       +            Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,                       out_count, &bytes_written);          } diff --git a/lib/transfer.c b/lib/transfer.c index c4e732191..b087fcd86 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -870,13 +870,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,                      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 */ @@ -273,13 +273,11 @@ CURLcode Curl_open(struct SessionHandle **curl)    CURLcode res = CURLE_OK;    struct SessionHandle *data;    /* 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)      /* this is a very serious error */      return CURLE_OUT_OF_MEMORY; -  memset(data, 0, sizeof(struct SessionHandle)); -  #ifdef USE_ARES    if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {      free(data); @@ -1859,7 +1857,6 @@ static int handleSock5Proxy(const char *proxy_name,    socksreq[3] = 1; /* IPv4 = 1 */    { -#ifndef ENABLE_IPV6      struct Curl_dns_entry *dns;      Curl_addrinfo *hp=NULL;      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)        hp=dns->addr; -    if (hp && hp->h_addr_list[0]) { -      socksreq[4] = ((char*)hp->h_addr_list[0])[0]; -      socksreq[5] = ((char*)hp->h_addr_list[0])[1]; -      socksreq[6] = ((char*)hp->h_addr_list[0])[2]; -      socksreq[7] = ((char*)hp->h_addr_list[0])[3]; +    if (hp) { +      char buf[64]; +      unsigned short ip[4]; +      Curl_printable_address(hp, buf, sizeof(buf)); + +      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 */      } -    else { +    if(!hp) {        failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",              conn->host.name);        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); @@ -1939,7 +1940,7 @@ static CURLcode ConnectPlease(struct connectdata *conn,                                bool *connected)  {    CURLcode result; -  Curl_ipconnect *addr; +  Curl_addrinfo *addr;    struct SessionHandle *data = conn->data;    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,                             hostaddr, -                           conn->port,                             &conn->sock[FIRSTSOCKET],                             &addr,                             connected);    if(CURLE_OK == result) { -    /* All is cool, then we store the current information from the hostaddr -       struct to the serv_addr, as it might be needed later. The address -       returned from the function above is crucial here. */ -    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 +    /* All is cool, then we store the current information */ +    conn->dns_entry = hostaddr; +    conn->ip_addr = addr;      if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {        return handleSock5Proxy(conn->proxyuser, @@ -1995,15 +1984,10 @@ static CURLcode ConnectPlease(struct connectdata *conn,  static void verboseconnect(struct connectdata *conn)  {    struct SessionHandle *data = conn->data; -  char addrbuf[256] = ""; -#ifdef ENABLE_IPV6 -  const Curl_ipconnect *addr = conn->serv_addr; -#else -  const Curl_ipconnect *addr = &conn->serv_addr.sin_addr; -#endif +  char addrbuf[256];    /* 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",          conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,          addrbuf[0] ? addrbuf : "??", conn->port); @@ -3221,8 +3205,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,    if(conn->bits.reuse) {      /* re-used connection, no resolving is necessary */      hostaddr = NULL; -    conn->connect_addr = NULL; /* we don't connect now so we don't have any -                                  fresh connect_addr struct to point to */ +    conn->dns_entry = NULL; /* we don't connect now so we don't have any fresh +                               dns entry struct to point to */    }    else {      /* this is a fresh connect */ @@ -3476,8 +3460,8 @@ CURLcode Curl_done(struct connectdata **connp,      conn->newurl = NULL;    } -  if(conn->connect_addr) -    Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ +  if(conn->dns_entry) +    Curl_resolv_unlock(conn->data, conn->dns_entry); /* done with this */  #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)    /* scan for DNS cache entries still marked as in use */ diff --git a/lib/urldata.h b/lib/urldata.h index 95aa5fb65..517dc0f3d 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -446,13 +446,9 @@ struct connectdata {  #define PROT_SSL     (1<<10) /* protocol requires SSL */    /* 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 */    struct hostname host; @@ -574,10 +570,6 @@ struct connectdata {      struct FTP *ftp;      struct FILEPROTO *file;      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;    } proto; | 
