]> git.pld-linux.org Git - packages/ncftp.git/blob - ncftp-kame-v6.patch
03b2ef5e5b27c49bc116ed33745ce5372a5493a5
[packages/ncftp.git] / ncftp-kame-v6.patch
1 Index: ncftp3/README.v6
2 diff -u /dev/null ncftp3/README.v6:1.1
3 --- /dev/null   Mon Nov  9 21:52:32 2009
4 +++ ncftp3/README.v6    Tue Aug  6 14:06:35 2002
5 @@ -0,0 +1,2 @@
6 +If you have problem/trouble/suggestion for IPv6 related code,
7 +Please contact to core@kame.net
8 Index: ncftp3/configure.in
9 diff -u ncftp3/configure.in:1.1.1.17 ncftp3/configure.in:1.28
10 --- ncftp3/configure.in:1.1.1.17        Thu Nov  5 16:20:41 2009
11 +++ ncftp3/configure.in Thu Nov  5 16:47:08 2009
12 @@ -13,8 +13,6 @@
13  wi_ARG_ENABLE_SSP
14  wi_ARG_DISABLE_MACOSX_UNIVERSAL
15  
16 -
17 -
18  dnl ---------------------------------------------------------------------------
19  dnl Environment and compiler settings.
20  dnl ---------------------------------------------------------------------------
21 @@ -113,6 +111,81 @@
22  wi_HEADER_SYS_SELECT_H dnl                             # sio
23  
24  
25 +dnl ---------------------------------------------------------------------------
26 +dnl Checks for IPv6.
27 +dnl ---------------------------------------------------------------------------
28 +dnl
29 +AC_MSG_CHECKING([whether to enable ipv6])
30 +AC_ARG_ENABLE(ipv6,
31 +[  --enable-ipv6               Enable ipv6 (with ipv4) support
32 +  --disable-ipv6               Disable ipv6 support],
33 +[ case "$enableval" in
34 +  no)
35 +       AC_MSG_RESULT(no)
36 +       ipv6=no
37 +       ;;
38 +  *)   AC_MSG_RESULT(yes)
39 +       AC_DEFINE(ENABLE_IPV6)
40 +       ipv6=yes
41 +       ;;
42 +  esac ],
43 +
44 +  AC_TRY_RUN([ /* AF_INET6 avalable check */
45 +#define INET6
46 +#include <sys/types.h>
47 +#include <sys/socket.h>
48 +main()
49 +{
50 + if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
51 +   exit(1);
52 + else
53 +   exit(0);
54 +}
55 +],
56 +  AC_MSG_RESULT(yes)
57 +  AC_DEFINE(ENABLE_IPV6)
58 +  ipv6=yes,
59 +  AC_MSG_RESULT(no)
60 +  ipv6=no,
61 +  AC_MSG_RESULT(no)
62 +  ipv6=no
63 +))
64 +
65 +AC_CHECK_FUNC(getaddrinfo, [
66 +  AC_DEFINE(HAVE_GETADDRINFO)], [
67 +  LIBOBJS="$LIBOBJS getaddrinfo.o"
68 +  LIBSOBJS="$LIBSOBJS getaddrinfo.so"
69 +])
70 +
71 +AC_CHECK_FUNC(getnameinfo, [
72 +  AC_DEFINE(HAVE_GETNAMEINFO)], [
73 +  LIBOBJS="$LIBOBJS getnameinfo.o"
74 +  LIBSOBJS="$LIBSOBJS getnameinfo.so"
75 +])
76 +
77 +# check if sockaddr has sa_len member
78 +AC_MSG_CHECKING(if sockaddr has sa_len member)
79 +AC_TRY_COMPILE([#include <sys/types.h>
80 +#include <sys/socket.h>],
81 +[struct sockaddr x;
82 +x.sa_len = 0;],
83 +       AC_MSG_RESULT(yes)
84 +       AC_DEFINE(HAVE_SOCKADDR_SA_LEN),
85 +       AC_MSG_RESULT(no))
86 +
87 +# check if sockaddr_storage has ss_family member
88 +AC_MSG_CHECKING(if sockaddr_storage has ss_family member)
89 +AC_TRY_COMPILE([#include <sys/types.h>
90 +#include <sys/socket.h>],
91 +[struct sockaddr_storage x;
92 +x.__ss_family = 0;],
93 +       AC_MSG_RESULT(yes)
94 +       AC_DEFINE(HAVE_SOCKADDR_STORAGE_SS_FAMILY),
95 +       AC_MSG_RESULT(no)
96 +       AC_DEFINE(HAVE_SOCKADDR_STORAGE___SS_FAMILY)
97 +       CPPFLAGS="$CPPFLAGS -D__ss_family=ss_family -D__ss_len=ss_len")
98 +
99 +CPPFLAGS="-I$MAINDIR $CPPFLAGS"
100  
101  dnl ---------------------------------------------------------------------------
102  dnl Checks for library functions.
103 @@ -258,6 +331,8 @@
104  AC_SUBST(Z30)
105  AC_SUBST(Z31)
106  AC_SUBST(LIBSET)
107 +AC_SUBST(LIBOBJS)
108 +AC_SUBST(LIBSOBJS)
109  AC_SUBST(MAINDIR)
110  AC_SUBST(NCFTP_VERSION)
111  AC_SUBST(LIBNCFTP_VERSION)
112 Index: ncftp3/Strn/tester
113 Index: ncftp3/libncftp/addrinfo.h
114 diff -u /dev/null ncftp3/libncftp/addrinfo.h:1.2
115 --- /dev/null   Mon Nov  9 21:52:32 2009
116 +++ ncftp3/libncftp/addrinfo.h  Tue Nov 20 02:53:11 2001
117 @@ -0,0 +1,104 @@
118 +/*
119 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
120 + * All rights reserved.
121 + * 
122 + * Redistribution and use in source and binary forms, with or without
123 + * modification, are permitted provided that the following conditions
124 + * are met:
125 + * 1. Redistributions of source code must retain the above copyright
126 + *    notice, this list of conditions and the following disclaimer.
127 + * 2. Redistributions in binary form must reproduce the above copyright
128 + *    notice, this list of conditions and the following disclaimer in the
129 + *    documentation and/or other materials provided with the distribution.
130 + * 3. Neither the name of the project nor the names of its contributors
131 + *    may be used to endorse or promote products derived from this software
132 + *    without specific prior written permission.
133 + * 
134 + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
135 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
136 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
137 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
138 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
139 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
140 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
141 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
142 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
143 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
144 + * SUCH DAMAGE.
145 + */
146 +
147 +#ifndef HAVE_GETADDRINFO
148 +
149 +/*
150 + * Error return codes from getaddrinfo()
151 + */
152 +#define        EAI_ADDRFAMILY   1      /* address family for hostname not supported */
153 +#define        EAI_AGAIN        2      /* temporary failure in name resolution */
154 +#define        EAI_BADFLAGS     3      /* invalid value for ai_flags */
155 +#define        EAI_FAIL         4      /* non-recoverable failure in name resolution */
156 +#define        EAI_FAMILY       5      /* ai_family not supported */
157 +#define        EAI_MEMORY       6      /* memory allocation failure */
158 +#define        EAI_NODATA       7      /* no address associated with hostname */
159 +#define        EAI_NONAME       8      /* hostname nor servname provided, or not known */
160 +#define        EAI_SERVICE      9      /* servname not supported for ai_socktype */
161 +#define        EAI_SOCKTYPE    10      /* ai_socktype not supported */
162 +#define        EAI_SYSTEM      11      /* system error returned in errno */
163 +#define EAI_BADHINTS   12
164 +#define EAI_PROTOCOL   13
165 +#define EAI_MAX                14
166 +
167 +/*
168 + * Flag values for getaddrinfo()
169 + */
170 +#define        AI_PASSIVE      0x00000001 /* get address to use bind() */
171 +#define        AI_CANONNAME    0x00000002 /* fill ai_canonname */
172 +#define        AI_NUMERICHOST  0x00000004 /* prevent name resolution */
173 +/* valid flags for addrinfo */
174 +#define        AI_MASK         (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
175 +
176 +#define        AI_ALL          0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
177 +#define        AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
178 +#define        AI_ADDRCONFIG   0x00000400 /* only if any address is assigned */
179 +#define        AI_V4MAPPED     0x00000800 /* accept IPv4-mapped IPv6 address */
180 +/* special recommended flags for getipnodebyname */
181 +#define        AI_DEFAULT      (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
182 +
183 +/*
184 + * Constants for getnameinfo()
185 + */
186 +#define        NI_MAXHOST      1025
187 +#define        NI_MAXSERV      32
188 +
189 +/*
190 + * Flag values for getnameinfo()
191 + */
192 +#define        NI_NOFQDN       0x00000001
193 +#define        NI_NUMERICHOST  0x00000002
194 +#define        NI_NAMEREQD     0x00000004
195 +#define        NI_NUMERICSERV  0x00000008
196 +#define        NI_DGRAM        0x00000010
197 +
198 +struct addrinfo {
199 +       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
200 +       int     ai_family;      /* PF_xxx */
201 +       int     ai_socktype;    /* SOCK_xxx */
202 +       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
203 +       size_t  ai_addrlen;     /* length of ai_addr */
204 +       char    *ai_canonname;  /* canonical name for hostname */
205 +       struct sockaddr *ai_addr;       /* binary address */
206 +       struct addrinfo *ai_next;       /* next structure in linked list */
207 +};
208 +
209 +struct sockaddr_storage {
210 +#ifdef HAVE_SOCKADDR_SA_LEN
211 +       u_int8_t        ss_len;         /* address length */
212 +       u_int8_t        ss_family;      /* address family */
213 +#else
214 +       u_int16_t       ss_family;
215 +#endif
216 +       u_int8_t fill[126];
217 +};
218 +
219 +extern void freehostent __P((struct hostent *));
220 +extern char *gai_strerror __P((int));
221 +#endif
222 --- ncftp-3.2.5/libncftp/ftp.c.orig     2009-10-24 01:31:22.000000000 +0200
223 +++ ncftp-3.2.5/libncftp/ftp.c  2011-03-27 15:36:20.209737273 +0200
224 @@ -50,6 +50,18 @@
225  #      define DisposeSocket(a) close(a)
226  #endif
227  
228 +#ifndef HAVE_SOCKADDR_SA_LEN
229 +#ifndef SA_LEN
230 +#ifdef ENABLE_IPV6
231 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
232 +               : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
233 +               : -1))
234 +#else  /* ENABLE_IPV6 */
235 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
236 +#endif /* ENABLE_IPV6 */
237 +#endif /* SA_LEN */
238 +#endif /* HAVE_SOCKADDR_SA_LEN */
239 +
240  static const char *gPrivateNetworks[] = {
241         "192.168.",
242         "10.",
243 @@ -101,9 +113,9 @@
244  
245  
246  static int
247 -GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
248 +GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr *saddr)
249  {
250 -       sockaddr_size_t len = (sockaddr_size_t) sizeof (struct sockaddr_in);
251 +       sockaddr_size_t len = (sockaddr_size_t) sizeof (struct sockaddr_storage);
252         int result = 0;
253  
254         if (getsockname(sockfd, (struct sockaddr *)saddr, &len) < 0) {
255 @@ -138,16 +150,16 @@
256  OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
257  {
258         struct sockaddr_in localAddr;
259 -       struct in_addr ip_address;
260         int err = 0;
261         int result;
262         int oerrno;
263         volatile int sockfd = -1;
264         volatile int sock2fd = -1;
265         ResponsePtr rp = NULL;
266 -       char **volatile curaddr;
267 -       int hpok, hprc;
268 -       struct hostent hp;
269 +       struct addrinfo hints;
270 +       struct addrinfo *res, *res0;
271 +       int error;
272 +       char buf[NI_MAXHOST];
273         char *volatile fhost;
274         unsigned int fport;
275  #ifndef NO_SIGNALS
276 @@ -181,35 +193,17 @@
277         cip->cin = NULL;
278         cip->cout = NULL;
279  
280 -       /* Make sure we use network byte-order. */
281 -       fport = (unsigned int) htons((unsigned short) fport);
282 -
283 -       cip->servCtlAddr.sin_port = (unsigned short) fport;
284 -
285 -       hprc = GetHostEntry(&hp, fhost, &ip_address, cip->buf, cip->bufSize);
286 -       if (hprc != 0) {
287 -               hpok = 0;
288 -               /* Okay, no Host entry, but maybe we have a numeric address
289 -                * in ip_address we can try.
290 -                */
291 -#ifdef DNSSEC_LOCAL_VALIDATION
292 -               if (hprc == -2) {
293 -                       FTPLogError(cip, kDontPerror, "%s: untrusted DNS response.\n", fhost);
294 -                       cip->errNo = kErrHostUnknown;
295 -                       return (kErrHostUnknown);
296 -               }
297 -#endif
298 -               if (ip_address.s_addr == INADDR_NONE) {
299 -                       FTPLogError(cip, kDontPerror, "%s: unknown host.\n", fhost);
300 -                       cip->errNo = kErrHostUnknown;
301 -                       return (kErrHostUnknown);
302 -               }
303 -               cip->servCtlAddr.sin_family = AF_INET;
304 -               cip->servCtlAddr.sin_addr.s_addr = ip_address.s_addr;
305 -       } else {
306 -               hpok = 1;
307 -               cip->servCtlAddr.sin_family = hp.h_addrtype;
308 -               /* We'll fill in the rest of the structure below. */
309 +       memset(&hints, 0, sizeof(hints));
310 +       hints.ai_flags = AI_CANONNAME;
311 +       hints.ai_family = PF_UNSPEC;
312 +       hints.ai_socktype = SOCK_STREAM;
313 +       hints.ai_protocol = IPPROTO_TCP;
314 +       sprintf(buf, "%d\0", fport);
315 +       error = getaddrinfo(fhost, buf, &hints, &res0);
316 +       if (error) {
317 +               FTPLogError(cip, kDontPerror, "%s: %s.\n", fhost, gai_strerror(error));
318 +               cip->errNo = kErrHostUnknown;
319 +               return (kErrHostUnknown);
320         }
321         
322         /* After obtaining a socket, try to connect it to a remote
323 @@ -218,23 +212,24 @@
324          * every address in the list from the host entry.
325          */
326  
327 -       if (hpok == 0) {
328 -               /* Since we're given a single raw address, and not a host entry,
329 -                * we can only try this one address and not any other addresses
330 -                * that could be present for a site with a host entry.
331 -                */
332 -
333 -               if ((sockfd = socket(cip->servCtlAddr.sin_family, SOCK_STREAM, 0)) < 0) {
334 +       /* We can try each address in the list.  We'll quit when we
335 +        * run out of addresses to try or get a successful connection.
336 +        */
337 +       for (res = res0; res; res = res->ai_next) {
338 +               (void) memcpy(&cip->servCtlAddr, res->ai_addr, (size_t)res->ai_addrlen);
339 +               if ((sockfd = socket(cip->servCtlAddr.ss_family, SOCK_STREAM, 0)) < 0) {
340 +                       if (res0->ai_next)
341 +                               continue;
342                         FTPLogError(cip, kDoPerror, "Could not get a socket.\n");
343                         cip->errNo = kErrNewStreamSocket;
344                         return (kErrNewStreamSocket);
345                 }
346  
347                 /* On rare occasions, the user may specify a local IP address to use. */
348 -               if (cip->preferredLocalAddr.sin_family != 0) {
349 +               if (cip->preferredLocalAddr.sin_family == AF_INET) {
350                         localAddr = cip->preferredLocalAddr;
351                         localAddr.sin_port = 0;
352 -                       if (BindToEphemeralPortNumber(sockfd, &localAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0) {
353 +                       if (BindToEphemeralPortNumber(sockfd, (struct sockaddr *)&localAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0) {
354                                 FTPLogError(cip, kDoPerror, "Could not bind the control socket");
355                                 result = kErrBindCtrlSocket;
356                                 cip->errNo = kErrBindCtrlSocket;
357 @@ -251,14 +246,14 @@
358                 (void) SetSocketBufSize(sockfd, cip->ctrlSocketRBufSize, cip->ctrlSocketSBufSize);
359  
360  #ifdef NO_SIGNALS
361 -               err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
362 +               err = SConnect(sockfd, (struct sockaddr *)&cip->servCtlAddr, (int) cip->connTimeout);
363  
364 -               if (err < 0) {
365 -                       oerrno = errno;
366 -                       (void) SClose(sockfd, 3);
367 -                       errno = oerrno;
368 -                       sockfd = -1;
369 -               }
370 +               if (err == 0)
371 +                       break;
372 +               oerrno = errno;
373 +               (void) SClose(sockfd, 3);
374 +               errno = oerrno;
375 +               sockfd = -1;
376  #else  /* NO_SIGNALS */
377                 osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
378                 if (cip->connTimeout > 0) {
379 @@ -287,6 +282,8 @@
380                                 Error(vcip, kDontPerror, "Connection attempt canceled.\n");
381                                 (void) kill(getpid(), SIGINT);
382                         } else if (gGotSig == SIGALRM) {
383 +                               if (res0->ai_next)
384 +                                       continue;
385                                 result = vcip->errNo = kErrConnectRetryableErr;
386                                 Error(vcip, kDontPerror, "Connection attempt timed-out.\n");
387                                 (void) kill(getpid(), SIGALRM);
388 @@ -297,7 +294,12 @@
389                         return (result);
390                 } else  {
391                         err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
392 -                                     (int) sizeof (cip->servCtlAddr));
393 +#ifdef HAVE_SOCKADDR_SA_LEN
394 +                                     cip->servCtlAddr.ss_len
395 +#else
396 +                                     SA_LEN((struct sockaddr *)&cip->servCtlAddr)
397 +#endif
398 +                               );
399                         if (cip->connTimeout > 0) {
400                                 (void) alarm(0);
401                                 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
402 @@ -311,106 +313,7 @@
403                         errno = oerrno;
404                         sockfd = -1;
405                 }
406 -#endif /* NO_SIGNALS */
407 -       } else {
408 -               /* We can try each address in the list.  We'll quit when we
409 -                * run out of addresses to try or get a successful connection.
410 -                */
411 -               for (curaddr = hp.h_addr_list; *curaddr != NULL; curaddr++) {
412 -                       if ((sockfd = socket(cip->servCtlAddr.sin_family, SOCK_STREAM, 0)) < 0) {
413 -                               FTPLogError(cip, kDoPerror, "Could not get a socket.\n");
414 -                               cip->errNo = kErrNewStreamSocket;
415 -                               return (kErrNewStreamSocket);
416 -                       }
417 -                       /* This could overwrite the address field in the structure,
418 -                        * but this is okay because the structure has a junk field
419 -                        * just for this purpose.
420 -                        */
421 -                       (void) memcpy(&cip->servCtlAddr.sin_addr, *curaddr, (size_t) hp.h_length);
422 -
423 -                       /* On rare occasions, the user may specify a local IP address to use. */
424 -                       if (cip->preferredLocalAddr.sin_family != 0) {
425 -                               localAddr = cip->preferredLocalAddr;
426 -                               localAddr.sin_port = 0;
427 -                               if (BindToEphemeralPortNumber(sockfd, &localAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0) {
428 -                                       FTPLogError(cip, kDoPerror, "Could not bind the control socket");
429 -                                       result = kErrBindCtrlSocket;
430 -                                       cip->errNo = kErrBindCtrlSocket;
431 -                                       (void) SClose(sockfd, 3);
432 -                                       return (kErrBindCtrlSocket);
433 -                               }
434 -                       }
435 -
436 -                       /* This doesn't do anything if you left these
437 -                        * at their defaults (zero).  Otherwise it
438 -                        * tries to set the buffer size to the
439 -                        * size specified.
440 -                        */
441 -                       (void) SetSocketBufSize(sockfd, cip->ctrlSocketRBufSize, cip->ctrlSocketSBufSize);
442 -
443 -#ifdef NO_SIGNALS
444 -                       err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
445 -
446 -                       if (err == 0)
447 -                               break;
448 -                       oerrno = errno;
449 -                       (void) SClose(sockfd, 3);
450 -                       errno = oerrno;
451 -                       sockfd = -1;
452 -#else  /* NO_SIGNALS */
453 -
454 -                       osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
455 -                       if (cip->connTimeout > 0) {
456 -                               osigalrm = (volatile FTPSigProc) signal(SIGALRM, CancelConnect);
457 -                               (void) alarm(cip->connTimeout);
458 -                       }
459 -
460 -                       vcip = cip;
461 -#ifdef HAVE_SIGSETJMP
462 -                       sj = sigsetjmp(gCancelConnectJmp, 1);
463 -#else
464 -                       sj = setjmp(gCancelConnectJmp);
465 -#endif /* HAVE_SIGSETJMP */
466 -
467 -                       if (sj != 0) {
468 -                               /* Interrupted by a signal. */
469 -                               (void) DisposeSocket(sockfd);
470 -                               (void) signal(SIGINT, (FTPSigProc) osigint);
471 -                               if (vcip->connTimeout > 0) {
472 -                                       (void) alarm(0);
473 -                                       (void) signal(SIGALRM, (FTPSigProc) osigalrm);
474 -                               }
475 -                               if (gGotSig == SIGINT) {
476 -                                       result = vcip->errNo = kErrConnectMiscErr;
477 -                                       Error(vcip, kDontPerror, "Connection attempt canceled.\n");
478 -                                       (void) kill(getpid(), SIGINT);
479 -                               } else if (gGotSig == SIGALRM) {
480 -                                       result = vcip->errNo = kErrConnectRetryableErr;
481 -                                       Error(vcip, kDontPerror, "Connection attempt timed-out.\n");
482 -                                       (void) kill(getpid(), SIGALRM);
483 -                               } else {
484 -                                       result = vcip->errNo = kErrConnectMiscErr;
485 -                                       Error(vcip, kDontPerror, "Connection attempt failed due to an unexpected signal (%d).\n", gGotSig);
486 -                               }
487 -                               return (result);
488 -                       } else {
489 -                               err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
490 -                                             (int) sizeof (cip->servCtlAddr));
491 -                               if (cip->connTimeout > 0) {
492 -                                       (void) alarm(0);
493 -                                       (void) signal(SIGALRM, (FTPSigProc) osigalrm);
494 -                               }
495 -                               (void) signal(SIGINT, (FTPSigProc) osigint);
496 -                       }
497 -
498 -                       if (err == 0)
499 -                               break;
500 -                       oerrno = errno;
501 -                       (void) DisposeSocket(sockfd);
502 -                       errno = oerrno;
503 -                       sockfd = -1;
504  #endif /* NO_SIGNALS */
505 -               }
506         }
507         
508         if (err < 0) {
509 @@ -469,7 +372,7 @@
510         }
511  
512         /* Get our end of the socket address for later use. */
513 -       if ((result = GetSocketAddress(cip, sockfd, &cip->ourCtlAddr)) < 0)
514 +       if ((result = GetSocketAddress(cip, sockfd, (struct sockaddr *)&cip->ourCtlAddr)) < 0)
515                 goto fatal;
516  
517         /* We want Out-of-band data to appear in the regular stream,
518 @@ -540,11 +443,20 @@
519  #endif
520  #endif /* NO_SIGNALS */
521  
522 -       InetNtoA(cip->ip, &cip->servCtlAddr.sin_addr, sizeof(cip->ip));
523 -       if ((hpok == 0) || (hp.h_name == NULL))
524 +       getnameinfo((struct sockaddr*)&cip->servCtlAddr,
525 +#ifdef HAVE_SOCKADDR_SA_LEN
526 +                   cip->servCtlAddr.ss_len,
527 +#else
528 +                   SA_LEN((struct sockaddr *)&cip->servCtlAddr),
529 +#endif
530 +                    buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
531 +       (void) STRNCPY(cip->ip, buf);
532 +       if ((res0 == NULL) || (res0->ai_canonname == NULL))
533                 (void) STRNCPY(cip->actualHost, fhost);
534         else
535 -               (void) STRNCPY(cip->actualHost, (char *) hp.h_name);
536 +               (void) STRNCPY(cip->actualHost, (char *) res0->ai_canonname);
537 +       freeaddrinfo(res0);
538 +       res0 = NULL;
539  
540         /* Read the startup message from the server. */ 
541         rp = InitResponse();
542 @@ -648,6 +560,10 @@
543         CloseFile(&cip->cout);
544         cip->ctrlSocketR = kClosedFileDescriptor;
545         cip->ctrlSocketW = kClosedFileDescriptor;
546 +       if (res0) {
547 +               freeaddrinfo(res0);
548 +               res0 = NULL;
549 +       }
550         return (result);
551  }      /* OpenControlConnection */
552  
553 @@ -741,11 +657,15 @@
554  
555  
556  int
557 -FTPSendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
558 +FTPSendPort(const FTPCIPtr cip, struct sockaddr *saddr)
559  {
560         char *a, *p;
561         int result;
562         ResponsePtr rp;
563 +       struct sockaddr_in *saddr4;
564 +#ifdef ENABLE_IPV6
565 +       struct sockaddr_in6 *saddr6;
566 +#endif
567  
568         rp = InitResponse();
569         if (rp == NULL) {
570 @@ -754,16 +674,46 @@
571                 return (cip->errNo);
572         }
573  
574 -       /* These will point to data in network byte order. */
575 -       a = (char *) &saddr->sin_addr;
576 -       p = (char *) &saddr->sin_port;
577  #define UC(x) (int) (((int) x) & 0xff)
578 +#ifdef ENABLE_IPV6
579 +       if (saddr->sa_family == AF_INET6) {
580 +               char host[NI_MAXHOST];
581 +               char port[NI_MAXSERV];
582 +
583 +               getnameinfo(saddr, sizeof(struct sockaddr_in6), host, sizeof(host),
584 +                           port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
585 +
586 +               saddr6 = (struct sockaddr_in6 *)saddr;
587 +               /* These will point to data in network byte order. */
588 +               a = (char *) &saddr6->sin6_addr;
589 +               p = (char *) &saddr6->sin6_port;
590 +               /* Need to tell the other side which host (the address) and
591 +                * which process (port) on that host to send data to.
592 +                */
593 +               result = RCmd(cip, rp, "EPRT |2|%s|%s|", host, port);
594 +               if (result != 2) {
595 +                       result = RCmd(cip, rp, "LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
596 +                                     UC(a[ 0]), UC(a[ 1]), UC(a[ 2]), UC(a[ 3]),
597 +                                     UC(a[ 4]), UC(a[ 5]), UC(a[ 6]), UC(a[ 7]),
598 +                                     UC(a[ 8]), UC(a[ 9]), UC(a[10]), UC(a[11]),
599 +                                     UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
600 +                                     UC(p[0]), UC(p[1]));
601 +               }
602 +       } else {
603 +#endif
604 +               saddr4 = (struct sockaddr_in *)saddr;
605 +               /* These will point to data in network byte order. */
606 +               a = (char *) &saddr4->sin_addr;
607 +               p = (char *) &saddr4->sin_port;
608  
609 -       /* Need to tell the other side which host (the address) and
610 -        * which process (port) on that host to send data to.
611 -        */
612 -       result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
613 -               UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
614 +               /* Need to tell the other side which host (the address) and
615 +                * which process (port) on that host to send data to.
616 +                */
617 +               result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
618 +                             UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
619 +#ifdef ENABLE_IPV6
620 +       }
621 +#endif
622  
623         DoneWithResponse(cip, rp);
624         if (result < 0) {
625 @@ -780,13 +730,18 @@
626  
627  
628  int
629 -FTPSendPassive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
630 +FTPSendPassive(const FTPCIPtr cip, struct sockaddr *saddr, int *weird)
631  {
632         ResponsePtr rp;
633 -       int i[6], j;
634 -       unsigned char n[6];
635 +       int i[18], j;
636 +       unsigned char n[18];
637         char *cp;
638         int result;
639 +       struct sockaddr_in *saddr4 = (struct sockaddr_in *)saddr;
640 +#ifdef ENABLE_IPV6
641 +       struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)saddr;
642 +#endif
643 +       unsigned short port;
644  
645         rp = InitResponse();
646         if (rp == NULL) {
647 @@ -795,56 +750,162 @@
648                 return (cip->errNo);
649         }
650  
651 -       result = RCmd(cip, rp, "PASV");
652 -       if (result < 0)
653 -               goto done;
654 -
655 -       if (rp->codeType != 2) {
656 -               /* Didn't understand or didn't want passive port selection. */
657 -               cip->errNo = result = kErrPASVFailed;
658 -               goto done;
659 -       }
660 -
661 -       /* The other side returns a specification in the form of
662 -        * an internet address as the first four integers (each
663 -        * integer stands for 8-bits of the real 32-bit address),
664 -        * and two more integers for the port (16-bit port).
665 -        *
666 -        * It should give us something like:
667 -        * "Entering Passive Mode (129,93,33,1,10,187)", so look for
668 -        * digits with sscanf() starting 24 characters down the string.
669 -        */
670 +       result = RCmd(cip, rp, "EPSV");
671 +       if (result != 2)
672 +               goto next;
673 +
674 +       if (rp->codeType != 2)
675 +               goto next;
676 +
677         for (cp = rp->msg.first->line; ; cp++) {
678                 if (*cp == '\0') {
679 -                       FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
680 -                       goto done;
681 +                       FTPLogError(cip, kDontPerror, "Cannot parse EPSV response: %s\n", rp->msg.first->line);
682 +                       goto next;
683                 }
684                 if (isdigit((int) *cp))
685                         break;
686         }
687 +       if (sscanf(cp, "%hd|", &port) != 1) {
688 +               FTPLogError(cip, kDontPerror, "Cannot parse EPSV response: %s\n", rp->msg.first->line);
689 +               goto next;
690 +       }
691 +
692  
693 -       if (sscanf(cp, "%d,%d,%d,%d,%d,%d",
694 -                       &i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) != 6) {
695 -               FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
696 -               goto done;
697 +#ifdef ENABLE_IPV6
698 +       if (saddr->sa_family == AF_INET6) {
699 +               saddr6->sin6_addr =
700 +                       ((struct sockaddr_in6 *)&cip->servCtlAddr)->sin6_addr;
701 +               saddr6->sin6_port = htons(port);
702 +       } else {
703 +#endif
704 +               saddr4->sin_addr =
705 +                       ((struct sockaddr_in *)&cip->servCtlAddr)->sin_addr;
706 +               saddr4->sin_port = htons(port);
707 +#ifdef ENABLE_IPV6
708         }
709 +#endif
710 +       goto done;
711  
712 -       if (weird != (int *) 0)
713 -               *weird = 0;
714 -               
715 -       for (j=0; j<6; j++) {
716 -               /* Some ftp servers return bogus port octets, such as
717 -                * boombox.micro.umn.edu.  Let the caller know if we got a
718 -                * weird looking octet.
719 -                */
720 -               if (((i[j] < 0) || (i[j] > 255)) && (weird != (int *) 0))
721 -                       *weird = *weird + 1;
722 -               n[j] = (unsigned char) (i[j] & 0xff);
723 + next:
724 +       rp = InitResponse();
725 +       if (rp == NULL) {
726 +               FTPLogError(cip, kDontPerror, "Malloc failed.\n");
727 +               cip->errNo = kErrMallocFailed;
728 +               return (cip->errNo);
729         }
730         
731 -       (void) memcpy(&saddr->sin_addr, &n[0], (size_t) 4);
732 -       (void) memcpy(&saddr->sin_port, &n[4], (size_t) 2);
733 +#ifdef ENABLE_IPV6
734 +       if (saddr->sa_family == AF_INET6) {
735 +               int af, hal, pal;
736 +
737 +               result = RCmd(cip, rp, "LPSV");
738 +               if (result < 0)
739 +                       goto done;
740 +
741 +               if (rp->codeType != 2) {
742 +                       /* Didn't understand or didn't want passive port selection. */
743 +                       cip->errNo = result = kErrPASVFailed;
744 +                       goto done;
745 +               }
746 +
747 +               /* The other side returns a specification in the form of
748 +                * an internet address as the first four integers (each
749 +                * integer stands for 8-bits of the real 32-bit address),
750 +                * and two more integers for the port (16-bit port).
751 +                *
752 +                * It should give us something like:
753 +                * "Entering Passive Mode (129,93,33,1,10,187)", so look for
754 +                * digits with sscanf() starting 24 characters down the string.
755 +                */
756 +               for (cp = rp->msg.first->line; ; cp++) {
757 +                       if (*cp == '\0') {
758 +                               FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
759 +                               goto done;
760 +                       }
761 +                       if (isdigit((int) *cp))
762 +                               break;
763 +               }
764  
765 +               if (sscanf(cp, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
766 +                          &af, &hal,
767 +                          &i[ 0], &i[ 1], &i[ 2], &i[ 3],
768 +                          &i[ 4], &i[ 5], &i[ 6], &i[ 7],
769 +                          &i[ 8], &i[ 9], &i[10], &i[11],
770 +                          &i[12], &i[13], &i[14], &i[15],
771 +                          &pal,
772 +                          &i[16], &i[17]) != 21) {
773 +                       FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
774 +                       goto done;
775 +               }
776 +               if (af != 6 || hal != 16 || pal != 2) {
777 +                       FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
778 +                       goto done;
779 +               }
780 +
781 +               for (j=0, *weird = 0; j<18; j++) {
782 +                       /* Some ftp servers return bogus port octets, such as
783 +                        * boombox.micro.umn.edu.  Let the caller know if we got a
784 +                        * weird looking octet.
785 +                        */
786 +                       if ((i[j] < 0) || (i[j] > 255))
787 +                               *weird = *weird + 1;
788 +                       n[j] = (unsigned char) (i[j] & 0xff);
789 +               }
790 +               (void) memcpy(&saddr6->sin6_addr, &n[ 0], (size_t) 16);
791 +               (void) memcpy(&saddr6->sin6_port, &n[16], (size_t) 2);
792 +       } else {
793 +#endif
794 +               result = RCmd(cip, rp, "PASV");
795 +               if (result < 0)
796 +                       goto done;
797 +
798 +               if (rp->codeType != 2) {
799 +                       /* Didn't understand or didn't want passive port selection. */
800 +                       cip->errNo = result = kErrPASVFailed;
801 +                       goto done;
802 +               }
803 +
804 +               /* The other side returns a specification in the form of
805 +                * an internet address as the first four integers (each
806 +                * integer stands for 8-bits of the real 32-bit address),
807 +                * and two more integers for the port (16-bit port).
808 +                *
809 +                * It should give us something like:
810 +                * "Entering Passive Mode (129,93,33,1,10,187)", so look for
811 +                * digits with sscanf() starting 24 characters down the string.
812 +                */
813 +               for (cp = rp->msg.first->line; ; cp++) {
814 +                       if (*cp == '\0') {
815 +                               FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
816 +                               goto done;
817 +                       }
818 +                       if (isdigit((int) *cp))
819 +                               break;
820 +               }
821 +
822 +               if (sscanf(cp, "%d,%d,%d,%d,%d,%d",
823 +                          &i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) != 6) {
824 +                       FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
825 +                       goto done;
826 +               }
827 +
828 +               if (weird != (int *) 0)
829 +                       *weird = 0;
830 +               
831 +               for (j=0; j<6; j++) {
832 +                       /* Some ftp servers return bogus port octets, such as
833 +                        * boombox.micro.umn.edu.  Let the caller know if we got a
834 +                        * weird looking octet.
835 +                        */
836 +                       if (((i[j] < 0) || (i[j] > 255)) && (weird != (int *) 0))
837 +                               *weird = *weird + 1;
838 +                       n[j] = (unsigned char) (i[j] & 0xff);
839 +               }
840 +               (void) memcpy(&saddr4->sin_addr, &n[0], (size_t) 4);
841 +               (void) memcpy(&saddr4->sin_port, &n[4], (size_t) 2);
842 +#ifdef ENABLE_IPV6
843 +       }
844 +#endif
845         result = kNoErr;
846  done:
847         DoneWithResponse(cip, rp);
848 @@ -861,8 +922,8 @@
849         char maybePrivateAddrStr[64];
850         char knownNonPrivateAddrToUseIfNeededStr[64];
851  
852 -       AddrToAddrStr(maybePrivateAddrStr, sizeof(maybePrivateAddrStr), maybePrivateAddr, 0, "%h");
853 -       AddrToAddrStr(knownNonPrivateAddrToUseIfNeededStr, sizeof(knownNonPrivateAddrToUseIfNeededStr), knownNonPrivateAddrToUseIfNeeded, 0, "%h");
854 +       AddrToAddrStr(maybePrivateAddrStr, sizeof(maybePrivateAddrStr), (struct sockaddr *)maybePrivateAddr, 0, "%h");
855 +       AddrToAddrStr(knownNonPrivateAddrToUseIfNeededStr, sizeof(knownNonPrivateAddrToUseIfNeededStr), (struct sockaddr *)knownNonPrivateAddrToUseIfNeeded, 0, "%h");
856  
857         if (strcmp(maybePrivateAddrStr, knownNonPrivateAddrToUseIfNeededStr) == 0)
858                 return (0);             /* Assume if we could reach the Ctl, we can reach Data. */
859 @@ -892,10 +953,10 @@
860         char servDataAddrStr[64];
861         char newDataAddrStr[64];
862  
863 -       memcpy(&oldServDataAddr, &cip->servDataAddr, sizeof(oldServDataAddr));
864 -       if (FTPFixPrivateAddr(&cip->servDataAddr, &cip->servCtlAddr)) {
865 -               AddrToAddrStr(servDataAddrStr, sizeof(servDataAddrStr), &oldServDataAddr, 0, NULL);
866 -               AddrToAddrStr(newDataAddrStr, sizeof(newDataAddrStr), &cip->servDataAddr, 0, NULL);
867 +       memcpy(&oldServDataAddr, (struct sockaddr_in *)&cip->servDataAddr, sizeof(oldServDataAddr));
868 +       if (FTPFixPrivateAddr((struct sockaddr_in *)&cip->servDataAddr, (struct sockaddr_in *)&cip->servCtlAddr)) {
869 +               AddrToAddrStr(servDataAddrStr, sizeof(servDataAddrStr), (struct sockaddr *)&oldServDataAddr, 0, NULL);
870 +               AddrToAddrStr(newDataAddrStr, sizeof(newDataAddrStr), (struct sockaddr *)&cip->servDataAddr, 0, NULL);
871                 PrintF(cip, "Fixing bogus PASV data address from %s to %s.\n", servDataAddrStr, newDataAddrStr);
872         }
873  }      /* FTPFixServerDataAddr */
874 @@ -914,11 +975,11 @@
875                 return;
876  
877         memcpy(&oldClientDataAddr, &cip->ourDataAddr, sizeof(oldClientDataAddr));
878 -       if (FTPFixPrivateAddr(&cip->ourDataAddr, &cip->clientKnownExternalAddr)) {
879 +       if (FTPFixPrivateAddr((struct sockaddr_in *)&cip->ourDataAddr, (struct sockaddr_in *)&cip->clientKnownExternalAddr)) {
880                 memcpy(&newClientDataAddr, &cip->clientKnownExternalAddr, sizeof(newClientDataAddr));
881 -               newClientDataAddr.sin_port = cip->ourDataAddr.sin_port;
882 -               AddrToAddrStr(ourDataAddrStr, sizeof(ourDataAddrStr), &oldClientDataAddr, 0, NULL);
883 -               AddrToAddrStr(newDataAddrStr, sizeof(newDataAddrStr), &newClientDataAddr, 0, NULL);
884 +               newClientDataAddr.sin_port = ((struct sockaddr_in *)&cip->ourDataAddr)->sin_port;
885 +               AddrToAddrStr(ourDataAddrStr, sizeof(ourDataAddrStr), (struct sockaddr *)&oldClientDataAddr, 0, NULL);
886 +               AddrToAddrStr(newDataAddrStr, sizeof(newDataAddrStr), (struct sockaddr *)&newClientDataAddr, 0, NULL);
887                 PrintF(cip, "Fixing what would have been a bogus PORT data address from %s to %s.\n", ourDataAddrStr, newDataAddrStr);
888         }
889  }      /* FTPFixClientDataAddr */
890 @@ -927,30 +988,45 @@
891  
892  
893  int
894 -BindToEphemeralPortNumber(const int sockfd, struct sockaddr_in *const addrp, const int ephemLo, const int ephemHi)
895 +BindToEphemeralPortNumber(const int sockfd, struct sockaddr *const addrp, const int ephemLo, const int ephemHi)
896  {
897         int i;
898         int result;
899         int rangesize;
900         unsigned short port;
901  
902 -       addrp->sin_family = AF_INET;
903         if (((int) ephemLo == 0) || ((int) ephemLo >= (int) ephemHi)) {
904                 /* Do it the normal way.  System will
905                  * pick one, typically in the range
906                  * of 1024-4999.
907                  */
908 -               addrp->sin_port = 0;    /* Let system pick one. */
909 -
910 -               result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
911 +#ifdef ENABLE_IPV6
912 +               if (addrp->sa_family == AF_INET6)
913 +                       ((struct sockaddr_in6 *)addrp)->sin6_port = 0;  /* Let system pick one. */
914 +               else
915 +#endif
916 +                       ((struct sockaddr_in *)addrp)->sin_port = 0;    /* Let system pick one. */
917 +#ifdef HAVE_SOCKADDR_SA_LEN
918 +               result = bind(sockfd, addrp, addrp->sa_len);
919 +#else
920 +               result = bind(sockfd, addrp, SA_LEN(addrp));
921 +#endif
922         } else {
923                 rangesize = (int) ((int) ephemHi - (int) ephemLo);
924                 result = 0;
925                 for (i=0; i<10; i++) {
926                         port = (unsigned short) (((int) rand() % rangesize) + (int) ephemLo);
927 -                       addrp->sin_port = htons(port);
928 -
929 -                       result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
930 +#ifdef ENABLE_IPV6
931 +                       if (addrp->sa_family == AF_INET6)
932 +                               ((struct sockaddr_in6 *)addrp)->sin6_port = htons(port);
933 +                       else
934 +#endif
935 +                               ((struct sockaddr_in *)addrp)->sin_port = htons(port);
936 +#ifdef HAVE_SOCKADDR_SA_LEN
937 +                       result = bind(sockfd, addrp, addrp->sa_len);
938 +#else
939 +                       result = bind(sockfd, addrp, SA_LEN(addrp));
940 +#endif
941                         if (result == 0)
942                                 break;
943                         sleep(1);
944 @@ -989,7 +1065,11 @@
945         result = 0;
946         CloseDataConnection(cip);       /* In case we didn't before... */
947  
948 +#ifdef ENABLE_IPV6
949 +       dataSocket = socket(cip->ourCtlAddr.ss_family, SOCK_STREAM, 0);
950 +#else
951         dataSocket = socket(AF_INET, SOCK_STREAM, 0);
952 +#endif
953         if (dataSocket < 0) {
954                 FTPLogError(cip, kDoPerror, "Could not get a data socket.\n");
955                 result = kErrNewStreamSocket;
956 @@ -1023,7 +1103,6 @@
957                  * which may have been set to something explicitly.
958                  */
959                 cip->ourDataAddr = cip->ourCtlAddr;
960 -               cip->ourDataAddr.sin_family = AF_INET;
961  
962  #ifdef HAVE_LIBSOCKS
963                 cip->ourDataAddr.sin_port = 0;
964 @@ -1031,7 +1110,7 @@
965                         (int) sizeof (cip->ourDataAddr),
966                         cip->servCtlAddr.sin_addr.s_addr) < 0) 
967  #else
968 -               if (BindToEphemeralPortNumber(dataSocket, &cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
969 +               if (BindToEphemeralPortNumber(dataSocket, (struct sockaddr *)&cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
970  #endif
971                 {
972                         FTPLogError(cip, kDoPerror, "Could not bind the data socket");
973 @@ -1043,7 +1122,7 @@
974                 /* Need to do this so we can figure out which port the system
975                  * gave to us.
976                  */
977 -               if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
978 +               if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *)&cip->ourDataAddr)) < 0)
979                         goto bad;
980         
981                 if (listen(dataSocket, 1) < 0) {
982 @@ -1053,8 +1132,9 @@
983                         goto bad;
984                 }
985  
986 -               FTPFixClientDataAddr(cip);
987 -               if ((result = FTPSendPort(cip, &cip->ourDataAddr)) < 0)
988 +               if (cip->ourDataAddr.ss_family == AF_INET)
989 +                       FTPFixClientDataAddr(cip);
990 +               if ((result = FTPSendPort(cip, (struct sockaddr *)&cip->ourDataAddr)) < 0)
991                         goto bad;
992         
993                 cip->dataPortMode = kSendPortMode;
994 @@ -1063,11 +1143,9 @@
995         
996                 while (--passiveAttemptsRemaining >= 0) {
997                         cip->servDataAddr = cip->servCtlAddr;
998 -                       cip->servDataAddr.sin_family = AF_INET;
999                         cip->ourDataAddr = cip->ourCtlAddr;
1000 -                       cip->ourDataAddr.sin_family = AF_INET;
1001  
1002 -                       if (FTPSendPassive(cip, &cip->servDataAddr, &weirdPort) < 0) {
1003 +                       if (FTPSendPassive(cip, (struct sockaddr *)&cip->servDataAddr, &weirdPort) < 0) {
1004                                 FTPLogError(cip, kDontPerror, "Passive mode refused.\n");
1005                                 cip->hasPASV = kCommandNotAvailable;
1006                                 
1007 @@ -1084,7 +1162,8 @@
1008                                 cip->errNo = kErrPassiveModeFailed;
1009                                 goto bad;
1010                         }
1011 -                       FTPFixServerDataAddr(cip);
1012 +                       if (cip->servDataAddr.ss_family == AF_INET)
1013 +                               FTPFixServerDataAddr(cip);
1014  
1015  #ifdef HAVE_LIBSOCKS
1016                         cip->ourDataAddr.sin_port = 0;
1017 @@ -1092,7 +1171,7 @@
1018                                 (int) sizeof (cip->ourDataAddr),
1019                                 cip->servCtlAddr.sin_addr.s_addr) < 0) 
1020  #else
1021 -                       if (BindToEphemeralPortNumber(dataSocket, &cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
1022 +                       if (BindToEphemeralPortNumber(dataSocket, (struct sockaddr *)&cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
1023  #endif
1024                         {
1025                                 FTPLogError(cip, kDoPerror, "Could not bind the data socket");
1026 @@ -1100,8 +1179,13 @@
1027                                 cip->errNo = kErrBindDataSocket;
1028                                 goto bad;
1029                         }
1030 -
1031 -                       result = SConnect(dataSocket, &cip->servDataAddr, (int) cip->connTimeout);
1032 +       
1033 +                       /* Need to do this so we can figure out which port the system
1034 +                        * gave to us.
1035 +                        */
1036 +                       if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *)&cip->ourDataAddr)) < 0)
1037 +                               goto bad;
1038 +                       result = SConnect(dataSocket, (struct sockaddr *)&cip->servDataAddr, (int) cip->connTimeout);
1039  
1040                         if (result == kTimeoutErr) {
1041                                 if (mode == kFallBackToSendPortMode) {
1042 @@ -1164,7 +1248,7 @@
1043                         if (dataSocket != kClosedFileDescriptor)
1044                                 (void) DisposeSocket(dataSocket);
1045  
1046 -                       dataSocket = socket(AF_INET, SOCK_STREAM, 0);
1047 +                       dataSocket = socket(cip->ourCtlAddr.ss_family, SOCK_STREAM, 0);
1048                         if (dataSocket < 0) {
1049                                 FTPLogError(cip, kDoPerror, "Could not get a data socket.\n");
1050                                 result = kErrNewStreamSocket;
1051 @@ -1180,7 +1264,7 @@
1052                 /* Need to do this so we can figure out which port the system
1053                  * gave to us.
1054                  */
1055 -               if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
1056 +               if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *) &cip->ourDataAddr)) < 0)
1057                         goto bad;
1058  
1059                 cip->hasPASV = kCommandAvailable;
1060 @@ -1225,9 +1309,9 @@
1061                 memset(&cip->servDataAddr, 0, sizeof(cip->servDataAddr));
1062  
1063  #ifdef NO_SIGNALS
1064 -               newSocket = SAccept(cip->dataSocket, &cip->servDataAddr, (int) cip->connTimeout);
1065 +               newSocket = SAccept(cip->dataSocket, (struct sockaddr *)&cip->servDataAddr, (int) cip->connTimeout);
1066  #else  /* NO_SIGNALS */
1067 -               len = (int) sizeof(cip->servDataAddr);
1068 +               len = (int) sizeof(struct sockaddr_storage);
1069                 if (cip->connTimeout > 0)
1070                         (void) alarm(cip->connTimeout);
1071                 newSocket = accept(cip->dataSocket, (struct sockaddr *) &cip->servDataAddr, &len);
1072 @@ -1242,11 +1326,10 @@
1073                         cip->errNo = kErrAcceptDataSocket;
1074                         return (kErrAcceptDataSocket);
1075                 }
1076 -       
1077                 if (cip->allowProxyForPORT == 0) {
1078 -                       if (memcmp(&cip->servDataAddr.sin_addr.s_addr, &cip->servCtlAddr.sin_addr.s_addr, sizeof(cip->servDataAddr.sin_addr.s_addr)) != 0) {
1079 -                               AddrToAddrStr(ctrlAddrStr, sizeof(ctrlAddrStr), &cip->servCtlAddr, 0, NULL);
1080 -                               AddrToAddrStr(dataAddrStr, sizeof(dataAddrStr), &cip->servDataAddr, 0, NULL);
1081 +                       AddrToAddrStr(ctrlAddrStr, sizeof(ctrlAddrStr), (struct sockaddr *)&cip->servCtlAddr, 0, "%h");
1082 +                       AddrToAddrStr(dataAddrStr, sizeof(dataAddrStr), (struct sockaddr *)&cip->servDataAddr, 0, "%h");
1083 +                       if (strcmp(ctrlAddrStr, dataAddrStr) != 0) {
1084                                 FTPLogError(cip, kDontPerror, "Data connection from %s did not originate from remote server %s!\n", dataAddrStr, ctrlAddrStr);
1085                                 (void) DisposeSocket(newSocket);
1086                                 cip->dataSocket = kClosedFileDescriptor;
1087 @@ -1254,21 +1337,57 @@
1088                                 return (kErrProxyDataConnectionsDisabled);
1089                         }
1090                 }
1091 -
1092                 if (cip->require20 != 0) {
1093 -                       remoteDataPort = ntohs(cip->servDataAddr.sin_port);
1094 -                       remoteCtrlPort = ntohs(cip->servCtlAddr.sin_port);
1095 -                       if ((int) remoteDataPort != ((int) remoteCtrlPort - 1)) {
1096 -                               FTPLogError(cip, kDontPerror, "Data connection did not originate on correct port (expecting %d, got %d)!\n", (int) remoteCtrlPort - 1, (int) remoteDataPort);
1097 -                               (void) DisposeSocket(newSocket);
1098 -                               cip->dataSocket = kClosedFileDescriptor;
1099 -                               cip->errNo = kErrDataConnOriginatedFromBadPort;
1100 -                               return (kErrDataConnOriginatedFromBadPort);
1101 +#ifdef ENABLE_IPV6
1102 +                       if (cip->servDataAddr.ss_family == AF_INET6) {
1103 +                               struct sockaddr_in6 *servDataAddr =
1104 +                                       (struct sockaddr_in6 *) &cip->servDataAddr;
1105 +                               struct sockaddr_in6 *servCtlAddr =
1106 +                                       (struct sockaddr_in6 *) &cip->servCtlAddr;
1107 +
1108 +                               remoteDataPort = ntohs(servDataAddr->sin6_port);
1109 +                               remoteCtrlPort = ntohs(servCtlAddr->sin6_port);
1110 +                               if ((int) remoteDataPort != ((int) remoteCtrlPort - 1)) {
1111 +                                       FTPLogError(cip, kDontPerror, "Data connection did not originate on correct port!\n");
1112 +                                       (void) DisposeSocket(newSocket);
1113 +                                       cip->dataSocket = kClosedFileDescriptor;
1114 +                                       cip->errNo = kErrAcceptDataSocket;
1115 +                                       return (kErrAcceptDataSocket);
1116 +                               } else if (memcmp(&servDataAddr->sin6_addr, &servCtlAddr->sin6_addr, sizeof(servDataAddr->sin6_addr)) != 0) {
1117 +                                       FTPLogError(cip, kDontPerror, "Data connection did not originate from remote server!\n");
1118 +                                       (void) DisposeSocket(newSocket);
1119 +                                       cip->dataSocket = kClosedFileDescriptor;
1120 +                                       cip->errNo = kErrAcceptDataSocket;
1121 +                                       return (kErrAcceptDataSocket);
1122 +                               }
1123 +                       } else {
1124 +#endif
1125 +                               struct sockaddr_in *servDataAddr =
1126 +                                       (struct sockaddr_in *) &cip->servDataAddr;
1127 +                               struct sockaddr_in *servCtlAddr =
1128 +                                       (struct sockaddr_in *) &cip->servCtlAddr;
1129 +
1130 +                               remoteDataPort = ntohs(servDataAddr->sin_port);
1131 +                               remoteCtrlPort = ntohs(servCtlAddr->sin_port);
1132 +                               if ((int) remoteDataPort != ((int) remoteCtrlPort - 1)) {
1133 +                                       FTPLogError(cip, kDontPerror, "Data connection did not originate on correct port!\n");
1134 +                                       (void) DisposeSocket(newSocket);
1135 +                                       cip->dataSocket = kClosedFileDescriptor;
1136 +                                       cip->errNo = kErrAcceptDataSocket;
1137 +                                       return (kErrAcceptDataSocket);
1138 +                               } else if (memcmp(&servDataAddr->sin_addr.s_addr, &servCtlAddr->sin_addr.s_addr, sizeof(servDataAddr->sin_addr.s_addr)) != 0) {
1139 +                                       FTPLogError(cip, kDontPerror, "Data connection did not originate on correct port (expecting %d, got %d)!\n", (int) remoteCtrlPort - 1, (int) remoteDataPort);
1140 +                                       (void) DisposeSocket(newSocket);
1141 +                                       cip->errNo = kErrDataConnOriginatedFromBadPort;
1142 +                                       cip->errNo = kErrAcceptDataSocket;
1143 +                                       return (kErrDataConnOriginatedFromBadPort);
1144 +                               }
1145 +#ifdef ENABLE_IPV6
1146                         }
1147 +#endif         
1148                 }
1149                 cip->dataSocket = newSocket;
1150         }
1151 -
1152         return (0);
1153  }      /* AcceptDataConnection */
1154  
1155 Index: ncftp3/libncftp/getaddrinfo.c
1156 diff -u /dev/null ncftp3/libncftp/getaddrinfo.c:1.1
1157 --- /dev/null   Mon Nov  9 21:52:32 2009
1158 +++ ncftp3/libncftp/getaddrinfo.c       Tue Nov  6 23:50:46 2001
1159 @@ -0,0 +1,607 @@
1160 +/*
1161 + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
1162 + * All rights reserved.
1163 + * 
1164 + * Redistribution and use in source and binary forms, with or without
1165 + * modification, are permitted provided that the following conditions
1166 + * are met:
1167 + * 1. Redistributions of source code must retain the above copyright
1168 + *    notice, this list of conditions and the following disclaimer.
1169 + * 2. Redistributions in binary form must reproduce the above copyright
1170 + *    notice, this list of conditions and the following disclaimer in the
1171 + *    documentation and/or other materials provided with the distribution.
1172 + * 3. Neither the name of the project nor the names of its contributors
1173 + *    may be used to endorse or promote products derived from this software
1174 + *    without specific prior written permission.
1175 + * 
1176 + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1177 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1178 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1179 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
1180 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1181 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1182 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1183 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1184 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1185 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1186 + * SUCH DAMAGE.
1187 + */
1188 +
1189 +/*
1190 + * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
1191 + *
1192 + * Issues to be discussed:
1193 + * - Thread safe-ness must be checked.
1194 + * - Return values.  There are nonstandard return values defined and used
1195 + *   in the source code.  This is because RFC2133 is silent about which error
1196 + *   code must be returned for which situation.
1197 + * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.
1198 + */
1199 +
1200 +#include <sys/types.h>
1201 +#include <sys/param.h>
1202 +#include <sys/sysctl.h>
1203 +#include <sys/socket.h>
1204 +#include <netinet/in.h>
1205 +#include <arpa/inet.h>
1206 +#include <arpa/nameser.h>
1207 +#include <netdb.h>
1208 +#include <resolv.h>
1209 +#include <string.h>
1210 +#include <stdlib.h>
1211 +#include <stddef.h>
1212 +#include <ctype.h>
1213 +#include <unistd.h>
1214 +
1215 +#include "addrinfo.h"
1216 +
1217 +#if defined(__KAME__) && defined(INET6)
1218 +# define FAITH
1219 +#endif
1220 +
1221 +#define SUCCESS 0
1222 +#define ANY 0
1223 +#define YES 1
1224 +#define NO  0
1225 +
1226 +#ifdef FAITH
1227 +static int translate = NO;
1228 +static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
1229 +#endif
1230 +
1231 +static const char in_addrany[] = { 0, 0, 0, 0 };
1232 +static const char in6_addrany[] = {
1233 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1234 +};
1235 +static const char in_loopback[] = { 127, 0, 0, 1 }; 
1236 +static const char in6_loopback[] = {
1237 +       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
1238 +};
1239 +
1240 +struct sockinet {
1241 +       u_char  si_len;
1242 +       u_char  si_family;
1243 +       u_short si_port;
1244 +};
1245 +
1246 +static struct afd {
1247 +       int a_af;
1248 +       int a_addrlen;
1249 +       int a_socklen;
1250 +       int a_off;
1251 +       const char *a_addrany;
1252 +       const char *a_loopback; 
1253 +} afdl [] = {
1254 +#ifdef INET6
1255 +#define N_INET6 0
1256 +       {PF_INET6, sizeof(struct in6_addr),
1257 +        sizeof(struct sockaddr_in6),
1258 +        offsetof(struct sockaddr_in6, sin6_addr),
1259 +        in6_addrany, in6_loopback},
1260 +#define N_INET  1
1261 +#else
1262 +#define N_INET  0
1263 +#endif
1264 +       {PF_INET, sizeof(struct in_addr),
1265 +        sizeof(struct sockaddr_in),
1266 +        offsetof(struct sockaddr_in, sin_addr),
1267 +        in_addrany, in_loopback},
1268 +       {0, 0, 0, 0, NULL, NULL},
1269 +};
1270 +
1271 +#ifdef INET6
1272 +#define PTON_MAX       16
1273 +#else
1274 +#define PTON_MAX       4
1275 +#endif
1276 +
1277 +
1278 +static int get_name __P((const char *, struct afd *,
1279 +                         struct addrinfo **, char *, struct addrinfo *,
1280 +                         int));
1281 +static int get_addr __P((const char *, int, struct addrinfo **,
1282 +                       struct addrinfo *, int));
1283 +static int str_isnumber __P((const char *));
1284 +       
1285 +static char *ai_errlist[] = {
1286 +       "success.",
1287 +       "address family for hostname not supported.",   /* EAI_ADDRFAMILY */
1288 +       "temporary failure in name resolution.",        /* EAI_AGAIN      */
1289 +       "invalid value for ai_flags.",                  /* EAI_BADFLAGS   */
1290 +       "non-recoverable failure in name resolution.",  /* EAI_FAIL       */
1291 +       "ai_family not supported.",                     /* EAI_FAMILY     */
1292 +       "memory allocation failure.",                   /* EAI_MEMORY     */
1293 +       "no address associated with hostname.",         /* EAI_NODATA     */
1294 +       "hostname nor servname provided, or not known.",/* EAI_NONAME     */
1295 +       "servname not supported for ai_socktype.",      /* EAI_SERVICE    */
1296 +       "ai_socktype not supported.",                   /* EAI_SOCKTYPE   */
1297 +       "system error returned in errno.",              /* EAI_SYSTEM     */
1298 +       "invalid value for hints.",                     /* EAI_BADHINTS   */
1299 +       "resolved protocol is unknown.",                /* EAI_PROTOCOL   */
1300 +       "unknown error.",                               /* EAI_MAX        */
1301 +};
1302 +
1303 +#define GET_CANONNAME(ai, str) \
1304 +if (pai->ai_flags & AI_CANONNAME) {\
1305 +       if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\
1306 +               strcpy((ai)->ai_canonname, (str));\
1307 +       } else {\
1308 +               error = EAI_MEMORY;\
1309 +               goto free;\
1310 +       }\
1311 +}
1312 +
1313 +#define GET_AI(ai, afd, addr, port) {\
1314 +       char *p;\
1315 +       if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\
1316 +                                             ((afd)->a_socklen)))\
1317 +           == NULL) goto free;\
1318 +       memcpy(ai, pai, sizeof(struct addrinfo));\
1319 +       (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\
1320 +       memset((ai)->ai_addr, 0, (afd)->a_socklen);\
1321 +       (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (afd)->a_socklen;\
1322 +       (ai)->ai_addr->sa_family = (ai)->ai_family = (afd)->a_af;\
1323 +       ((struct sockinet *)(ai)->ai_addr)->si_port = port;\
1324 +       p = (char *)((ai)->ai_addr);\
1325 +       memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\
1326 +}
1327 +
1328 +#define ERR(err) { error = (err); goto bad; }
1329 +
1330 +char *
1331 +gai_strerror(ecode)
1332 +       int ecode;
1333 +{
1334 +       if (ecode < 0 || ecode > EAI_MAX)
1335 +               ecode = EAI_MAX;
1336 +       return ai_errlist[ecode];
1337 +}
1338 +
1339 +void
1340 +freeaddrinfo(ai)
1341 +       struct addrinfo *ai;
1342 +{
1343 +       struct addrinfo *next;
1344 +
1345 +       do {
1346 +               next = ai->ai_next;
1347 +               if (ai->ai_canonname)
1348 +                       free(ai->ai_canonname);
1349 +               /* no need to free(ai->ai_addr) */
1350 +               free(ai);
1351 +       } while ((ai = next) != NULL);
1352 +}
1353 +
1354 +static int
1355 +str_isnumber(p)
1356 +       const char *p;
1357 +{
1358 +       char *q = (char *)p;
1359 +       while (*q) {
1360 +               if (! isdigit(*q))
1361 +                       return NO;
1362 +               q++;
1363 +       }
1364 +       return YES;
1365 +}
1366 +
1367 +int
1368 +getaddrinfo(hostname, servname, hints, res)
1369 +       const char *hostname, *servname;
1370 +       const struct addrinfo *hints;
1371 +       struct addrinfo **res;
1372 +{
1373 +       struct addrinfo sentinel;
1374 +       struct addrinfo *top = NULL;
1375 +       struct addrinfo *cur;
1376 +       int i, error = 0;
1377 +       char pton[PTON_MAX];
1378 +       struct addrinfo ai;
1379 +       struct addrinfo *pai;
1380 +       u_short port;
1381 +
1382 +#ifdef FAITH
1383 +       static int firsttime = 1;
1384 +
1385 +       if (firsttime) {
1386 +               /* translator hack */
1387 +               {
1388 +                       char *q = getenv("GAI");
1389 +                       if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
1390 +                               translate = YES;
1391 +               }
1392 +               firsttime = 0;
1393 +       }
1394 +#endif
1395 +
1396 +       /* initialize file static vars */
1397 +       sentinel.ai_next = NULL;
1398 +       cur = &sentinel;
1399 +       pai = &ai;
1400 +       pai->ai_flags = 0;
1401 +       pai->ai_family = PF_UNSPEC;
1402 +       pai->ai_socktype = ANY;
1403 +       pai->ai_protocol = ANY;
1404 +       pai->ai_addrlen = 0;
1405 +       pai->ai_canonname = NULL;
1406 +       pai->ai_addr = NULL;
1407 +       pai->ai_next = NULL;
1408 +       port = ANY;
1409 +       
1410 +       if (hostname == NULL && servname == NULL)
1411 +               return EAI_NONAME;
1412 +       if (hints) {
1413 +               /* error check for hints */
1414 +               if (hints->ai_addrlen || hints->ai_canonname ||
1415 +                   hints->ai_addr || hints->ai_next)
1416 +                       ERR(EAI_BADHINTS); /* xxx */
1417 +               if (hints->ai_flags & ~AI_MASK)
1418 +                       ERR(EAI_BADFLAGS);
1419 +               switch (hints->ai_family) {
1420 +               case PF_UNSPEC:
1421 +               case PF_INET:
1422 +#ifdef INET6
1423 +               case PF_INET6:
1424 +#endif
1425 +                       break;
1426 +               default:
1427 +                       ERR(EAI_FAMILY);
1428 +               }
1429 +               memcpy(pai, hints, sizeof(*pai));
1430 +               switch (pai->ai_socktype) {
1431 +               case ANY:
1432 +                       switch (pai->ai_protocol) {
1433 +                       case ANY:
1434 +                               break;
1435 +                       case IPPROTO_UDP:
1436 +                               pai->ai_socktype = SOCK_DGRAM;
1437 +                               break;
1438 +                       case IPPROTO_TCP:
1439 +                               pai->ai_socktype = SOCK_STREAM;
1440 +                               break;
1441 +                       default:
1442 +                               pai->ai_socktype = SOCK_RAW;
1443 +                               break;
1444 +                       }
1445 +                       break;
1446 +               case SOCK_RAW:
1447 +                       break;
1448 +               case SOCK_DGRAM:
1449 +                       if (pai->ai_protocol != IPPROTO_UDP &&
1450 +                           pai->ai_protocol != ANY)
1451 +                               ERR(EAI_BADHINTS);      /*xxx*/
1452 +                       pai->ai_protocol = IPPROTO_UDP;
1453 +                       break;
1454 +               case SOCK_STREAM:
1455 +                       if (pai->ai_protocol != IPPROTO_TCP &&
1456 +                           pai->ai_protocol != ANY)
1457 +                               ERR(EAI_BADHINTS);      /*xxx*/
1458 +                       pai->ai_protocol = IPPROTO_TCP;
1459 +                       break;
1460 +               default:
1461 +                       ERR(EAI_SOCKTYPE);
1462 +                       break;
1463 +               }
1464 +       }
1465 +
1466 +       /*
1467 +        * service port
1468 +        */
1469 +       if (servname) {
1470 +               if (str_isnumber(servname)) {
1471 +                       if (pai->ai_socktype == ANY) {
1472 +                               /* caller accept *ANY* socktype */
1473 +                               pai->ai_socktype = SOCK_DGRAM;
1474 +                               pai->ai_protocol = IPPROTO_UDP;
1475 +                       }
1476 +                       port = htons(atoi(servname));
1477 +               } else {
1478 +                       struct servent *sp;
1479 +                       char *proto;
1480 +
1481 +                       proto = NULL;
1482 +                       switch (pai->ai_socktype) {
1483 +                       case ANY:
1484 +                               proto = NULL;
1485 +                               break;
1486 +                       case SOCK_DGRAM:
1487 +                               proto = "udp";
1488 +                               break;
1489 +                       case SOCK_STREAM:
1490 +                               proto = "tcp";
1491 +                               break;
1492 +                       default:
1493 +                               fprintf(stderr, "panic!\n");
1494 +                               break;
1495 +                       }
1496 +                       if ((sp = getservbyname(servname, proto)) == NULL)
1497 +                               ERR(EAI_SERVICE);
1498 +                       port = sp->s_port;
1499 +                       if (pai->ai_socktype == ANY)
1500 +                               if (strcmp(sp->s_proto, "udp") == 0) {
1501 +                                       pai->ai_socktype = SOCK_DGRAM;
1502 +                                       pai->ai_protocol = IPPROTO_UDP;
1503 +                               } else if (strcmp(sp->s_proto, "tcp") == 0) {
1504 +                                       pai->ai_socktype = SOCK_STREAM;
1505 +                                       pai->ai_protocol = IPPROTO_TCP;
1506 +                               } else
1507 +                                       ERR(EAI_PROTOCOL);      /*xxx*/
1508 +               }
1509 +       }
1510 +       
1511 +       /*
1512 +        * hostname == NULL.
1513 +        * passive socket -> anyaddr (0.0.0.0 or ::)
1514 +        * non-passive socket -> localhost (127.0.0.1 or ::1)
1515 +        */
1516 +       if (hostname == NULL) {
1517 +               struct afd *afd;
1518 +
1519 +               for (afd = &afdl[0]; afd->a_af; afd++) {
1520 +                       if (!(pai->ai_family == PF_UNSPEC
1521 +                          || pai->ai_family == afd->a_af)) {
1522 +                               continue;
1523 +                       }
1524 +
1525 +                       if (pai->ai_flags & AI_PASSIVE) {
1526 +                               GET_AI(cur->ai_next, afd, afd->a_addrany, port);
1527 +                               /* xxx meaningless?
1528 +                                * GET_CANONNAME(cur->ai_next, "anyaddr");
1529 +                                */
1530 +                       } else {
1531 +                               GET_AI(cur->ai_next, afd, afd->a_loopback,
1532 +                                       port);
1533 +                               /* xxx meaningless?
1534 +                                * GET_CANONNAME(cur->ai_next, "localhost");
1535 +                                */
1536 +                       }
1537 +                       cur = cur->ai_next;
1538 +               }
1539 +               top = sentinel.ai_next;
1540 +               if (top)
1541 +                       goto good;
1542 +               else
1543 +                       ERR(EAI_FAMILY);
1544 +       }
1545 +       
1546 +       /* hostname as numeric name */
1547 +       for (i = 0; afdl[i].a_af; i++) {
1548 +               if (inet_pton(afdl[i].a_af, hostname, pton)) {
1549 +                       u_long v4a;
1550 +                       u_char pfx;
1551 +
1552 +                       switch (afdl[i].a_af) {
1553 +                       case AF_INET:
1554 +                               v4a = ((struct in_addr *)pton)->s_addr;
1555 +                               if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
1556 +                                       pai->ai_flags &= ~AI_CANONNAME;
1557 +                               v4a >>= IN_CLASSA_NSHIFT;
1558 +                               if (v4a == 0 || v4a == IN_LOOPBACKNET)
1559 +                                       pai->ai_flags &= ~AI_CANONNAME;
1560 +                               break;
1561 +#ifdef INET6
1562 +                       case AF_INET6:
1563 +                               pfx = ((struct in6_addr *)pton)->s6_addr8[0];
1564 +                               if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
1565 +                                       pai->ai_flags &= ~AI_CANONNAME;
1566 +                               break;
1567 +#endif
1568 +                       }
1569 +                       
1570 +                       if (pai->ai_family == afdl[i].a_af ||
1571 +                           pai->ai_family == PF_UNSPEC) {
1572 +                               if (! (pai->ai_flags & AI_CANONNAME)) {
1573 +                                       GET_AI(top, &afdl[i], pton, port);
1574 +                                       goto good;
1575 +                               }
1576 +                               /*
1577 +                                * if AI_CANONNAME and if reverse lookup
1578 +                                * fail, return ai anyway to pacify
1579 +                                * calling application.
1580 +                                *
1581 +                                * XXX getaddrinfo() is a name->address
1582 +                                * translation function, and it looks strange
1583 +                                * that we do addr->name translation here.
1584 +                                */
1585 +                               get_name(pton, &afdl[i], &top, pton, pai, port);
1586 +                               goto good;
1587 +                       } else 
1588 +                               ERR(EAI_FAMILY);        /*xxx*/
1589 +               }
1590 +       }
1591 +
1592 +       if (pai->ai_flags & AI_NUMERICHOST)
1593 +               ERR(EAI_NONAME);
1594 +
1595 +       /* hostname as alphabetical name */
1596 +       error = get_addr(hostname, pai->ai_family, &top, pai, port);
1597 +       if (error == 0) {
1598 +               if (top) {
1599 + good:
1600 +                       *res = top;
1601 +                       return SUCCESS;
1602 +               } else
1603 +                       error = EAI_FAIL;
1604 +       }
1605 + free:
1606 +       if (top)
1607 +               freeaddrinfo(top);
1608 + bad:
1609 +       *res = NULL;
1610 +       return error;
1611 +}
1612 +
1613 +static int
1614 +get_name(addr, afd, res, numaddr, pai, port0)
1615 +       const char *addr;
1616 +       struct afd *afd;
1617 +       struct addrinfo **res;
1618 +       char *numaddr;
1619 +       struct addrinfo *pai;
1620 +       int port0;
1621 +{
1622 +       u_short port = port0 & 0xffff;
1623 +       struct hostent *hp;
1624 +       struct addrinfo *cur;
1625 +       int error = 0, h_error;
1626 +       
1627 +#ifdef INET6
1628 +       hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
1629 +#else
1630 +       hp = gethostbyaddr(addr, afd->a_addrlen, AF_INET);
1631 +#endif
1632 +       if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
1633 +               GET_AI(cur, afd, hp->h_addr_list[0], port);
1634 +               GET_CANONNAME(cur, hp->h_name);
1635 +       } else
1636 +               GET_AI(cur, afd, numaddr, port);
1637 +       
1638 +#ifdef INET6
1639 +       if (hp)
1640 +               freehostent(hp);
1641 +#endif
1642 +       *res = cur;
1643 +       return SUCCESS;
1644 + free:
1645 +       if (cur)
1646 +               freeaddrinfo(cur);
1647 +#ifdef INET6
1648 +       if (hp)
1649 +               freehostent(hp);
1650 +#endif
1651 + /* bad: */
1652 +       *res = NULL;
1653 +       return error;
1654 +}
1655 +
1656 +static int
1657 +get_addr(hostname, af, res, pai, port0)
1658 +       const char *hostname;
1659 +       int af;
1660 +       struct addrinfo **res;
1661 +       struct addrinfo *pai;
1662 +       int port0;
1663 +{
1664 +       u_short port = port0 & 0xffff;
1665 +       struct addrinfo sentinel;
1666 +       struct hostent *hp;
1667 +       struct addrinfo *top, *cur;
1668 +       struct afd *afd;
1669 +       int i, error = 0, h_error;
1670 +       char *ap;
1671 +#ifndef INET6
1672 +       extern int h_errno;
1673 +#endif
1674 +
1675 +       top = NULL;
1676 +       sentinel.ai_next = NULL;
1677 +       cur = &sentinel;
1678 +#ifdef INET6
1679 +       if (af == AF_UNSPEC) {
1680 +               hp = getipnodebyname(hostname, AF_INET6,
1681 +                               AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
1682 +       } else
1683 +               hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
1684 +#else
1685 +       hp = gethostbyname(hostname);
1686 +       h_error = h_errno;
1687 +#endif
1688 +       if (hp == NULL) {
1689 +               switch (h_error) {
1690 +               case HOST_NOT_FOUND:
1691 +               case NO_DATA:
1692 +                       error = EAI_NODATA;
1693 +                       break;
1694 +               case TRY_AGAIN:
1695 +                       error = EAI_AGAIN;
1696 +                       break;
1697 +               case NO_RECOVERY:
1698 +               default:
1699 +                       error = EAI_FAIL;
1700 +                       break;
1701 +               }
1702 +               goto bad;
1703 +       }
1704 +
1705 +       if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
1706 +           (hp->h_addr_list[0] == NULL))
1707 +               ERR(EAI_FAIL);
1708 +       
1709 +       for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
1710 +               switch (af) {
1711 +#ifdef INET6
1712 +               case AF_INET6:
1713 +                       afd = &afdl[N_INET6];
1714 +                       break;
1715 +#endif
1716 +#ifndef INET6
1717 +               default:        /* AF_UNSPEC */
1718 +#endif
1719 +               case AF_INET:
1720 +                       afd = &afdl[N_INET];
1721 +                       break;
1722 +#ifdef INET6
1723 +               default:        /* AF_UNSPEC */
1724 +                       if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
1725 +                               ap += sizeof(struct in6_addr) -
1726 +                                       sizeof(struct in_addr);
1727 +                               afd = &afdl[N_INET];
1728 +                       } else
1729 +                               afd = &afdl[N_INET6];
1730 +                       break;
1731 +#endif
1732 +               }
1733 +#ifdef FAITH
1734 +               if (translate && afd->a_af == AF_INET) {
1735 +                       struct in6_addr *in6;
1736 +
1737 +                       GET_AI(cur->ai_next, &afdl[N_INET6], ap, port);
1738 +                       in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;
1739 +                       memcpy(&in6->s6_addr32[0], &faith_prefix,
1740 +                           sizeof(struct in6_addr) - sizeof(struct in_addr));
1741 +                       memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));
1742 +               } else
1743 +#endif /* FAITH */
1744 +               GET_AI(cur->ai_next, afd, ap, port);
1745 +               if (cur == &sentinel) {
1746 +                       top = cur->ai_next;
1747 +                       GET_CANONNAME(top, hp->h_name);
1748 +               }
1749 +               cur = cur->ai_next;
1750 +       }
1751 +#ifdef INET6
1752 +       freehostent(hp);
1753 +#endif
1754 +       *res = top;
1755 +       return SUCCESS;
1756 + free:
1757 +       if (top)
1758 +               freeaddrinfo(top);
1759 +#ifdef INET6
1760 +       if (hp)
1761 +               freehostent(hp);
1762 +#endif
1763 + bad:
1764 +       *res = NULL;
1765 +       return error;
1766 +}
1767 Index: ncftp3/libncftp/getnameinfo.c
1768 diff -u /dev/null ncftp3/libncftp/getnameinfo.c:1.1
1769 --- /dev/null   Mon Nov  9 21:52:32 2009
1770 +++ ncftp3/libncftp/getnameinfo.c       Tue Nov  6 23:50:47 2001
1771 @@ -0,0 +1,203 @@
1772 +/*
1773 + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
1774 + * All rights reserved.
1775 + * 
1776 + * Redistribution and use in source and binary forms, with or without
1777 + * modification, are permitted provided that the following conditions
1778 + * are met:
1779 + * 1. Redistributions of source code must retain the above copyright
1780 + *    notice, this list of conditions and the following disclaimer.
1781 + * 2. Redistributions in binary form must reproduce the above copyright
1782 + *    notice, this list of conditions and the following disclaimer in the
1783 + *    documentation and/or other materials provided with the distribution.
1784 + * 3. Neither the name of the project nor the names of its contributors
1785 + *    may be used to endorse or promote products derived from this software
1786 + *    without specific prior written permission.
1787 + * 
1788 + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1789 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1790 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1791 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
1792 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1793 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1794 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1795 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1796 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1797 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1798 + * SUCH DAMAGE.
1799 + */
1800 +
1801 +/*
1802 + * Issues to be discussed:
1803 + * - Thread safe-ness must be checked
1804 + * - Return values.  There seems to be no standard for return value (RFC2133)
1805 + *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
1806 + */
1807 +
1808 +#include <sys/types.h>
1809 +#include <sys/socket.h>
1810 +#include <netinet/in.h>
1811 +#include <arpa/inet.h>
1812 +#include <arpa/nameser.h>
1813 +#include <netdb.h>
1814 +#include <resolv.h>
1815 +#include <string.h>
1816 +#include <stddef.h>
1817 +
1818 +#include "addrinfo.h"
1819 +
1820 +#define SUCCESS 0
1821 +#define ANY 0
1822 +#define YES 1
1823 +#define NO  0
1824 +
1825 +static struct afd {
1826 +       int a_af;
1827 +       int a_addrlen;
1828 +       int a_socklen;
1829 +       int a_off;
1830 +} afdl [] = {
1831 +#ifdef INET6
1832 +       {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
1833 +               offsetof(struct sockaddr_in6, sin6_addr)},
1834 +#endif
1835 +       {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
1836 +               offsetof(struct sockaddr_in, sin_addr)},
1837 +       {0, 0, 0},
1838 +};
1839 +
1840 +struct sockinet {
1841 +       u_char  si_len;
1842 +       u_char  si_family;
1843 +       u_short si_port;
1844 +};
1845 +
1846 +#define ENI_NOSOCKET   0
1847 +#define ENI_NOSERVNAME 1
1848 +#define ENI_NOHOSTNAME 2
1849 +#define ENI_MEMORY     3
1850 +#define ENI_SYSTEM     4
1851 +#define ENI_FAMILY     5
1852 +#define ENI_SALEN      6
1853 +
1854 +int
1855 +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
1856 +       const struct sockaddr *sa;
1857 +       size_t salen;
1858 +       char *host;
1859 +       size_t hostlen;
1860 +       char *serv;
1861 +       size_t servlen;
1862 +       int flags;
1863 +{
1864 +       struct afd *afd;
1865 +       struct servent *sp;
1866 +       struct hostent *hp;
1867 +       u_short port;
1868 +       int family, len, i;
1869 +       char *addr, *p;
1870 +       u_long v4a;
1871 +       u_char pfx;
1872 +       int h_error;
1873 +       char numserv[512];
1874 +       char numaddr[512];
1875 +
1876 +       if (sa == NULL)
1877 +               return ENI_NOSOCKET;
1878 +
1879 +       len = sa->sa_len;
1880 +       if (len != salen) return ENI_SALEN;
1881 +       
1882 +       family = sa->sa_family;
1883 +       for (i = 0; afdl[i].a_af; i++)
1884 +               if (afdl[i].a_af == family) {
1885 +                       afd = &afdl[i];
1886 +                       goto found;
1887 +               }
1888 +       return ENI_FAMILY;
1889 +       
1890 + found:
1891 +       if (len != afd->a_socklen) return ENI_SALEN;
1892 +       
1893 +       port = ((struct sockinet *)sa)->si_port; /* network byte order */
1894 +       addr = (char *)sa + afd->a_off;
1895 +
1896 +       if (serv == NULL || servlen == 0) {
1897 +               /* what we should do? */
1898 +       } else if (flags & NI_NUMERICSERV) {
1899 +               snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
1900 +               if (strlen(numserv) > servlen)
1901 +                       return ENI_MEMORY;
1902 +               strcpy(serv, numserv);
1903 +       } else {
1904 +               sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
1905 +               if (sp) {
1906 +                       if (strlen(sp->s_name) > servlen)
1907 +                               return ENI_MEMORY;
1908 +                       strcpy(serv, sp->s_name);
1909 +               } else
1910 +                       return ENI_NOSERVNAME;
1911 +       }
1912 +
1913 +       switch (sa->sa_family) {
1914 +       case AF_INET:
1915 +               v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
1916 +               if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
1917 +                       flags |= NI_NUMERICHOST;
1918 +               v4a >>= IN_CLASSA_NSHIFT;
1919 +               if (v4a == 0 || v4a == IN_LOOPBACKNET)
1920 +                       flags |= NI_NUMERICHOST;                        
1921 +               break;
1922 +#ifdef INET6
1923 +       case AF_INET6:
1924 +               pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
1925 +               if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
1926 +                       flags |= NI_NUMERICHOST;
1927 +               break;
1928 +#endif
1929 +       }
1930 +       if (host == NULL || hostlen == 0) {
1931 +               /* what should we do? */
1932 +       } else if (flags & NI_NUMERICHOST) {
1933 +               if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
1934 +                   == NULL)
1935 +                       return ENI_SYSTEM;
1936 +               if (strlen(numaddr) > hostlen)
1937 +                       return ENI_MEMORY;
1938 +               strcpy(host, numaddr);
1939 +       } else {
1940 +#ifdef INET6
1941 +               hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
1942 +#else
1943 +               hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
1944 +               h_error = h_errno;
1945 +#endif
1946 +
1947 +               if (hp) {
1948 +                       if (flags & NI_NOFQDN) {
1949 +                               p = strchr(hp->h_name, '.');
1950 +                               if (p) *p = '\0';
1951 +                       }
1952 +                       if (strlen(hp->h_name) > hostlen) {
1953 +#ifdef INET6
1954 +                               freehostent(hp);
1955 +#endif
1956 +                               return ENI_MEMORY;
1957 +                       }
1958 +                       strcpy(host, hp->h_name);
1959 +#ifdef INET6
1960 +                       freehostent(hp);
1961 +#endif
1962 +               } else {
1963 +                       if (flags & NI_NAMEREQD)
1964 +                               return ENI_NOHOSTNAME;
1965 +                       if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
1966 +                           == NULL)
1967 +                               return ENI_NOHOSTNAME;
1968 +                       if (strlen(numaddr) > hostlen)
1969 +                               return ENI_MEMORY;
1970 +                       strcpy(host, numaddr);
1971 +               }
1972 +       }
1973 +       return SUCCESS;
1974 +}
1975 Index: ncftp3/libncftp/ncftp.h
1976 diff -u ncftp3/libncftp/ncftp.h:1.1.1.23 ncftp3/libncftp/ncftp.h:1.28
1977 --- ncftp3/libncftp/ncftp.h:1.1.1.23    Thu Nov  5 16:20:41 2009
1978 +++ ncftp3/libncftp/ncftp.h     Thu Nov  5 16:47:09 2009
1979 @@ -378,11 +378,10 @@
1980         int mlsFeatures;                        /* Do not modify this field. */
1981         int STATfileParamWorks;                 /* Do not modify this field. */
1982         int NLSTfileParamWorks;                 /* Do not modify this field. */
1983 -
1984 -       struct sockaddr_in servCtlAddr;         /* Do not modify this field. */
1985 -       struct sockaddr_in servDataAddr;        /* Do not modify this field. */
1986 -       struct sockaddr_in ourCtlAddr;          /* Do not modify this field. */
1987 -       struct sockaddr_in ourDataAddr;         /* Do not modify this field. */
1988 +       struct sockaddr_storage servCtlAddr;    /* Do not modify this field. */
1989 +       struct sockaddr_storage servDataAddr;   /* Do not modify this field. */
1990 +       struct sockaddr_storage ourCtlAddr;     /* Do not modify this field. */
1991 +       struct sockaddr_storage ourDataAddr;    /* Do not modify this field. */
1992         int netMode;                            /* Do not use or modify. */
1993         char *buf;                              /* Do not modify this field. */
1994         size_t bufSize;                         /* Do not modify this field. */
1995 @@ -997,8 +996,8 @@
1996  
1997  /* Everything else below are private routines, or stuff for testing */
1998  int FTPInitConnectionInfo2(const FTPLIPtr lip, const FTPCIPtr cip, char *const buf, size_t bufSize);
1999 -int FTPSendPort(const FTPCIPtr cip, struct sockaddr_in *saddr);
2000 -int FTPSendPassive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird);
2001 +int FTPSendPort(const FTPCIPtr cip, struct sockaddr *saddr);
2002 +int FTPSendPassive(const FTPCIPtr cip, struct sockaddr *saddr, int *weird);
2003  int FTPSetStartOffset(const FTPCIPtr cip, longest_int restartPt);
2004  void FTPCloseControlConnection(const FTPCIPtr cip);
2005  int FTPSendCommandStr(const FTPCIPtr cip, char *const command, const size_t siz);
2006 @@ -1060,7 +1059,7 @@
2007  int FTPFileExists2(const FTPCIPtr cip, const char *const file, const int tryMDTM, const int trySIZE, const int tryMLST, const int trySTAT, const int tryNLST);
2008  
2009  void FTPGetDateStr(time_t t, const char *fmt, char *const ltstr1, const size_t ltstr1size, char *const gtstr1, const size_t gtstr1size);
2010 -int BindToEphemeralPortNumber(const int sockfd, struct sockaddr_in *const addrp, const int ephemLo, const int ephemHi);
2011 +int BindToEphemeralPortNumber(const int sockfd, struct sockaddr *const addrp, const int ephemLo, const int ephemHi);
2012  int BufferGets(char *, size_t, int, char *, char **, char **, size_t);
2013  void DisposeFileInfoListContents(FTPFileInfoListPtr);
2014  void InitFileInfoList(FTPFileInfoListPtr);
2015 Index: ncftp3/libncftp/syshdrs.h
2016 diff -u ncftp3/libncftp/syshdrs.h:1.1.1.15 ncftp3/libncftp/syshdrs.h:1.14
2017 --- ncftp3/libncftp/syshdrs.h:1.1.1.15  Thu Nov  5 16:20:41 2009
2018 +++ ncftp3/libncftp/syshdrs.h   Thu Nov  5 16:47:09 2009
2019 @@ -24,6 +24,10 @@
2020  #              define _WIN32_WINNT 0x0400
2021  #      endif
2022  #      include <windows.h>             /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2023 +#      ifdef ENABLE_IPV6
2024 +#      include <ws2tcpip.h>
2025 +#      define INET6_ADDRSTRLEN 46
2026 +#      endif /* ENABLE_IPV6 */
2027  #      include <shlobj.h>
2028  #      include <io.h>
2029  #      include <conio.h>
2030 @@ -164,6 +168,9 @@
2031  #              include <resolv.h>
2032  #      endif
2033  
2034 +#      ifndef HAVE_GETADDRINFO
2035 +#      include "addrinfo.h"
2036 +#      endif
2037  #      ifdef CAN_USE_SYS_SELECT_H
2038  #              include <sys/select.h>
2039  #      endif
2040 --- ncftp-3.2.5/ncftp/cmds.c.orig       2010-04-05 21:33:21.000000000 +0200
2041 +++ ncftp-3.2.5/ncftp/cmds.c    2011-03-27 15:37:19.813736435 +0200
2042 @@ -2580,8 +2580,7 @@
2043                          return (-1);
2044                  }
2045  #endif
2046 -               (void) STRNCPY(gConn.host, ipstr);
2047 -               OpenMsg("Connecting to %s...", ipstr);
2048 +               OpenMsg("Connecting to %s...", gConn.host);
2049         } else {
2050                 OpenMsg("Connecting to %s via %s...", gConn.host, gConn.firewallHost);
2051                 Trace(0, "Fw: %s  Type: %d  User: %s  Pass: %s  Port: %u\n", 
2052 @@ -3784,8 +3783,8 @@
2053         char preferredLocalAddrStr[64];
2054  
2055         preferredLocalAddrStr[0] = '\0';
2056 -       if (gConn.preferredLocalAddr.sin_family != 0)
2057 -               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), &gConn.preferredLocalAddr, 0, "%h");
2058 +       if (gConn.preferredLocalAddr.sin_family == AF_INET)
2059 +               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), (struct sockaddr *)&gConn.preferredLocalAddr, 0, "%h");
2060  
2061         if (ftwip->depth >= 50) {
2062                 Trace(-1, "Aborting -- recursion depth is %u.\nPerhaps an infinite loop exists on the remote filesystem?", (unsigned int) ftwip->depth);
2063 @@ -3952,8 +3951,8 @@
2064         char preferredLocalAddrStr[64];
2065  
2066         preferredLocalAddrStr[0] = '\0';
2067 -       if (gConn.preferredLocalAddr.sin_family != 0)
2068 -               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), &gConn.preferredLocalAddr, 0, "%h");
2069 +       if (gConn.preferredLocalAddr.sin_family == AF_INET)
2070 +               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), (struct sockaddr *)&gConn.preferredLocalAddr, 0, "%h");
2071  
2072         cinfo.xtype = gBm.xferType;
2073         cinfo.deleteFlag = kDeleteNo;
2074 @@ -4160,8 +4159,8 @@
2075         char preferredLocalAddrStr[64];
2076  
2077         preferredLocalAddrStr[0] = '\0';
2078 -       if (gConn.preferredLocalAddr.sin_family != 0)
2079 -               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), &gConn.preferredLocalAddr, 0, "%h");
2080 +       if (gConn.preferredLocalAddr.sin_family == AF_INET)
2081 +               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), (struct sockaddr *)&gConn.preferredLocalAddr, 0, "%h");
2082  
2083         cinfop = (SpoolCmdInfo *) ftwip->userdata;
2084         /* rerpath = ftwip->curPath + ftwip->startPathLen + 1; */
2085 @@ -4321,8 +4320,8 @@
2086         char preferredLocalAddrStr[64];
2087  
2088         preferredLocalAddrStr[0] = '\0';
2089 -       if (gConn.preferredLocalAddr.sin_family != 0)
2090 -               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), &gConn.preferredLocalAddr, 0, "%h");
2091 +       if (gConn.preferredLocalAddr.sin_family == AF_INET)
2092 +               AddrToAddrStr(preferredLocalAddrStr, sizeof(preferredLocalAddrStr), (struct sockaddr *)&gConn.preferredLocalAddr, 0, "%h");
2093  
2094         cinfo.xtype = gBm.xferType;
2095         cinfo.deleteFlag = kDeleteNo;
2096 Index: ncftp3/ncftp/syshdrs.h
2097 diff -u ncftp3/ncftp/syshdrs.h:1.1.1.15 ncftp3/ncftp/syshdrs.h:1.13
2098 --- ncftp3/ncftp/syshdrs.h:1.1.1.15     Thu Nov  5 16:20:41 2009
2099 +++ ncftp3/ncftp/syshdrs.h      Thu Nov  5 16:47:09 2009
2100 @@ -33,6 +33,9 @@
2101  #              define _WIN32_WINNT 0x0400
2102  #      endif
2103  #      include <windows.h>             /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2104 +#ifdef ENABLE_IPV6
2105 +#      include <ws2tcpip.h>
2106 +#endif /* ENABLE_IPV6 */
2107  #      include <shlobj.h>
2108  #      include <process.h>
2109  #      include <direct.h>
2110 @@ -174,6 +177,9 @@
2111  #      include <time.h>
2112  #      include <pwd.h>
2113  #      include <fcntl.h>
2114 +#      ifndef HAVE_GETADDRINFO
2115 +#              include "addrinfo.h"
2116 +#      endif
2117  #      if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
2118  #              include <sys/ioctl.h>
2119  #              include <termios.h>
2120 --- ncftp-3.2.5/ncftp/util.c.orig       2010-10-30 23:34:25.000000000 +0200
2121 +++ ncftp-3.2.5/ncftp/util.c    2011-03-27 15:41:18.901729730 +0200
2122 @@ -666,47 +666,29 @@
2123  int
2124  MyGetHostByName(char *const volatile dst, size_t dsize, const char *const hn, int t)
2125  {
2126 +       struct addrinfo hints;
2127 +       struct addrinfo *res;
2128 +       int error;
2129  #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
2130 -       struct hostent *hp;
2131 -       struct in_addr ina;
2132 -
2133 -       if (inet_addr(hn) != (unsigned long) 0xFFFFFFFF) {
2134 -               /* Address is an IP address string, which is what we want. */
2135 -               (void) Strncpy(dst, hn, dsize);
2136 -               return (0);
2137 -       }
2138 -
2139 -       hp = gethostbyname(hn);
2140 -       if (hp != NULL) {
2141 -               (void) memcpy(&ina.s_addr, hp->h_addr_list[0], (size_t) hp->h_length);
2142 -               InetNtoA(dst, ((struct in_addr **) hp->h_addr_list)[0], dsize);
2143 +       memset(&hints, 0, sizeof(hints));
2144 +       hints.ai_family = PF_UNSPEC;
2145 +       hints.ai_socktype = SOCK_STREAM;
2146 +       error = getaddrinfo(hn, NULL, &hints, &res);
2147 +
2148 +       if (error == 0) {
2149 +               char buf[NI_MAXHOST];
2150 +
2151 +               getnameinfo(res->ai_addr, res->ai_addrlen,
2152 +                           buf, sizeof(buf),
2153 +                           NULL, 0, NI_NUMERICHOST);
2154 +               (void) Strncpy(dst, buf, dsize);
2155 +               freeaddrinfo(res);
2156                 return (0);
2157         }
2158  
2159  #else
2160         int sj;
2161         vsigproc_t osigpipe, osigint, osigalrm;
2162 -       struct hostent *hp;
2163 -#ifdef HAVE_INET_ATON
2164 -       struct in_addr ina;
2165 -#endif
2166 -#ifdef DNSSEC_LOCAL_VALIDATION
2167 -        val_status_t val_status;
2168 -#endif
2169 -
2170 -#ifdef HAVE_INET_ATON
2171 -       if (inet_aton(hn, &ina) != 0) {
2172 -               /* Address is an IP address string, which is what we want. */
2173 -               (void) Strncpy(dst, hn, dsize);
2174 -               return (0);
2175 -       }
2176 -#else
2177 -       if (inet_addr(hn) != (unsigned long) 0xFFFFFFFF) {
2178 -               /* Address is an IP address string, which is what we want. */
2179 -               (void) Strncpy(dst, hn, dsize);
2180 -               return (0);
2181 -       }
2182 -#endif
2183  
2184  #ifdef HAVE_SIGSETJMP
2185         osigpipe = osigint = osigalrm = (sigproc_t) 0;
2186 @@ -731,30 +713,27 @@
2187                 osigalrm = NcSignal(SIGALRM, CancelGetHostByName);
2188                 if (t > 0)
2189                         (void) alarm((unsigned int) t);
2190 -#ifndef DNSSEC_LOCAL_VALIDATION
2191 -               hp = gethostbyname(hn);
2192 -#else
2193 -                hp = val_gethostbyname(NULL, hn, &val_status);
2194 -#endif
2195 +               memset(&hints, 0, sizeof(hints));
2196 +               hints.ai_flags = 0;
2197 +               hints.ai_family = PF_UNSPEC;
2198 +               hints.ai_socktype = SOCK_STREAM;
2199 +               hints.ai_protocol = 0;
2200 +               error = getaddrinfo(hn, NULL, &hints, &res);
2201                 if (t > 0)
2202                         (void) alarm(0);
2203                 (void) NcSignal(SIGPIPE, osigpipe);
2204                 (void) NcSignal(SIGINT, osigint);
2205                 (void) NcSignal(SIGALRM, osigalrm);
2206 -#ifdef DNSSEC_LOCAL_VALIDATION
2207 -                /*
2208 -                 * It would be nice to pass a little more information back,
2209 -                 * but that would mean an API change to MyGetHostByName.
2210 -                 */
2211 -                if ((hp != NULL) && ! val_istrusted(val_status)) {
2212 -                    *dst = '\0';
2213 -                    return (-2);
2214 -                }
2215 -#endif
2216 -               if (hp != NULL) {
2217 -                       InetNtoA(dst, ((struct in_addr **) hp->h_addr_list)[0], dsize);
2218 -                       return (0);
2219 -               }
2220 +               if (error == 0) {
2221 +                       char buf[NI_MAXHOST];
2222 +
2223 +                       getnameinfo(res->ai_addr, res->ai_addrlen,
2224 +                                   buf, sizeof(buf),
2225 +                                   NULL, 0, NI_NUMERICHOST);
2226 +                       (void) Strncpy(dst, buf, dsize);
2227 +                       freeaddrinfo(res);
2228 +                       return (0);
2229 +               }
2230         }
2231  #endif /* !Windows */
2232  
2233 Index: ncftp3/sh_util/ncftpbatch.c
2234 diff -u ncftp3/sh_util/ncftpbatch.c:1.1.1.20 ncftp3/sh_util/ncftpbatch.c:1.2
2235 --- ncftp3/sh_util/ncftpbatch.c:1.1.1.20        Thu Nov  5 16:20:41 2009
2236 +++ ncftp3/sh_util/ncftpbatch.c Mon Nov  9 21:51:14 2009
2237 @@ -1203,7 +1203,7 @@
2238                 }
2239  
2240                 if (gSourceAddrStr[0] != '\0')
2241 -                       (void) AddrStrToAddr(gSourceAddrStr, &gConn.preferredLocalAddr, 21);
2242 +                       (void) AddrStrToAddr(gSourceAddrStr, (struct sockaddr *)&gConn.preferredLocalAddr, 21);
2243                 
2244                 gConn.connTimeout = 30;
2245                 gConn.ctrlTimeout = 135;
2246 Index: ncftp3/sh_util/ncftpget.c
2247 diff -u ncftp3/sh_util/ncftpget.c:1.1.1.19 ncftp3/sh_util/ncftpget.c:1.2
2248 --- ncftp3/sh_util/ncftpget.c:1.1.1.19  Thu Nov  5 16:20:41 2009
2249 +++ ncftp3/sh_util/ncftpget.c   Mon Nov  9 21:51:14 2009
2250 @@ -371,7 +371,7 @@
2251                         ftpcat = 2;
2252                         break;
2253                 case 'I':
2254 -                       if (AddrStrToAddr(opt.arg, &fi.preferredLocalAddr, 21) < 0) {
2255 +                       if (AddrStrToAddr(opt.arg, (struct sockaddr *)&fi.preferredLocalAddr, 21) < 0) {
2256                                 fprintf(stderr, "Bad IP address (\"%s\") used with -I.\n", opt.arg);
2257                                 Usage();
2258                         }
2259 Index: ncftp3/sh_util/ncftpls.c
2260 diff -u ncftp3/sh_util/ncftpls.c:1.1.1.16 ncftp3/sh_util/ncftpls.c:1.2
2261 --- ncftp3/sh_util/ncftpls.c:1.1.1.16   Thu Nov  5 16:20:41 2009
2262 +++ ncftp3/sh_util/ncftpls.c    Mon Nov  9 21:51:14 2009
2263 @@ -489,7 +489,7 @@
2264                         do_listings = 0;
2265                         break;
2266                 case 'I':
2267 -                       if (AddrStrToAddr(opt.arg, &fi.preferredLocalAddr, 21) < 0) {
2268 +                       if (AddrStrToAddr(opt.arg, (struct sockaddr *)&fi.preferredLocalAddr, 21) < 0) {
2269                                 fprintf(stderr, "Bad IP address (\"%s\") used with -I.\n", opt.arg);
2270                                 Usage();
2271                         }
2272 Index: ncftp3/sh_util/ncftpput.c
2273 diff -u ncftp3/sh_util/ncftpput.c:1.1.1.18 ncftp3/sh_util/ncftpput.c:1.2
2274 --- ncftp3/sh_util/ncftpput.c:1.1.1.18  Thu Nov  5 16:20:41 2009
2275 +++ ncftp3/sh_util/ncftpput.c   Mon Nov  9 21:51:14 2009
2276 @@ -388,7 +388,7 @@
2277                         STRNCAT(postcmd, "\n");
2278                         break;
2279                 case 'I':
2280 -                       if (AddrStrToAddr(opt.arg, &fi.preferredLocalAddr, 21) < 0) {
2281 +                       if (AddrStrToAddr(opt.arg, (struct sockaddr *)&fi.preferredLocalAddr, 21) < 0) {
2282                                 fprintf(stderr, "Bad IP address (\"%s\") used with -I.\n", opt.arg);
2283                                 Usage();
2284                         }
2285 Index: ncftp3/sh_util/syshdrs.h
2286 diff -u ncftp3/sh_util/syshdrs.h:1.1.1.11 ncftp3/sh_util/syshdrs.h:1.11
2287 --- ncftp3/sh_util/syshdrs.h:1.1.1.11   Thu Nov  5 16:20:41 2009
2288 +++ ncftp3/sh_util/syshdrs.h    Thu Nov  5 16:47:09 2009
2289 @@ -33,6 +33,9 @@
2290  #              define _WIN32_WINNT 0x0400
2291  #      endif
2292  #      include <windows.h>             /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2293 +#ifdef ENABLE_IPV6
2294 +#      include <ws2tcpip.h>
2295 +#endif /* ENABLE_IPV6 */
2296  #      include <shlobj.h>
2297  #      include <tchar.h>
2298  #      include <process.h>
2299 @@ -167,6 +170,9 @@
2300  #      include <pwd.h>
2301  #      include <fcntl.h>
2302  #      include <dirent.h>
2303 +#      ifndef HAVE_GETADDRINFO
2304 +#              include "addrinfo.h"
2305 +#      endif
2306  #      ifdef HAVE_LOCALE_H
2307  #              include <locale.h>
2308  #      endif
2309 Index: ncftp3/sio/SAccept.c
2310 diff -u ncftp3/sio/SAccept.c:1.1.1.1 ncftp3/sio/SAccept.c:1.4
2311 --- ncftp3/sio/SAccept.c:1.1.1.1        Thu Jan  8 19:51:19 2004
2312 +++ ncftp3/sio/SAccept.c        Wed Aug 25 21:33:11 2004
2313 @@ -3,8 +3,20 @@
2314  #      pragma hdrstop
2315  #endif
2316  
2317 +#ifndef HAVE_SOCKADDR_SA_LEN
2318 +#ifndef SA_LEN
2319 +#ifdef ENABLE_IPV6
2320 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2321 +               : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
2322 +               : -1))
2323 +#else  /* ENABLE_IPV6 */
2324 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
2325 +#endif /* ENABLE_IPV6 */
2326 +#endif /* SA_LEN */
2327 +#endif /* HAVE_SOCKADDR_SA_LEN */
2328 +
2329  int
2330 -SAccept(int sfd, struct sockaddr_in *const addr, int tlen)
2331 +SAccept(int sfd, struct sockaddr *const addr, int tlen)
2332  {
2333         int result;
2334         fd_set ss;
2335 @@ -22,7 +34,7 @@
2336         if (tlen <= 0) {
2337                 errno = 0;
2338                 for (;;) {
2339 -                       size = (sockaddr_size_t) sizeof(struct sockaddr_in);
2340 +                       size = (sockaddr_size_t) sizeof(struct sockaddr_storage);
2341                         result = accept(sfd, (struct sockaddr *) addr, &size);
2342                         if ((result >= 0) || (errno != EINTR)) {
2343                                 RESTORE_SIGPIPE
2344 @@ -61,7 +73,7 @@
2345         }
2346  
2347         do {
2348 -               size = (sockaddr_size_t) sizeof(struct sockaddr_in);
2349 +               size = (sockaddr_size_t) sizeof(struct sockaddr_storage);
2350                 result = accept(sfd, (struct sockaddr *) addr, &size);
2351         } while ((result < 0) && (errno == EINTR));
2352  
2353 Index: ncftp3/sio/SConnect.c
2354 diff -u ncftp3/sio/SConnect.c:1.1.1.10 ncftp3/sio/SConnect.c:1.18
2355 --- ncftp3/sio/SConnect.c:1.1.1.10      Thu Nov  5 16:20:41 2009
2356 +++ ncftp3/sio/SConnect.c       Thu Nov  5 16:47:09 2009
2357 @@ -3,14 +3,30 @@
2358  #      pragma hdrstop
2359  #endif
2360  
2361 -int _SConnect(const int sfd, const struct sockaddr_in *const addr, const size_t saddrsiz, const int tlen);
2362 +int _SConnect(const int sfd, const struct sockaddr *const addr, const size_t saddrsiz, const int tlen);
2363 +
2364 +#ifndef HAVE_SOCKADDR_SA_LEN
2365 +#ifndef SA_LEN
2366 +#ifdef ENABLE_IPV6
2367 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2368 +               : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
2369 +               : -1))
2370 +#else  /* ENABLE_IPV6 */
2371 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
2372 +#endif /* ENABLE_IPV6 */
2373 +#endif /* SA_LEN */
2374 +#endif /* HAVE_SOCKADDR_SA_LEN */
2375  
2376  int
2377 -SConnect(int sfd, const struct sockaddr_in *const addr, int tlen)
2378 +SConnect(int sfd, const struct sockaddr *const addr, int tlen)
2379  {
2380         int result;
2381         
2382 -       result = _SConnect(sfd, addr, (size_t) sizeof(struct sockaddr_in), tlen);
2383 +#ifdef HAVE_SOCKADDR_SA_LEN
2384 +       result = _SConnect(sfd, addr, addr->sa_len, tlen);
2385 +#else
2386 +       result = _SConnect(sfd, addr, SA_LEN(addr), tlen);
2387 +#endif
2388         return (result);
2389  }      /* SConnect */
2390  
2391 @@ -54,7 +70,7 @@
2392  
2393  
2394  int
2395 -_SConnect(const int sfd, const struct sockaddr_in *const addr, const size_t saddrsiz, const int tlen)
2396 +_SConnect(const int sfd, const struct sockaddr *const addr, const size_t saddrsiz, const int tlen)
2397  {
2398         fd_set ss, xx;
2399         struct timeval tv;
2400 Index: ncftp3/sio/SConnectByName.c
2401 diff -u ncftp3/sio/SConnectByName.c:1.1.1.3 ncftp3/sio/SConnectByName.c:1.3
2402 --- ncftp3/sio/SConnectByName.c:1.1.1.3 Thu Jan  8 19:51:16 2004
2403 +++ ncftp3/sio/SConnectByName.c Thu Jan  8 20:09:33 2004
2404 @@ -7,15 +7,15 @@
2405  SConnectByName(int sfd, const char * const addrStr, const int tlen)
2406  {
2407         int result;
2408 -       struct sockaddr_in remoteAddr;
2409 +       struct sockaddr_storage remoteAddr;
2410         
2411         if (addrStr == NULL) {
2412                 errno = EINVAL;
2413                 return (-1);
2414         }
2415  
2416 -       if ((result = AddrStrToAddr(addrStr, &remoteAddr, -1)) == 0) {
2417 -               result = SConnect(sfd, &remoteAddr, tlen);
2418 +       if ((result = AddrStrToAddr(addrStr, (struct sockaddr *)&remoteAddr, -1)) == 0) {
2419 +               result = SConnect(sfd, (struct sockaddr *)&remoteAddr, tlen);
2420         }
2421         return (result);
2422  }      /* SConnectByName */
2423 Index: ncftp3/sio/SRecvfrom.c
2424 diff -u ncftp3/sio/SRecvfrom.c:1.1.1.5 ncftp3/sio/SRecvfrom.c:1.4
2425 --- ncftp3/sio/SRecvfrom.c:1.1.1.5      Thu Jan  8 19:51:18 2004
2426 +++ ncftp3/sio/SRecvfrom.c      Thu Jan  8 20:09:33 2004
2427 @@ -4,7 +4,7 @@
2428  #endif
2429  
2430  int
2431 -SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_in *const fromAddr, int tlen)
2432 +SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr *const fromAddr, int tlen)
2433  {
2434         recv_return_t nread;
2435         int tleft;
2436 @@ -56,7 +56,7 @@
2437  
2438                 IGNORE_SIGPIPE
2439                 nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
2440 -                       (struct sockaddr *) fromAddr, &alen);
2441 +                       fromAddr, &alen);
2442                 RESTORE_SIGPIPE
2443  
2444                 if (nread >= 0)
2445 Index: ncftp3/sio/SSendto.c
2446 diff -u ncftp3/sio/SSendto.c:1.1.1.5 ncftp3/sio/SSendto.c:1.5
2447 --- ncftp3/sio/SSendto.c:1.1.1.5        Thu Jan  8 19:51:18 2004
2448 +++ ncftp3/sio/SSendto.c        Thu Jan  8 20:09:33 2004
2449 @@ -3,8 +3,21 @@
2450  #      pragma hdrstop
2451  #endif
2452  
2453 +#ifndef HAVE_SOCKADDR_SA_LEN
2454 +#ifndef SA_LEN
2455 +#ifdef ENABLE_IPV6
2456 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2457 +                               : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
2458 +                                                       : -1))
2459 +#else  /* ENABLE_IPV6 */
2460 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
2461 +#endif /* ENABLE_IPV6 */
2462 +#endif /* SA_LEN */
2463 +#endif /* HAVE_SOCKADDR_SA_LEN */
2464 +
2465 +
2466  int
2467 -SSendto(int sfd, const char *const buf, size_t size, int fl, const struct sockaddr_in *const toAddr, int tlen)
2468 +SSendto(int sfd, const char *const buf, size_t size, int fl, const struct sockaddr *const toAddr, int tlen)
2469  {
2470         send_return_t nwrote;
2471         int tleft;
2472 @@ -58,9 +71,15 @@
2473                 }
2474  
2475                 IGNORE_SIGPIPE
2476 +#ifdef HAVE_SOCKADDR_SA_LEN
2477 +               nwrote = sendto(sfd, buf, (send_size_t) size, fl,
2478 +                       toAddr,
2479 +                       toAddr->sa_len);
2480 +#else
2481                 nwrote = sendto(sfd, buf, (send_size_t) size, fl,
2482 -                       (const struct sockaddr *) toAddr,
2483 -                       (sockaddr_size_t) sizeof(struct sockaddr_in));
2484 +                        toAddr,
2485 +                        SA_LEN(toAddr));
2486 +#endif
2487                 RESTORE_SIGPIPE
2488  
2489                 if (nwrote >= 0)
2490 @@ -77,7 +96,7 @@
2491  
2492  
2493  int
2494 -Sendto(int sfd, const char *const buf, size_t size, const struct sockaddr_in *const toAddr)
2495 +Sendto(int sfd, const char *const buf, size_t size, const struct sockaddr *toAddr)
2496  {
2497         int result;
2498         DECL_SIGPIPE_VARS
2499 @@ -89,9 +108,15 @@
2500         
2501         IGNORE_SIGPIPE
2502         do {
2503 +#ifdef HAVE_SOCKADDR_SA_LEN
2504 +               result = (int) sendto(sfd, buf, (send_size_t) size, 0,
2505 +                               toAddr,
2506 +                               toAddr->sa_len);
2507 +#else
2508                 result = (int) sendto(sfd, buf, (send_size_t) size, 0,
2509 -                               (const struct sockaddr *) toAddr,
2510 -                               (sockaddr_size_t) sizeof(struct sockaddr_in));
2511 +                                toAddr,
2512 +                                SA_LEN(toAddr));
2513 +#endif
2514         } while ((result < 0) && (errno == EINTR));
2515         RESTORE_SIGPIPE
2516         return (result);
2517 Index: ncftp3/sio/SSendtoByName.c
2518 diff -u ncftp3/sio/SSendtoByName.c:1.1.1.5 ncftp3/sio/SSendtoByName.c:1.4
2519 --- ncftp3/sio/SSendtoByName.c:1.1.1.5  Thu Jan  8 19:51:18 2004
2520 +++ ncftp3/sio/SSendtoByName.c  Thu Jan  8 20:09:33 2004
2521 @@ -11,7 +11,7 @@
2522         time_t done, now;
2523         fd_set ss;
2524         struct timeval tv;
2525 -       struct sockaddr_in toAddr;
2526 +       struct sockaddr_storage toAddr;
2527         DECL_SIGPIPE_VARS
2528         
2529         if ((buf == NULL) || (size == 0) || (toAddrStr == NULL) || (toAddrStr[0] == '\0') || (tlen <= 0)) {
2530 @@ -19,7 +19,7 @@
2531                 return (-1);
2532         }
2533  
2534 -       if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) {
2535 +       if ((result = AddrStrToAddr(toAddrStr, (struct sockaddr *)&toAddr, -1)) < 0) {
2536                 return (result);
2537         }
2538  
2539 @@ -81,7 +81,7 @@
2540  SendtoByName(int sfd, const char *const buf, size_t size, const char *const toAddrStr)
2541  {
2542         int result;
2543 -       struct sockaddr_in toAddr;
2544 +       struct sockaddr_storage toAddr;
2545         DECL_SIGPIPE_VARS
2546         
2547         if ((buf == NULL) || (size == 0) || (toAddrStr == NULL)) {
2548 @@ -89,8 +89,7 @@
2549                 return (-1);
2550         }
2551         
2552 -
2553 -       if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) {
2554 +       if ((result = AddrStrToAddr(toAddrStr, (struct sockaddr *)&toAddr, -1)) < 0) {
2555                 return (result);
2556         }
2557  
2558 --- ncftp-3.2.5/sio/StrAddr.c.orig      2009-10-24 01:31:23.000000000 +0200
2559 +++ ncftp-3.2.5/sio/StrAddr.c   2011-03-27 15:42:56.665738111 +0200
2560 @@ -6,6 +6,19 @@
2561  #      pragma hdrstop
2562  #endif
2563  
2564 +#ifndef HAVE_SOCKADDR_SA_LEN
2565 +#ifndef SA_LEN
2566 +#ifdef ENABLE_IPV6
2567 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2568 +                               : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
2569 +                                                       : -1))
2570 +#else  /* ENABLE_IPV6 */
2571 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
2572 +#endif /* ENABLE_IPV6 */
2573 +#endif /* SA_LEN */
2574 +#endif /* HAVE_SOCKADDR_SA_LEN */
2575 +
2576 +
2577  #ifndef INADDR_ANY
2578  #      define INADDR_ANY              ((unsigned long int) 0x00000000)
2579  #endif
2580 @@ -25,14 +38,10 @@
2581  {
2582         char str[64];
2583         char *cp;
2584 -#if defined(HAVE_GETSERVBYNAME_R) && (defined(AIX) || defined(TRU64UNIX) || defined(DIGITAL_UNIX))
2585 -       struct servent *sp;
2586 -#elif defined(HAVE_GETSERVBYNAME_R) && (defined(LINUX) || defined(SOLARIS) || defined(IRIX) || defined(BSDOS))
2587 -       struct servent se, *sp;
2588 -       char spbuf[256];
2589 -#else
2590 -       struct servent *sp;
2591 -#endif
2592 +       struct addrinfo hints, *res;
2593 +       int error;
2594 +       unsigned int port;
2595 +
2596         strncpy(str, s, sizeof(str) - 1);
2597         str[sizeof(str) - 1] = '\0';
2598         cp = str;
2599 @@ -49,55 +58,29 @@
2600         }
2601         *cp = '\0';
2602  
2603 -       sp = NULL;
2604 -#if defined(HAVE_GETSERVBYNAME_R) && (defined(SOLARIS) || defined(IRIX) || defined(BSDOS))
2605 -       if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
2606 -               memset(spbuf, 0, sizeof(spbuf));
2607 -               sp = getservbyname_r(str, "tcp", &se, spbuf, sizeof(spbuf));
2608 -       }
2609 -       if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2610 -               memset(spbuf, 0, sizeof(spbuf));
2611 -               sp = getservbyname_r(str, "udp", &se, spbuf, sizeof(spbuf));
2612 -       }
2613 -#elif defined(HAVE_GETSERVBYNAME_R) && defined(LINUX)
2614 -       if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
2615 -               memset(spbuf, 0, sizeof(spbuf));
2616 -               if (getservbyname_r(str, "tcp", &se, spbuf, sizeof(spbuf), &sp) != 0)
2617 -                       sp = NULL;
2618 -       }
2619 -       if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2620 -               memset(spbuf, 0, sizeof(spbuf));
2621 -               if (getservbyname_r(str, "udp", &se, spbuf, sizeof(spbuf), &sp) != 0)
2622 -                       sp = NULL;
2623 -       }
2624 -#elif defined(HAVE_GETSERVBYNAME_R) && defined(AIX)
2625 -       {
2626 -               struct servent_data sed;
2627 -               if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
2628 -                       memset(&sed, 0, sizeof(sed));
2629 -                       if (getservbyname_r(str, "tcp", sp, &sed) != 0)
2630 -                               sp = NULL;
2631 -               }
2632 -               if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2633 -                       memset(&sed, 0, sizeof(sed));
2634 -                       if (getservbyname_r(str, "udp", sp, &sed) != 0)
2635 -                               sp = NULL;
2636 -               }
2637 -       }
2638 -#else
2639 -       /* Note: getservbyname is already threadsafe on: HP-UX, Tru64 */
2640 -       if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
2641 -               sp = getservbyname(str, "tcp");
2642 -       }
2643 -       if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2644 -               sp = getservbyname(str, "udp");
2645 -       }
2646 -#endif
2647 -
2648 -       if (sp != NULL) {
2649 -               return ((unsigned int) ntohs((unsigned short) sp->s_port));
2650 +       error = 1;
2651 +       memset(&hints, 0, sizeof(hints));
2652 +       hints.ai_family = PF_UNSPEC;
2653 +       if ((error != 0) && ((proto == 0) || (proto == 't'))) {
2654 +               hints.ai_socktype = SOCK_STREAM;
2655 +               error = getaddrinfo(NULL, str, &hints, &res);
2656 +       }
2657 +       if ((error != 0) && ((proto == 0) || (proto == 'u'))) {
2658 +               hints.ai_socktype = SOCK_DGRAM;
2659 +               error = getaddrinfo(NULL, str, &hints, &res);
2660 +       }
2661 +       if (error != 0) {
2662 +               return (0);     /* error */
2663 +       }
2664 +       if (res->ai_addr->sa_family == AF_INET) {
2665 +               port = ((struct sockaddr_in *)res->ai_addr)->sin_port;
2666 +       } else if (res->ai_addr->sa_family == AF_INET6) {
2667 +               port = ((struct sockaddr_in6 *)res->ai_addr)->sin6_port;
2668 +       } else {
2669 +               port = 0;       /* error */
2670         }
2671 -       return (0);     /* error */
2672 +       freeaddrinfo(res);
2673 +       return ((unsigned int) ntohs((unsigned short) port));
2674  }      /* ServiceNameToPortNumber */
2675  
2676  
2677 @@ -203,15 +186,13 @@
2678  
2679  
2680  int
2681 -AddrStrToAddr(const char * const s, struct sockaddr_in * const sa, const int defaultport)
2682 +AddrStrToAddr(const char * const s, struct sockaddr * const sa, const int defaultport)
2683  {
2684 -       char portstr[128];
2685 -       unsigned int ipnum;
2686 -       unsigned int port;
2687 -       struct hostent *hp;
2688 -       char *hostcp, *atsign, *colon, *cp, *p2;
2689 +       char portstr[128], portstr2[128];
2690 +       struct addrinfo hints, *res;
2691 +       char *hostcp, *atsign, *colon, *cp, *p2, *portp;
2692 +       int error;
2693  
2694 -       memset(sa, 0, sizeof(struct sockaddr_in));
2695         strncpy(portstr, s, sizeof(portstr));
2696         portstr[sizeof(portstr) - 1] = '\0';
2697  
2698 @@ -219,7 +200,6 @@
2699                 /* Does it look like a URL?  http://host ? */
2700                 if ((colon[1] == '/') && (colon[2] == '/')) {
2701                         *colon = '\0';
2702 -                       port = 0;
2703                         hostcp = colon + 3;
2704                         for (cp = hostcp; *cp != '\0'; cp++) {
2705                                 if ((!ISALNUM(*cp)) && (*cp != '.')) {
2706 @@ -230,29 +210,27 @@
2707                                                 while (isdigit((int) *cp))
2708                                                         cp++;
2709                                                 *cp = '\0';
2710 -                                               port = atoi(p2);
2711                                         }
2712                                         *cp = '\0';
2713                                         break;
2714                                 }
2715                         }
2716 -                       if (port == 0)
2717 -                               port = ServiceNameToPortNumber(portstr, 0);
2718                 } else {
2719                         /* Look for host.name.domain:port */
2720                         *colon = '\0';
2721                         hostcp = portstr;
2722 -                       port = (unsigned int) atoi(colon + 1);
2723                 }
2724 +               portp = portstr;
2725         } else if ((atsign = strchr(portstr, '@')) != NULL) {
2726                 /* Look for port@host.name.domain */
2727                 *atsign = '\0';
2728                 hostcp = atsign + 1;
2729 -               port = (unsigned int) atoi(portstr);
2730 +               portp = portstr;
2731         } else if (defaultport > 0) {
2732                 /* Have just host.name.domain, use that w/ default port. */
2733 -               port = (unsigned int) defaultport;
2734 +               sprintf(portstr2, "%d", defaultport);
2735                 hostcp = portstr;
2736 +               portp = portstr2;
2737         } else {
2738                 /* If defaultport <= 0, they must supply a port number
2739                  * in the host/port string.
2740 @@ -260,33 +238,14 @@
2741                 errno = EADDRNOTAVAIL;
2742                 return (kAddrStrToAddrMiscErr);
2743         }
2744 -
2745 -       sa->sin_port = htons((short) port);
2746 -
2747 -       ipnum = inet_addr(hostcp);
2748 -       if (ipnum != INADDR_NONE) {
2749 -               sa->sin_family = AF_INET;
2750 -               sa->sin_addr.s_addr = ipnum;
2751 -       } else {
2752 -#ifdef DNSSEC_LOCAL_VALIDATION
2753 -               val_status_t val_status;
2754 -               errno = 0;
2755 -               hp = val_gethostbyname(NULL,hostcp,&val_status);
2756 -               if ((hp != NULL) && (!val_istrusted(val_status)))
2757 -                       hp = NULL;
2758 -#else
2759 -               errno = 0;
2760 -               hp = gethostbyname(hostcp);
2761 -#endif
2762 -               if (hp == NULL) {
2763 -                       if (errno == 0)
2764 -                               errno = ENOENT;
2765 -                       return (kAddrStrToAddrBadHost);
2766 -               }
2767 -               sa->sin_family = hp->h_addrtype;
2768 -               memcpy(&sa->sin_addr.s_addr, hp->h_addr_list[0],
2769 -                       (size_t) hp->h_length);
2770 -       }
2771 +       memset(&hints, 0, sizeof(hints));
2772 +       hints.ai_family = PF_UNSPEC;
2773 +       hints.ai_socktype = SOCK_STREAM;
2774 +       error = getaddrinfo(hostcp, portp, &hints, &res);
2775 +       if (error != 0)
2776 +               return (kAddrStrToAddrBadHost);
2777 +       memcpy(sa, res->ai_addr, res->ai_addrlen);
2778 +       freeaddrinfo(res);
2779         return (0);
2780  }      /* AddrStrToAddr */
2781  
2782 @@ -294,12 +253,12 @@
2783  
2784  
2785  char *
2786 -AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt)
2787 +AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr * const saddrp, int dns, const char *fmt)
2788  {
2789         char addrName[128];
2790         char *addrNamePtr;
2791 -       struct hostent *hp;
2792 -       char str[128];
2793 +       char portName[128];
2794 +       char portNum[128];
2795         char s_name[64];
2796         char *dlim, *dp;
2797         const char *cp;
2798 @@ -308,26 +267,25 @@
2799                 return NULL;
2800         memset(dst, 0, dsize);
2801  
2802 -       addrNamePtr = NULL;
2803 -       if (dns == 0) {
2804 -               InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
2805 -               addrNamePtr = addrName;
2806 -       } else {
2807 -#ifdef DNSSEC_LOCAL_VALIDATION
2808 -               val_status_t val_status;
2809 -               hp = val_gethostbyaddr(NULL, (const char*)&saddrp->sin_addr, sizeof(struct in_addr), AF_INET, &val_status);
2810 -               if ((hp != NULL) && (!val_istrusted(val_status)))
2811 -                       hp = NULL;
2812 +       addrNamePtr = addrName;
2813 +       if (dns == 0)
2814 +               dns = NI_NUMERICHOST;
2815 +       else
2816 +               dns = 0;
2817 +       getnameinfo(saddrp,
2818 +#ifdef HAVE_SOCKADDR_SA_LEN
2819 +                   saddrp->sa_len,
2820  #else
2821 -               hp = gethostbyaddr((gethost_addrptr_t) &saddrp->sin_addr, sizeof(struct in_addr), AF_INET);
2822 +                   SA_LEN(saddrp),
2823  #endif
2824 -               if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) {
2825 -                       addrNamePtr = hp->h_name;
2826 -               } else {
2827 -                       InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
2828 -                       addrNamePtr = addrName;
2829 -               }
2830 -       }
2831 +                   addrName, sizeof(addrName), portName, sizeof(portName), dns);
2832 +       getnameinfo(saddrp,
2833 +#ifdef HAVE_SOCKADDR_SA_LEN
2834 +                   saddrp->sa_len,
2835 +#else
2836 +                   SA_LEN(saddrp),
2837 +#endif
2838 +                   NULL, 0, portNum, sizeof(portNum), NI_NUMERICSERV);
2839         if (fmt == NULL)
2840                 fmt = "%h:%p";
2841         for (dp = dst, dlim = dp + dsize - 1; ; fmt++) {
2842 @@ -339,8 +297,7 @@
2843                                 if (dp < dlim)
2844                                         *dp++ = '%';
2845                         } else if (*fmt == 'p') {
2846 -                               sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
2847 -                               for (cp = str; *cp != '\0'; cp++)
2848 +                               for (cp = portNum; *cp != '\0'; cp++)
2849                                         if (dp < dlim)
2850                                                 *dp++ = *cp;
2851                                 *dp = '\0';
2852 @@ -355,16 +312,20 @@
2853                                                 *dp++ = *cp;
2854                                 *dp = '\0';
2855                         } else if (*fmt == 's') {
2856 -                               cp = s_name;
2857 -                               (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), 0);
2858 -                               for ( ; *cp != '\0'; cp++)
2859 +                               for (cp = portName ; *cp != '\0'; cp++)
2860                                         if (dp < dlim)
2861                                                 *dp++ = *cp;
2862                                 /* endservent(); */
2863                                 *dp = '\0';
2864                         } else if ((*fmt == 't') || (*fmt == 'u')) {
2865                                 cp = s_name;
2866 -                               (void) ServicePortNumberToName(ntohs(saddrp->sin_port), s_name, sizeof(s_name), (int) *fmt);
2867 +                               if (saddrp->sa_family == AF_INET) {
2868 +                                       (void) ServicePortNumberToName(ntohs(((struct sockaddr_in *)saddrp)->sin_port), s_name, sizeof(s_name), (int) *fmt);
2869 +                               } else if (saddrp->sa_family == AF_INET6) {
2870 +                                       (void) ServicePortNumberToName(ntohs(((struct sockaddr_in6 *)saddrp)->sin6_port), s_name, sizeof(s_name), (int) *fmt);
2871 +                               } else {
2872 +                                       cp = '\0';
2873 +                               }
2874                                 for ( ; *cp != '\0'; cp++)
2875                                         if (dp < dlim)
2876                                                 *dp++ = *cp;
2877 @@ -391,16 +352,16 @@
2878  AddrStrToIPStr(char *const dst, size_t dsize, const char *const src, const int defaultport)
2879  {
2880         int rc;
2881 -       struct sockaddr_in sa;
2882 +       struct sockaddr_storage ss;
2883  
2884         if (dsize == 0)
2885                 return NULL;
2886         memset(dst, 0, dsize);
2887  
2888 -       rc = AddrStrToAddr(src, &sa, (defaultport <= 0) ? 21 : defaultport);
2889 +       rc = AddrStrToAddr(src, (struct sockaddr *)&ss, (defaultport <= 0) ? 21 : defaultport);
2890         if (rc < 0)
2891                 return (NULL);
2892  
2893 -       AddrToAddrStr(dst, dsize, &sa, 0, (defaultport <= 0) ? "%h" : "%h:%p");
2894 +       AddrToAddrStr(dst, dsize, (struct sockaddr *)&ss, 0, (defaultport <= 0) ? "%h" : "%h:%p");
2895         return (dst);
2896  }      /* AddrStrToIPStr */
2897 Index: ncftp3/sio/sio.h
2898 diff -u ncftp3/sio/sio.h:1.1.1.10 ncftp3/sio/sio.h:1.14
2899 --- ncftp3/sio/sio.h:1.1.1.10   Mon Aug 11 15:38:23 2008
2900 +++ ncftp3/sio/sio.h    Mon Aug 11 16:24:16 2008
2901 @@ -197,7 +197,7 @@
2902  int PWrite(int, const char *const, size_t);
2903  
2904  /* SAccept.c */
2905 -int SAccept(int, struct sockaddr_in *const, int);
2906 +int SAccept(int, struct sockaddr *const, int);
2907  
2908  /* SBind.c */
2909  int SBind(int, const int, const int, const int);
2910 @@ -208,7 +208,7 @@
2911  int SClose(int, int);
2912  
2913  /* SConnect.c */
2914 -int SConnect(int, const struct sockaddr_in *const, int);
2915 +int SConnect(int, const struct sockaddr *const, int);
2916  
2917  /* SConnectByName.c */
2918  int SConnectByName(int, const char *const, const int);
2919 @@ -232,7 +232,7 @@
2920  int SRecv(int, char *const, size_t, int, int, int);
2921  
2922  /* SRecvfrom.c */
2923 -int SRecvfrom(int, char *const, size_t, int, struct sockaddr_in *const, int);
2924 +int SRecvfrom(int, char *const, size_t, int, struct sockaddr *const, int);
2925  
2926  /* SRecvmsg.c */
2927  int SRecvmsg(int, void *const, int, int);
2928 @@ -248,8 +248,8 @@
2929  int SSend(int, char *, size_t, int, int);
2930  
2931  /* SSendto.c */
2932 -int SSendto(int, const char *const, size_t, int, const struct sockaddr_in *const, int);
2933 -int Sendto(int, const char *const, size_t, const struct sockaddr_in *const);
2934 +int SSendto(int, const char *const, size_t, int, const struct sockaddr *const, int);
2935 +int Sendto(int, const char *const, size_t, const struct sockaddr *const);
2936  
2937  /* SSendtoByName.c */
2938  int SSendtoByName(int, const char *const, size_t, int, const char *const, int);
2939 @@ -280,8 +280,8 @@
2940  unsigned int ServiceNameToPortNumber(const char *const s, const int proto);
2941  int ServicePortNumberToName(unsigned short port, char *const dst, const size_t dsize, const int proto);
2942  void InetNtoA(char *dst, struct in_addr *ia, size_t siz);
2943 -int AddrStrToAddr(const char *const, struct sockaddr_in *const, const int);
2944 -char *AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt);
2945 +int AddrStrToAddr(const char *const, struct sockaddr *const, const int);
2946 +char *AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr * const saddrp, int dns, const char *fmt);
2947  char *AddrStrToIPStr(char *const dst, size_t dsize, const char *const src, const int defaultport);
2948  
2949  /* SError.c */
2950 Index: ncftp3/sio/syshdrs.h
2951 diff -u ncftp3/sio/syshdrs.h:1.1.1.9 ncftp3/sio/syshdrs.h:1.10
2952 --- ncftp3/sio/syshdrs.h:1.1.1.9        Mon Aug 11 15:38:23 2008
2953 +++ ncftp3/sio/syshdrs.h        Mon Aug 11 16:24:16 2008
2954 @@ -20,6 +20,9 @@
2955  #      define WINVER 0x0400
2956  #      define _WIN32_WINNT 0x0400
2957  #      include <windows.h>             /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2958 +#ifdef ENABLE_IPV6
2959 +#      include <ws2tcpip.h>
2960 +#endif /* ENABLE_IPV6 */
2961  #      include <io.h>
2962  #      include <errno.h>
2963  #      include <stdio.h>
2964 Index: ncftp3/vis/syshdrs.h
2965 diff -u ncftp3/vis/syshdrs.h:1.1.1.10 ncftp3/vis/syshdrs.h:1.7
2966 --- ncftp3/vis/syshdrs.h:1.1.1.10       Thu Nov  5 16:20:41 2009
2967 +++ ncftp3/vis/syshdrs.h        Thu Nov  5 16:47:09 2009
2968 @@ -94,6 +94,9 @@
2969  #include <time.h>
2970  #include <pwd.h>
2971  #include <fcntl.h>
2972 +#ifndef HAVE_GETADDRINFO
2973 +#      include "addrinfo.h"
2974 +#endif
2975  
2976  #ifdef HAVE_LOCALE_H
2977  #      include <locale.h>
This page took 0.255722 seconds and 2 git commands to generate.