]> sjero.net Git - wget/blob - src/connect.c
619fd41753e722841f27608d2678ea953cdbdd28
[wget] / src / connect.c
1 /* Establishing and handling network connections.
2    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <sys/types.h>
24 #ifdef HAVE_UNISTD_H
25 # include <unistd.h>
26 #endif
27 #include <assert.h>
28
29 #ifdef WINDOWS
30 # include <winsock.h>
31 #else
32 # include <sys/socket.h>
33 # include <netdb.h>
34 # include <netinet/in.h>
35 #ifndef __BEOS__
36 # include <arpa/inet.h>
37 #endif
38 #endif /* WINDOWS */
39
40 #include <errno.h>
41 #ifdef HAVE_STRING_H
42 # include <string.h>
43 #else
44 # include <strings.h>
45 #endif /* HAVE_STRING_H */
46 #ifdef HAVE_SYS_SELECT_H
47 # include <sys/select.h>
48 #endif /* HAVE_SYS_SELECT_H */
49
50 #include "wget.h"
51 #include "connect.h"
52 #include "host.h"
53
54 #ifndef errno
55 extern int errno;
56 #endif
57
58 /* Variables shared by bindport and acceptport: */
59 static int msock = -1;
60 static struct sockaddr *addr;
61
62 /* A kludge, but still better than passing the host name all the way
63    to connect_to_one.  */
64 static const char *connection_host_name;
65
66 void
67 set_connection_host_name (const char *host)
68 {
69   if (host)
70     assert (connection_host_name == NULL);
71   else
72     assert (connection_host_name != NULL);
73
74   connection_host_name = host;
75 }
76
77 /* Connect to a remote host whose address has been resolved. */
78 static int
79 connect_to_one (unsigned char *addr, unsigned short port, int silent)
80 {
81   struct sockaddr_in sock_name;
82   int sock, save_errno;
83
84   /* Set port and protocol */
85   sock_name.sin_family = AF_INET;
86   sock_name.sin_port = htons (port);
87   memcpy ((unsigned char *)&sock_name.sin_addr, addr, 4);
88
89   if (!silent)
90     {
91       char *pretty_addr = pretty_print_address (addr);
92       if (connection_host_name
93           && 0 != strcmp (connection_host_name, pretty_addr))
94         logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "),
95                    connection_host_name, pretty_addr, port);
96       else
97         logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "),
98                    pretty_addr, port);
99     }
100
101   /* Make an internet socket, stream type.  */
102   sock = socket (AF_INET, SOCK_STREAM, 0);
103   if (sock < 0)
104     goto out;
105
106   if (opt.bind_address)
107     {
108       /* Bind the client side to the requested address. */
109       if (bind (sock, (struct sockaddr *)opt.bind_address,
110                 sizeof (*opt.bind_address)))
111         {
112           close (sock);
113           sock = -1;
114           goto out;
115         }
116     }
117
118   /* Connect the socket to the remote host.  */
119   if (connect (sock, (struct sockaddr *)&sock_name, sizeof (sock_name)) < 0)
120     {
121       close (sock);
122       sock = -1;
123       goto out;
124     }
125
126  out:
127   if (sock >= 0)
128     {
129       /* Success. */
130       if (!silent)
131         logprintf (LOG_VERBOSE, _("connected.\n"));
132       DEBUGP (("Created socket %d.\n", sock));
133     }
134   else
135     {
136       save_errno = errno;
137       if (!silent)
138         logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
139       errno = save_errno;
140     }
141
142   return sock;
143 }
144
145 /* Connect to a remote host whose address has been resolved. */
146 int
147 connect_to_many (struct address_list *al, unsigned short port, int silent)
148 {
149   int i;
150
151   for (i = 0; i < address_list_count (al); i++)
152     {
153       unsigned char addr[4];
154       int sock;
155       address_list_copy_one (al, i, addr);
156
157       sock = connect_to_one (addr, port, silent);
158       if (sock >= 0)
159         return sock;
160
161       /* Perhaps we should have a way of removing the failing entry
162          from the address list?  */
163
164       /* The attempt to connect has failed.  Continue with the loop
165          and try next address. */
166     }
167
168   return -1;
169 }
170
171 int
172 test_socket_open (int sock)
173 {
174 #ifdef HAVE_SELECT
175   fd_set check_set;
176   struct timeval to;
177
178   /* Check if we still have a valid (non-EOF) connection.  From Andrew
179    * Maholski's code in the Unix Socket FAQ.  */
180
181   FD_ZERO (&check_set);
182   FD_SET (sock, &check_set);
183
184   /* Wait one microsecond */
185   to.tv_sec = 0;
186   to.tv_usec = 1;
187
188   /* If we get a timeout, then that means still connected */
189   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
190     {
191       /* Connection is valid (not EOF), so continue */
192       return 1;
193     }
194   else
195     return 0;
196 #else
197   /* Without select, it's hard to know for sure. */
198   return 1;
199 #endif
200 }
201
202 /* Bind the local port PORT.  This does all the necessary work, which
203    is creating a socket, setting SO_REUSEADDR option on it, then
204    calling bind() and listen().  If *PORT is 0, a random port is
205    chosen by the system, and its value is stored to *PORT.  The
206    internal variable MPORT is set to the value of the ensuing master
207    socket.  Call acceptport() to block for and accept a connection.  */
208 uerr_t
209 bindport (unsigned short *port)
210 {
211   int optval = 1;
212   static struct sockaddr_in srv;
213
214   msock = -1;
215   addr = (struct sockaddr *) &srv;
216   if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
217     return CONSOCKERR;
218   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
219                   (char *)&optval, sizeof (optval)) < 0)
220     return CONSOCKERR;
221
222   if (opt.bind_address == NULL)
223     {
224       srv.sin_family = AF_INET;
225       srv.sin_addr.s_addr = htonl (INADDR_ANY);
226     }
227   else
228     srv = *opt.bind_address;
229
230   srv.sin_port = htons (*port);
231   if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
232     {
233       CLOSE (msock);
234       msock = -1;
235       return BINDERR;
236     }
237   DEBUGP (("Master socket fd %d bound.\n", msock));
238   if (!*port)
239     {
240       /* #### addrlen should be a 32-bit type, which int is not
241          guaranteed to be.  Oh, and don't try to make it a size_t,
242          because that can be 64-bit.  */
243       int addrlen = sizeof (struct sockaddr_in);
244       if (getsockname (msock, addr, &addrlen) < 0)
245         {
246           CLOSE (msock);
247           msock = -1;
248           return CONPORTERR;
249         }
250       *port = ntohs (srv.sin_port);
251     }
252   if (listen (msock, 1) < 0)
253     {
254       CLOSE (msock);
255       msock = -1;
256       return LISTENERR;
257     }
258   return BINDOK;
259 }
260
261 #ifdef HAVE_SELECT
262 /* Wait for file descriptor FD to be readable, MAXTIME being the
263    timeout in seconds.  If WRITEP is non-zero, checks for FD being
264    writable instead.
265
266    Returns 1 if FD is accessible, 0 for timeout and -1 for error in
267    select().  */
268 int
269 select_fd (int fd, int maxtime, int writep)
270 {
271   fd_set fds, exceptfds;
272   struct timeval timeout;
273
274   FD_ZERO (&fds);
275   FD_SET (fd, &fds);
276   FD_ZERO (&exceptfds);
277   FD_SET (fd, &exceptfds);
278   timeout.tv_sec = maxtime;
279   timeout.tv_usec = 0;
280   /* HPUX reportedly warns here.  What is the correct incantation?  */
281   return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
282                  &exceptfds, &timeout);
283 }
284 #endif /* HAVE_SELECT */
285
286 /* Call accept() on MSOCK and store the result to *SOCK.  This assumes
287    that bindport() has been used to initialize MSOCK to a correct
288    value.  It blocks the caller until a connection is established.  If
289    no connection is established for OPT.TIMEOUT seconds, the function
290    exits with an error status.  */
291 uerr_t
292 acceptport (int *sock)
293 {
294   int addrlen = sizeof (struct sockaddr_in);
295
296 #ifdef HAVE_SELECT
297   if (select_fd (msock, opt.timeout, 0) <= 0)
298     return ACCEPTERR;
299 #endif
300   if ((*sock = accept (msock, addr, &addrlen)) < 0)
301     return ACCEPTERR;
302   DEBUGP (("Created socket fd %d.\n", *sock));
303   return ACCEPTOK;
304 }
305
306 /* Close SOCK, as well as the most recently remembered MSOCK, created
307    via bindport().  If SOCK is -1, close MSOCK only.  */
308 void
309 closeport (int sock)
310 {
311   /*shutdown (sock, 2);*/
312   if (sock != -1)
313     CLOSE (sock);
314   if (msock != -1)
315     CLOSE (msock);
316   msock = -1;
317 }
318
319 /* Return the local IP address associated with the connection on FD.
320    It is returned in a static buffer.  */
321 unsigned char *
322 conaddr (int fd)
323 {
324   static unsigned char res[4];
325   struct sockaddr_in mysrv;
326   struct sockaddr *myaddr;
327   int addrlen = sizeof (mysrv); /* see bindport() for discussion of
328                                    using `int' here. */
329
330   myaddr = (struct sockaddr *) (&mysrv);
331   if (getsockname (fd, myaddr, (int *)&addrlen) < 0)
332     return NULL;
333   memcpy (res, &mysrv.sin_addr, 4);
334   return res;
335 }
336
337 /* Read at most LEN bytes from FD, storing them to BUF.  This is
338    virtually the same as read(), but takes care of EINTR braindamage
339    and uses select() to timeout the stale connections (a connection is
340    stale if more than OPT.TIMEOUT time is spent in select() or
341    read()).  */
342 int
343 iread (int fd, char *buf, int len)
344 {
345   int res;
346
347   do
348     {
349 #ifdef HAVE_SELECT
350       if (opt.timeout)
351         {
352           do
353             {
354               res = select_fd (fd, opt.timeout, 0);
355             }
356           while (res == -1 && errno == EINTR);
357           if (res <= 0)
358             {
359               /* Set errno to ETIMEDOUT on timeout.  */
360               if (res == 0)
361                 /* #### Potentially evil!  */
362                 errno = ETIMEDOUT;
363               return -1;
364             }
365         }
366 #endif
367       res = READ (fd, buf, len);
368     }
369   while (res == -1 && errno == EINTR);
370
371   return res;
372 }
373
374 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
375    doesn't bother with select().  Unlike iread(), it makes sure that
376    all of BUF is actually written to FD, so callers needn't bother
377    with checking that the return value equals to LEN.  Instead, you
378    should simply check for -1.  */
379 int
380 iwrite (int fd, char *buf, int len)
381 {
382   int res = 0;
383
384   /* `write' may write less than LEN bytes, thus the outward loop
385      keeps trying it until all was written, or an error occurred.  The
386      inner loop is reserved for the usual EINTR f*kage, and the
387      innermost loop deals with the same during select().  */
388   while (len > 0)
389     {
390       do
391         {
392 #ifdef HAVE_SELECT
393           if (opt.timeout)
394             {
395               do
396                 {
397                   res = select_fd (fd, opt.timeout, 1);
398                 }
399               while (res == -1 && errno == EINTR);
400               if (res <= 0)
401                 {
402                   /* Set errno to ETIMEDOUT on timeout.  */
403                   if (res == 0)
404                     /* #### Potentially evil!  */
405                     errno = ETIMEDOUT;
406                   return -1;
407                 }
408             }
409 #endif
410           res = WRITE (fd, buf, len);
411         }
412       while (res == -1 && errno == EINTR);
413       if (res <= 0)
414         break;
415       buf += res;
416       len -= res;
417     }
418   return res;
419 }