Submitted in <sxsd6zz2jf7.fsf@florida.arsdigita.de>.
+2002-01-24 Hrvoje Niksic <hniksic@arsdigita.com>
+
+ * connect.c (resolve_bind_address): New function.
+ (connect_to_one): Use it.
+ (bindport): Ditto.
+
+ * init.c: Don't resolve bind-address here.
+
+ * host.c (wget_sockaddr_set_address): Would bug out with ADDR == NULL.
+
2002-01-24 Hrvoje Niksic <hniksic@arsdigita.com>
* host.c (lookup_host): Use sizeof(ip4_address) to calculate the
2002-01-24 Hrvoje Niksic <hniksic@arsdigita.com>
- * source: Integrated IPv6 support by Thomas Lussnig.
+ * source: Integrated IPv6 support.
+ Written by Thomas Lussnig <thomas.lussnig@bewegungsmelder.de>.
2002-01-15 Ian Abbott <abbotti@mev.co.uk>
/* Establishing and handling network connections.
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Wget.
#endif /* HAVE_SYS_SELECT_H */
#include "wget.h"
-#include "connect.h"
#include "host.h"
+#include "connect.h"
#ifndef errno
extern int errno;
static int msock = -1;
static struct sockaddr *addr;
+static ip_address bind_address;
+static int bind_address_resolved;
+
+static void
+resolve_bind_address (void)
+{
+ struct address_list *al;
+
+ if (bind_address_resolved || opt.bind_address == NULL)
+ /* Nothing to do. */
+ return;
+
+ al = lookup_host (opt.bind_address, 1);
+ if (!al)
+ {
+ logprintf (LOG_NOTQUIET,
+ _("Unable to convert `%s' to a bind address. Reverting to ANY.\n"),
+ opt.bind_address);
+ return;
+ }
+
+ address_list_copy_one (al, 0, &bind_address);
+ address_list_release (al);
+ bind_address_resolved = 1;
+}
+
/* A kludge, but still better than passing the host name all the way
to connect_to_one. */
static const char *connection_host_name;
if (sock < 0)
goto out;
- if (opt.bind_address)
+ resolve_bind_address ();
+ if (bind_address_resolved)
{
/* Bind the client side to the requested address. */
- if (bind (sock, (struct sockaddr *)opt.bind_address, sockaddr_len ()))
+ wget_sockaddr bsa;
+ wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address);
+ if (bind (sock, &bsa.sa, sockaddr_len ()))
{
close (sock);
sock = -1;
(char *)&optval, sizeof (optval)) < 0)
return CONSOCKERR;
- if (opt.bind_address == NULL)
- wget_sockaddr_set_address (&srv, ip_default_family, htons (*port), NULL);
- else
- srv = *opt.bind_address;
- wget_sockaddr_set_port (&srv, *port);
+ 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)
{
CLOSE (msock);
#ifndef CONNECT_H
#define CONNECT_H
-struct address_list;
+#include "host.h"
/* Function declarations */
/* Need it for struct rbuf. */
#include "rbuf.h"
+#include "host.h"
+
/* System types. */
enum stype
{
void
address_list_copy_one (struct address_list *al, int index, ip_address *ip_store)
{
- assert (index >= al->faulty && index < al->count && ip_store!=NULL );
+ assert (index >= al->faulty && index < al->count);
memcpy (ip_store, al->addresses + index, sizeof (ip_address));
}
{
if (ip_family == AF_INET)
{
- ip4_address addr4;
- if (!map_ip_to_ipv4 (addr, &addr4))
- /* should the callers have prevented this? */
- abort ();
sa->sin.sin_family = ip_family;
sa->sin.sin_port = htons (port);
if (addr == NULL)
memset (&sa->sin.sin_addr, 0, sizeof(ip4_address));
- else
- memcpy (&sa->sin.sin_addr, &addr4, sizeof(ip4_address));
+ else
+ {
+ ip4_address addr4;
+ if (!map_ip_to_ipv4 (addr, &addr4))
+ /* should the callers have prevented this? */
+ abort ();
+ memcpy (&sa->sin.sin_addr, &addr4, sizeof(ip4_address));
+ }
return;
}
#ifdef INET6
#define CMD_DECLARE(func) static int func \
PARAMS ((const char *, const char *, void *))
-CMD_DECLARE (cmd_address);
CMD_DECLARE (cmd_boolean);
CMD_DECLARE (cmd_bytes);
CMD_DECLARE (cmd_directory_vector);
{ "backupconverted", &opt.backup_converted, cmd_boolean },
{ "backups", &opt.backups, cmd_number },
{ "base", &opt.base_href, cmd_string },
- { "bindaddress", &opt.bind_address, cmd_address },
+ { "bindaddress", &opt.bind_address, cmd_string },
{ "cache", &opt.allow_cache, cmd_boolean },
{ "continue", &opt.always_rest, cmd_boolean },
{ "convertlinks", &opt.convert_links, cmd_boolean },
static int myatoi PARAMS ((const char *s));
-/* Interpret VAL as an Internet address (a hostname or a dotted-quad
- IP address), and write it (in network order) to a malloc-allocated
- address. That address gets stored to the memory pointed to by
- CLOSURE. COM is ignored, except for error messages.
-
- #### IMHO it's a mistake to do this kind of work so early in the
- process (before any download even started!) opt.bind_address
- should simply remember the provided value as a string. Another
- function should do the lookup, when needed, and cache the
- result. --hniksic */
-static int
-cmd_address (const char *com, const char *val, void *closure)
-{
- struct address_list *al;
- wget_sockaddr sa;
- wget_sockaddr **target = (wget_sockaddr **)closure;
-
- memset (&sa, '\0', sizeof (sa));
-
- al = lookup_host (val, 1);
- if (!al)
- {
- fprintf (stderr, _("%s: %s: Cannot convert `%s' to an IP address.\n"),
- exec_name, com, val);
- return 0;
- }
- sa.sa.sa_family = ip_default_family;
- wget_sockaddr_set_port (&sa, 0);
- address_list_copy_one (al, 0, wget_sockaddr_get_addr (&sa));
- address_list_release (al);
-
- FREE_MAYBE (*target);
-
- *target = xmalloc (sizeof (sa));
- memcpy (*target, &sa, sizeof (sa));
-
- return 1;
-}
-
/* Store the boolean value from VAL to CLOSURE. COM is ignored,
except for error messages. */
static int
/* Needed for FDP. */
#include <stdio.h>
-#include "host.h"
struct options
{
int page_requisites; /* Whether we need to download all files
necessary to display a page properly. */
- wget_sockaddr *bind_address; /* What local IP address to bind to. */
+ char *bind_address; /* What local IP address to bind to. */
#ifdef HAVE_SSL
char *sslcertfile; /* external client cert to use. */
char *sslcertkey; /* the keyfile for this certificate