]> sjero.net Git - wget/blobdiff - src/connect.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / connect.c
index b85998c22ceac441ea80e50498a5f3df30dec438..ab1fd08e7a03e7430136622db3ab54e3b274ac05 100644 (file)
@@ -1,11 +1,11 @@
 /* Establishing and handling network connections.
-   Copyright (C) 1996-2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-2006 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
 GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software Foundation, Inc.,
-51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
 In addition, as a special exception, the Free Software Foundation
 gives permission to link the code of its release of Wget with the
@@ -73,27 +72,27 @@ so, delete this exception statement from your version.  */
 static void
 sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
 {
-  switch (ip->type)
+  switch (ip->family)
     {
-    case IPV4_ADDRESS:
+    case AF_INET:
       {
        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
        xzero (*sin);
        sin->sin_family = AF_INET;
        sin->sin_port = htons (port);
-       sin->sin_addr = ADDRESS_IPV4_IN_ADDR (ip);
+       sin->sin_addr = ip->data.d4;
        break;
       }
 #ifdef ENABLE_IPV6
-    case IPV6_ADDRESS:
+    case AF_INET6:
       {
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
        xzero (*sin6);
        sin6->sin6_family = AF_INET6;
        sin6->sin6_port = htons (port);
-       sin6->sin6_addr = ADDRESS_IPV6_IN6_ADDR (ip);
+       sin6->sin6_addr = ip->data.d6;
 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
-       sin6->sin6_scope_id = ADDRESS_IPV6_SCOPE (ip);
+       sin6->sin6_scope_id = ip->ipv6_scope;
 #endif
        break;
       }
@@ -117,8 +116,8 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
        if (ip)
          {
-           ip->type = IPV4_ADDRESS;
-           ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr;
+           ip->family = AF_INET;
+           ip->data.d4 = sin->sin_addr;
          }
        if (port)
          *port = ntohs (sin->sin_port);
@@ -130,10 +129,10 @@ sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
        if (ip)
          {
-           ip->type = IPV6_ADDRESS;
-           ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr;
+           ip->family = AF_INET6;
+           ip->data.d6 = sin6->sin6_addr;
 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
-           ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id;
+           ip->ipv6_scope = sin6->sin6_scope_id;
 #endif
          }
        if (port)
@@ -415,7 +414,6 @@ int
 bind_local (const ip_address *bind_address, int *port)
 {
   int sock;
-  int family = AF_INET;
   struct sockaddr_storage ss;
   struct sockaddr *sa = (struct sockaddr *)&ss;
 
@@ -424,12 +422,7 @@ bind_local (const ip_address *bind_address, int *port)
   void *setopt_ptr = (void *)&setopt_val;
   socklen_t setopt_size = sizeof (setopt_val);
 
-#ifdef ENABLE_IPV6
-  if (bind_address->type == IPV6_ADDRESS) 
-    family = AF_INET6;
-#endif
-
-  sock = socket (family, SOCK_STREAM, 0);
+  sock = socket (bind_address->family, SOCK_STREAM, 0);
   if (sock < 0)
     return -1;
 
@@ -529,16 +522,16 @@ socket_ip_address (int sock, ip_address *ip, int endpoint)
   if (ret < 0)
     return false;
 
+  ip->family = sockaddr->sa_family;
   switch (sockaddr->sa_family)
     {
 #ifdef ENABLE_IPV6
     case AF_INET6:
       {
        struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
-       ip->type = IPV6_ADDRESS;
-       ADDRESS_IPV6_IN6_ADDR (ip) = sa6->sin6_addr;
+       ip->data.d6 = sa6->sin6_addr;
 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
-       ADDRESS_IPV6_SCOPE (ip) = sa6->sin6_scope_id;
+       ip->ipv6_scope = sa6->sin6_scope_id;
 #endif
        DEBUGP (("conaddr is: %s\n", print_address (ip)));
        return true;
@@ -547,8 +540,7 @@ socket_ip_address (int sock, ip_address *ip, int endpoint)
     case AF_INET:
       {
        struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
-       ip->type = IPV4_ADDRESS;
-       ADDRESS_IPV4_IN_ADDR (ip) = sa->sin_addr;
+       ip->data.d4 = sa->sin_addr;
        DEBUGP (("conaddr is: %s\n", print_address (ip)));
        return true;
       }
@@ -665,11 +657,12 @@ test_socket_open (int sock)
   to.tv_sec = 0;
   to.tv_usec = 1;
 
-  /* If we get a timeout, then that means still connected */
   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
-    /* Connection is valid (not EOF), so continue */
+    /* We got a timeout, it means we're still connected. */
     return true;
   else
+    /* Read now would not wait, it means we have either pending data
+       or EOF/error. */
     return false;
 }
 \f
@@ -770,7 +763,7 @@ fd_register_transport (int fd, struct transport_implementation *imp, void *ctx)
   info->ctx = ctx;
   if (!transport_map)
     transport_map = hash_table_new (0, NULL, NULL);
-  hash_table_put (transport_map, (void *) fd, info);
+  hash_table_put (transport_map, (void *)(intptr_t) fd, info);
   ++transport_map_modified_tick;
 }
 
@@ -781,7 +774,7 @@ fd_register_transport (int fd, struct transport_implementation *imp, void *ctx)
 void *
 fd_transport_context (int fd)
 {
-  struct transport_info *info = hash_table_get (transport_map, (void *) fd);
+  struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd);
   return info->ctx;
 }
 
@@ -796,14 +789,15 @@ fd_transport_context (int fd)
 
 #define LAZY_RETRIEVE_INFO(info) do {                                  \
   static struct transport_info *last_info;                             \
-  static int last_fd = -1, last_tick;                                  \
+  static int last_fd = -1;                                             \
+  static unsigned int last_tick;                                       \
   if (!transport_map)                                                  \
     info = NULL;                                                       \
   else if (last_fd == fd && last_tick == transport_map_modified_tick)  \
     info = last_info;                                                  \
   else                                                                 \
     {                                                                  \
-      info = hash_table_get (transport_map, (void *) fd);              \
+      info = hash_table_get (transport_map, (void *)(intptr_t) fd);    \
       last_fd = fd;                                                    \
       last_info = info;                                                        \
       last_tick = transport_map_modified_tick;                         \
@@ -911,7 +905,8 @@ fd_write (int fd, char *buf, int bufsize, double timeout)
    used.
 
    If the transport doesn't support error messages or doesn't supply
-   one, strerror(errno) is returned.  */
+   one, strerror(errno) is returned.  The returned error message
+   should not be used after fd_close has been called.  */
 
 const char *
 fd_errstr (int fd)
@@ -920,7 +915,7 @@ fd_errstr (int fd)
      in case of error, never in a tight loop.  */
   struct transport_info *info = NULL;
   if (transport_map)
-    info = hash_table_get (transport_map, (void *) fd);
+    info = hash_table_get (transport_map, (void *)(intptr_t) fd);
 
   if (info && info->imp->errstr)
     {
@@ -945,7 +940,7 @@ fd_close (int fd)
      per socket, so that particular optimization wouldn't work.  */
   info = NULL;
   if (transport_map)
-    info = hash_table_get (transport_map, (void *) fd);
+    info = hash_table_get (transport_map, (void *)(intptr_t) fd);
 
   if (info && info->imp->closer)
     info->imp->closer (fd, info->ctx);
@@ -954,7 +949,7 @@ fd_close (int fd)
 
   if (info)
     {
-      hash_table_remove (transport_map, (void *) fd);
+      hash_table_remove (transport_map, (void *)(intptr_t) fd);
       xfree (info);
       ++transport_map_modified_tick;
     }