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
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
14 wi_ARG_DISABLE_MACOSX_UNIVERSAL
18 dnl ---------------------------------------------------------------------------
19 dnl Environment and compiler settings.
20 dnl ---------------------------------------------------------------------------
22 wi_HEADER_SYS_SELECT_H dnl # sio
25 +dnl ---------------------------------------------------------------------------
27 +dnl ---------------------------------------------------------------------------
29 +AC_MSG_CHECKING([whether to enable ipv6])
31 +[ --enable-ipv6 Enable ipv6 (with ipv4) support
32 + --disable-ipv6 Disable ipv6 support],
33 +[ case "$enableval" in
38 + *) AC_MSG_RESULT(yes)
39 + AC_DEFINE(ENABLE_IPV6)
44 + AC_TRY_RUN([ /* AF_INET6 avalable check */
46 +#include <sys/types.h>
47 +#include <sys/socket.h>
50 + if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
57 + AC_DEFINE(ENABLE_IPV6)
65 +AC_CHECK_FUNC(getaddrinfo, [
66 + AC_DEFINE(HAVE_GETADDRINFO)], [
67 + LIBOBJS="$LIBOBJS getaddrinfo.o"
68 + LIBSOBJS="$LIBSOBJS getaddrinfo.so"
71 +AC_CHECK_FUNC(getnameinfo, [
72 + AC_DEFINE(HAVE_GETNAMEINFO)], [
73 + LIBOBJS="$LIBOBJS getnameinfo.o"
74 + LIBSOBJS="$LIBSOBJS getnameinfo.so"
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>],
84 + AC_DEFINE(HAVE_SOCKADDR_SA_LEN),
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;
94 + AC_DEFINE(HAVE_SOCKADDR_STORAGE_SS_FAMILY),
96 + AC_DEFINE(HAVE_SOCKADDR_STORAGE___SS_FAMILY)
97 + CPPFLAGS="$CPPFLAGS -D__ss_family=ss_family -D__ss_len=ss_len")
99 +CPPFLAGS="-I$MAINDIR $CPPFLAGS"
101 dnl ---------------------------------------------------------------------------
102 dnl Checks for library functions.
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
119 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
120 + * All rights reserved.
122 + * Redistribution and use in source and binary forms, with or without
123 + * modification, are permitted provided that the following conditions
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.
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
147 +#ifndef HAVE_GETADDRINFO
150 + * Error return codes from getaddrinfo()
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
168 + * Flag values for getaddrinfo()
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)
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)
184 + * Constants for getnameinfo()
186 +#define NI_MAXHOST 1025
187 +#define NI_MAXSERV 32
190 + * Flag values for getnameinfo()
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
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 */
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 */
214 + u_int16_t ss_family;
216 + u_int8_t fill[126];
219 +extern void freehostent __P((struct hostent *));
220 +extern char *gai_strerror __P((int));
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
225 # define DisposeSocket(a) close(a)
228 +#ifndef HAVE_SOCKADDR_SA_LEN
231 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
232 + : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
234 +#else /* ENABLE_IPV6 */
235 +#define SA_LEN(x) (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : -1)
236 +#endif /* ENABLE_IPV6 */
238 +#endif /* HAVE_SOCKADDR_SA_LEN */
240 static const char *gPrivateNetworks[] = {
247 -GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
248 +GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr *saddr)
250 - sockaddr_size_t len = (sockaddr_size_t) sizeof (struct sockaddr_in);
251 + sockaddr_size_t len = (sockaddr_size_t) sizeof (struct sockaddr_storage);
254 if (getsockname(sockfd, (struct sockaddr *)saddr, &len) < 0) {
255 @@ -138,16 +150,16 @@
256 OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
258 struct sockaddr_in localAddr;
259 - struct in_addr ip_address;
263 volatile int sockfd = -1;
264 volatile int sock2fd = -1;
265 ResponsePtr rp = NULL;
266 - char **volatile curaddr;
269 + struct addrinfo hints;
270 + struct addrinfo *res, *res0;
272 + char buf[NI_MAXHOST];
273 char *volatile fhost;
276 @@ -181,35 +193,17 @@
280 - /* Make sure we use network byte-order. */
281 - fport = (unsigned int) htons((unsigned short) fport);
283 - cip->servCtlAddr.sin_port = (unsigned short) fport;
285 - hprc = GetHostEntry(&hp, fhost, &ip_address, cip->buf, cip->bufSize);
288 - /* Okay, no Host entry, but maybe we have a numeric address
289 - * in ip_address we can try.
291 -#ifdef DNSSEC_LOCAL_VALIDATION
293 - FTPLogError(cip, kDontPerror, "%s: untrusted DNS response.\n", fhost);
294 - cip->errNo = kErrHostUnknown;
295 - return (kErrHostUnknown);
298 - if (ip_address.s_addr == INADDR_NONE) {
299 - FTPLogError(cip, kDontPerror, "%s: unknown host.\n", fhost);
300 - cip->errNo = kErrHostUnknown;
301 - return (kErrHostUnknown);
303 - cip->servCtlAddr.sin_family = AF_INET;
304 - cip->servCtlAddr.sin_addr.s_addr = ip_address.s_addr;
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);
317 + FTPLogError(cip, kDontPerror, "%s: %s.\n", fhost, gai_strerror(error));
318 + cip->errNo = kErrHostUnknown;
319 + return (kErrHostUnknown);
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.
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.
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.
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) {
342 FTPLogError(cip, kDoPerror, "Could not get a socket.\n");
343 cip->errNo = kErrNewStreamSocket;
344 return (kErrNewStreamSocket);
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);
361 - err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
362 + err = SConnect(sockfd, (struct sockaddr *)&cip->servCtlAddr, (int) cip->connTimeout);
366 - (void) SClose(sockfd, 3);
373 + (void) SClose(sockfd, 3);
376 #else /* NO_SIGNALS */
377 osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
378 if (cip->connTimeout > 0) {
380 Error(vcip, kDontPerror, "Connection attempt canceled.\n");
381 (void) kill(getpid(), SIGINT);
382 } else if (gGotSig == SIGALRM) {
385 result = vcip->errNo = kErrConnectRetryableErr;
386 Error(vcip, kDontPerror, "Connection attempt timed-out.\n");
387 (void) kill(getpid(), SIGALRM);
391 err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
392 - (int) sizeof (cip->servCtlAddr));
393 +#ifdef HAVE_SOCKADDR_SA_LEN
394 + cip->servCtlAddr.ss_len
396 + SA_LEN((struct sockaddr *)&cip->servCtlAddr)
399 if (cip->connTimeout > 0) {
401 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
402 @@ -311,106 +313,7 @@
406 -#endif /* NO_SIGNALS */
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.
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);
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.
421 - (void) memcpy(&cip->servCtlAddr.sin_addr, *curaddr, (size_t) hp.h_length);
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);
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
441 - (void) SetSocketBufSize(sockfd, cip->ctrlSocketRBufSize, cip->ctrlSocketSBufSize);
444 - err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
449 - (void) SClose(sockfd, 3);
452 -#else /* NO_SIGNALS */
454 - osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
455 - if (cip->connTimeout > 0) {
456 - osigalrm = (volatile FTPSigProc) signal(SIGALRM, CancelConnect);
457 - (void) alarm(cip->connTimeout);
461 -#ifdef HAVE_SIGSETJMP
462 - sj = sigsetjmp(gCancelConnectJmp, 1);
464 - sj = setjmp(gCancelConnectJmp);
465 -#endif /* HAVE_SIGSETJMP */
468 - /* Interrupted by a signal. */
469 - (void) DisposeSocket(sockfd);
470 - (void) signal(SIGINT, (FTPSigProc) osigint);
471 - if (vcip->connTimeout > 0) {
473 - (void) signal(SIGALRM, (FTPSigProc) osigalrm);
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);
484 - result = vcip->errNo = kErrConnectMiscErr;
485 - Error(vcip, kDontPerror, "Connection attempt failed due to an unexpected signal (%d).\n", gGotSig);
489 - err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
490 - (int) sizeof (cip->servCtlAddr));
491 - if (cip->connTimeout > 0) {
493 - (void) signal(SIGALRM, (FTPSigProc) osigalrm);
495 - (void) signal(SIGINT, (FTPSigProc) osigint);
501 - (void) DisposeSocket(sockfd);
504 #endif /* NO_SIGNALS */
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)
517 /* We want Out-of-band data to appear in the regular stream,
518 @@ -540,11 +443,20 @@
520 #endif /* NO_SIGNALS */
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,
528 + SA_LEN((struct sockaddr *)&cip->servCtlAddr),
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);
535 - (void) STRNCPY(cip->actualHost, (char *) hp.h_name);
536 + (void) STRNCPY(cip->actualHost, (char *) res0->ai_canonname);
537 + freeaddrinfo(res0);
540 /* Read the startup message from the server. */
543 CloseFile(&cip->cout);
544 cip->ctrlSocketR = kClosedFileDescriptor;
545 cip->ctrlSocketW = kClosedFileDescriptor;
547 + freeaddrinfo(res0);
551 } /* OpenControlConnection */
553 @@ -741,11 +657,15 @@
557 -FTPSendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
558 +FTPSendPort(const FTPCIPtr cip, struct sockaddr *saddr)
563 + struct sockaddr_in *saddr4;
565 + struct sockaddr_in6 *saddr6;
570 @@ -754,16 +674,46 @@
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)
579 + if (saddr->sa_family == AF_INET6) {
580 + char host[NI_MAXHOST];
581 + char port[NI_MAXSERV];
583 + getnameinfo(saddr, sizeof(struct sockaddr_in6), host, sizeof(host),
584 + port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
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.
593 + result = RCmd(cip, rp, "EPRT |2|%s|%s|", host, port);
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]));
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;
609 - /* Need to tell the other side which host (the address) and
610 - * which process (port) on that host to send data to.
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.
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]));
623 DoneWithResponse(cip, rp);
625 @@ -780,13 +730,18 @@
629 -FTPSendPassive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
630 +FTPSendPassive(const FTPCIPtr cip, struct sockaddr *saddr, int *weird)
634 - unsigned char n[6];
636 + unsigned char n[18];
639 + struct sockaddr_in *saddr4 = (struct sockaddr_in *)saddr;
641 + struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)saddr;
643 + unsigned short port;
647 @@ -795,56 +750,162 @@
651 - result = RCmd(cip, rp, "PASV");
655 - if (rp->codeType != 2) {
656 - /* Didn't understand or didn't want passive port selection. */
657 - cip->errNo = result = kErrPASVFailed;
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).
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.
670 + result = RCmd(cip, rp, "EPSV");
674 + if (rp->codeType != 2)
677 for (cp = rp->msg.first->line; ; cp++) {
679 - FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
681 + FTPLogError(cip, kDontPerror, "Cannot parse EPSV response: %s\n", rp->msg.first->line);
684 if (isdigit((int) *cp))
687 + if (sscanf(cp, "%hd|", &port) != 1) {
688 + FTPLogError(cip, kDontPerror, "Cannot parse EPSV response: %s\n", rp->msg.first->line);
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);
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);
705 + ((struct sockaddr_in *)&cip->servCtlAddr)->sin_addr;
706 + saddr4->sin_port = htons(port);
712 - if (weird != (int *) 0)
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.
720 - if (((i[j] < 0) || (i[j] > 255)) && (weird != (int *) 0))
721 - *weird = *weird + 1;
722 - n[j] = (unsigned char) (i[j] & 0xff);
724 + rp = InitResponse();
726 + FTPLogError(cip, kDontPerror, "Malloc failed.\n");
727 + cip->errNo = kErrMallocFailed;
728 + return (cip->errNo);
731 - (void) memcpy(&saddr->sin_addr, &n[0], (size_t) 4);
732 - (void) memcpy(&saddr->sin_port, &n[4], (size_t) 2);
734 + if (saddr->sa_family == AF_INET6) {
737 + result = RCmd(cip, rp, "LPSV");
741 + if (rp->codeType != 2) {
742 + /* Didn't understand or didn't want passive port selection. */
743 + cip->errNo = result = kErrPASVFailed;
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).
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.
756 + for (cp = rp->msg.first->line; ; cp++) {
758 + FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
761 + if (isdigit((int) *cp))
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",
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],
772 + &i[16], &i[17]) != 21) {
773 + FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
776 + if (af != 6 || hal != 16 || pal != 2) {
777 + FTPLogError(cip, kDontPerror, "Cannot parse LPSV response: %s\n", rp->msg.first->line);
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.
786 + if ((i[j] < 0) || (i[j] > 255))
787 + *weird = *weird + 1;
788 + n[j] = (unsigned char) (i[j] & 0xff);
790 + (void) memcpy(&saddr6->sin6_addr, &n[ 0], (size_t) 16);
791 + (void) memcpy(&saddr6->sin6_port, &n[16], (size_t) 2);
794 + result = RCmd(cip, rp, "PASV");
798 + if (rp->codeType != 2) {
799 + /* Didn't understand or didn't want passive port selection. */
800 + cip->errNo = result = kErrPASVFailed;
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).
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.
813 + for (cp = rp->msg.first->line; ; cp++) {
815 + FTPLogError(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
818 + if (isdigit((int) *cp))
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);
828 + if (weird != (int *) 0)
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.
836 + if (((i[j] < 0) || (i[j] > 255)) && (weird != (int *) 0))
837 + *weird = *weird + 1;
838 + n[j] = (unsigned char) (i[j] & 0xff);
840 + (void) memcpy(&saddr4->sin_addr, &n[0], (size_t) 4);
841 + (void) memcpy(&saddr4->sin_port, &n[4], (size_t) 2);
847 DoneWithResponse(cip, rp);
849 char maybePrivateAddrStr[64];
850 char knownNonPrivateAddrToUseIfNeededStr[64];
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");
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];
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);
873 } /* FTPFixServerDataAddr */
874 @@ -914,11 +975,11 @@
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);
889 } /* FTPFixClientDataAddr */
890 @@ -927,30 +988,45 @@
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)
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
908 - addrp->sin_port = 0; /* Let system pick one. */
910 - result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
912 + if (addrp->sa_family == AF_INET6)
913 + ((struct sockaddr_in6 *)addrp)->sin6_port = 0; /* Let system pick one. */
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);
920 + result = bind(sockfd, addrp, SA_LEN(addrp));
923 rangesize = (int) ((int) ephemHi - (int) ephemLo);
925 for (i=0; i<10; i++) {
926 port = (unsigned short) (((int) rand() % rangesize) + (int) ephemLo);
927 - addrp->sin_port = htons(port);
929 - result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
931 + if (addrp->sa_family == AF_INET6)
932 + ((struct sockaddr_in6 *)addrp)->sin6_port = htons(port);
935 + ((struct sockaddr_in *)addrp)->sin_port = htons(port);
936 +#ifdef HAVE_SOCKADDR_SA_LEN
937 + result = bind(sockfd, addrp, addrp->sa_len);
939 + result = bind(sockfd, addrp, SA_LEN(addrp));
944 @@ -989,7 +1065,11 @@
946 CloseDataConnection(cip); /* In case we didn't before... */
949 + dataSocket = socket(cip->ourCtlAddr.ss_family, SOCK_STREAM, 0);
951 dataSocket = socket(AF_INET, SOCK_STREAM, 0);
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.
959 cip->ourDataAddr = cip->ourCtlAddr;
960 - cip->ourDataAddr.sin_family = AF_INET;
963 cip->ourDataAddr.sin_port = 0;
964 @@ -1031,7 +1110,7 @@
965 (int) sizeof (cip->ourDataAddr),
966 cip->servCtlAddr.sin_addr.s_addr) < 0)
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)
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
977 - if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
978 + if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *)&cip->ourDataAddr)) < 0)
981 if (listen(dataSocket, 1) < 0) {
982 @@ -1053,8 +1132,9 @@
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)
993 cip->dataPortMode = kSendPortMode;
994 @@ -1063,11 +1143,9 @@
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;
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;
1007 @@ -1084,7 +1162,8 @@
1008 cip->errNo = kErrPassiveModeFailed;
1011 - FTPFixServerDataAddr(cip);
1012 + if (cip->servDataAddr.ss_family == AF_INET)
1013 + FTPFixServerDataAddr(cip);
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)
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)
1025 FTPLogError(cip, kDoPerror, "Could not bind the data socket");
1026 @@ -1100,8 +1179,13 @@
1027 cip->errNo = kErrBindDataSocket;
1031 - result = SConnect(dataSocket, &cip->servDataAddr, (int) cip->connTimeout);
1033 + /* Need to do this so we can figure out which port the system
1036 + if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *)&cip->ourDataAddr)) < 0)
1038 + result = SConnect(dataSocket, (struct sockaddr *)&cip->servDataAddr, (int) cip->connTimeout);
1040 if (result == kTimeoutErr) {
1041 if (mode == kFallBackToSendPortMode) {
1042 @@ -1164,7 +1248,7 @@
1043 if (dataSocket != kClosedFileDescriptor)
1044 (void) DisposeSocket(dataSocket);
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
1055 - if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
1056 + if ((result = GetSocketAddress(cip, dataSocket, (struct sockaddr *) &cip->ourDataAddr)) < 0)
1059 cip->hasPASV = kCommandAvailable;
1060 @@ -1225,9 +1309,9 @@
1061 memset(&cip->servDataAddr, 0, sizeof(cip->servDataAddr));
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);
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);
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);
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;
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);
1125 + struct sockaddr_in *servDataAddr =
1126 + (struct sockaddr_in *) &cip->servDataAddr;
1127 + struct sockaddr_in *servCtlAddr =
1128 + (struct sockaddr_in *) &cip->servCtlAddr;
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);
1149 cip->dataSocket = newSocket;
1153 } /* AcceptDataConnection */
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
1161 + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
1162 + * All rights reserved.
1164 + * Redistribution and use in source and binary forms, with or without
1165 + * modification, are permitted provided that the following conditions
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.
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
1190 + * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
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.
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>
1208 +#include <resolv.h>
1209 +#include <string.h>
1210 +#include <stdlib.h>
1211 +#include <stddef.h>
1213 +#include <unistd.h>
1215 +#include "addrinfo.h"
1217 +#if defined(__KAME__) && defined(INET6)
1227 +static int translate = NO;
1228 +static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
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
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
1246 +static struct afd {
1251 + const char *a_addrany;
1252 + const char *a_loopback;
1256 + {PF_INET6, sizeof(struct in6_addr),
1257 + sizeof(struct sockaddr_in6),
1258 + offsetof(struct sockaddr_in6, sin6_addr),
1259 + in6_addrany, in6_loopback},
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},
1272 +#define PTON_MAX 16
1278 +static int get_name __P((const char *, struct afd *,
1279 + struct addrinfo **, char *, struct addrinfo *,
1281 +static int get_addr __P((const char *, int, struct addrinfo **,
1282 + struct addrinfo *, int));
1283 +static int str_isnumber __P((const char *));
1285 +static char *ai_errlist[] = {
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 */
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));\
1308 + error = EAI_MEMORY;\
1313 +#define GET_AI(ai, afd, addr, port) {\
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);\
1328 +#define ERR(err) { error = (err); goto bad; }
1331 +gai_strerror(ecode)
1334 + if (ecode < 0 || ecode > EAI_MAX)
1336 + return ai_errlist[ecode];
1341 + struct addrinfo *ai;
1343 + struct addrinfo *next;
1346 + next = ai->ai_next;
1347 + if (ai->ai_canonname)
1348 + free(ai->ai_canonname);
1349 + /* no need to free(ai->ai_addr) */
1351 + } while ((ai = next) != NULL);
1358 + char *q = (char *)p;
1360 + if (! isdigit(*q))
1368 +getaddrinfo(hostname, servname, hints, res)
1369 + const char *hostname, *servname;
1370 + const struct addrinfo *hints;
1371 + struct addrinfo **res;
1373 + struct addrinfo sentinel;
1374 + struct addrinfo *top = NULL;
1375 + struct addrinfo *cur;
1377 + char pton[PTON_MAX];
1378 + struct addrinfo ai;
1379 + struct addrinfo *pai;
1383 + static int firsttime = 1;
1386 + /* translator hack */
1388 + char *q = getenv("GAI");
1389 + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
1396 + /* initialize file static vars */
1397 + sentinel.ai_next = NULL;
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;
1410 + if (hostname == NULL && servname == NULL)
1411 + return EAI_NONAME;
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) {
1429 + memcpy(pai, hints, sizeof(*pai));
1430 + switch (pai->ai_socktype) {
1432 + switch (pai->ai_protocol) {
1436 + pai->ai_socktype = SOCK_DGRAM;
1439 + pai->ai_socktype = SOCK_STREAM;
1442 + pai->ai_socktype = SOCK_RAW;
1449 + if (pai->ai_protocol != IPPROTO_UDP &&
1450 + pai->ai_protocol != ANY)
1451 + ERR(EAI_BADHINTS); /*xxx*/
1452 + pai->ai_protocol = IPPROTO_UDP;
1455 + if (pai->ai_protocol != IPPROTO_TCP &&
1456 + pai->ai_protocol != ANY)
1457 + ERR(EAI_BADHINTS); /*xxx*/
1458 + pai->ai_protocol = IPPROTO_TCP;
1461 + ERR(EAI_SOCKTYPE);
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;
1476 + port = htons(atoi(servname));
1478 + struct servent *sp;
1482 + switch (pai->ai_socktype) {
1493 + fprintf(stderr, "panic!\n");
1496 + if ((sp = getservbyname(servname, proto)) == NULL)
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;
1507 + ERR(EAI_PROTOCOL); /*xxx*/
1512 + * hostname == NULL.
1513 + * passive socket -> anyaddr (0.0.0.0 or ::)
1514 + * non-passive socket -> localhost (127.0.0.1 or ::1)
1516 + if (hostname == NULL) {
1519 + for (afd = &afdl[0]; afd->a_af; afd++) {
1520 + if (!(pai->ai_family == PF_UNSPEC
1521 + || pai->ai_family == afd->a_af)) {
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");
1531 + GET_AI(cur->ai_next, afd, afd->a_loopback,
1533 + /* xxx meaningless?
1534 + * GET_CANONNAME(cur->ai_next, "localhost");
1537 + cur = cur->ai_next;
1539 + top = sentinel.ai_next;
1546 + /* hostname as numeric name */
1547 + for (i = 0; afdl[i].a_af; i++) {
1548 + if (inet_pton(afdl[i].a_af, hostname, pton)) {
1552 + switch (afdl[i].a_af) {
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;
1563 + pfx = ((struct in6_addr *)pton)->s6_addr8[0];
1564 + if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
1565 + pai->ai_flags &= ~AI_CANONNAME;
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);
1577 + * if AI_CANONNAME and if reverse lookup
1578 + * fail, return ai anyway to pacify
1579 + * calling application.
1581 + * XXX getaddrinfo() is a name->address
1582 + * translation function, and it looks strange
1583 + * that we do addr->name translation here.
1585 + get_name(pton, &afdl[i], &top, pton, pai, port);
1588 + ERR(EAI_FAMILY); /*xxx*/
1592 + if (pai->ai_flags & AI_NUMERICHOST)
1595 + /* hostname as alphabetical name */
1596 + error = get_addr(hostname, pai->ai_family, &top, pai, port);
1607 + freeaddrinfo(top);
1614 +get_name(addr, afd, res, numaddr, pai, port0)
1617 + struct addrinfo **res;
1619 + struct addrinfo *pai;
1622 + u_short port = port0 & 0xffff;
1623 + struct hostent *hp;
1624 + struct addrinfo *cur;
1625 + int error = 0, h_error;
1628 + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
1630 + hp = gethostbyaddr(addr, afd->a_addrlen, AF_INET);
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);
1636 + GET_AI(cur, afd, numaddr, port);
1646 + freeaddrinfo(cur);
1657 +get_addr(hostname, af, res, pai, port0)
1658 + const char *hostname;
1660 + struct addrinfo **res;
1661 + struct addrinfo *pai;
1664 + u_short port = port0 & 0xffff;
1665 + struct addrinfo sentinel;
1666 + struct hostent *hp;
1667 + struct addrinfo *top, *cur;
1669 + int i, error = 0, h_error;
1672 + extern int h_errno;
1676 + sentinel.ai_next = NULL;
1679 + if (af == AF_UNSPEC) {
1680 + hp = getipnodebyname(hostname, AF_INET6,
1681 + AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);
1683 + hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);
1685 + hp = gethostbyname(hostname);
1686 + h_error = h_errno;
1689 + switch (h_error) {
1690 + case HOST_NOT_FOUND:
1692 + error = EAI_NODATA;
1695 + error = EAI_AGAIN;
1705 + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
1706 + (hp->h_addr_list[0] == NULL))
1709 + for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {
1713 + afd = &afdl[N_INET6];
1717 + default: /* AF_UNSPEC */
1720 + afd = &afdl[N_INET];
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];
1729 + afd = &afdl[N_INET6];
1734 + if (translate && afd->a_af == AF_INET) {
1735 + struct in6_addr *in6;
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));
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);
1749 + cur = cur->ai_next;
1758 + freeaddrinfo(top);
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
1773 + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
1774 + * All rights reserved.
1776 + * Redistribution and use in source and binary forms, with or without
1777 + * modification, are permitted provided that the following conditions
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.
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
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().
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>
1814 +#include <resolv.h>
1815 +#include <string.h>
1816 +#include <stddef.h>
1818 +#include "addrinfo.h"
1825 +static struct afd {
1832 + {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
1833 + offsetof(struct sockaddr_in6, sin6_addr)},
1835 + {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
1836 + offsetof(struct sockaddr_in, sin_addr)},
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
1855 +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
1856 + const struct sockaddr *sa;
1865 + struct servent *sp;
1866 + struct hostent *hp;
1868 + int family, len, i;
1873 + char numserv[512];
1874 + char numaddr[512];
1877 + return ENI_NOSOCKET;
1880 + if (len != salen) return ENI_SALEN;
1882 + family = sa->sa_family;
1883 + for (i = 0; afdl[i].a_af; i++)
1884 + if (afdl[i].a_af == family) {
1888 + return ENI_FAMILY;
1891 + if (len != afd->a_socklen) return ENI_SALEN;
1893 + port = ((struct sockinet *)sa)->si_port; /* network byte order */
1894 + addr = (char *)sa + afd->a_off;
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);
1904 + sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
1906 + if (strlen(sp->s_name) > servlen)
1907 + return ENI_MEMORY;
1908 + strcpy(serv, sp->s_name);
1910 + return ENI_NOSERVNAME;
1913 + switch (sa->sa_family) {
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;
1924 + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];
1925 + if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
1926 + flags |= NI_NUMERICHOST;
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))
1935 + return ENI_SYSTEM;
1936 + if (strlen(numaddr) > hostlen)
1937 + return ENI_MEMORY;
1938 + strcpy(host, numaddr);
1941 + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
1943 + hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
1944 + h_error = h_errno;
1948 + if (flags & NI_NOFQDN) {
1949 + p = strchr(hp->h_name, '.');
1952 + if (strlen(hp->h_name) > hostlen) {
1956 + return ENI_MEMORY;
1958 + strcpy(host, hp->h_name);
1963 + if (flags & NI_NAMEREQD)
1964 + return ENI_NOHOSTNAME;
1965 + if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
1967 + return ENI_NOHOSTNAME;
1968 + if (strlen(numaddr) > hostlen)
1969 + return ENI_MEMORY;
1970 + strcpy(host, numaddr);
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. */
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. */
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);
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
2020 # define _WIN32_WINNT 0x0400
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>
2031 # include <resolv.h>
2034 +# ifndef HAVE_GETADDRINFO
2035 +# include "addrinfo.h"
2037 # ifdef CAN_USE_SYS_SELECT_H
2038 # include <sys/select.h>
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 @@
2046 - (void) STRNCPY(gConn.host, ipstr);
2047 - OpenMsg("Connecting to %s...", ipstr);
2048 + OpenMsg("Connecting to %s...", gConn.host);
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];
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");
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];
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");
2072 cinfo.xtype = gBm.xferType;
2073 cinfo.deleteFlag = kDeleteNo;
2074 @@ -4160,8 +4159,8 @@
2075 char preferredLocalAddrStr[64];
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");
2083 cinfop = (SpoolCmdInfo *) ftwip->userdata;
2084 /* rerpath = ftwip->curPath + ftwip->startPathLen + 1; */
2085 @@ -4321,8 +4320,8 @@
2086 char preferredLocalAddrStr[64];
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");
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
2101 # define _WIN32_WINNT 0x0400
2103 # include <windows.h> /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2105 +# include <ws2tcpip.h>
2106 +#endif /* ENABLE_IPV6 */
2107 # include <shlobj.h>
2108 # include <process.h>
2109 # include <direct.h>
2114 +# ifndef HAVE_GETADDRINFO
2115 +# include "addrinfo.h"
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 @@
2124 MyGetHostByName(char *const volatile dst, size_t dsize, const char *const hn, int t)
2126 + struct addrinfo hints;
2127 + struct addrinfo *res;
2129 #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
2130 - struct hostent *hp;
2131 - struct in_addr ina;
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);
2139 - hp = gethostbyname(hn);
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);
2149 + char buf[NI_MAXHOST];
2151 + getnameinfo(res->ai_addr, res->ai_addrlen,
2153 + NULL, 0, NI_NUMERICHOST);
2154 + (void) Strncpy(dst, buf, dsize);
2155 + freeaddrinfo(res);
2161 vsigproc_t osigpipe, osigint, osigalrm;
2162 - struct hostent *hp;
2163 -#ifdef HAVE_INET_ATON
2164 - struct in_addr ina;
2166 -#ifdef DNSSEC_LOCAL_VALIDATION
2167 - val_status_t val_status;
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);
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);
2184 #ifdef HAVE_SIGSETJMP
2185 osigpipe = osigint = osigalrm = (sigproc_t) 0;
2186 @@ -731,30 +713,27 @@
2187 osigalrm = NcSignal(SIGALRM, CancelGetHostByName);
2189 (void) alarm((unsigned int) t);
2190 -#ifndef DNSSEC_LOCAL_VALIDATION
2191 - hp = gethostbyname(hn);
2193 - hp = val_gethostbyname(NULL, hn, &val_status);
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);
2203 (void) NcSignal(SIGPIPE, osigpipe);
2204 (void) NcSignal(SIGINT, osigint);
2205 (void) NcSignal(SIGALRM, osigalrm);
2206 -#ifdef DNSSEC_LOCAL_VALIDATION
2208 - * It would be nice to pass a little more information back,
2209 - * but that would mean an API change to MyGetHostByName.
2211 - if ((hp != NULL) && ! val_istrusted(val_status)) {
2217 - InetNtoA(dst, ((struct in_addr **) hp->h_addr_list)[0], dsize);
2221 + char buf[NI_MAXHOST];
2223 + getnameinfo(res->ai_addr, res->ai_addrlen,
2225 + NULL, 0, NI_NUMERICHOST);
2226 + (void) Strncpy(dst, buf, dsize);
2227 + freeaddrinfo(res);
2231 #endif /* !Windows */
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 @@
2240 if (gSourceAddrStr[0] != '\0')
2241 - (void) AddrStrToAddr(gSourceAddrStr, &gConn.preferredLocalAddr, 21);
2242 + (void) AddrStrToAddr(gSourceAddrStr, (struct sockaddr *)&gConn.preferredLocalAddr, 21);
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
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);
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
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);
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
2277 STRNCAT(postcmd, "\n");
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);
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
2290 # define _WIN32_WINNT 0x0400
2292 # include <windows.h> /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2294 +# include <ws2tcpip.h>
2295 +#endif /* ENABLE_IPV6 */
2296 # include <shlobj.h>
2298 # include <process.h>
2302 # include <dirent.h>
2303 +# ifndef HAVE_GETADDRINFO
2304 +# include "addrinfo.h"
2306 # ifdef HAVE_LOCALE_H
2307 # include <locale.h>
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
2317 +#ifndef HAVE_SOCKADDR_SA_LEN
2320 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2321 + : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
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 */
2330 -SAccept(int sfd, struct sockaddr_in *const addr, int tlen)
2331 +SAccept(int sfd, struct sockaddr *const addr, int tlen)
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)) {
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));
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
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);
2364 +#ifndef HAVE_SOCKADDR_SA_LEN
2367 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2368 + : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
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 */
2377 -SConnect(int sfd, const struct sockaddr_in *const addr, int tlen)
2378 +SConnect(int sfd, const struct sockaddr *const addr, int tlen)
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);
2386 + result = _SConnect(sfd, addr, SA_LEN(addr), tlen);
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)
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
2405 SConnectByName(int sfd, const char * const addrStr, const int tlen)
2408 - struct sockaddr_in remoteAddr;
2409 + struct sockaddr_storage remoteAddr;
2411 if (addrStr == NULL) {
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);
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
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)
2434 recv_return_t nread;
2439 nread = recvfrom(sfd, buf, (recv_size_t) size, fl,
2440 - (struct sockaddr *) fromAddr, &alen);
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
2453 +#ifndef HAVE_SOCKADDR_SA_LEN
2456 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2457 + : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
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 */
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)
2470 send_return_t nwrote;
2476 +#ifdef HAVE_SOCKADDR_SA_LEN
2477 + nwrote = sendto(sfd, buf, (send_size_t) size, fl,
2481 nwrote = sendto(sfd, buf, (send_size_t) size, fl,
2482 - (const struct sockaddr *) toAddr,
2483 - (sockaddr_size_t) sizeof(struct sockaddr_in));
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)
2503 +#ifdef HAVE_SOCKADDR_SA_LEN
2504 + result = (int) sendto(sfd, buf, (send_size_t) size, 0,
2508 result = (int) sendto(sfd, buf, (send_size_t) size, 0,
2509 - (const struct sockaddr *) toAddr,
2510 - (sockaddr_size_t) sizeof(struct sockaddr_in));
2514 } while ((result < 0) && (errno == EINTR));
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
2525 - struct sockaddr_in toAddr;
2526 + struct sockaddr_storage toAddr;
2529 if ((buf == NULL) || (size == 0) || (toAddrStr == NULL) || (toAddrStr[0] == '\0') || (tlen <= 0)) {
2534 - if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) {
2535 + if ((result = AddrStrToAddr(toAddrStr, (struct sockaddr *)&toAddr, -1)) < 0) {
2540 SendtoByName(int sfd, const char *const buf, size_t size, const char *const toAddrStr)
2543 - struct sockaddr_in toAddr;
2544 + struct sockaddr_storage toAddr;
2547 if ((buf == NULL) || (size == 0) || (toAddrStr == NULL)) {
2553 - if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) {
2554 + if ((result = AddrStrToAddr(toAddrStr, (struct sockaddr *)&toAddr, -1)) < 0) {
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
2564 +#ifndef HAVE_SOCKADDR_SA_LEN
2567 +#define SA_LEN(x) (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
2568 + : (((x)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
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 */
2578 # define INADDR_ANY ((unsigned long int) 0x00000000)
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;
2590 - struct servent *sp;
2592 + struct addrinfo hints, *res;
2594 + unsigned int port;
2596 strncpy(str, s, sizeof(str) - 1);
2597 str[sizeof(str) - 1] = '\0';
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));
2609 - if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2610 - memset(spbuf, 0, sizeof(spbuf));
2611 - sp = getservbyname_r(str, "udp", &se, spbuf, sizeof(spbuf));
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)
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)
2624 -#elif defined(HAVE_GETSERVBYNAME_R) && defined(AIX)
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)
2632 - if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2633 - memset(&sed, 0, sizeof(sed));
2634 - if (getservbyname_r(str, "udp", sp, &sed) != 0)
2639 - /* Note: getservbyname is already threadsafe on: HP-UX, Tru64 */
2640 - if ((sp == NULL) && ((proto == 0) || (proto == 't'))) {
2641 - sp = getservbyname(str, "tcp");
2643 - if ((sp == NULL) && ((proto == 0) || (proto == 'u'))) {
2644 - sp = getservbyname(str, "udp");
2649 - return ((unsigned int) ntohs((unsigned short) sp->s_port));
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);
2657 + if ((error != 0) && ((proto == 0) || (proto == 'u'))) {
2658 + hints.ai_socktype = SOCK_DGRAM;
2659 + error = getaddrinfo(NULL, str, &hints, &res);
2662 + return (0); /* error */
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;
2669 + port = 0; /* error */
2671 - return (0); /* error */
2672 + freeaddrinfo(res);
2673 + return ((unsigned int) ntohs((unsigned short) port));
2674 } /* ServiceNameToPortNumber */
2677 @@ -203,15 +186,13 @@
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)
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;
2694 - memset(sa, 0, sizeof(struct sockaddr_in));
2695 strncpy(portstr, s, sizeof(portstr));
2696 portstr[sizeof(portstr) - 1] = '\0';
2699 /* Does it look like a URL? http://host ? */
2700 if ((colon[1] == '/') && (colon[2] == '/')) {
2704 for (cp = hostcp; *cp != '\0'; cp++) {
2705 if ((!ISALNUM(*cp)) && (*cp != '.')) {
2706 @@ -230,29 +210,27 @@
2707 while (isdigit((int) *cp))
2717 - port = ServiceNameToPortNumber(portstr, 0);
2719 /* Look for host.name.domain:port */
2722 - port = (unsigned int) atoi(colon + 1);
2725 } else if ((atsign = strchr(portstr, '@')) != NULL) {
2726 /* Look for port@host.name.domain */
2728 hostcp = atsign + 1;
2729 - port = (unsigned int) atoi(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);
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);
2745 - sa->sin_port = htons((short) port);
2747 - ipnum = inet_addr(hostcp);
2748 - if (ipnum != INADDR_NONE) {
2749 - sa->sin_family = AF_INET;
2750 - sa->sin_addr.s_addr = ipnum;
2752 -#ifdef DNSSEC_LOCAL_VALIDATION
2753 - val_status_t val_status;
2755 - hp = val_gethostbyname(NULL,hostcp,&val_status);
2756 - if ((hp != NULL) && (!val_istrusted(val_status)))
2760 - hp = gethostbyname(hostcp);
2765 - return (kAddrStrToAddrBadHost);
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);
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);
2776 + return (kAddrStrToAddrBadHost);
2777 + memcpy(sa, res->ai_addr, res->ai_addrlen);
2778 + freeaddrinfo(res);
2780 } /* AddrStrToAddr */
2782 @@ -294,12 +253,12 @@
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)
2791 - struct hostent *hp;
2793 + char portName[128];
2794 + char portNum[128];
2798 @@ -308,26 +267,25 @@
2800 memset(dst, 0, dsize);
2802 - addrNamePtr = NULL;
2804 - InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
2805 - addrNamePtr = addrName;
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)))
2812 + addrNamePtr = addrName;
2814 + dns = NI_NUMERICHOST;
2817 + getnameinfo(saddrp,
2818 +#ifdef HAVE_SOCKADDR_SA_LEN
2821 - hp = gethostbyaddr((gethost_addrptr_t) &saddrp->sin_addr, sizeof(struct in_addr), AF_INET);
2824 - if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) {
2825 - addrNamePtr = hp->h_name;
2827 - InetNtoA(addrName, &saddrp->sin_addr, sizeof(addrName));
2828 - addrNamePtr = addrName;
2831 + addrName, sizeof(addrName), portName, sizeof(portName), dns);
2832 + getnameinfo(saddrp,
2833 +#ifdef HAVE_SOCKADDR_SA_LEN
2838 + NULL, 0, portNum, sizeof(portNum), NI_NUMERICSERV);
2841 for (dp = dst, dlim = dp + dsize - 1; ; fmt++) {
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++)
2852 @@ -355,16 +312,20 @@
2855 } else if (*fmt == 's') {
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++)
2864 } else if ((*fmt == 't') || (*fmt == 'u')) {
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);
2874 for ( ; *cp != '\0'; cp++)
2877 @@ -391,16 +352,16 @@
2878 AddrStrToIPStr(char *const dst, size_t dsize, const char *const src, const int defaultport)
2881 - struct sockaddr_in sa;
2882 + struct sockaddr_storage ss;
2886 memset(dst, 0, dsize);
2888 - rc = AddrStrToAddr(src, &sa, (defaultport <= 0) ? 21 : defaultport);
2889 + rc = AddrStrToAddr(src, (struct sockaddr *)&ss, (defaultport <= 0) ? 21 : defaultport);
2893 - AddrToAddrStr(dst, dsize, &sa, 0, (defaultport <= 0) ? "%h" : "%h:%p");
2894 + AddrToAddrStr(dst, dsize, (struct sockaddr *)&ss, 0, (defaultport <= 0) ? "%h" : "%h:%p");
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
2902 int PWrite(int, const char *const, size_t);
2905 -int SAccept(int, struct sockaddr_in *const, int);
2906 +int SAccept(int, struct sockaddr *const, int);
2909 int SBind(int, const int, const int, const int);
2911 int SClose(int, int);
2914 -int SConnect(int, const struct sockaddr_in *const, int);
2915 +int SConnect(int, const struct sockaddr *const, int);
2917 /* SConnectByName.c */
2918 int SConnectByName(int, const char *const, const int);
2920 int SRecv(int, char *const, size_t, int, int, int);
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);
2927 int SRecvmsg(int, void *const, int, int);
2929 int SSend(int, char *, size_t, int, int);
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);
2937 /* SSendtoByName.c */
2938 int SSendtoByName(int, const char *const, size_t, int, const char *const, int);
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);
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
2955 # define WINVER 0x0400
2956 # define _WIN32_WINNT 0x0400
2957 # include <windows.h> /* includes <winsock2.h> if _WIN32_WINNT >= 0x400 */
2959 +# include <ws2tcpip.h>
2960 +#endif /* ENABLE_IPV6 */
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
2972 +#ifndef HAVE_GETADDRINFO
2973 +# include "addrinfo.h"
2976 #ifdef HAVE_LOCALE_H
2977 # include <locale.h>