]> sjero.net Git - wget/blob - src/connect.c
175db605121680096a549a5d1f9cf4e3c5c458b3
[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 Wget.
5
6 This program 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 This program 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 this program; 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
28 #ifdef WINDOWS
29 # include <winsock.h>
30 #else
31 # include <sys/socket.h>
32 # include <netdb.h>
33 # include <netinet/in.h>
34 # include <arpa/inet.h>
35 #endif /* WINDOWS */
36
37 #include <errno.h>
38 #ifdef HAVE_STRING_H
39 # include <string.h>
40 #else
41 # include <strings.h>
42 #endif /* HAVE_STRING_H */
43 #ifdef HAVE_SYS_SELECT_H
44 # include <sys/select.h>
45 #endif /* HAVE_SYS_SELECT_H */
46
47 #include "wget.h"
48 #include "connect.h"
49 #include "host.h"
50
51 #ifndef errno
52 extern int errno;
53 #endif
54
55 /* Variables shared by bindport and acceptport: */
56 static int msock = -1;
57 static struct sockaddr *addr;
58
59
60 /* Create an internet connection to HOSTNAME on PORT.  The created
61    socket will be stored to *SOCK.  */
62 uerr_t
63 make_connection (int *sock, char *hostname, unsigned short port)
64 {
65   struct sockaddr_in sock_name;
66   /* struct hostent *hptr; */
67
68   /* Get internet address of the host.  We can do it either by calling
69      ngethostbyname, or by calling store_hostaddress, from host.c.
70      storehostaddress is better since it caches calls to
71      gethostbyname.  */
72 #if 1
73   if (!store_hostaddress ((unsigned char *)&sock_name.sin_addr, hostname))
74     return HOSTERR;
75 #else  /* never */
76   if (!(hptr = ngethostbyname (hostname)))
77     return HOSTERR;
78   /* Copy the address of the host to socket description.  */
79   memcpy (&sock_name.sin_addr, hptr->h_addr, hptr->h_length);
80 #endif /* never */
81
82   /* Set port and protocol */
83   sock_name.sin_family = AF_INET;
84   sock_name.sin_port = htons (port);
85
86   /* Make an internet socket, stream type.  */
87   if ((*sock = socket (AF_INET, SOCK_STREAM, 0)) == -1)
88     return CONSOCKERR;
89
90   /* Connect the socket to the remote host.  */
91   if (connect (*sock, (struct sockaddr *) &sock_name, sizeof (sock_name)))
92     {
93       if (errno == ECONNREFUSED)
94         return CONREFUSED;
95       else
96         return CONERROR;
97     }
98   DEBUGP (("Created fd %d.\n", *sock));
99   return NOCONERROR;
100 }
101
102 /* Bind the local port PORT.  This does all the necessary work, which
103    is creating a socket, setting SO_REUSEADDR option on it, then
104    calling bind() and listen().  If *PORT is 0, a random port is
105    chosen by the system, and its value is stored to *PORT.  The
106    internal variable MPORT is set to the value of the ensuing master
107    socket.  Call acceptport() to block for and accept a connection.  */
108 uerr_t
109 bindport (unsigned short *port)
110 {
111   int optval = 1;
112   static struct sockaddr_in srv;
113
114   msock = -1;
115   addr = (struct sockaddr *) &srv;
116   if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
117     return CONSOCKERR;
118   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
119                   (char *)&optval, sizeof (optval)) < 0)
120     return CONSOCKERR;
121   srv.sin_family = AF_INET;
122   srv.sin_addr.s_addr = htonl (INADDR_ANY);
123   srv.sin_port = htons (*port);
124   if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
125     {
126       CLOSE (msock);
127       msock = -1;
128       return BINDERR;
129     }
130   DEBUGP (("Master socket fd %d bound.\n", msock));
131   if (!*port)
132     {
133       size_t addrlen = sizeof (struct sockaddr_in);
134       if (getsockname (msock, addr, (int *)&addrlen) < 0)
135         {
136           CLOSE (msock);
137           msock = -1;
138           return CONPORTERR;
139         }
140       *port = ntohs (srv.sin_port);
141     }
142   if (listen (msock, 1) < 0)
143     {
144       CLOSE (msock);
145       msock = -1;
146       return LISTENERR;
147     }
148   return BINDOK;
149 }
150
151 #ifdef HAVE_SELECT
152 /* Wait for file descriptor FD to be readable, MAXTIME being the
153    timeout in seconds.  If WRITEP is non-zero, checks for FD being
154    writable instead.
155
156    Returns 1 if FD is accessible, 0 for timeout and -1 for error in
157    select().  */
158 static int
159 select_fd (int fd, int maxtime, int writep)
160 {
161   fd_set fds, exceptfds;
162   struct timeval timeout;
163
164   FD_ZERO (&fds);
165   FD_SET (fd, &fds);
166   FD_ZERO (&exceptfds);
167   FD_SET (fd, &exceptfds);
168   timeout.tv_sec = maxtime;
169   timeout.tv_usec = 0;
170   /* HPUX reportedly warns here.  What is the correct incantation?  */
171   return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
172                  &exceptfds, &timeout);
173 }
174 #endif /* HAVE_SELECT */
175
176 /* Call accept() on MSOCK and store the result to *SOCK.  This assumes
177    that bindport() has been used to initialize MSOCK to a correct
178    value.  It blocks the caller until a connection is established.  If
179    no connection is established for OPT.TIMEOUT seconds, the function
180    exits with an error status.  */
181 uerr_t
182 acceptport (int *sock)
183 {
184   int addrlen = sizeof (struct sockaddr_in);
185
186 #ifdef HAVE_SELECT
187   if (select_fd (msock, opt.timeout, 0) <= 0)
188     return ACCEPTERR;
189 #endif
190   if ((*sock = accept (msock, addr, &addrlen)) < 0)
191     return ACCEPTERR;
192   DEBUGP (("Created socket fd %d.\n", *sock));
193   return ACCEPTOK;
194 }
195
196 /* Close SOCK, as well as the most recently remembered MSOCK, created
197    via bindport().  If SOCK is -1, close MSOCK only.  */
198 void
199 closeport (int sock)
200 {
201   /*shutdown (sock, 2);*/
202   if (sock != -1)
203     CLOSE (sock);
204   if (msock != -1)
205     CLOSE (msock);
206   msock = -1;
207 }
208
209 /* Return the local IP address associated with the connection on FD.
210    It is returned in a static buffer.  */
211 unsigned char *
212 conaddr (int fd)
213 {
214   static unsigned char res[4];
215   struct sockaddr_in mysrv;
216   struct sockaddr *myaddr;
217   size_t addrlen = sizeof (mysrv);
218
219   myaddr = (struct sockaddr *) (&mysrv);
220   if (getsockname (fd, myaddr, (int *)&addrlen) < 0)
221     return NULL;
222   memcpy (res, &mysrv.sin_addr, 4);
223   return res;
224 }
225
226 /* Read at most LEN bytes from FD, storing them to BUF.  This is
227    virtually the same as read(), but takes care of EINTR braindamage
228    and uses select() to timeout the stale connections (a connection is
229    stale if more than OPT.TIMEOUT time is spent in select() or
230    read()).  */
231 int
232 iread (int fd, char *buf, int len)
233 {
234   int res;
235
236   do
237     {
238 #ifdef HAVE_SELECT
239       if (opt.timeout)
240         {
241           do
242             {
243               res = select_fd (fd, opt.timeout, 0);
244             }
245           while (res == -1 && errno == EINTR);
246           if (res <= 0)
247             {
248               /* Set errno to ETIMEDOUT on timeout.  */
249               if (res == 0)
250                 /* #### Potentially evil!  */
251                 errno = ETIMEDOUT;
252               return -1;
253             }
254         }
255 #endif
256       res = READ (fd, buf, len);
257     }
258   while (res == -1 && errno == EINTR);
259
260   return res;
261 }
262
263 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
264    doesn't bother with select().  Unlike iread(), it makes sure that
265    all of BUF is actually written to FD, so callers needn't bother
266    with checking that the return value equals to LEN.  Instead, you
267    should simply check for -1.  */
268 int
269 iwrite (int fd, char *buf, int len)
270 {
271   int res = 0;
272
273   /* `write' may write less than LEN bytes, thus the outward loop
274      keeps trying it until all was written, or an error occurred.  The
275      inner loop is reserved for the usual EINTR f*kage, and the
276      innermost loop deals with the same during select().  */
277   while (len > 0)
278     {
279       do
280         {
281 #ifdef HAVE_SELECT
282           if (opt.timeout)
283             {
284               do
285                 {
286                   res = select_fd (fd, opt.timeout, 1);
287                 }
288               while (res == -1 && errno == EINTR);
289               if (res <= 0)
290                 {
291                   /* Set errno to ETIMEDOUT on timeout.  */
292                   if (res == 0)
293                     /* #### Potentially evil!  */
294                     errno = ETIMEDOUT;
295                   return -1;
296                 }
297             }
298 #endif
299           res = WRITE (fd, buf, len);
300         }
301       while (res == -1 && errno == EINTR);
302       if (res <= 0)
303         break;
304       buf += res;
305       len -= res;
306     }
307   return res;
308 }