X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fconnect.c;h=619fd41753e722841f27608d2678ea953cdbdd28;hb=024cb5ed3a0263775bc750b06bca74c91b389d2d;hp=aa3153ede2fba79c37da561c64b4d66aa6d0430e;hpb=f6921edc7366cc63d7e65ea8a9d87940ade71a06;p=wget diff --git a/src/connect.c b/src/connect.c index aa3153ed..619fd417 100644 --- a/src/connect.c +++ b/src/connect.c @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_UNISTD_H # include #endif +#include #ifdef WINDOWS # include @@ -58,43 +59,113 @@ extern int errno; static int msock = -1; static struct sockaddr *addr; +/* A kludge, but still better than passing the host name all the way + to connect_to_one. */ +static const char *connection_host_name; -/* Create an internet connection to HOSTNAME on PORT. The created - socket will be stored to *SOCK. */ -uerr_t -make_connection (int *sock, char *hostname, unsigned short port) +void +set_connection_host_name (const char *host) { - struct sockaddr_in sock_name; + if (host) + assert (connection_host_name == NULL); + else + assert (connection_host_name != NULL); - if (!lookup_host (hostname, (unsigned char *)&sock_name.sin_addr)) - return HOSTERR; + connection_host_name = host; +} + +/* Connect to a remote host whose address has been resolved. */ +static int +connect_to_one (unsigned char *addr, unsigned short port, int silent) +{ + struct sockaddr_in sock_name; + int sock, save_errno; /* Set port and protocol */ sock_name.sin_family = AF_INET; sock_name.sin_port = htons (port); + memcpy ((unsigned char *)&sock_name.sin_addr, addr, 4); + + if (!silent) + { + char *pretty_addr = pretty_print_address (addr); + if (connection_host_name + && 0 != strcmp (connection_host_name, pretty_addr)) + logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "), + connection_host_name, pretty_addr, port); + else + logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), + pretty_addr, port); + } /* Make an internet socket, stream type. */ - if ((*sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) - return CONSOCKERR; + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + goto out; - if (opt.bind_address != NULL) + if (opt.bind_address) { /* Bind the client side to the requested address. */ - if (bind (*sock, (struct sockaddr *) opt.bind_address, + if (bind (sock, (struct sockaddr *)opt.bind_address, sizeof (*opt.bind_address))) - return CONSOCKERR; + { + close (sock); + sock = -1; + goto out; + } } /* Connect the socket to the remote host. */ - if (connect (*sock, (struct sockaddr *) &sock_name, sizeof (sock_name))) + if (connect (sock, (struct sockaddr *)&sock_name, sizeof (sock_name)) < 0) { - if (errno == ECONNREFUSED) - return CONREFUSED; - else - return CONERROR; + close (sock); + sock = -1; + goto out; + } + + out: + if (sock >= 0) + { + /* Success. */ + if (!silent) + logprintf (LOG_VERBOSE, _("connected.\n")); + DEBUGP (("Created socket %d.\n", sock)); + } + else + { + save_errno = errno; + if (!silent) + logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno)); + errno = save_errno; } - DEBUGP (("Created fd %d.\n", *sock)); - return NOCONERROR; + + 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; + + for (i = 0; i < address_list_count (al); i++) + { + unsigned char addr[4]; + int sock; + address_list_copy_one (al, i, addr); + + sock = connect_to_one (addr, port, silent); + if (sock >= 0) + return sock; + + /* Perhaps we should have a way of removing the failing entry + from the address list? */ + + /* The attempt to connect has failed. Continue with the loop + and try next address. */ + } + + return -1; } int