]> sjero.net Git - wget/blob - src/connect.c
28d2f6aa3395a5b37c904a0717286ed562490661
[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 int
79 connect_to_one (const 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, start, end;
150
151   address_list_get_bounds (al, &start, &end);
152   for (i = start; i < end; i++)
153     {
154       unsigned char addr[4];
155       int sock;
156       address_list_copy_one (al, i, addr);
157
158       sock = connect_to_one (addr, port, silent);
159       if (sock >= 0)
160         /* Success. */
161         return sock;
162
163       address_list_set_faulty (al, i);
164
165       /* The attempt to connect has failed.  Continue with the loop
166          and try next address. */
167     }
168
169   return -1;
170 }
171
172 int
173 test_socket_open (int sock)
174 {
175 #ifdef HAVE_SELECT
176   fd_set check_set;
177   struct timeval to;
178
179   /* Check if we still have a valid (non-EOF) connection.  From Andrew
180    * Maholski's code in the Unix Socket FAQ.  */
181
182   FD_ZERO (&check_set);
183   FD_SET (sock, &check_set);
184
185   /* Wait one microsecond */
186   to.tv_sec = 0;
187   to.tv_usec = 1;
188
189   /* If we get a timeout, then that means still connected */
190   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
191     {
192       /* Connection is valid (not EOF), so continue */
193       return 1;
194     }
195   else
196     return 0;
197 #else
198   /* Without select, it's hard to know for sure. */
199   return 1;
200 #endif
201 }
202
203 /* Bind the local port PORT.  This does all the necessary work, which
204    is creating a socket, setting SO_REUSEADDR option on it, then
205    calling bind() and listen().  If *PORT is 0, a random port is
206    chosen by the system, and its value is stored to *PORT.  The
207    internal variable MPORT is set to the value of the ensuing master
208    socket.  Call acceptport() to block for and accept a connection.  */
209 uerr_t
210 bindport (unsigned short *port)
211 {
212   int optval = 1;
213   static struct sockaddr_in srv;
214
215   msock = -1;
216   addr = (struct sockaddr *) &srv;
217   if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
218     return CONSOCKERR;
219   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
220                   (char *)&optval, sizeof (optval)) < 0)
221     return CONSOCKERR;
222
223   if (opt.bind_address == NULL)
224     {
225       srv.sin_family = AF_INET;
226       srv.sin_addr.s_addr = htonl (INADDR_ANY);
227     }
228   else
229     srv = *opt.bind_address;
230
231   srv.sin_port = htons (*port);
232   if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
233     {
234       CLOSE (msock);
235       msock = -1;
236       return BINDERR;
237     }
238   DEBUGP (("Master socket fd %d bound.\n", msock));
239   if (!*port)
240     {
241       /* #### addrlen should be a 32-bit type, which int is not
242          guaranteed to be.  Oh, and don't try to make it a size_t,
243          because that can be 64-bit.  */
244       int addrlen = sizeof (struct sockaddr_in);
245       if (getsockname (msock, addr, &addrlen) < 0)
246         {
247           CLOSE (msock);
248           msock = -1;
249           return CONPORTERR;
250         }
251       *port = ntohs (srv.sin_port);
252     }
253   if (listen (msock, 1) < 0)
254     {
255       CLOSE (msock);
256       msock = -1;
257       return LISTENERR;
258     }
259   return BINDOK;
260 }
261
262 #ifdef HAVE_SELECT
263 /* Wait for file descriptor FD to be readable, MAXTIME being the
264    timeout in seconds.  If WRITEP is non-zero, checks for FD being
265    writable instead.
266
267    Returns 1 if FD is accessible, 0 for timeout and -1 for error in
268    select().  */
269 int
270 select_fd (int fd, int maxtime, int writep)
271 {
272   fd_set fds, exceptfds;
273   struct timeval timeout;
274
275   FD_ZERO (&fds);
276   FD_SET (fd, &fds);
277   FD_ZERO (&exceptfds);
278   FD_SET (fd, &exceptfds);
279   timeout.tv_sec = maxtime;
280   timeout.tv_usec = 0;
281   /* HPUX reportedly warns here.  What is the correct incantation?  */
282   return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
283                  &exceptfds, &timeout);
284 }
285 #endif /* HAVE_SELECT */
286
287 /* Call accept() on MSOCK and store the result to *SOCK.  This assumes
288    that bindport() has been used to initialize MSOCK to a correct
289    value.  It blocks the caller until a connection is established.  If
290    no connection is established for OPT.TIMEOUT seconds, the function
291    exits with an error status.  */
292 uerr_t
293 acceptport (int *sock)
294 {
295   int addrlen = sizeof (struct sockaddr_in);
296
297 #ifdef HAVE_SELECT
298   if (select_fd (msock, opt.timeout, 0) <= 0)
299     return ACCEPTERR;
300 #endif
301   if ((*sock = accept (msock, addr, &addrlen)) < 0)
302     return ACCEPTERR;
303   DEBUGP (("Created socket fd %d.\n", *sock));
304   return ACCEPTOK;
305 }
306
307 /* Close SOCK, as well as the most recently remembered MSOCK, created
308    via bindport().  If SOCK is -1, close MSOCK only.  */
309 void
310 closeport (int sock)
311 {
312   /*shutdown (sock, 2);*/
313   if (sock != -1)
314     CLOSE (sock);
315   if (msock != -1)
316     CLOSE (msock);
317   msock = -1;
318 }
319
320 /* Return the local IP address associated with the connection on FD.
321    It is returned in a static buffer.  */
322 unsigned char *
323 conaddr (int fd)
324 {
325   static unsigned char res[4];
326   struct sockaddr_in mysrv;
327   struct sockaddr *myaddr;
328   int addrlen = sizeof (mysrv); /* see bindport() for discussion of
329                                    using `int' here. */
330
331   myaddr = (struct sockaddr *) (&mysrv);
332   if (getsockname (fd, myaddr, (int *)&addrlen) < 0)
333     return NULL;
334   memcpy (res, &mysrv.sin_addr, 4);
335   return res;
336 }
337
338 /* Read at most LEN bytes from FD, storing them to BUF.  This is
339    virtually the same as read(), but takes care of EINTR braindamage
340    and uses select() to timeout the stale connections (a connection is
341    stale if more than OPT.TIMEOUT time is spent in select() or
342    read()).  */
343 int
344 iread (int fd, char *buf, int len)
345 {
346   int res;
347
348   do
349     {
350 #ifdef HAVE_SELECT
351       if (opt.timeout)
352         {
353           do
354             {
355               res = select_fd (fd, opt.timeout, 0);
356             }
357           while (res == -1 && errno == EINTR);
358           if (res <= 0)
359             {
360               /* Set errno to ETIMEDOUT on timeout.  */
361               if (res == 0)
362                 /* #### Potentially evil!  */
363                 errno = ETIMEDOUT;
364               return -1;
365             }
366         }
367 #endif
368       res = READ (fd, buf, len);
369     }
370   while (res == -1 && errno == EINTR);
371
372   return res;
373 }
374
375 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
376    doesn't bother with select().  Unlike iread(), it makes sure that
377    all of BUF is actually written to FD, so callers needn't bother
378    with checking that the return value equals to LEN.  Instead, you
379    should simply check for -1.  */
380 int
381 iwrite (int fd, char *buf, int len)
382 {
383   int res = 0;
384
385   /* `write' may write less than LEN bytes, thus the outward loop
386      keeps trying it until all was written, or an error occurred.  The
387      inner loop is reserved for the usual EINTR f*kage, and the
388      innermost loop deals with the same during select().  */
389   while (len > 0)
390     {
391       do
392         {
393 #ifdef HAVE_SELECT
394           if (opt.timeout)
395             {
396               do
397                 {
398                   res = select_fd (fd, opt.timeout, 1);
399                 }
400               while (res == -1 && errno == EINTR);
401               if (res <= 0)
402                 {
403                   /* Set errno to ETIMEDOUT on timeout.  */
404                   if (res == 0)
405                     /* #### Potentially evil!  */
406                     errno = ETIMEDOUT;
407                   return -1;
408                 }
409             }
410 #endif
411           res = WRITE (fd, buf, len);
412         }
413       while (res == -1 && errno == EINTR);
414       if (res <= 0)
415         break;
416       buf += res;
417       len -= res;
418     }
419   return res;
420 }