summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Fitzgerald <gregf@gentoo.org>2003-11-18 06:15:02 +0000
committerGreg Fitzgerald <gregf@gentoo.org>2003-11-18 06:15:02 +0000
commita76e4c75f67c5090037829fa1e5fb372617989dd (patch)
tree83b0c1083012c634bb533cee451f4db51c9fe4c5 /net-misc/wget
parentDep fix (diff)
downloadhistorical-a76e4c75f67c5090037829fa1e5fb372617989dd.tar.gz
historical-a76e4c75f67c5090037829fa1e5fb372617989dd.tar.bz2
historical-a76e4c75f67c5090037829fa1e5fb372617989dd.zip
patch to fix ip6
Diffstat (limited to 'net-misc/wget')
-rw-r--r--net-misc/wget/files/wget-1.9.1+ipvmisc.patch795
1 files changed, 795 insertions, 0 deletions
diff --git a/net-misc/wget/files/wget-1.9.1+ipvmisc.patch b/net-misc/wget/files/wget-1.9.1+ipvmisc.patch
new file mode 100644
index 000000000000..27768bfaa29e
--- /dev/null
+++ b/net-misc/wget/files/wget-1.9.1+ipvmisc.patch
@@ -0,0 +1,795 @@
+Dual-family (IPv4+IPv6) support for wget 1.9
+
+Without this patch, IPv6 support completely disables IPv4, since dual-family
+support was incomplete. Read MODIFICATIONS.ari for details.
+
+This patch also adds the configuration option --with-ipv4-default, which
+will sort resolved addresses so that those with the AF_INET family will be
+attempted first. Remember to run autoconf in the top-level wget source
+directory after patching.
+
+NOTE: I do not currently have an IPv6-enabled system on hand in order to
+properly test IPv6 functionality. If wget 1.9 had any problems
+communicating over IPv6, it is not likely that this patch will have
+corrected them. Until this functionality is committed into wget, please
+send any relevant IPv6 problems to me.
+
+
+ari edelkind (10/27/2003)
+last modified 10/27/2003
+
+
+diff -ruN --exclude configure wget-1.9.orig/MODIFICATIONS.ari wget-1.9/MODIFICATIONS.ari
+--- wget-1.9.orig/MODIFICATIONS.ari Wed Dec 31 19:00:00 1969
++++ wget-1.9/MODIFICATIONS.ari Mon Oct 27 04:05:34 2003
+@@ -0,0 +1,40 @@
++
++- added an ip_addrset structure to host.h, containing an ip_address type and
++ a family.
++
++- Changed the address_list structure to use an array of ip_addrset types
++ instead of ip_address types.
++
++- Changed usage of ip_address type to ip_addrset type in any location where
++ it would be useful to have the family for a particular ip address or
++ connection. Modified all dereferences accordingly, and removed
++ ip_default_family altogether.
++
++- added a family option to the sockaddr_len() function in host.c, and the
++ bindport() function in connect.c.
++
++- Added --with-ipv4-default option to configure.in. If this option is set,
++ AF_INET will be used as the default domain, even when ipv6 is enabled.
++ This configure option defines the macro USE_IPV4_DEFAULT.
++
++- Changed the --disable-ipv6 comment in configure.in to --enable-ipv6.
++ Since ipv6 is currently enabled neither by default nor by configure
++ checks, and --enable-ipv6 must be passed in order to do so, this will make
++ the option more intuitive. When configure is modified to check for ipv6
++ support by default, this comment should be reverted. Be sure to run
++ autoconf to recreate the configure file.
++
++- host.c: getaddrinfo functions were conditionally included depending on
++ whether ENABLE_IPV6 was defined, yet in lookup_host(), they are called
++ depending on whether HAVE_GETADDRINFO is defined. Switched the relevant
++ ENABLE_IPV6 conditional define to use HAVE_GETADDRINFO.
++
++- Added the function address_list_sort_family() to host.c if
++ USE_IPV4_DEFAULT is defined. When the address list is gathered from name
++ resolution, any addresses associated with an AF_INET family will be first
++ in the al->addrsets array. They will therefore be tried before AF_INET6
++ types.
++
++- ftp.c, getftp(): Used conaddr() to initially populate passive_addrset with
++ RBUF_FD(&con->rbuf), so that the family of the requested connection may be
++ known to other functions.
+diff -ruN --exclude configure wget-1.9.orig/configure.in wget-1.9/configure.in
+--- wget-1.9.orig/configure.in Thu Oct 16 10:27:39 2003
++++ wget-1.9/configure.in Mon Oct 27 00:24:54 2003
+@@ -59,6 +59,10 @@
+ [[ --with-ssl[=SSL-ROOT] link with SSL support [default=auto]
+ --without-ssl disable SSL autodetection]])
+
++AC_ARG_WITH(ipv4-default,
++[ --with-ipv4-default use IPv4 by default when IPv6 is enabled],
++[AC_DEFINE(USE_IPV4_DEFAULT)])
++
+ AC_ARG_ENABLE(opie,
+ [ --disable-opie disable support for opie or s/key FTP login],
+ USE_OPIE=$enableval, USE_OPIE=yes)
+@@ -455,7 +459,7 @@
+ ipv6=
+ check_for_ipv6=no
+ AC_ARG_ENABLE(ipv6,
+- AC_HELP_STRING([--disable-ipv6],[disable IPv6 support]),
++ AC_HELP_STRING([--enable-ipv6],[enable IPv6 support]),
+ [case "${enable_ipv6}" in
+ no)
+ AC_MSG_NOTICE([Disabling IPv6 at user request])
+diff -ruN --exclude configure wget-1.9.orig/src/config.h.in wget-1.9/src/config.h.in
+--- wget-1.9.orig/src/config.h.in Mon Oct 13 10:20:45 2003
++++ wget-1.9/src/config.h.in Mon Oct 27 00:24:54 2003
+@@ -272,6 +272,9 @@
+ /* Define if you want to enable the IPv6 support. */
+ #undef ENABLE_IPV6
+
++/* Define if you want to use IPv4 by default when IPv6 is supported. */
++#undef USE_IPV4_DEFAULT
++
+ /* Defined to int or size_t on systems without socklen_t. */
+ #undef socklen_t
+
+diff -ruN --exclude configure wget-1.9.orig/src/connect.c wget-1.9/src/connect.c
+--- wget-1.9.orig/src/connect.c Fri Oct 10 21:39:07 2003
++++ wget-1.9/src/connect.c Mon Oct 27 00:24:54 2003
+@@ -69,7 +69,7 @@
+ static int msock = -1;
+ static struct sockaddr *addr;
+
+-static ip_address bind_address;
++static ip_addrset bind_address;
+ static int bind_address_resolved;
+
+ static void
+@@ -149,17 +149,17 @@
+
+ /* Connect to a remote host whose address has been resolved. */
+ int
+-connect_to_one (ip_address *addr, unsigned short port, int silent)
++connect_to_one (ip_addrset *addrset, unsigned short port, int silent)
+ {
+ wget_sockaddr sa;
+ int sock, save_errno;
+
+ /* Set port and protocol */
+- wget_sockaddr_set_address (&sa, ip_default_family, port, addr);
++ wget_sockaddr_set_address (&sa, addrset->family, port, &addrset->addr);
+
+ if (!silent)
+ {
+- char *pretty_addr = pretty_print_address (addr);
++ char *pretty_addr = pretty_print_address (&addrset->addr);
+ if (connection_host_name
+ && 0 != strcmp (connection_host_name, pretty_addr))
+ logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "),
+@@ -170,7 +170,7 @@
+ }
+
+ /* Make an internet socket, stream type. */
+- sock = socket (ip_default_family, SOCK_STREAM, 0);
++ sock = socket (addrset->family, SOCK_STREAM, 0);
+ if (sock < 0)
+ goto out;
+
+@@ -196,8 +196,9 @@
+ {
+ /* Bind the client side to the requested address. */
+ wget_sockaddr bsa;
+- wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address);
+- if (bind (sock, &bsa.sa, sockaddr_len ()))
++ wget_sockaddr_set_address (&bsa, bind_address.family, 0,
++ &bind_address.addr);
++ if (bind (sock, &bsa.sa, sockaddr_len (addrset->family)))
+ {
+ CLOSE (sock);
+ sock = -1;
+@@ -206,7 +207,7 @@
+ }
+
+ /* Connect the socket to the remote host. */
+- if (connect_with_timeout (sock, &sa.sa, sockaddr_len (),
++ if (connect_with_timeout (sock, &sa.sa, sockaddr_len (addrset->family),
+ opt.connect_timeout) < 0)
+ {
+ CLOSE (sock);
+@@ -233,20 +234,20 @@
+ return sock;
+ }
+
++
+ /* Connect to a remote host whose address has been resolved. */
+ int
+ connect_to_many (struct address_list *al, unsigned short port, int silent)
+ {
+- int i, start, end;
++ int i, start, end, sock;
++ ip_addrset addrset;
+
+ address_list_get_bounds (al, &start, &end);
+ for (i = start; i < end; i++)
+ {
+- ip_address addr;
+- int sock;
+- address_list_copy_one (al, i, &addr);
++ address_list_copy_one (al, i, &addrset);
+
+- sock = connect_to_one (&addr, port, silent);
++ sock = connect_to_one (&addrset, port, silent);
+ if (sock >= 0)
+ /* Success. */
+ return sock;
+@@ -298,7 +299,7 @@
+ internal variable MPORT is set to the value of the ensuing master
+ socket. Call acceptport() to block for and accept a connection. */
+ uerr_t
+-bindport (unsigned short *port, int family)
++bindport (unsigned short *port, int ip_family)
+ {
+ int optval = 1;
+ wget_sockaddr srv;
+@@ -306,7 +307,7 @@
+
+ msock = -1;
+
+- if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
++ if ((msock = socket (ip_family, SOCK_STREAM, 0)) < 0)
+ return CONSOCKERR;
+
+ #ifdef SO_REUSEADDR
+@@ -316,9 +317,9 @@
+ #endif
+
+ resolve_bind_address ();
+- wget_sockaddr_set_address (&srv, ip_default_family, htons (*port),
+- bind_address_resolved ? &bind_address : NULL);
+- if (bind (msock, &srv.sa, sockaddr_len ()) < 0)
++ wget_sockaddr_set_address (&srv, ip_family, htons (*port),
++ bind_address_resolved ? &bind_address.addr : NULL);
++ if (bind (msock, &srv.sa, sockaddr_len (ip_family)) < 0)
+ {
+ CLOSE (msock);
+ msock = -1;
+@@ -327,7 +328,7 @@
+ DEBUGP (("Master socket fd %d bound.\n", msock));
+ if (!*port)
+ {
+- socklen_t sa_len = sockaddr_len ();
++ socklen_t sa_len = sockaddr_len (ip_family);
+ if (getsockname (msock, &srv.sa, &sa_len) < 0)
+ {
+ CLOSE (msock);
+@@ -389,7 +390,13 @@
+ uerr_t
+ acceptport (int *sock)
+ {
+- socklen_t addrlen = sockaddr_len ();
++ socklen_t addrlen;
++ ip_addrset addrset;
++
++ if (!conaddr (msock, &addrset))
++ return ACCEPTERR;
++
++ addrlen = sockaddr_len (addrset.family);
+
+ #ifdef HAVE_SELECT
+ if (select_fd (msock, opt.connect_timeout, 0) <= 0)
+@@ -417,22 +424,22 @@
+ /* Return the local IP address associated with the connection on FD. */
+
+ int
+-conaddr (int fd, ip_address *ip)
++conaddr (int fd, ip_addrset *ip)
+ {
+ wget_sockaddr mysrv;
+ socklen_t addrlen = sizeof (mysrv);
+ if (getsockname (fd, &mysrv.sa, &addrlen) < 0)
+ return 0;
+
+- switch (mysrv.sa.sa_family)
++ switch (ip->family = mysrv.sa.sa_family)
+ {
+ #ifdef ENABLE_IPV6
+ case AF_INET6:
+- memcpy (ip, &mysrv.sin6.sin6_addr, 16);
++ memcpy (&ip->addr, &mysrv.sin6.sin6_addr, 16);
+ return 1;
+ #endif
+ case AF_INET:
+- map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, ip);
++ map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, &ip->addr);
+ return 1;
+ default:
+ abort ();
+diff -ruN --exclude configure wget-1.9.orig/src/connect.h wget-1.9/src/connect.h
+--- wget-1.9.orig/src/connect.h Sat Sep 20 19:12:18 2003
++++ wget-1.9/src/connect.h Mon Oct 27 00:24:54 2003
+@@ -34,7 +34,7 @@
+
+ /* Function declarations */
+
+-int connect_to_one PARAMS ((ip_address *, unsigned short, int));
++int connect_to_one PARAMS ((ip_addrset *, unsigned short, int));
+ int connect_to_many PARAMS ((struct address_list *, unsigned short, int));
+ void set_connection_host_name PARAMS ((const char *));
+
+@@ -43,7 +43,7 @@
+ uerr_t bindport PARAMS ((unsigned short *, int));
+ uerr_t acceptport PARAMS ((int *));
+ void closeport PARAMS ((int));
+-int conaddr PARAMS ((int, ip_address *));
++int conaddr PARAMS ((int, ip_addrset *));
+
+ int iread PARAMS ((int, char *, int));
+ int iwrite PARAMS ((int, char *, int));
+diff -ruN --exclude configure wget-1.9.orig/src/ftp-basic.c wget-1.9/src/ftp-basic.c
+--- wget-1.9.orig/src/ftp-basic.c Fri Oct 10 21:39:07 2003
++++ wget-1.9/src/ftp-basic.c Mon Oct 27 00:24:54 2003
+@@ -259,23 +259,24 @@
+ uerr_t err;
+
+ char *request, *respline;
+- ip_address in_addr;
++ ip_addrset in_addrset;
+ unsigned short port;
+
+ char ipv6 [8 * (4 * 3 + 3) + 8];
+ char *bytes;
+
++ /* Get the address of this side of the connection. */
++ if (!conaddr (RBUF_FD (rbuf), &in_addrset))
++ /* Huh? This is not BINDERR! */
++ return BINDERR;
++
+ /* Setting port to 0 lets the system choose a free port. */
+ port = 0;
+- err = bindport (&port, ip_default_family);
++ err = bindport (&port, in_addrset.family);
+ if (err != BINDOK) /* Bind the port. */
+ return err;
+
+- /* Get the address of this side of the connection. */
+- if (!conaddr (RBUF_FD (rbuf), &in_addr))
+- /* Huh? This is not BINDERR! */
+- return BINDERR;
+- inet_ntop (AF_INET6, &in_addr, ipv6, sizeof (ipv6));
++ inet_ntop (AF_INET6, &in_addrset.addr, ipv6, sizeof (ipv6));
+
+ /* Construct the argument of EPRT (of the form |2|IPv6.ascii|PORT.ascii|). */
+ bytes = alloca (3 + strlen (ipv6) + 1 + numdigit (port) + 1 + 1);
+@@ -318,17 +319,27 @@
+ char *request, *respline;
+ char bytes[6 * 4 +1];
+
+- ip_address in_addr;
++ ip_addrset in_addrset;
+ ip4_address in_addr_4;
+ unsigned char *in_addr4_ptr = (unsigned char *)&in_addr_4;
+
+ int nwritten;
+ unsigned short port;
++
++
++ /* Get the address of this side of the connection and convert it
++ (back) to IPv4. */
++ if (!conaddr (RBUF_FD (rbuf), &in_addrset))
++ /* Huh? This is not BINDERR! */
++ return BINDERR;
++ if (!map_ip_to_ipv4 (&in_addrset.addr, &in_addr_4))
++ return BINDERR;
++
+ #ifdef ENABLE_IPV6
+ /*
+ Only try the Extented Version if we actually use IPv6
+ */
+- if (ip_default_family == AF_INET6)
++ if (in_addrset.family == AF_INET6)
+ {
+ err = ftp_eprt (rbuf);
+ if (err == FTPOK)
+@@ -338,18 +349,10 @@
+ /* Setting port to 0 lets the system choose a free port. */
+ port = 0;
+
+- err = bindport (&port, AF_INET);
++ err = bindport (&port, in_addrset.family);
+ if (err != BINDOK)
+ return err;
+
+- /* Get the address of this side of the connection and convert it
+- (back) to IPv4. */
+- if (!conaddr (RBUF_FD (rbuf), &in_addr))
+- /* Huh? This is not BINDERR! */
+- return BINDERR;
+- if (!map_ip_to_ipv4 (&in_addr, &in_addr_4))
+- return BINDERR;
+-
+ /* Construct the argument of PORT (of the form a,b,c,d,e,f). Port
+ is unsigned short so (unsigned) (port & 0xff000) >> 8 is the same
+ like port >> 8
+@@ -384,7 +387,7 @@
+
+ #ifdef ENABLE_IPV6
+ uerr_t
+-ftp_epsv (struct rbuf *rbuf, ip_address *addr, unsigned short *port,
++ftp_epsv (struct rbuf *rbuf, ip_addrset *addrset, unsigned short *port,
+ char *typ)
+ {
+ int err;
+@@ -423,13 +426,13 @@
+ socklen_t addrlen = sizeof (remote);
+ struct sockaddr_in *ipv4_sock = (struct sockaddr_in *)&remote;
+ getpeername (RBUF_FD (rbuf), (struct sockaddr *)&remote, &addrlen);
+- switch(remote.sa.sa_family)
++ switch(addrset->family = remote.sa.sa_family)
+ {
+ case AF_INET6:
+- memcpy (addr, &remote.sin6.sin6_addr, 16);
++ memcpy (&addrset->addr, &remote.sin6.sin6_addr, 16);
+ break;
+ case AF_INET:
+- map_ipv4_to_ip ((ip4_address *)&ipv4_sock->sin_addr, addr);
++ map_ipv4_to_ip ((ip4_address *)&ipv4_sock->sin_addr, &addrset->addr);
+ break;
+ default:
+ abort();
+@@ -446,7 +449,7 @@
+ transfer. Reads the response from server and parses it. Reads the
+ host and port addresses and returns them. */
+ uerr_t
+-ftp_pasv (struct rbuf *rbuf, ip_address *addr, unsigned short *port)
++ftp_pasv (struct rbuf *rbuf, ip_addrset *addrset, unsigned short *port)
+ {
+ char *request, *respline, *s;
+ int nwritten, i;
+@@ -454,12 +457,12 @@
+ unsigned char addr4[4];
+
+ #ifdef ENABLE_IPV6
+- if (ip_default_family == AF_INET6)
++ if (addrset->family == AF_INET6)
+ {
+- err = ftp_epsv (rbuf, addr, port, "2"); /* try IPv6 with EPSV */
++ err = ftp_epsv (rbuf, addrset, port, "2"); /* try IPv6 with EPSV */
+ if (FTPOK == err)
+ return FTPOK;
+- err = ftp_epsv (rbuf, addr, port, "1"); /* try IPv4 with EPSV */
++ err = ftp_epsv (rbuf, addrset, port, "1"); /* try IPv4 with EPSV */
+ if (FTPOK == err)
+ return FTPOK;
+ }
+@@ -507,7 +510,7 @@
+ }
+
+ /* Eventually make an IPv4 in IPv6 adress if needed */
+- map_ipv4_to_ip ((ip4_address *)addr4, addr);
++ map_ipv4_to_ip ((ip4_address *)addr4, &addrset->addr);
+
+ *port=0;
+ for (; ISDIGIT (*s); s++)
+diff -ruN --exclude configure wget-1.9.orig/src/ftp.c wget-1.9/src/ftp.c
+--- wget-1.9.orig/src/ftp.c Tue Oct 14 18:52:12 2003
++++ wget-1.9/src/ftp.c Mon Oct 27 00:24:54 2003
+@@ -538,11 +538,15 @@
+ {
+ if (opt.ftp_pasv > 0)
+ {
+- ip_address passive_addr;
++ ip_addrset passive_addrset;
+ unsigned short passive_port;
+ if (!opt.server_response)
+ logputs (LOG_VERBOSE, "==> PASV ... ");
+- err = ftp_pasv (&con->rbuf, &passive_addr, &passive_port);
++
++ if (!conaddr (RBUF_FD (&con->rbuf), &passive_addrset))
++ return HOSTERR;
++
++ err = ftp_pasv (&con->rbuf, &passive_addrset, &passive_port);
+ /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
+ switch (err)
+ {
+@@ -579,14 +583,14 @@
+ } /* switch(err) */
+ if (err==FTPOK)
+ {
+- dtsock = connect_to_one (&passive_addr, passive_port, 1);
++ dtsock = connect_to_one (&passive_addrset, passive_port, 1);
+ if (dtsock < 0)
+ {
+ int save_errno = errno;
+ CLOSE (csock);
+ rbuf_uninitialize (&con->rbuf);
+ logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"),
+- pretty_print_address (&passive_addr), passive_port,
++ pretty_print_address (&passive_addrset.addr), passive_port,
+ strerror (save_errno));
+ return CONNECT_ERROR (save_errno);
+ }
+diff -ruN --exclude configure wget-1.9.orig/src/ftp.h wget-1.9/src/ftp.h
+--- wget-1.9.orig/src/ftp.h Thu Sep 18 09:46:17 2003
++++ wget-1.9/src/ftp.h Mon Oct 27 00:24:54 2003
+@@ -49,9 +49,9 @@
+ uerr_t ftp_response PARAMS ((struct rbuf *, char **));
+ uerr_t ftp_login PARAMS ((struct rbuf *, const char *, const char *));
+ uerr_t ftp_port PARAMS ((struct rbuf *));
+-uerr_t ftp_pasv PARAMS ((struct rbuf *, ip_address *, unsigned short *));
++uerr_t ftp_pasv PARAMS ((struct rbuf *, ip_addrset *, unsigned short *));
+ #ifdef ENABLE_IPV6
+-uerr_t ftp_epsv PARAMS ((struct rbuf *, ip_address *, unsigned short *,
++uerr_t ftp_epsv PARAMS ((struct rbuf *, ip_addrset *, unsigned short *,
+ char *));
+ #endif
+ uerr_t ftp_type PARAMS ((struct rbuf *, int));
+diff -ruN --exclude configure wget-1.9.orig/src/host.c wget-1.9/src/host.c
+--- wget-1.9.orig/src/host.c Fri Oct 10 22:27:41 2003
++++ wget-1.9/src/host.c Mon Oct 27 00:24:54 2003
+@@ -81,11 +81,6 @@
+ # endif
+ #endif
+
+-#ifdef ENABLE_IPV6
+-int ip_default_family = AF_INET6;
+-#else
+-int ip_default_family = AF_INET;
+-#endif
+
+ /* Mapping between known hosts and to lists of their addresses. */
+
+@@ -96,7 +91,7 @@
+
+ struct address_list {
+ int count; /* number of adrresses */
+- ip_address *addresses; /* pointer to the string of addresses */
++ ip_addrset *addrsets; /* pointer to the string of address sets */
+
+ int faulty; /* number of addresses known not to work. */
+ int refcount; /* so we know whether to free it or not. */
+@@ -114,10 +109,10 @@
+ /* Copy address number INDEX to IP_STORE. */
+
+ void
+-address_list_copy_one (struct address_list *al, int index, ip_address *ip_store)
++address_list_copy_one (struct address_list *al, int index, ip_addrset *ip_store)
+ {
+ assert (index >= al->faulty && index < al->count);
+- memcpy (ip_store, al->addresses + index, sizeof (ip_address));
++ memcpy (ip_store, al->addrsets + index, sizeof (ip_addrset));
+ }
+
+ /* Check whether two address lists have all their IPs in common. */
+@@ -129,8 +124,8 @@
+ return 1;
+ if (al1->count != al2->count)
+ return 0;
+- return 0 == memcmp (al1->addresses, al2->addresses,
+- al1->count * sizeof (ip_address));
++ return 0 == memcmp (al1->addrsets, al2->addrsets,
++ al1->count * sizeof (ip_addrset));
+ }
+
+ /* Mark the INDEXth element of AL as faulty, so that the next time
+@@ -153,6 +148,36 @@
+ al->faulty = 0;
+ }
+
++#ifdef USE_IPV4_DEFAULT
++static inline void
++address_list_sort_family (struct address_list *al, int family)
++{
++ int i, j = 0, len;
++ ip_addrset *copysets;
++
++ len = sizeof(ip_addrset) * al->count;
++
++ if (!(copysets = malloc (len))) return;
++
++ for (i = 0; i < al->count; i++)
++ {
++ if (al->addrsets[i].family == family)
++ address_list_copy_one (al, i, &copysets[j++]);
++ }
++
++ if (j < al->count) {
++ for (i = 0; i < al->count; i++)
++ {
++ if (al->addrsets[i].family != family)
++ address_list_copy_one (al, i, &copysets[j++]);
++ }
++ }
++
++ memcpy (al->addrsets, copysets, len);
++ free (copysets);
++}
++#endif
++
+ #ifdef HAVE_GETADDRINFO
+ /**
+ * address_list_from_addrinfo
+@@ -180,7 +205,7 @@
+ return NULL;
+
+ al = xmalloc (sizeof (struct address_list));
+- al->addresses = xmalloc (cnt * sizeof (ip_address));
++ al->addrsets = xmalloc (cnt * sizeof (ip_addrset));
+ al->count = cnt;
+ al->faulty = 0;
+ al->refcount = 1;
+@@ -189,13 +214,15 @@
+ if (ai->ai_family == AF_INET6)
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
+- memcpy (al->addresses + i, &sin6->sin6_addr, 16);
++ memcpy (&al->addrsets[i].addr, &sin6->sin6_addr, 16);
++ al->addrsets[i].family = AF_INET6;
+ ++i;
+ }
+ else if (ai->ai_family == AF_INET)
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
+- map_ipv4_to_ip ((ip4_address *)&sin->sin_addr, al->addresses + i);
++ map_ipv4_to_ip ((ip4_address *)&sin->sin_addr, &al->addrsets[i].addr);
++ al->addrsets[i].family = AF_INET;
+ ++i;
+ }
+ assert (i == cnt);
+@@ -216,11 +243,13 @@
+ assert (count > 0);
+ al->count = count;
+ al->faulty = 0;
+- al->addresses = xmalloc (count * sizeof (ip_address));
++ al->addrsets = xmalloc (count * sizeof (ip_addrset));
+ al->refcount = 1;
+
+- for (i = 0; i < count; i++)
+- map_ipv4_to_ip ((ip4_address *)h_addr_list[i], al->addresses + i);
++ for (i = 0; i < count; i++) {
++ al->addrsets[i].family = AF_INET;
++ map_ipv4_to_ip ((ip4_address *)h_addr_list[i], &al->addrsets[i].addr);
++ }
+
+ return al;
+ }
+@@ -230,14 +259,15 @@
+ address. */
+
+ static struct address_list *
+-address_list_from_single (ip_address *addr)
++address_list_from_single (ip_address *addr, int ip_family)
+ {
+ struct address_list *al = xmalloc (sizeof (struct address_list));
+ al->count = 1;
+ al->faulty = 0;
+- al->addresses = xmalloc (sizeof (ip_address));
++ al->addrsets = xmalloc (sizeof (ip_addrset));
+ al->refcount = 1;
+- memcpy (al->addresses, addr, sizeof (ip_address));
++ memcpy (&al->addrsets->addr, addr, sizeof (ip_address));
++ al->addrsets->family = ip_family;
+
+ return al;
+ }
+@@ -245,7 +275,7 @@
+ static void
+ address_list_delete (struct address_list *al)
+ {
+- xfree (al->addresses);
++ xfree (al->addrsets);
+ xfree (al);
+ }
+
+@@ -422,12 +452,12 @@
+ * socklen_t structure length for socket options
+ */
+ socklen_t
+-sockaddr_len ()
++sockaddr_len (int ip_family)
+ {
+- if (ip_default_family == AF_INET)
++ if (ip_family == AF_INET)
+ return sizeof (struct sockaddr_in);
+ #ifdef ENABLE_IPV6
+- if (ip_default_family == AF_INET6)
++ if (ip_family == AF_INET6)
+ return sizeof (struct sockaddr_in6);
+ #endif
+ abort();
+@@ -474,7 +504,7 @@
+
+ /* Versions of gethostbyname and getaddrinfo that support timeout. */
+
+-#ifndef ENABLE_IPV6
++#ifndef HAVE_GETADDRINFO
+
+ struct ghbnwt_context {
+ const char *host_name;
+@@ -509,7 +539,7 @@
+ return ctx.hptr;
+ }
+
+-#else /* ENABLE_IPV6 */
++#else /* HAVE_GETADDRINFO */
+
+ struct gaiwt_context {
+ const char *node;
+@@ -548,8 +578,7 @@
+ }
+ return ctx.exit_code;
+ }
+-
+-#endif /* ENABLE_IPV6 */
++#endif /* HAVE_GETADDRINFO */
+
+ /* Pretty-print ADDR. When compiled without IPv6, this is the same as
+ inet_ntoa. With IPv6, it either prints an IPv6 address or an IPv4
+@@ -591,7 +620,8 @@
+ int i;
+ debug_logprintf ("Caching %s =>", host);
+ for (i = 0; i < al->count; i++)
+- debug_logprintf (" %s", pretty_print_address (al->addresses + i));
++ debug_logprintf (" %s",
++ pretty_print_address (&al->addrsets[i].addr));
+ debug_logprintf ("\n");
+ }
+ #endif
+@@ -609,7 +639,7 @@
+
+ #ifdef ENABLE_IPV6
+ if (inet_pton (AF_INET6, host, &addr) > 0)
+- return address_list_from_single (&addr);
++ return address_list_from_single (&addr, AF_INET6);
+ #endif
+
+ addr_ipv4 = (u_int32_t)inet_addr (host);
+@@ -618,7 +648,7 @@
+ /* ADDR is defined to be in network byte order, which is what
+ this returns, so we can just copy it to STORE_IP. */
+ map_ipv4_to_ip ((ip4_address *)&addr_ipv4, &addr);
+- return address_list_from_single (&addr);
++ return address_list_from_single (&addr, AF_INET6);
+ }
+
+ if (host_name_addresses_map)
+@@ -643,11 +673,14 @@
+ int err;
+
+ memset (&hints, 0, sizeof (hints));
+- if (ip_default_family == AF_INET)
+- hints.ai_family = AF_INET;
+- else
+- hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
++
++# if !defined (ENABLE_IPV6)
++ hints.ai_family = AF_INET;
++# else
++ hints.ai_family = AF_UNSPEC;
++# endif
++
+ err = getaddrinfo_with_timeout (host, NULL, &hints, &ai, opt.dns_timeout);
+
+ if (err != 0 || ai == NULL)
+@@ -681,6 +714,10 @@
+ }
+ #endif
+
++#ifdef USE_IPV4_DEFAULT
++ address_list_sort_family (al, AF_INET);
++#endif
++
+ /* Print the addresses determined by DNS lookup, but no more than
+ three. */
+ if (!silent)
+@@ -690,7 +727,7 @@
+ for (i = 0; i < printmax; i++)
+ {
+ logprintf (LOG_VERBOSE, "%s",
+- pretty_print_address (al->addresses + i));
++ pretty_print_address (&al->addrsets[i].addr));
+ if (i < printmax - 1)
+ logputs (LOG_VERBOSE, ", ");
+ }
+diff -ruN --exclude configure wget-1.9.orig/src/host.h wget-1.9/src/host.h
+--- wget-1.9.orig/src/host.h Fri Oct 10 21:39:07 2003
++++ wget-1.9/src/host.h Mon Oct 27 03:36:52 2003
+@@ -73,13 +73,18 @@
+ unsigned char bytes[MAX_IP_ADDRESS_SIZE];
+ } ip_address;
+
++typedef struct {
++ ip_address addr;
++ int family;
++} ip_addrset;
++
+ /* Function declarations */
+ struct address_list *lookup_host PARAMS ((const char *, int));
+ char *herrmsg PARAMS ((int));
+
+ void address_list_get_bounds PARAMS ((struct address_list *, int *, int *));
+ void address_list_copy_one PARAMS ((struct address_list *, int,
+- ip_address *));
++ ip_addrset *));
+ int address_list_match_all PARAMS ((struct address_list *,
+ struct address_list *));
+ void address_list_set_faulty PARAMS ((struct address_list *, int));
+@@ -97,11 +102,9 @@
+ void wget_sockaddr_set_port PARAMS((wget_sockaddr *, unsigned short));
+ void *wget_sockaddr_get_addr PARAMS((wget_sockaddr *));
+ unsigned short wget_sockaddr_get_port PARAMS((const wget_sockaddr *));
+-socklen_t sockaddr_len PARAMS(());
++socklen_t sockaddr_len PARAMS((int));
+ void map_ipv4_to_ip PARAMS((ip4_address *, ip_address *));
+ int map_ip_to_ipv4 PARAMS((ip_address *, ip4_address *));
+
+-extern int ip_default_family; /* defined in host.c */
+-
+
+ #endif /* HOST_H */