]> git.pld-linux.org Git - packages/ftp.git/blame - netkit-ftp-usagi-ipv6.patch
- added desktop file and png icon (based on lftp icon).
[packages/ftp.git] / netkit-ftp-usagi-ipv6.patch
CommitLineData
37a2e2e3 1diff -uNr netkit-ftp-0.17/CVS/Entries netkit-ftp/CVS/Entries
2diff -uNr netkit-ftp-0.17/ChangeLog netkit-ftp/ChangeLog
3--- netkit-ftp-0.17/ChangeLog Sun Jul 23 04:38:08 2000
4+++ netkit-ftp/ChangeLog Tue Nov 28 03:50:10 2000
5@@ -1,3 +1,6 @@
6+28-Nov-2000:
7+ IPv6 support. (Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
8+
9 8-Jul-2000:
10 Fix misused printf-function call (not %n-exploitable though).
11
12diff -uNr netkit-ftp-0.17/configure netkit-ftp/configure
13--- netkit-ftp-0.17/configure Sat Jul 29 21:00:28 2000
14+++ netkit-ftp/configure Sat Jan 27 06:14:54 2001
15@@ -24,6 +24,7 @@
16 --binmode=mode Mode for binaries [755]
17 --manmode=mode Mode for manual pages [644]
18 --with-c-compiler=cc Program for compiling C source [guessed]
19+ --enable-ipv6 Enable IPv6 support
20 EOF
21 exit 0;;
22 --verbose) ;;
23@@ -39,6 +40,11 @@
24 --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
25 --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
26 --without-readline|--disable-readline) WITHOUT_READLINE=1;;
27+
28+ --disable-ipv6) ENABLE_IPV6=no;;
29+ --enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;;
30+ --enable-ipv6) ENABLE_IPV6=yes;;
31+
32 *) echo "Unrecognized option: $1"; exit 1;;
33 esac
34 shift
35@@ -142,6 +148,42 @@
36
37 LDFLAGS=
38 LIBS=
39+
40+rm -f __conftest*
41+
42+##################################################
43+## Enable IPv6
44+echo -n "Whether to enable IPv6 support... "
45+if [ x"$ENABLE_IPV6" = x"yes" ]; then
46+ echo yes
47+ CFLAGS="$CFLAGS -DINET6"
48+else
49+ echo no
50+fi
51+
52+rm -f __conftest*
53+
54+## Search IPv6 Library / Headers
55+if [ x"$ENABLE_IPV6" = x"yes" ]; then
56+ echo -n "Search for IPv6 library... "
57+ inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib"
58+ inet6libs="inet6"
59+ inet6found=no
60+ for inet6libdir in $inet6libdirs; do
61+ for inet6lib in $inet6libs; do
62+ if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then
63+ inet6found=yes
64+ break 2
65+ fi
66+ done
67+ done
68+ if [ x"$inet6found" = x"yes" ]; then
69+ echo "$inet6libdir/lib$inet6lib.a"
70+ LIBS="$LIBS -L$inet6libdir -l$inet6lib"
71+ else
72+ echo "not found"
73+ fi
74+fi
75
76 rm -f __conftest*
77
78diff -uNr netkit-ftp-0.17/ftp/CVS/Entries netkit-ftp/ftp/CVS/Entries
79--- netkit-ftp-0.17/ftp/CVS/Entries Thu Jan 1 02:00:00 1970
80+++ netkit-ftp/ftp/CVS/Entries Mon Feb 19 06:50:49 2001
81@@ -0,0 +1,16 @@
82+/.cvsignore/1.1.1.1/Fri Nov 3 19:18:15 2000//
83+/Makefile/1.4/Sat Jan 27 05:57:08 2001//
84+/cmds.c/1.3/Fri Jan 12 21:36:27 2001//
85+/cmds.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
86+/cmdtab.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
87+/domacro.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
88+/ftp.1/1.1.1.1/Fri Nov 3 19:18:15 2000//
89+/ftp.c/1.11/Sun Feb 11 12:26:59 2001//
90+/ftp_var.h/1.3/Fri Jan 12 21:36:27 2001//
91+/glob.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
92+/glob.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
93+/main.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
94+/netrc.5/1.1.1.1/Fri Nov 3 19:18:15 2000//
95+/pathnames.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
96+/ruserpass.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
97+D
98diff -uNr netkit-ftp-0.17/ftp/CVS/Repository netkit-ftp/ftp/CVS/Repository
99--- netkit-ftp-0.17/ftp/CVS/Repository Thu Jan 1 02:00:00 1970
100+++ netkit-ftp/ftp/CVS/Repository Mon Feb 19 06:50:49 2001
101@@ -0,0 +1 @@
102+usagi/src/netkit-ftp/ftp
103diff -uNr netkit-ftp-0.17/ftp/CVS/Root netkit-ftp/ftp/CVS/Root
104--- netkit-ftp-0.17/ftp/CVS/Root Thu Jan 1 02:00:00 1970
105+++ netkit-ftp/ftp/CVS/Root Mon Feb 19 06:50:49 2001
106@@ -0,0 +1 @@
107+:pserver:anoncvs@anoncvs.linux-ipv6.org:/cvsroot/usagi
108diff -uNr netkit-ftp-0.17/ftp/Makefile netkit-ftp/ftp/Makefile
109--- netkit-ftp-0.17/ftp/Makefile Sun Aug 1 09:00:12 1999
110+++ netkit-ftp/ftp/Makefile Sat Jan 27 07:57:08 2001
111@@ -16,10 +16,13 @@
112 cmds.o glob.o: glob.h
113
114 install: ftp
115+ install -d $(INSTALLROOT)$(BINDIR)
116 install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR)
117 ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp
118+ install -d $(INSTALLROOT)$(MANDIR)/man1
119 install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1
120 ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1
121+ install -d $(INSTALLROOT)$(MANDIR)/man5
122 install -m$(MANMODE) netrc.5 $(INSTALLROOT)$(MANDIR)/man5
123
124 clean:
125diff -uNr netkit-ftp-0.17/ftp/cmds.c netkit-ftp/ftp/cmds.c
126--- netkit-ftp-0.17/ftp/cmds.c Sun Jul 23 04:36:59 2000
127+++ netkit-ftp/ftp/cmds.c Fri Jan 12 23:36:27 2001
128@@ -1,3 +1,5 @@
129+/* $USAGI$ */
130+
131 /*
132 * Copyright (c) 1985, 1989 Regents of the University of California.
133 * All rights reserved.
134@@ -35,7 +37,7 @@
135 * from: @(#)cmds.c 5.26 (Berkeley) 3/5/91
136 */
137 char cmds_rcsid[] =
138- "$Id$";
139+ "$Id$";
140
141 /*
142 * FTP User Program -- Command Routines.
143@@ -190,7 +192,7 @@
144 setpeer(int argc, char *argv[])
145 {
146 char *host;
147- unsigned short port;
148+ char *port;
149
150 if (connected) {
151 printf("Already connected to %s, use close first.\n",
152@@ -205,22 +207,17 @@
153 code = -1;
154 return;
155 }
156- port = ftp_port;
157+ port = NULL;
158 if (argc > 2) {
159- port = atoi(argv[2]);
160- if (port < 1) {
161- printf("%s: bad port number-- %s\n", argv[1], argv[2]);
162- printf ("usage: %s host-name [port]\n", argv[0]);
163- code = -1;
164- return;
165- }
166- port = htons(port);
167+ port = argv[2];
168 }
169 host = hookup(argv[1], port);
170 if (host) {
171 int overbose;
172
173 connected = 1;
174+ try_epsv = 1;
175+ try_eprt = 1;
176 /*
177 * Set up defaults for FTP.
178 */
179diff -uNr netkit-ftp-0.17/ftp/cmdtab.c netkit-ftp/ftp/cmdtab.c
180--- netkit-ftp-0.17/ftp/cmdtab.c Tue Sep 28 18:36:05 1999
181+++ netkit-ftp/ftp/cmdtab.c Fri Nov 3 21:18:15 2000
182@@ -35,7 +35,7 @@
183 * from: @(#)cmdtab.c 5.10 (Berkeley) 6/1/90
184 */
185 char cmdtab_rcsid[] =
186- "$Id$";
187+ "$Id$";
188
189 #include <string.h> /* for NULL */
190 #include "ftp_var.h"
191diff -uNr netkit-ftp-0.17/ftp/domacro.c netkit-ftp/ftp/domacro.c
192--- netkit-ftp-0.17/ftp/domacro.c Thu Aug 15 02:27:28 1996
193+++ netkit-ftp/ftp/domacro.c Fri Nov 3 21:18:15 2000
194@@ -35,7 +35,7 @@
195 * from: @(#)domacro.c 1.8 (Berkeley) 9/28/90
196 */
197 char domacro_rcsid[] =
198- "$Id$";
199+ "$Id$";
200
201 #include <errno.h>
202 #include <ctype.h>
203diff -uNr netkit-ftp-0.17/ftp/ftp.1 netkit-ftp/ftp/ftp.1
204--- netkit-ftp-0.17/ftp/ftp.1 Mon Jul 31 02:56:59 2000
205+++ netkit-ftp/ftp/ftp.1 Fri Nov 3 21:18:15 2000
206@@ -30,7 +30,7 @@
207 .\" SUCH DAMAGE.
208 .\"
209 .\" from: @(#)ftp.1 6.18 (Berkeley) 7/30/91
210-.\" $Id$
211+.\" $Id$
212 .\"
213 .Dd August 15, 1999
214 .Dt FTP 1
215diff -uNr netkit-ftp-0.17/ftp/ftp.c netkit-ftp/ftp/ftp.c
216--- netkit-ftp-0.17/ftp/ftp.c Mon Dec 13 22:33:20 1999
217+++ netkit-ftp/ftp/ftp.c Sun Feb 11 14:26:59 2001
218@@ -1,3 +1,34 @@
219+/* $USAGI$ */
220+
221+/*
222+ * Copyright (C) 1997 and 1998 WIDE Project.
223+ * All rights reserved.
224+ *
225+ * Redistribution and use in source and binary forms, with or without
226+ * modification, are permitted provided that the following conditions
227+ * are met:
228+ * 1. Redistributions of source code must retain the above copyright
229+ * notice, this list of conditions and the following disclaimer.
230+ * 2. Redistributions in binary form must reproduce the above copyright
231+ * notice, this list of conditions and the following disclaimer in the
232+ * documentation and/or other materials provided with the distribution.
233+ * 3. Neither the name of the project nor the names of its contributors
234+ * may be used to endorse or promote products derived from this software
235+ * without specific prior written permission.
236+ *
237+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
238+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
241+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
242+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
243+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
244+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
247+ * SUCH DAMAGE.
248+ */
249+
250 /*
251 * Copyright (c) 1985, 1989 Regents of the University of California.
252 * All rights reserved.
253@@ -35,7 +66,7 @@
254 * From: @(#)ftp.c 5.38 (Berkeley) 4/22/91
255 */
256 char ftp_rcsid[] =
257- "$Id$";
258+ "$Id$";
259
260 #include <sys/param.h>
261 #include <sys/stat.h>
262@@ -63,14 +94,38 @@
263 #include "ftp_var.h"
264 #include "cmds.h"
265
266+#ifdef _USAGI
267+#include "version.h"
268+#else
269 #include "../version.h"
270+#endif
271+
272+union sockunion {
273+ struct sockinet {
274+ u_short si_family;
275+ u_short si_port;
276+ } su_si;
277+ struct sockaddr su_sa;
278+ struct sockaddr_in su_sin;
279+#ifdef INET6
280+ struct sockaddr_in6 su_sin6;
281+#endif
282+};
283+#define su_family su_sa.sa_family
284+#define su_port su_si.si_port
285+
286+#ifdef INET6
287+#define ex_af2prot(a) (a == AF_INET ? 1 : (a == AF_INET6 ? 2 : 0))
288+#else
289+#define ex_af2prot(a) (a == AF_INET ? 1 : 0)
290+#endif
291
292 int data = -1;
293 off_t restart_point = 0;
294
295-static struct sockaddr_in hisctladdr;
296-static struct sockaddr_in data_addr;
297-static struct sockaddr_in myctladdr;
298+static union sockunion hisctladdr;
299+static union sockunion data_addr;
300+static union sockunion myctladdr;
301 static int ptflag = 0;
302 static sigjmp_buf recvabort;
303 static sigjmp_buf sendabort;
304@@ -96,79 +151,119 @@
305 static FILE *dataconn(const char *);
306
307 char *
308-hookup(char *host, int port)
309+hookup(const char *host, const char *port)
310 {
311- register struct hostent *hp = 0;
312- int s, tos;
313+ int s, tos, error;
314 socklen_t len;
315 static char hostnamebuf[256];
316-
317+ struct addrinfo hints, *res, *res0;
318+ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
319+ char *cause = "ftp: unknown";
320+
321+ if (port) {
322+ strncpy(pbuf, port, sizeof(pbuf) - 1);
323+ pbuf[sizeof(pbuf) - 1] = '\0';
324+ } else {
325+ sprintf(pbuf, "%d", ntohs(ftp_port));
326+ }
327 memset(&hisctladdr, 0, sizeof(hisctladdr));
328- if (inet_aton(host, &hisctladdr.sin_addr)) {
329- hisctladdr.sin_family = AF_INET;
330- strncpy(hostnamebuf, host, sizeof(hostnamebuf));
331- hostnamebuf[sizeof(hostnamebuf)-1]=0;
332- }
333- else {
334- hp = gethostbyname(host);
335- if (hp == NULL) {
336- fprintf(stderr, "ftp: %s: ", host);
337- herror((char *)NULL);
338- code = -1;
339- return((char *) 0);
340+ memset(&hints, 0, sizeof(hints));
341+ hints.ai_flags = AI_CANONNAME;
342+ hints.ai_socktype = SOCK_STREAM;
343+ error = getaddrinfo(host, pbuf, &hints, &res0);
344+ if (error) {
345+ if (port) {
346+ strcpy(hbuf, " ");
347+ } else {
348+ hbuf[0] = '\0';
349+ pbuf[0] = '\0';
350 }
351- hisctladdr.sin_family = hp->h_addrtype;
352- if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
353- hp->h_length = sizeof(hisctladdr.sin_addr);
354- }
355- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);
356- (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
357- hostnamebuf[sizeof(hostnamebuf)-1] = 0;
358- }
359- hostname = hostnamebuf;
360- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
361- if (s < 0) {
362- perror("ftp: socket");
363+ fprintf(stderr, "ftp: %s%s%s: %s\n", host, hbuf, pbuf,
364+ gai_strerror(error));
365 code = -1;
366 return (0);
367 }
368- hisctladdr.sin_port = port;
369- while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
370- if (hp && hp->h_addr_list[1]) {
371- int oerrno = errno;
372-
373- fprintf(stderr, "ftp: connect to address %s: ",
374- inet_ntoa(hisctladdr.sin_addr));
375- errno = oerrno;
376- perror((char *) 0);
377- hp->h_addr_list++;
378- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
379- hp->h_length);
380- fprintf(stdout, "Trying %s...\n",
381- inet_ntoa(hisctladdr.sin_addr));
382- (void) close(s);
383- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
384- if (s < 0) {
385- perror("ftp: socket");
386- code = -1;
387- return (0);
388+
389+ if (res0->ai_canonname) {
390+ struct addrinfo h, *a;
391+ memset(&h, 0, sizeof(h));
392+ h.ai_family = PF_UNSPEC;
393+ h.ai_socktype = SOCK_STREAM;
394+ h.ai_flags = AI_NUMERICHOST;
395+ if (!getaddrinfo(res0->ai_canonname, NULL, &h, &a)) {
396+ strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
397+ freeaddrinfo(a);
398+ } else
399+ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
400+ }
401+ else
402+ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
403+ hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
404+ hostname = hostnamebuf;
405+
406+ s = -1;
407+ for (res = res0; res; res = res->ai_next) {
408+ if (!ex_af2prot(res->ai_family)) {
409+ cause = "ftp: mismatch address family";
410+ errno = EPROTONOSUPPORT;
411+ continue;
412+ }
413+ if ((size_t)res->ai_addrlen > sizeof(hisctladdr)) {
414+ cause = "ftp: mismatch struct sockaddr size";
415+ errno = EPROTO;
416+ continue;
417+ }
418+ if (getnameinfo(res->ai_addr, res->ai_addrlen,
419+ hbuf, sizeof(hbuf), NULL, 0,
420+ NI_NUMERICHOST))
421+ strcpy(hbuf, "???");
422+ if (res0->ai_next) /* if we have multiple possibilities */
423+ fprintf(stdout, "Trying %s...\n", hbuf);
424+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
425+ if (s < 0) {
426+ cause = "ftp: socket";
427+ continue;
428+ }
429+ while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
430+ && errno == EINTR) {
431+ ;
432+ }
433+ if (error) {
434+ /* this "if" clause is to prevent print warning twice */
435+ if (res->ai_next) {
436+ fprintf(stderr,
437+ "ftp: connect to address %s", hbuf);
438+ perror("");
439 }
440+ cause = "ftp: connect";
441+ close(s);
442+ s = -1;
443 continue;
444 }
445- perror("ftp: connect");
446+ /* finally we got one */
447+ break;
448+ }
449+ if (s < 0) {
450+ perror(cause);
451 code = -1;
452- goto bad;
453+ freeaddrinfo(res0);
454+ return NULL;
455 }
456- len = sizeof (myctladdr);
457+ len = res->ai_addrlen;
458+ memcpy(&hisctladdr, res->ai_addr, len);
459+ freeaddrinfo(res0);
460 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
461 perror("ftp: getsockname");
462 code = -1;
463 goto bad;
464 }
465 #ifdef IP_TOS
466+ if (hisctladdr.su_family == AF_INET)
467+ {
468 tos = IPTOS_LOWDELAY;
469 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
470 perror("ftp: setsockopt TOS (ignored)");
471+ }
472 #endif
473 cin = fdopen(s, "r");
474 cout = fdopen(s, "w");
475@@ -182,7 +277,7 @@
476 goto bad;
477 }
478 if (verbose)
479- printf("Connected to %s.\n", hostname);
480+ printf("Connected to %s (%s).\n", hostname, hbuf);
481 if (getreply(0) > 2) { /* read startup message from server */
482 if (cin)
483 (void) fclose(cin);
484@@ -392,8 +487,10 @@
485 }
486 if (dig < 4 && isdigit(c))
487 code = code * 10 + (c - '0');
488- if (!pflag && code == 227)
489+ if (!pflag && (code == 227 || code == 228))
490 pflag = 1;
491+ else if (!pflag && code == 229)
492+ pflag = 100;
493 if (dig > 4 && pflag == 1 && isdigit(c))
494 pflag = 2;
495 if (pflag == 2) {
496@@ -405,6 +502,8 @@
497 pflag = 3;
498 }
499 }
500+ if (pflag == 100 && c == '(')
501+ pflag = 2;
502 if (dig == 4 && c == '-') {
503 if (continuation)
504 code = 0;
505@@ -1083,15 +1182,25 @@
506 static int
507 initconn(void)
508 {
509- register char *p, *a;
510+ u_char *p, *a;
511 int result, tmpno = 0;
512 socklen_t len;
513 int on = 1;
514- int tos;
515- u_long a1,a2,a3,a4,p1,p2;
516-
517+ int tos, error = 0;
518+ u_int ad[16], po[2], af, alen, plen;
519+ char *pasvcmd = NULL;
520+ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
521+
522+#ifdef INET6
523+ if (myctladdr.su_family == AF_INET6
524+ && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
525+ || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
526+ fprintf(stderr, "use of scoped address can be troublesome\n");
527+ }
528+#endif
529 if (passivemode) {
530- data = socket(AF_INET, SOCK_STREAM, 0);
531+ data_addr = hisctladdr;
532+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
533 if (data < 0) {
534 perror("ftp: socket");
535 return(1);
536@@ -1100,52 +1209,201 @@
537 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
538 sizeof (on)) < 0)
539 perror("ftp: setsockopt (ignored)");
540- if (command("PASV") != COMPLETE) {
541+ switch (data_addr.su_family) {
542+ case AF_INET:
543+#if 0
544+ if (try_epsv) {
545+ result = command(pasvcmd = "EPSV 1");
546+ if (code / 10 == 22 && code != 229) {
547+ fprintf(stderr,
548+ "wrong server: return code must be 229\n");
549+ result = COMPLETE + 1;
550+ }
551+ } else {
552+#endif
553+ result = COMPLETE + 1;
554+
555+ if (result != COMPLETE) {
556+ try_epsv = 0;
557+ result = command(pasvcmd = "PASV");
558+ }
559+ break;
560+#ifdef INET6
561+ case AF_INET6:
562+ if (try_epsv) {
563+ result = command(pasvcmd = "EPSV 2");
564+ if (code / 10 == 22 && code != 229) {
565+ fprintf(stderr,
566+ "wrong server: return code must be 229\n");
567+ result = COMPLETE + 1;
568+ }
569+ } else {
570+ result = COMPLETE + 1;
571+ }
572+ if (result != COMPLETE) {
573+ try_epsv = 0;
574+ result = command(pasvcmd = "LPSV");
575+ }
576+ break;
577+#endif
578+ default:
579+ result = COMPLETE + 1;
580+ break;
581+ }
582+ if (result != COMPLETE) {
583 printf("Passive mode refused.\n");
584- return(1);
585+ goto bad;
586 }
587
588+#define pack2(var) \
589+ (((var[0] & 0xff) << 8) | ((var[1] & 0xff) << 0))
590+#define pack4(var) \
591+ ((((var)[0] & 0xff) << 24) | (((var)[1] & 0xff) << 16) | \
592+ (((var)[2] & 0xff) << 8) | (((var)[3] & 0xff) << 0))
593+
594 /*
595 * What we've got at this point is a string of comma separated
596 * one-byte unsigned integer values, separated by commas.
597- * The first four are the an IP address. The fifth is the MSB
598- * of the port number, the sixth is the LSB. From that we'll
599- * prepare a sockaddr_in.
600 */
601-
602- if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",
603- &a1,&a2,&a3,&a4,&p1,&p2)
604- != 6)
605- {
606- printf("Passive mode address scan failure. Shouldn't happen!\n");
607- return(1);
608+ error = 0;
609+ if (strcmp(pasvcmd, "PASV") == 0) {
610+ if (data_addr.su_family != AF_INET) {
611+ error = 2;
612+ goto psv_done;
613+ }
614+ if (code / 10 == 22 && code != 227) {
615+ error = 227;
616+ goto psv_done;
617+ }
618+ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u",
619+ &ad[0], &ad[1], &ad[2], &ad[3],
620+ &po[0], &po[1]) != 6) {
621+ error = 1;
622+ goto psv_done;
623+ }
624+ data_addr.su_sin.sin_addr.s_addr = htonl(pack4(ad));
625+ data_addr.su_port = htons(pack2(po));
626+ } else
627+ if (strcmp(pasvcmd, "LPSV") == 0) {
628+ if (code / 10 == 22 && code != 228) {
629+ error = 228;
630+ goto psv_done;
631+ }
632+ switch (data_addr.su_family) {
633+ case AF_INET:
634+ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u,%u,%u,%u",
635+ &af, &alen,
636+ &ad[0], &ad[1], &ad[2], &ad[3],
637+ &plen, &po[0], &po[1]) != 9) {
638+ error = 1;
639+ goto psv_done;
640+ }
641+ if (af != 4 || alen != 4 || plen != 2) {
642+ error = 2;
643+ goto psv_done;
644+ }
645+ data_addr.su_sin.sin_addr.s_addr =
646+ htonl(pack4(ad));
647+ data_addr.su_port = htons(pack2(po));
648+ break;
649+#ifdef INET6
650+ case AF_INET6:
651+ if (sscanf(pasv,
652+ "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
653+ &af, &alen,
654+ &ad[0], &ad[1], &ad[2], &ad[3],
655+ &ad[4], &ad[5], &ad[6], &ad[7],
656+ &ad[8], &ad[9], &ad[10], &ad[11],
657+ &ad[12], &ad[13], &ad[14], &ad[15],
658+ &plen, &po[0], &po[1]) != 21) {
659+ error = 1;
660+ goto psv_done;
661+ }
662+ if (af != 6 || alen != 16 || plen != 2) {
663+ error = 2;
664+ goto psv_done;
665+ }
666+ data_addr.su_sin6.sin6_addr.s6_addr32[0] =
667+ htonl(pack4(ad));
668+ data_addr.su_sin6.sin6_addr.s6_addr32[1] =
669+ htonl(pack4(ad+4));
670+ data_addr.su_sin6.sin6_addr.s6_addr32[2] =
671+ htonl(pack4(ad+8));
672+ data_addr.su_sin6.sin6_addr.s6_addr32[3] =
673+ htonl(pack4(ad+12));
674+ data_addr.su_port = htons(pack2(po));
675+ break;
676+#endif
677+ default:
678+ error = 1;
679+ }
680+ } else if (strncmp(pasvcmd, "EPSV", 4) == 0) {
681+ char delim[4];
682+ u_int epsvpo;
683+
684+ if (code / 10 == 22 && code != 229) {
685+ error = 229;
686+ goto psv_done;
687+ }
688+ if (sscanf(pasv, "%c%c%c%u%c", &delim[0], &delim[1],
689+ &delim[2], &epsvpo, &delim[3]) != 5) {
690+ error = 1;
691+ goto psv_done;
692+ }
693+ if (delim[0] != delim[1] || delim[0] != delim[2]
694+ || delim[0] != delim[3]) {
695+ error = 1;
696+ goto psv_done;
697+ }
698+ data_addr.su_port = htons(epsvpo);
699+ } else {
700+ error = 1;
701+ }
702+psv_done:
703+ switch (error) {
704+ case 0:
705+ break;
706+ case 1:
707+ fprintf(stderr,
708+ "Passive mode address scan failure. Shouldn't happen!\n");
709+ goto bad;
710+ case 2:
711+ fprintf(stderr,
712+ "Passive mode AF mismatch. Shouldn't happen!\n");
713+ goto bad;
714+ case 227:
715+ case 228:
716+ case 229:
717+ fprintf(stderr,
718+ "wrong server: return code must be %d\n", error);
719+ goto bad;
720+ default:
721+ fprintf(stderr, "Bug\n");
722 }
723
724- data_addr.sin_family = AF_INET;
725- data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
726- (a3 << 8) | a4);
727- data_addr.sin_port = htons((p1 << 8) | p2);
728-
729 if (connect(data, (struct sockaddr *) &data_addr,
730 sizeof(data_addr))<0) {
731 perror("ftp: connect");
732 return(1);
733 }
734 #ifdef IP_TOS
735+ if (data_addr.su_family == AF_INET)
736+ {
737 tos = IPTOS_THROUGHPUT;
738 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
739 sizeof(tos)) < 0)
740 perror("ftp: setsockopt TOS (ignored)");
741+ }
742 #endif
743 return(0);
744 }
745 noport:
746 data_addr = myctladdr;
747 if (sendport)
748- data_addr.sin_port = 0; /* let system pick one */
749+ data_addr.su_port = 0; /* let system pick one */
750 if (data != -1)
751 (void) close(data);
752- data = socket(AF_INET, SOCK_STREAM, 0);
753+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
754 if (data < 0) {
755 perror("ftp: socket");
756 if (tmpno)
757@@ -1172,13 +1430,47 @@
758 if (listen(data, 1) < 0)
759 perror("ftp: listen");
760 if (sendport) {
761- a = (char *)&data_addr.sin_addr;
762- p = (char *)&data_addr.sin_port;
763-#define UC(b) (((int)b)&0xff)
764- result =
765- command("PORT %d,%d,%d,%d,%d,%d",
766- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
767- UC(p[0]), UC(p[1]));
768+ af = ex_af2prot(data_addr.su_family);
769+ if (try_eprt && af > 1) { /* only IPv6 */
770+ if (getnameinfo((struct sockaddr *)&data_addr, len,
771+ hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
772+ NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
773+ result = command("EPRT |%d|%s|%s|",
774+ af, hbuf, pbuf);
775+ if (result != COMPLETE) {
776+ try_eprt = 0;
777+ }
778+ } else {
779+ result = ERROR;
780+ }
781+ } else {
782+ result = COMPLETE + 1;
783+ }
784+ if (result == COMPLETE)
785+ goto prt_done;
786+
787+ p = (u_char *)&data_addr.su_port;
788+ switch (data_addr.su_family) {
789+ case AF_INET:
790+ a = (u_char *)&data_addr.su_sin.sin_addr;
791+ result = command("PORT %u,%u,%u,%u,%u,%u",
792+ a[0], a[1], a[2], a[3], p[0], p[1]);
793+ break;
794+#ifdef INET6
795+ case AF_INET6:
796+ a = (u_char *)&data_addr.su_sin6.sin6_addr;
797+ result = command(
798+ "LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
799+ a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
800+ a[8], a[9],a[10],a[11],a[12],a[13],a[14],a[15],
801+ p[0], p[1]);
802+ break;
803+#endif
804+ default:
805+ result = COMPLETE + 1; /* xxx */
806+ }
807+
808+ prt_done:
809 if (result == ERROR && sendport == -1) {
810 sendport = 0;
811 tmpno = 1;
812@@ -1189,9 +1481,12 @@
813 if (tmpno)
814 sendport = 1;
815 #ifdef IP_TOS
816+ if (data_addr.su_family == AF_INET)
817+ {
818 on = IPTOS_THROUGHPUT;
819 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
820 perror("ftp: setsockopt TOS (ignored)");
821+ }
822 #endif
823 return (0);
824 bad:
825@@ -1204,7 +1499,7 @@
826 static FILE *
827 dataconn(const char *lmode)
828 {
829- struct sockaddr_in from;
830+ union sockunion from;
831 int s, tos;
832 socklen_t fromlen = sizeof(from);
833
834@@ -1220,9 +1515,12 @@
835 (void) close(data);
836 data = s;
837 #ifdef IP_TOS
838+ if (from.su_family == AF_INET)
839+ {
840 tos = IPTOS_THROUGHPUT;
841 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
842 perror("ftp: setsockopt TOS (ignored)");
843+ }
844 #endif
845 return (fdopen(data, lmode));
846 }
847@@ -1284,8 +1582,8 @@
848 static struct comvars {
849 int connect;
850 char name[MAXHOSTNAMELEN];
851- struct sockaddr_in mctl;
852- struct sockaddr_in hctl;
853+ union sockunion mctl;
854+ union sockunion hctl;
855 FILE *in;
856 FILE *out;
857 int tpe;
858@@ -1323,7 +1621,7 @@
859 connected = op->connect;
860 if (hostname) {
861 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
862- ip->name[strlen(ip->name)] = '\0';
863+ ip->name[sizeof(ip->name) - 1] = '\0';
864 }
865 else {
866 ip->name[0] = 0;
867@@ -1352,18 +1650,18 @@
868 ip->ntflg = ntflag;
869 ntflag = op->ntflg;
870 (void) strncpy(ip->nti, ntin, 16);
871- (ip->nti)[strlen(ip->nti)] = '\0';
872+ (ip->nti)[16] = '\0'; /* shouldn't use strlen */
873 (void) strcpy(ntin, op->nti);
874 (void) strncpy(ip->nto, ntout, 16);
875- (ip->nto)[strlen(ip->nto)] = '\0';
876+ (ip->nto)[16] = '\0';
877 (void) strcpy(ntout, op->nto);
878 ip->mapflg = mapflag;
879 mapflag = op->mapflg;
880 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
881- (ip->mi)[strlen(ip->mi)] = '\0';
882+ (ip->mi)[MAXPATHLEN - 1] = '\0';
883 (void) strcpy(mapin, op->mi);
884 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
885- (ip->mo)[strlen(ip->mo)] = '\0';
886+ (ip->mo)[MAXPATHLEN - 1] = '\0';
887 (void) strcpy(mapout, op->mo);
888 (void) signal(SIGINT, oldintr);
889 if (abrtflag) {
890diff -uNr netkit-ftp-0.17/ftp/ftp_var.h netkit-ftp/ftp/ftp_var.h
891--- netkit-ftp-0.17/ftp/ftp_var.h Sat Oct 2 21:39:17 1999
892+++ netkit-ftp/ftp/ftp_var.h Fri Jan 12 23:36:27 2001
893@@ -1,3 +1,5 @@
894+/* $USAGI$ */
895+
896 /*
897 * Copyright (c) 1985, 1989 Regents of the University of California.
898 * All rights reserved.
899@@ -31,7 +33,7 @@
900 * SUCH DAMAGE.
901 *
902 * from: @(#)ftp_var.h 5.9 (Berkeley) 6/1/90
903- * $Id$
904+ * $Id$
905 */
906
907 /*
908@@ -112,6 +114,8 @@
909 Extern int mflag; /* flag: if != 0, then active multi command */
910
911 Extern int options; /* used during socket creation */
912+Extern int try_epsv; /* try EPSV for this session */
913+Extern int try_eprt; /* try EPRT for this session */
914
915 /*
916 * Format of command table.
917@@ -140,7 +144,7 @@
918 Extern char macbuf[4096];
919 #define MACBUF_SIZE 4096
920
921-char *hookup(char *host, int port);
922+char *hookup(const char *host, const char *port);
923 struct cmd *getcmd(const char *);
924 char **makeargv(int *pargc, char **parg);
925 int dologin(const char *host);
This page took 0.184886 seconds and 4 git commands to generate.