]> git.pld-linux.org Git - packages/wget.git/blob - wget-ipv6.patch
- updated to 1.10.2 (http-ntlm security fix)
[packages/wget.git] / wget-ipv6.patch
1 diff -ur wget-1.8.1.orig/src/connect.c wget-1.8.1/src/connect.c
2 --- wget-1.8.1.orig/src/connect.c       Tue Nov 27 23:55:40 2001
3 +++ wget-1.8.1/src/connect.c    Tue Feb 19 03:02:05 2002
4 @@ -78,17 +78,49 @@
5  int
6  connect_to_one (const unsigned char *addr, unsigned short port, int silent)
7  {
8 +#ifdef INET6
9 +  struct addrinfo hints, *res;
10 +  struct sockaddr_storage sock_name;
11 +  char portstr[NI_MAXSERV];
12 +  int err;
13 +#else
14    struct sockaddr_in sock_name;
15 -  int sock, save_errno;
16 +#endif
17 +  int sock, save_errno, salen;
18  
19    /* Set port and protocol */
20 +#ifdef INET6
21 +  memset(&hints, 0, sizeof(hints));
22 +  hints.ai_family = PF_UNSPEC;
23 +  hints.ai_socktype = SOCK_STREAM;
24 +  hints.ai_flags = AI_NUMERICHOST;
25 +  snprintf(portstr, sizeof(portstr), "%d", port);
26 +  err = getaddrinfo(addr, portstr, &hints, &res);
27 +  if (err)
28 +    {
29 +      if (!silent)
30 +       logprintf (LOG_VERBOSE, "getaddrinfo: %s.\n", gai_strerror (err));
31 +      return -1;
32 +    }
33 +  memset (&sock_name, 0, sizeof (sock_name));
34 +  memcpy (&sock_name, res->ai_addr, res->ai_addrlen);
35 +  salen = res->ai_addrlen;
36 +  freeaddrinfo (res);
37 +#else
38    sock_name.sin_family = AF_INET;
39    sock_name.sin_port = htons (port);
40    memcpy ((unsigned char *)&sock_name.sin_addr, addr, 4);
41 +  salen = sizeof (sock_name);
42 +#endif
43  
44    if (!silent)
45      {
46 +#ifdef INET6
47 +      char pretty_addr[INET6_ADDRSTRLEN];
48 +      pretty_print_address_sa (&sock_name, salen, pretty_addr);
49 +#else
50        char *pretty_addr = pretty_print_address (addr);
51 +#endif
52        if (connection_host_name
53           && 0 != strcmp (connection_host_name, pretty_addr))
54         logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "),
55 @@ -99,26 +131,29 @@
56      }
57  
58    /* Make an internet socket, stream type.  */
59 -  sock = socket (AF_INET, SOCK_STREAM, 0);
60 +  sock = socket (((struct sockaddr *)&sock_name)->sa_family, SOCK_STREAM, 0);
61    if (sock < 0)
62      goto out;
63  
64    if (opt.bind_address)
65      {
66        /* Bind the client side to the requested address. */
67 -      if (bind (sock, (struct sockaddr *)opt.bind_address,
68 -               sizeof (*opt.bind_address)))
69 +      if (bind (sock, (struct sockaddr *)opt.bind_address, salen))
70         {
71 -         close (sock);
72 +         save_errno = errno;
73 +         CLOSE (sock);
74 +         errno = save_errno;
75           sock = -1;
76           goto out;
77         }
78      }
79  
80    /* Connect the socket to the remote host.  */
81 -  if (connect (sock, (struct sockaddr *)&sock_name, sizeof (sock_name)) < 0)
82 +  if (connect (sock, (struct sockaddr *)&sock_name, salen) < 0)
83      {
84 -      close (sock);
85 +      save_errno = errno;
86 +      CLOSE (sock);
87 +      errno = save_errno;
88        sock = -1;
89        goto out;
90      }
91 @@ -130,6 +165,10 @@
92        if (!silent)
93         logprintf (LOG_VERBOSE, _("connected.\n"));
94        DEBUGP (("Created socket %d.\n", sock));
95 +#ifdef INET6
96 +      opt.conn_inet6 = ((struct sockaddr *)&sock_name)->sa_family == AF_INET6 ?
97 +                       1 : 0;
98 +#endif
99      }
100    else
101      {
102 @@ -151,10 +190,28 @@
103    address_list_get_bounds (al, &start, &end);
104    for (i = start; i < end; i++)
105      {
106 +#ifdef INET6
107 +      struct addrinfo ai;
108 +      unsigned char *addr = (unsigned char *)&ai;
109 +      char hbuf[INET6_ADDRSTRLEN];
110 +      int err;
111 +#else
112        unsigned char addr[4];
113 +#endif
114        int sock;
115        address_list_copy_one (al, i, addr);
116  
117 +#ifdef INET6
118 +      err = getnameinfo(ai.ai_addr, ai.ai_addrlen, hbuf, sizeof (hbuf),
119 +                       NULL, 0, NI_NUMERICHOST);
120 +      if (err)
121 +       {
122 +         if (!silent)
123 +           logprintf (LOG_VERBOSE, "getnameinfo: %s.\n", gai_strerror (err));
124 +         continue;
125 +       }
126 +      addr = (unsigned char *)hbuf;
127 +#endif
128        sock = connect_to_one (addr, port, silent);
129        if (sock >= 0)
130         /* Success. */
131 @@ -207,14 +264,27 @@
132     internal variable MPORT is set to the value of the ensuing master
133     socket.  Call acceptport() to block for and accept a connection.  */
134  uerr_t
135 -bindport (unsigned short *port)
136 +bindport_af (unsigned short *port, int af)
137  {
138    int optval = 1;
139 +#ifdef INET6
140 +  static struct sockaddr_storage srv;
141 +#else
142    static struct sockaddr_in srv;
143 +#endif
144 +  int alen;
145  
146    msock = -1;
147    addr = (struct sockaddr *) &srv;
148 -  if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
149 +  if (af == AF_INET)
150 +    alen = sizeof (struct sockaddr_in);
151 +#ifdef INET6
152 +  else if (af == AF_INET6)
153 +    alen = sizeof (struct sockaddr_in6);
154 +#endif
155 +  else
156 +    return CONSOCKERR;
157 +  if ((msock = socket (af, SOCK_STREAM, 0)) < 0)
158      return CONSOCKERR;
159    if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
160                   (char *)&optval, sizeof (optval)) < 0)
161 @@ -222,14 +292,18 @@
162  
163    if (opt.bind_address == NULL)
164      {
165 -      srv.sin_family = AF_INET;
166 +      memset (&srv, 0, sizeof (srv));
167 +      ((struct sockaddr *)&srv)->sa_family = af;
168 +      /* in6addr_any : all 0 */
169 +#ifndef INET6
170        srv.sin_addr.s_addr = htonl (INADDR_ANY);
171 +#endif
172      }
173    else
174      srv = *opt.bind_address;
175  
176 -  srv.sin_port = htons (*port);
177 -  if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
178 +  ((struct sockaddr_in *)&srv)->sin_port = htons (*port); /* same sin6 */
179 +  if (bind (msock, addr, alen) < 0)
180      {
181        CLOSE (msock);
182        msock = -1;
183 @@ -241,14 +315,14 @@
184        /* #### addrlen should be a 32-bit type, which int is not
185           guaranteed to be.  Oh, and don't try to make it a size_t,
186           because that can be 64-bit.  */
187 -      int addrlen = sizeof (struct sockaddr_in);
188 +      int addrlen = sizeof (srv);
189        if (getsockname (msock, addr, &addrlen) < 0)
190         {
191           CLOSE (msock);
192           msock = -1;
193           return CONPORTERR;
194         }
195 -      *port = ntohs (srv.sin_port);
196 +      *port = ntohs (((struct sockaddr_in *)addr)->sin_port); /* same sin6 */
197      }
198    if (listen (msock, 1) < 0)
199      {
200 @@ -257,6 +331,12 @@
201        return LISTENERR;
202      }
203    return BINDOK;
204 +}
205 +
206 +uerr_t
207 +bindport (unsigned short *port)
208 +{
209 +  return bindport_af (port, AF_INET);
210  }
211  
212  #ifdef HAVE_SELECT
213 diff -ur wget-1.8.1.orig/src/connect.h wget-1.8.1/src/connect.h
214 --- wget-1.8.1.orig/src/connect.h       Fri Nov 30 03:22:18 2001
215 +++ wget-1.8.1/src/connect.h    Mon Feb 11 23:53:31 2002
216 @@ -30,6 +30,7 @@
217  
218  int test_socket_open PARAMS ((int));
219  int select_fd PARAMS ((int, int, int));
220 +uerr_t bindport_af PARAMS ((unsigned short *, int));
221  uerr_t bindport PARAMS ((unsigned short *));
222  uerr_t acceptport PARAMS ((int *));
223  void closeport PARAMS ((int));
224 diff -ur wget-1.8.1.orig/src/ftp-basic.c wget-1.8.1/src/ftp-basic.c
225 --- wget-1.8.1.orig/src/ftp-basic.c     Mon Dec 10 11:29:11 2001
226 +++ wget-1.8.1/src/ftp-basic.c  Tue Feb 19 00:29:13 2002
227 @@ -35,7 +35,12 @@
228  
229  #ifdef WINDOWS
230  # include <winsock.h>
231 +#else
232 +#include <sys/socket.h>
233 +#include <netinet/in.h>
234 +#include <netdb.h>
235  #endif
236 +#include <limits.h>
237  
238  #include "wget.h"
239  #include "utils.h"
240 @@ -340,6 +345,137 @@
241    xfree (respline);
242    return FTPOK;
243  }
244 +
245 +#ifdef INET6
246 +/* Bind a port and send the appropriate EPRT command to the FTP
247 +   server.  Use acceptport after RETR, to get the socket of data
248 +   connection.  */
249 +uerr_t
250 +ftp_eprt (struct rbuf *rbuf)
251 +{
252 +  uerr_t err;
253 +  char *request, *respline, *bytes;
254 +  int nwritten;
255 +  unsigned short port;
256 +  struct sockaddr_storage ss;
257 +  int sslen;
258 +  char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
259 +  int af;
260 +
261 +  /* Get the address of this side of the connection.  */
262 +  sslen = sizeof(ss);
263 +  if (getsockname(RBUF_FD (rbuf), (struct sockaddr *)&ss, &sslen) < 0)
264 +    return HOSTERR;
265 +  /* Construct the argument of EPRT. */
266 +  if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf),
267 +       NULL, 0, NI_NUMERICHOST) != 0)
268 +    return HOSTERR;
269 +  /* Setting port to 0 lets the system choose a free port.  */
270 +  port = 0;
271 +  /* Bind the port.  */
272 +  err = bindport_af (&port, ((struct sockaddr *)&ss)->sa_family);
273 +  if (err != BINDOK)
274 +    return err;
275 +  sprintf(pbuf, "%u", port);
276 +  af = ((struct sockaddr *)&ss)->sa_family == AF_INET6 ? 2 : 1;
277 +  bytes = (char *)alloca (1 + strlen(hbuf) + strlen(pbuf) + 4 + 1);
278 +  sprintf (bytes, "|%d|%s|%s|", af, hbuf, pbuf);
279 +  /* Send EPRT request.  */
280 +  request = ftp_request ("EPRT", bytes);
281 +  nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
282 +  if (nwritten < 0)
283 +    {
284 +      free (request);
285 +      return WRITEFAILED;
286 +    }
287 +  free (request);
288 +  /* Get appropriate response.  */
289 +  err = ftp_response (rbuf, &respline);
290 +  if (err != FTPOK)
291 +    {
292 +      free (respline);
293 +      return err;
294 +    }
295 +  if (*respline != '2')
296 +    {
297 +      free (respline);
298 +      return FTPPORTERR;
299 +    }
300 +  free (respline);
301 +  return FTPOK;
302 +}
303 +
304 +/* Similar to ftp_eprt, but uses `EPSV' to initiate the passive FTP
305 +   transfer.  Reads the response from server and parses it.  Reads the
306 +   host and port addresses and returns them.  */
307 +uerr_t
308 +ftp_epsv (struct rbuf *rbuf, char *hbuf, unsigned short *pport)
309 +{
310 +  char *request, *respline, *s, *ep, delim;
311 +  long rcv;
312 +  int nwritten;
313 +  uerr_t err;
314 +  struct sockaddr_storage ss;
315 +  int sslen = sizeof(ss);
316 +
317 +  if (getpeername(RBUF_FD (rbuf), (struct sockaddr *)&ss, &sslen) < 0)
318 +    return HOSTERR;
319 +  if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, INET6_ADDRSTRLEN,
320 +       NULL, 0, NI_NUMERICHOST) != 0)
321 +    return HOSTERR;
322 +
323 +  /* Form the request.  */
324 +  request = ftp_request ("EPSV", NULL);
325 +  /* And send it.  */
326 +  nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
327 +  if (nwritten < 0)
328 +    {
329 +      free (request);
330 +      return WRITEFAILED;
331 +    }
332 +  free (request);
333 +  /* Get the server response.  */
334 +  err = ftp_response (rbuf, &respline);
335 +  if (err != FTPOK)
336 +    goto fin;
337 +  if (strncmp(respline, "229", 3) != 0)
338 +    {
339 +      err = FTPNOPASV;
340 +      goto fin;
341 +    }
342 +  /* Parse the request.  */
343 +  s = respline;
344 +  for (s += 4; *s && *s != '('; s++);
345 +  if (!*s)
346 +    {
347 +      err = FTPINVPASV;
348 +      goto fin;
349 +    }
350 +  s++;
351 +  if (s[0] && s[0] == s[1] && s[0] == s[2])
352 +    {
353 +      delim = s[0];
354 +      s += 3;
355 +    }
356 +  else
357 +    {
358 +      err = FTPINVPASV;
359 +      goto fin;
360 +    }
361 +  rcv = strtol (s, &ep, 10);
362 +  if (rcv <= 0 || rcv > USHRT_MAX || *ep != delim)
363 +    {
364 +      err = FTPINVPASV;
365 +      goto fin;
366 +    }
367 +  *pport = (unsigned short)rcv;
368 +  err = FTPOK;
369 +
370 +fin:
371 +  free (respline);
372 +  return err;
373 +}
374 +#endif
375  
376  /* Sends the TYPE request to the server.  */
377  uerr_t
378 diff -ur wget-1.8.1.orig/src/ftp.c wget-1.8.1/src/ftp.c
379 --- wget-1.8.1.orig/src/ftp.c   Tue Dec  4 02:22:05 2001
380 +++ wget-1.8.1/src/ftp.c        Tue Feb 19 03:35:12 2002
381 @@ -33,6 +33,9 @@
382  #include <sys/types.h>
383  #include <assert.h>
384  #include <errno.h>
385 +#include <sys/socket.h>
386 +#include <netinet/in.h>
387 +#include <arpa/inet.h>
388  
389  #include "wget.h"
390  #include "utils.h"
391 @@ -489,6 +492,54 @@
392      {
393        if (opt.ftp_pasv > 0)
394         {
395 +         unsigned short tport;
396 +#ifdef INET6
397 +         char thost[64];
398 +
399 +         if (!opt.conn_inet6)
400 +           goto noepsv;
401 +         if (!opt.server_response)
402 +           logputs (LOG_VERBOSE, "==> EPSV ... ");
403 +         err = ftp_epsv (&con->rbuf, thost, &tport);
404 +         /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV, HOSTERR */
405 +         switch (err)
406 +           {
407 +           case FTPRERR:
408 +             logputs (LOG_VERBOSE, "\n");
409 +             logputs (LOG_NOTQUIET, _("\
410 +Error in server response, closing control connection.\n"));
411 +             break;
412 +           case WRITEFAILED:
413 +             logputs (LOG_VERBOSE, "\n");
414 +             logputs (LOG_NOTQUIET,
415 +                      _("Write failed, closing control connection.\n"));
416 +             break;
417 +           case FTPNOPASV:
418 +             logputs (LOG_VERBOSE, "\n");
419 +             logputs (LOG_NOTQUIET, _("Cannot initiate EPSV transfer.\n"));
420 +             goto tryeprt;
421 +           case FTPINVPASV:
422 +             logputs (LOG_VERBOSE, "\n");
423 +             logputs (LOG_NOTQUIET, _("Cannot parse EPSV response.\n"));
424 +             goto tryeprt;
425 +           case HOSTERR:
426 +             logputs (LOG_VERBOSE, "\n");
427 +             logprintf (LOG_NOTQUIET, "%s: error\n", u->host);
428 +             break;
429 +           case FTPOK:
430 +             /* fine and dandy */
431 +             inet_aton(thost, (struct in_addr *)pasv_addr);
432 +             goto pasvok;
433 +           default:
434 +             abort ();
435 +             break;
436 +           }
437 +         CLOSE (csock);
438 +         rbuf_uninitialize (&con->rbuf);
439 +         return err;
440 +
441 +    noepsv:
442 +#endif
443           if (!opt.server_response)
444             logputs (LOG_VERBOSE, "==> PASV ... ");
445           err = ftp_pasv (&con->rbuf, pasv_addr);
446 @@ -528,10 +579,17 @@
447             }
448           if (err==FTPOK)
449             {
450 -             unsigned short tport;
451 -
452 +#ifdef INET6
453 +             inet_ntop (AF_INET, pasv_addr, thost, sizeof (thost));
454 +#endif
455               tport = (pasv_addr[4] << 8) + pasv_addr[5];
456 +
457 +#ifdef INET6
458 +       pasvok:
459 +             dtsock = connect_to_one (thost, tport, 1);
460 +#else
461               dtsock = connect_to_one (pasv_addr, tport, 1);
462 +#endif
463  
464               if (dtsock < 0)
465                 {
466 @@ -539,7 +597,11 @@
467                   CLOSE (csock);
468                   rbuf_uninitialize (&con->rbuf);
469                   logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"),
470 +#ifdef INET6
471 +                                       thost, tport,
472 +#else
473                              pretty_print_address (pasv_addr), tport,
474 +#endif
475                              strerror (save_errno));
476                   return save_errno == ECONNREFUSED ? CONREFUSED : CONERROR;
477                 }
478 @@ -552,6 +614,61 @@
479  
480        if (!passive_mode_open)   /* Try to use a port command if PASV failed */
481         {
482 +#ifdef INET6
483 +         if (!opt.conn_inet6)
484 +           goto noeprt;
485 +    tryeprt:
486 +         if (!opt.server_response)
487 +           logputs (LOG_VERBOSE, "==> EPRT ... ");
488 +         err = ftp_eprt (&con->rbuf);
489 +         /* FTPRERR, WRITEFAILED, bindport (CONSOCKERR, CONPORTERR, BINDERR,
490 +            LISTENERR), HOSTERR, FTPPORTERR */
491 +         switch (err)
492 +           {
493 +           case FTPRERR:
494 +             logputs (LOG_VERBOSE, "\n");
495 +             logputs (LOG_NOTQUIET, _("\
496 +Error in server response, closing control connection.\n"));
497 +             break;
498 +           case WRITEFAILED:
499 +             logputs (LOG_VERBOSE, "\n");
500 +             logputs (LOG_NOTQUIET,
501 +                      _("Write failed, closing control connection.\n"));
502 +             break;
503 +           case CONSOCKERR:
504 +             logputs (LOG_VERBOSE, "\n");
505 +             logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
506 +             break;
507 +           case CONPORTERR: case BINDERR: case LISTENERR:
508 +             /* What now?  These problems are local...  */
509 +             logputs (LOG_VERBOSE, "\n");
510 +             logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
511 +                        strerror (errno));
512 +             closeport (dtsock);
513 +             return err;
514 +             break;
515 +           case HOSTERR:
516 +             logputs (LOG_VERBOSE, "\n");
517 +             logprintf (LOG_NOTQUIET, "%s: error\n", u->host);
518 +             break;
519 +           case FTPPORTERR:
520 +             logputs (LOG_VERBOSE, "\n");
521 +             logputs (LOG_NOTQUIET, _("Invalid EPRT.\n"));
522 +             break;
523 +           case FTPOK:
524 +             /* fine and dandy */
525 +             goto portok;
526 +           default:
527 +             abort ();
528 +             break;
529 +           } /* eprt switch */
530 +         CLOSE (csock);
531 +         closeport (dtsock);
532 +         rbuf_uninitialize (&con->rbuf);
533 +         return err;
534 +
535 +    noeprt:
536 +#endif
537           if (!opt.server_response)
538             logputs (LOG_VERBOSE, "==> PORT ... ");
539           err = ftp_port (&con->rbuf);
540 @@ -608,6 +725,9 @@
541               abort ();
542               break;
543             } /* port switch */
544 +#ifdef INET6
545 +       portok:
546 +#endif
547           if (!opt.server_response)
548             logputs (LOG_VERBOSE, _("done.    "));
549         } /* dtsock == -1 */
550 diff -ur wget-1.8.1.orig/src/ftp.h wget-1.8.1/src/ftp.h
551 --- wget-1.8.1.orig/src/ftp.h   Thu Nov 22 09:24:27 2001
552 +++ wget-1.8.1/src/ftp.h        Tue Feb 19 00:32:35 2002
553 @@ -37,6 +37,10 @@
554  uerr_t ftp_login PARAMS ((struct rbuf *, const char *, const char *));
555  uerr_t ftp_port PARAMS ((struct rbuf *));
556  uerr_t ftp_pasv PARAMS ((struct rbuf *, unsigned char *));
557 +#ifdef INET6
558 +uerr_t ftp_eprt PARAMS ((struct rbuf *));
559 +uerr_t ftp_epsv PARAMS ((struct rbuf *, char *, unsigned short *));
560 +#endif
561  uerr_t ftp_type PARAMS ((struct rbuf *, int));
562  uerr_t ftp_cwd PARAMS ((struct rbuf *, const char *));
563  uerr_t ftp_retr PARAMS ((struct rbuf *, const char *));
564 diff -ur wget-1.8.1.orig/src/host.c wget-1.8.1/src/host.c
565 --- wget-1.8.1.orig/src/host.c  Tue Dec 11 17:32:57 2001
566 +++ wget-1.8.1/src/host.c       Wed Feb 13 04:14:11 2002
567 @@ -77,7 +77,11 @@
568  
569  struct address_list {
570    int count;                   /* number of adrresses */
571 +#ifdef INET6
572 +  struct addrinfo *addresses;
573 +#else
574    ipv4_address *addresses;     /* pointer to the string of addresses */
575 +#endif
576  
577    int faulty;                  /* number of addresses known not to
578                                    work. */
579 @@ -100,8 +104,17 @@
580  address_list_copy_one (struct address_list *al, int index,
581                        unsigned char *ip_store)
582  {
583 +#ifdef INET6
584 +  struct addrinfo *ai;
585 +  assert (index >= al->faulty && index < al->count);
586 +  for (ai = al->addresses; ai; ai = ai->ai_next, index--)
587 +    if (index <= 0)
588 +      break;
589 +  memcpy (ip_store, ai, sizeof (*ai));
590 +#else
591    assert (index >= al->faulty && index < al->count);
592    memcpy (ip_store, al->addresses + index, sizeof (ipv4_address));
593 +#endif
594  }
595  
596  /* Check whether two address lists have all their IPs in common.  */
597 @@ -109,12 +122,27 @@
598  int
599  address_list_match_all (struct address_list *al1, struct address_list *al2)
600  {
601 +#ifdef INET6
602 +  struct addrinfo *ai1, *ai2;
603 +#endif
604    if (al1 == al2)
605      return 1;
606    if (al1->count != al2->count)
607      return 0;
608 +#ifdef INET6
609 +  for (ai1 = al1->addresses, ai2 = al2->addresses; ai1;
610 +       ai1 = ai1->ai_next, ai2 = ai2->ai_next)
611 +    {
612 +      if (ai1->ai_addrlen != ai2->ai_addrlen)
613 +       return 0;
614 +      if (memcmp (ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen))
615 +       return 0;
616 +    }
617 +  return 1;
618 +#else
619    return 0 == memcmp (al1->addresses, al2->addresses,
620                       al1->count * sizeof (ipv4_address));
621 +#endif
622  }
623  
624  /* Mark the INDEXth element of AL as faulty, so that the next time
625 @@ -141,26 +169,44 @@
626     as returned by gethostbyname.  */
627  
628  static struct address_list *
629 +#ifdef INET6
630 +address_list_new (struct addrinfo *ai)
631 +{
632 +  struct addrinfo *res;
633 +#else
634  address_list_new (char **h_addr_list)
635  {
636 -  int count = 0, i;
637 +  int i;
638 +#endif
639 +  int count = 0;
640  
641    struct address_list *al = xmalloc (sizeof (struct address_list));
642  
643 +#ifdef INET6
644 +  for (res = ai; res; res = res->ai_next)
645 +#else
646    while (h_addr_list[count])
647 +#endif
648      ++count;
649    assert (count > 0);
650    al->count     = count;
651    al->faulty    = 0;
652 +#ifdef INET6
653 +  al->addresses = ai;
654 +#else
655    al->addresses = xmalloc (count * sizeof (ipv4_address));
656 +#endif
657    al->refcount  = 1;
658  
659 +#ifndef INET6
660    for (i = 0; i < count; i++)
661      memcpy (al->addresses + i, h_addr_list[i], sizeof (ipv4_address));
662 +#endif
663  
664    return al;
665  }
666  
667 +#ifndef INET6
668  /* Like address_list_new, but initialized with only one address. */
669  
670  static struct address_list *
671 @@ -175,11 +221,16 @@
672  
673    return al;
674  }
675 +#endif
676  
677  static void
678  address_list_delete (struct address_list *al)
679  {
680 +#ifdef INET6
681 +  freeaddrinfo (al->addresses);
682 +#else
683    xfree (al->addresses);
684 +#endif
685    xfree (al);
686  }
687  
688 @@ -203,6 +254,17 @@
689  {
690    return inet_ntoa (*(struct in_addr *)addr);
691  }
692 +#ifdef INET6
693 +int
694 +pretty_print_address_sa (const void *addr, int alen, char *abuf)
695 +{
696 +  int err = getnameinfo((struct sockaddr *)addr, alen, abuf, INET6_ADDRSTRLEN,
697 +                       NULL, 0, NI_NUMERICHOST);
698 +  if (err)
699 +    strcpy (abuf, "???");
700 +  return err;
701 +}
702 +#endif
703  
704  /* Add host name HOST with the address ADDR_TEXT to the cache.
705     ADDR_LIST is a NULL-terminated list of addresses, as in struct
706 @@ -220,10 +282,23 @@
707  #ifdef DEBUG
708    if (opt.debug)
709      {
710 +#ifdef INET6
711 +      struct addrinfo *ai;
712 +#else
713        int i;
714 +#endif
715        debug_logprintf ("Caching %s =>", host);
716 +#ifdef INET6
717 +      for (ai = al->addresses; ai; ai = ai->ai_next)
718 +       {
719 +         char hbuf[INET6_ADDRSTRLEN];
720 +         pretty_print_address_sa (ai->ai_addr, ai->ai_addrlen, hbuf);
721 +         debug_logprintf (" %s", hbuf);
722 +       }
723 +#else
724        for (i = 0; i < al->count; i++)
725         debug_logprintf (" %s", pretty_print_address (al->addresses + i));
726 +#endif
727        debug_logprintf ("\n");
728      }
729  #endif
730 @@ -233,6 +308,24 @@
731  lookup_host (const char *host, int silent)
732  {
733    struct address_list *al = NULL;
734 +#ifdef INET6
735 +  struct addrinfo hints, *res;
736 +  int error;
737 +
738 +  memset(&hints, 0, sizeof(hints));
739 +  if (opt.inet)
740 +    hints.ai_family = AF_INET;
741 +  else if (opt.inet6)
742 +    hints.ai_family = AF_INET6;
743 +  else
744 +    hints.ai_family = AF_UNSPEC;
745 +  hints.ai_socktype = SOCK_STREAM;
746 +  hints.ai_flags = AI_NUMERICHOST;
747 +  /* check `N.N.N.N' or 'X:X:X:X:X:X:X:X'. */
748 +  if (!getaddrinfo(host, NULL, &hints, &res))
749 +    return address_list_new (res);
750 +
751 +#else
752    unsigned long addr;
753    struct hostent *hptr;
754  
755 @@ -254,6 +347,7 @@
756  #endif
757        return address_list_new_one ((char *)&addr + offset);
758      }
759 +#endif /* INET6 */
760  
761    /* By now we know that the host name we got is not of the form
762       d.d.d.d.  Try to find it in our cache of host names.  */
763 @@ -270,12 +364,29 @@
764    if (!silent)
765      logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
766  
767 +#ifdef INET6
768 +  memset(&hints, 0, sizeof(hints));
769 +  if (opt.inet)
770 +    hints.ai_family = AF_INET;
771 +  else if (opt.inet6)
772 +    hints.ai_family = AF_INET6;
773 +  else
774 +    hints.ai_family = AF_UNSPEC;
775 +  hints.ai_socktype = SOCK_STREAM;
776 +  error = getaddrinfo(host, NULL, &hints, &res);
777 +  if (error)
778 +#else
779    /* Look up the host using gethostbyname().  */
780    hptr = gethostbyname (host);
781    if (!hptr)
782 +#endif
783      {
784        if (!silent)
785 +#ifdef INET6
786 +       logprintf (LOG_VERBOSE, _("failed: %s.\n"), gai_strerror(error));
787 +#else
788         logprintf (LOG_VERBOSE, _("failed: %s.\n"), herrmsg (h_errno));
789 +#endif
790        return NULL;
791      }
792  
793 @@ -284,7 +395,11 @@
794  
795    /* Do all systems have h_addr_list, or is it a newer thing?  If the
796       latter, use address_list_new_one.  */
797 +#ifdef INET6
798 +  al = address_list_new (res);
799 +#else
800    al = address_list_new (hptr->h_addr_list);
801 +#endif
802  
803    /* Cache the lookup information. */
804    cache_host_lookup (host, al);
805 diff -ur wget-1.8.1.orig/src/host.h wget-1.8.1/src/host.h
806 --- wget-1.8.1.orig/src/host.h  Tue Dec 11 17:32:58 2001
807 +++ wget-1.8.1/src/host.h       Wed Feb 13 00:14:42 2002
808 @@ -38,6 +38,9 @@
809  /* This was originally going to be a macro, but then every caller
810     would have to #include the netinet stuff.  */
811  char *pretty_print_address PARAMS ((const void *));
812 +#ifdef INET6
813 +int pretty_print_address_sa PARAMS ((const void *, int, char *));
814 +#endif
815  
816  int accept_domain PARAMS ((struct url *));
817  int sufmatch PARAMS ((const char **, const char *));
818 diff -ur wget-1.8.1.orig/src/http.c wget-1.8.1/src/http.c
819 --- wget-1.8.1.orig/src/http.c  Fri Dec 14 01:46:56 2001
820 +++ wget-1.8.1/src/http.c       Sun Jan 27 08:19:10 2002
821 @@ -559,6 +559,11 @@
822    /* Whether keep-alive should be inhibited. */
823    int inhibit_keep_alive;
824  
825 +  /* Whether we need to print the host header with braces around host,
826 +     e.g. "Host: [3ffe:8100:200:2::2]:1234" instead of the usual
827 +     "Host: symbolic-name:1234". */
828 +  int squares_around_host = 0;
829 +
830  #ifdef HAVE_SSL
831    /* initialize ssl_ctx on first run */
832    if (!ssl_ctx)
833 @@ -811,6 +816,9 @@
834         "param=value", full_path will be "/foo/bar?param=value".  */
835      full_path = url_full_path (u);
836  
837 +  if (strchr (u->host, ':'))
838 +    squares_around_host = 1;
839 +
840    /* Allocate the memory for the request.  */
841    request = (char *)alloca (strlen (command)
842                             + strlen (full_path)
843 @@ -832,11 +840,12 @@
844    sprintf (request, "\
845  %s %s HTTP/1.0\r\n\
846  User-Agent: %s\r\n\
847 -Host: %s%s\r\n\
848 +Host: %s%s%s%s\r\n\
849  Accept: %s\r\n\
850  %s%s%s%s%s%s%s%s\r\n",
851            command, full_path,
852 -          useragent, u->host,
853 +          useragent,
854 +          squares_around_host ? "[" : "", u->host, squares_around_host ? "]" : "",
855            port_maybe ? port_maybe : "",
856            HTTP_ACCEPT,
857            request_keep_alive ? request_keep_alive : "",
858 diff -ur wget-1.8.1.orig/src/init.c wget-1.8.1/src/init.c
859 --- wget-1.8.1.orig/src/init.c  Fri Dec 14 04:19:03 2001
860 +++ wget-1.8.1/src/init.c       Tue Feb 19 02:45:18 2002
861 @@ -38,6 +38,7 @@
862  #else
863  # include <sys/socket.h>
864  # include <netinet/in.h>
865 +# include <netdb.h>
866  #ifndef __BEOS__
867  # include <arpa/inet.h>
868  #endif
869 @@ -142,6 +143,10 @@
870    { "ignorelength",    &opt.ignore_length,     cmd_boolean },
871    { "ignoretags",      &opt.ignore_tags,       cmd_vector },
872    { "includedirectories", &opt.includes,       cmd_directory_vector },
873 +#ifdef INET6
874 +  { "inet",            &opt.inet,              cmd_boolean },
875 +  { "inet6",           &opt.inet6,             cmd_boolean },
876 +#endif
877    { "input",           &opt.input_filename,    cmd_file },
878    { "killlonger",      &opt.kill_longer,       cmd_boolean },
879    { "limitrate",       &opt.limit_rate,        cmd_bytes },
880 @@ -526,10 +531,18 @@
881  cmd_address (const char *com, const char *val, void *closure)
882  {
883    struct address_list *al;
884 +#ifdef INET6
885 +  struct addrinfo ai;
886 +  struct sockaddr_storage ss;
887 +  int slen;
888 +#else
889    struct sockaddr_in sin;
890 +#endif
891    struct sockaddr_in **target = (struct sockaddr_in **)closure;
892  
893 +#ifndef INET6
894    memset (&sin, '\0', sizeof (sin));
895 +#endif
896  
897    al = lookup_host (val, 1);
898    if (!al)
899 @@ -538,16 +551,29 @@
900                exec_name, com, val);
901        return 0;
902      }
903 +#ifdef INET6
904 +  address_list_copy_one (al, 0, (unsigned char *)&ai);
905 +  slen = ai.ai_addrlen;
906 +  memcpy (&ss, ai.ai_addr, slen);
907 +#else
908    address_list_copy_one (al, 0, (unsigned char *)&sin.sin_addr);
909 +#endif
910    address_list_release (al);
911  
912 +#ifndef INET6
913    sin.sin_family = AF_INET;
914    sin.sin_port = 0;
915 +#endif
916  
917    FREE_MAYBE (*target);
918  
919 +#ifdef INET6
920 +  *target = xmalloc (sizeof (ss));
921 +  memcpy (*target, &ss, slen);
922 +#else
923    *target = xmalloc (sizeof (sin));
924    memcpy (*target, &sin, sizeof (sin));
925 +#endif
926  
927    return 1;
928  }
929 diff -ur wget-1.8.1.orig/src/main.c wget-1.8.1/src/main.c
930 --- wget-1.8.1.orig/src/main.c  Mon Dec 10 14:31:44 2001
931 +++ wget-1.8.1/src/main.c       Tue Feb 19 02:41:12 2002
932 @@ -171,6 +171,12 @@
933    -Q,  --quota=NUMBER           set retrieval quota to NUMBER.\n\
934         --limit-rate=RATE        limit download rate to RATE.\n\
935  \n"), stdout);
936 +#ifdef INET6
937 +  fputs (_("\
938 +       --inet                   use IP version 4 socket.\n\
939 +       --inet6                  use IP version 6 socket.\n\
940 +\n"), stdout);
941 +#endif /* INET6 */
942    fputs (_("\
943  Directories:\n\
944    -nd  --no-directories            don\'t create directories.\n\
945 @@ -256,6 +262,10 @@
946      { "help", no_argument, NULL, 'h' },
947      { "html-extension", no_argument, NULL, 'E' },
948      { "ignore-length", no_argument, NULL, 138 },
949 +#ifdef INET6
950 +    { "inet", no_argument, NULL, '4' },
951 +    { "inet6", no_argument, NULL, '6' },
952 +#endif
953      { "mirror", no_argument, NULL, 'm' },
954      { "no-clobber", no_argument, NULL, 141 },
955      { "no-directories", no_argument, NULL, 147 },
956 @@ -407,6 +417,16 @@
957         case 165:
958           setval ("randomwait", "on");
959           break;
960 +#ifdef INET6
961 +       case '4':
962 +         setval ("inet", "on");
963 +         setval ("inet6", "off");
964 +         break;
965 +       case '6':
966 +         setval ("inet6", "on");
967 +         setval ("inet", "off");
968 +         break;
969 +#endif
970         case 'b':
971           setval ("background", "on");
972           break;
973 @@ -703,6 +723,14 @@
974        print_usage ();
975        exit (1);
976      }
977 +#ifdef INET6
978 +  if (opt.inet && opt.inet6)
979 +    {
980 +      printf (_("Can't inet and inet6 be specified at the same time.\n"));
981 +      print_usage ();
982 +      exit (1);
983 +    }
984 +#endif
985    if (opt.timestamping && opt.noclobber)
986      {
987        printf (_("\
988 diff -ur wget-1.8.1.orig/src/options.h wget-1.8.1/src/options.h
989 --- wget-1.8.1.orig/src/options.h       Fri Nov 30 16:39:08 2001
990 +++ wget-1.8.1/src/options.h    Tue Feb 19 02:49:40 2002
991 @@ -153,7 +153,14 @@
992    int page_requisites;         /* Whether we need to download all files
993                                    necessary to display a page properly. */
994  
995 +#ifdef INET6
996 +  int inet;
997 +  int inet6;
998 +  int conn_inet6;              /* connect IPv6? */
999 +  struct sockaddr_storage *bind_address;
1000 +#else
1001    struct sockaddr_in *bind_address; /* What local IP address to bind to. */
1002 +#endif
1003  
1004  #ifdef HAVE_SSL
1005    char *sslcertfile;           /* external client cert to use. */
1006 diff -ur wget-1.8.1.orig/src/url.c wget-1.8.1/src/url.c
1007 --- wget-1.8.1.orig/src/url.c   Sat Dec 15 00:45:59 2001
1008 +++ wget-1.8.1/src/url.c        Sun Jan 27 05:43:17 2002
1009 @@ -111,7 +111,7 @@
1010   RU,  0,  0,  0,   0,  0,  0,  0,   /* @   A   B   C    D   E   F   G   */
1011    0,  0,  0,  0,   0,  0,  0,  0,   /* H   I   J   K    L   M   N   O   */
1012    0,  0,  0,  0,   0,  0,  0,  0,   /* P   Q   R   S    T   U   V   W   */
1013 -  0,  0,  0,  U,   U,  U,  U,  0,   /* X   Y   Z   [    \   ]   ^   _   */
1014 +  0,  0,  0, RU,   U, RU,  U,  0,   /* X   Y   Z   [    \   ]   ^   _   */
1015    U,  0,  0,  0,   0,  0,  0,  0,   /* `   a   b   c    d   e   f   g   */
1016    0,  0,  0,  0,   0,  0,  0,  0,   /* h   i   j   k    l   m   n   o   */
1017    0,  0,  0,  0,   0,  0,  0,  0,   /* p   q   r   s    t   u   v   w   */
1018 @@ -528,6 +528,11 @@
1019    memcpy (*user, str, len);
1020    (*user)[len] = '\0';
1021  
1022 +  if (*user)
1023 +    decode_string (*user);
1024 +  if (*passwd)
1025 +    decode_string (*passwd);
1026 +
1027    return 1;
1028  }
1029  
1030 @@ -617,16 +622,20 @@
1031  }
1032  
1033  static char *parse_errors[] = {
1034 -#define PE_NO_ERROR            0
1035 +#define PE_NO_ERROR                    0
1036    "No error",
1037 -#define PE_UNSUPPORTED_SCHEME 1
1038 +#define PE_UNSUPPORTED_SCHEME          1
1039    "Unsupported scheme",
1040 -#define PE_EMPTY_HOST          2
1041 +#define PE_EMPTY_HOST                  2
1042    "Empty host",
1043 -#define PE_BAD_PORT_NUMBER     3
1044 +#define PE_BAD_PORT_NUMBER             3
1045    "Bad port number",
1046 -#define PE_INVALID_USER_NAME   4
1047 -  "Invalid user name"
1048 +#define PE_INVALID_USER_NAME           4
1049 +  "Invalid user name",
1050 +#define PE_UNTERMINATED_IPV6_ADDRESS   5
1051 +  "Unterminated IPv6 numeric address",
1052 +#define PE_INVALID_IPV6_ADDRESS                6
1053 +  "Invalid char in IPv6 numeric address"
1054  };
1055  
1056  #define SETERR(p, v) do {                      \
1057 @@ -688,8 +697,45 @@
1058    fragment_b = fragment_e = NULL;
1059  
1060    host_b = p;
1061 -  p = strpbrk_or_eos (p, ":/;?#");
1062 -  host_e = p;
1063 +
1064 +  if (*p == '[')
1065 +    {
1066 +      /* Support http://[::1]/ used by IPv6. */
1067 +      int invalid = 0;
1068 +      ++p;
1069 +      while (1)
1070 +       {
1071 +         char c = *p++;
1072 +         switch (c)
1073 +           {
1074 +           case ']':
1075 +             goto out;
1076 +           case '\0':
1077 +             SETERR (error, PE_UNTERMINATED_IPV6_ADDRESS);
1078 +             return NULL;
1079 +           case ':': case '.':
1080 +             break;
1081 +           default:
1082 +             if (ISXDIGIT (c))
1083 +               break;
1084 +             invalid = 1;
1085 +           }
1086 +       }
1087 +    out:
1088 +      if (invalid)
1089 +       {
1090 +         SETERR (error, PE_INVALID_IPV6_ADDRESS);
1091 +         return NULL;
1092 +       }
1093 +      /* Don't include brackets in [host_b, host_p). */
1094 +      ++host_b;
1095 +      host_e = p - 1;
1096 +    }
1097 +  else
1098 +    {
1099 +      p = strpbrk_or_eos (p, ":/;?#");
1100 +      host_e = p;
1101 +    }
1102  
1103    if (host_b == host_e)
1104      {
1105 @@ -1575,6 +1621,37 @@
1106           memcpy (constr + baselength, link, linklength);
1107           constr[baselength + linklength] = '\0';
1108         }
1109 +      else if (linklength > 1 && *link == '/' && *(link + 1) == '/')
1110 +       {
1111 +         /* LINK begins with "//" and so is a net path: we need to
1112 +            replace everything after (and including) the double slash
1113 +            with LINK. */
1114 +
1115 +         /* uri_merge("foo", "//new/bar")            -> "//new/bar"      */
1116 +         /* uri_merge("//old/foo", "//new/bar")      -> "//new/bar"      */
1117 +         /* uri_merge("http://old/foo", "//new/bar") -> "http://new/bar" */
1118 +
1119 +         int span;
1120 +         const char *slash;
1121 +         const char *start_insert;
1122 +
1123 +         /* Look for first slash. */
1124 +         slash = memchr (base, '/', end - base);
1125 +         /* If found slash and it is a double slash, then replace
1126 +            from this point, else default to replacing from the
1127 +            beginning.  */
1128 +         if (slash && *(slash + 1) == '/')
1129 +           start_insert = slash;
1130 +         else
1131 +           start_insert = base;
1132 +
1133 +         span = start_insert - base;
1134 +         constr = (char *)xmalloc (span + linklength + 1);
1135 +         if (span)
1136 +           memcpy (constr, base, span);
1137 +         memcpy (constr + span, link, linklength);
1138 +         constr[span + linklength] = '\0';
1139 +       }
1140        else if (*link == '/')
1141         {
1142           /* LINK is an absolute path: we need to replace everything
1143 @@ -1734,6 +1811,8 @@
1144    char *scheme_str = supported_schemes[url->scheme].leading_string;
1145    int fplen = full_path_length (url);
1146  
1147 +  int brackets_around_host = 0;
1148 +
1149    assert (scheme_str != NULL);
1150  
1151    /* Make sure the user name and password are quoted. */
1152 @@ -1749,8 +1828,12 @@
1153         }
1154      }
1155  
1156 +  if (strchr (url->host, ':'))
1157 +    brackets_around_host = 1;
1158 +
1159    size = (strlen (scheme_str)
1160           + strlen (url->host)
1161 +         + (brackets_around_host ? 2 : 0)
1162           + fplen
1163           + 1);
1164    if (url->port != scheme_port)
1165 @@ -1776,7 +1859,11 @@
1166        *p++ = '@';
1167      }
1168  
1169 +  if (brackets_around_host)
1170 +    *p++ = '[';
1171    APPEND (p, url->host);
1172 +  if (brackets_around_host)
1173 +    *p++ = ']';
1174    if (url->port != scheme_port)
1175      {
1176        *p++ = ':';
1177 --- wget-1.8.2/configure.in.orig        Wed Jun  5 20:57:48 2002
1178 +++ wget-1.8.2/configure.in     Wed Jun  5 21:02:38 2002
1179 @@ -74,6 +74,11 @@
1180  DEBUG=$enableval, DEBUG=yes)
1181  test x"${DEBUG}" = xyes && AC_DEFINE(DEBUG,,[Support for debugging output])
1182  
1183 +AC_ARG_ENABLE(ipv6,
1184 +[  --enable-ipv6           enable IPv6 support],
1185 +INET6=$enableval, INET6=yes)
1186 +test x"${INET6}" = xyes && AC_DEFINE(INET6,,[IPv6 support])
1187 +
1188  wget_need_md5=no
1189  
1190  case "${USE_OPIE}${USE_DIGEST}" in
1191 --- wget-1.8.2/po/pl.po.orig    Sun May 19 05:18:59 2002
1192 +++ wget-1.8.2/po/pl.po Wed Jun  5 21:07:23 2002
1193 @@ -1227,3 +1227,29 @@
1194  #, c-format
1195  msgid "Failed to unlink symlink `%s': %s\n"
1196  msgstr "Nie uda³o siê usun±æ dowi±zania symbolicznego `%s': %s\n"
1197 +
1198 +#: src/ftp.c:529
1199 +msgid "Cannot initiate EPSV transfer.\n"
1200 +msgstr "Nie mo¿na rozpocz±æ transferu EPSV.\n"
1201 +
1202 +#: src/ftp.c:533
1203 +msgid "Cannot parse EPSV response.\n"
1204 +msgstr "Nie powiod³a siê analiza odpowiedzi EPSV.\n"
1205 +
1206 +#: src/ftp.c:666
1207 +msgid "Invalid EPRT.\n"
1208 +msgstr "B³êdny EPRT.\n"
1209 +
1210 +#: src/main.c:185
1211 +msgid ""
1212 +"       --inet                   use IP version 4 socket.\n"
1213 +"       --inet6                  use IP version 6 socket.\n"
1214 +"\n"
1215 +msgstr ""
1216 +"       --inet                   u¿ywa gniazd IP w wersji 4.\n"
1217 +"       --inet6                  u¿ywa gniazd IP w wersji 6.\n"
1218 +"\n"
1219 +
1220 +#: src/main.c:739
1221 +msgid "Can't inet and inet6 be specified at the same time.\n"
1222 +msgstr "Opcje inet i inet6 nie mog± byæ podane jednocze¶nie.\n"
This page took 0.29361 seconds and 3 git commands to generate.