Blame SOURCES/netkit-ftp.usagi-ipv6.patch

4f574c
diff -uNr netkit-ftp-0.17/CVS/Entries netkit-ftp/CVS/Entries
4f574c
diff -uNr netkit-ftp-0.17/ChangeLog netkit-ftp/ChangeLog
4f574c
--- netkit-ftp-0.17/ChangeLog	Sun Jul 23 04:38:08 2000
4f574c
+++ netkit-ftp/ChangeLog	Tue Nov 28 03:50:10 2000
4f574c
@@ -1,3 +1,6 @@
4f574c
+28-Nov-2000:
4f574c
+	IPv6 support. (Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
4f574c
+
4f574c
 8-Jul-2000:
4f574c
 	Fix misused printf-function call (not %n-exploitable though).
4f574c
 
4f574c
diff -uNr netkit-ftp-0.17/configure netkit-ftp/configure
4f574c
--- netkit-ftp-0.17/configure	Sat Jul 29 21:00:28 2000
4f574c
+++ netkit-ftp/configure	Sat Jan 27 06:14:54 2001
4f574c
@@ -24,6 +24,7 @@
4f574c
     --binmode=mode        Mode for binaries [755]
4f574c
     --manmode=mode        Mode for manual pages [644]
4f574c
     --with-c-compiler=cc  Program for compiling C source [guessed]
4f574c
+    --enable-ipv6         Enable IPv6 support
4f574c
 EOF
4f574c
 	exit 0;;
4f574c
 	--verbose) ;;
4f574c
@@ -39,6 +40,11 @@
4f574c
 	--manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
4f574c
 	--with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
4f574c
 	--without-readline|--disable-readline) WITHOUT_READLINE=1;;
4f574c
+
4f574c
+	--disable-ipv6) ENABLE_IPV6=no;;
4f574c
+	--enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;;
4f574c
+	--enable-ipv6) ENABLE_IPV6=yes;;
4f574c
+
4f574c
 	*) echo "Unrecognized option: $1"; exit 1;;
4f574c
 esac 
4f574c
 shift
4f574c
@@ -142,6 +148,42 @@
4f574c
 
4f574c
 LDFLAGS=
4f574c
 LIBS=
4f574c
+
4f574c
+rm -f __conftest*
4f574c
+
4f574c
+##################################################
4f574c
+## Enable IPv6
4f574c
+echo -n "Whether to enable IPv6 support... "
4f574c
+if [ x"$ENABLE_IPV6" = x"yes" ]; then
4f574c
+    echo yes
4f574c
+    CFLAGS="$CFLAGS -DINET6"
4f574c
+else
4f574c
+    echo no
4f574c
+fi
4f574c
+
4f574c
+rm -f __conftest*
4f574c
+
4f574c
+## Search IPv6 Library / Headers
4f574c
+if [ x"$ENABLE_IPV6" = x"yes" ]; then
4f574c
+    echo -n "Search for IPv6 library... "
4f574c
+    inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib"
4f574c
+    inet6libs="inet6"
4f574c
+    inet6found=no
4f574c
+    for inet6libdir in $inet6libdirs; do
4f574c
+        for inet6lib in $inet6libs; do
4f574c
+            if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then
4f574c
+                inet6found=yes
4f574c
+                break 2
4f574c
+            fi
4f574c
+        done
4f574c
+    done
4f574c
+    if [ x"$inet6found" = x"yes" ]; then
4f574c
+        echo "$inet6libdir/lib$inet6lib.a"
4f574c
+        LIBS="$LIBS -L$inet6libdir -l$inet6lib"
4f574c
+    else
4f574c
+        echo "not found"
4f574c
+    fi
4f574c
+fi
4f574c
 
4f574c
 rm -f __conftest*
4f574c
 
4f574c
diff -uNr netkit-ftp-0.17/ftp/CVS/Entries netkit-ftp/ftp/CVS/Entries
4f574c
--- netkit-ftp-0.17/ftp/CVS/Entries	Thu Jan  1 02:00:00 1970
4f574c
+++ netkit-ftp/ftp/CVS/Entries	Mon Feb 19 06:50:49 2001
4f574c
@@ -0,0 +1,16 @@
4f574c
+/.cvsignore/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/Makefile/1.4/Sat Jan 27 05:57:08 2001//
4f574c
+/cmds.c/1.3/Fri Jan 12 21:36:27 2001//
4f574c
+/cmds.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/cmdtab.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/domacro.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/ftp.1/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/ftp.c/1.11/Sun Feb 11 12:26:59 2001//
4f574c
+/ftp_var.h/1.3/Fri Jan 12 21:36:27 2001//
4f574c
+/glob.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/glob.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/main.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/netrc.5/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/pathnames.h/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+/ruserpass.c/1.1.1.1/Fri Nov  3 19:18:15 2000//
4f574c
+D
4f574c
diff -uNr netkit-ftp-0.17/ftp/CVS/Repository netkit-ftp/ftp/CVS/Repository
4f574c
--- netkit-ftp-0.17/ftp/CVS/Repository	Thu Jan  1 02:00:00 1970
4f574c
+++ netkit-ftp/ftp/CVS/Repository	Mon Feb 19 06:50:49 2001
4f574c
@@ -0,0 +1 @@
4f574c
+usagi/src/netkit-ftp/ftp
4f574c
diff -uNr netkit-ftp-0.17/ftp/CVS/Root netkit-ftp/ftp/CVS/Root
4f574c
--- netkit-ftp-0.17/ftp/CVS/Root	Thu Jan  1 02:00:00 1970
4f574c
+++ netkit-ftp/ftp/CVS/Root	Mon Feb 19 06:50:49 2001
4f574c
@@ -0,0 +1 @@
4f574c
+:pserver:anoncvs@anoncvs.linux-ipv6.org:/cvsroot/usagi
4f574c
diff -uNr netkit-ftp-0.17/ftp/Makefile netkit-ftp/ftp/Makefile
4f574c
--- netkit-ftp-0.17/ftp/Makefile	Sun Aug  1 09:00:12 1999
4f574c
+++ netkit-ftp/ftp/Makefile	Sat Jan 27 07:57:08 2001
4f574c
@@ -16,10 +16,13 @@
4f574c
 cmds.o glob.o: glob.h
4f574c
 
4f574c
 install: ftp
4f574c
+	install -d $(INSTALLROOT)$(BINDIR)
4f574c
 	install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR)
4f574c
 	ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp
4f574c
+	install -d $(INSTALLROOT)$(MANDIR)/man1
4f574c
 	install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1
4f574c
 	ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1
4f574c
+	install -d $(INSTALLROOT)$(MANDIR)/man5
4f574c
 	install -m$(MANMODE) netrc.5 $(INSTALLROOT)$(MANDIR)/man5
4f574c
 
4f574c
 clean:
4f574c
diff -uNr netkit-ftp-0.17/ftp/cmds.c netkit-ftp/ftp/cmds.c
4f574c
--- netkit-ftp-0.17/ftp/cmds.c	Sun Jul 23 04:36:59 2000
4f574c
+++ netkit-ftp/ftp/cmds.c	Fri Jan 12 23:36:27 2001
4f574c
@@ -1,3 +1,5 @@
4f574c
+/* $USAGI$ */
4f574c
+
4f574c
 /*
4f574c
  * Copyright (c) 1985, 1989 Regents of the University of California.
4f574c
  * All rights reserved.
4f574c
@@ -35,7 +37,7 @@
4f574c
  * from: @(#)cmds.c	5.26 (Berkeley) 3/5/91
4f574c
  */
4f574c
 char cmds_rcsid[] = 
4f574c
-   "$Id: cmds.c,v 1.33 2000/07/23 01:36:59 dholland Exp $";
4f574c
+   "$Id: cmds.c,v 1.3 2001/01/12 21:36:27 sekiya Exp $";
4f574c
 
4f574c
 /*
4f574c
  * FTP User Program -- Command Routines.
4f574c
@@ -190,7 +192,7 @@
4f574c
 setpeer(int argc, char *argv[])
4f574c
 {
4f574c
 	char *host;
4f574c
-	unsigned short port;
4f574c
+	char *port;
4f574c
 
4f574c
 	if (connected) {
4f574c
 		printf("Already connected to %s, use close first.\n",
4f574c
@@ -205,22 +207,17 @@
4f574c
 		code = -1;
4f574c
 		return;
4f574c
 	}
4f574c
-	port = ftp_port;
4f574c
+	port = NULL;
4f574c
 	if (argc > 2) {
4f574c
-		port = atoi(argv[2]);
4f574c
-		if (port < 1) {
4f574c
-			printf("%s: bad port number-- %s\n", argv[1], argv[2]);
4f574c
-			printf ("usage: %s host-name [port]\n", argv[0]);
4f574c
-			code = -1;
4f574c
-			return;
4f574c
-		}
4f574c
-		port = htons(port);
4f574c
+		port = argv[2];
4f574c
 	}
4f574c
 	host = hookup(argv[1], port);
4f574c
 	if (host) {
4f574c
 		int overbose;
4f574c
 
4f574c
 		connected = 1;
4f574c
+		try_epsv = 1;
4f574c
+		try_eprt = 1;
4f574c
 		/*
4f574c
 		 * Set up defaults for FTP.
4f574c
 		 */
4f574c
diff -uNr netkit-ftp-0.17/ftp/cmdtab.c netkit-ftp/ftp/cmdtab.c
4f574c
--- netkit-ftp-0.17/ftp/cmdtab.c	Tue Sep 28 18:36:05 1999
4f574c
+++ netkit-ftp/ftp/cmdtab.c	Fri Nov  3 21:18:15 2000
4f574c
@@ -35,7 +35,7 @@
4f574c
  * from: @(#)cmdtab.c	5.10 (Berkeley) 6/1/90
4f574c
  */
4f574c
 char cmdtab_rcsid[] = 
4f574c
-  "$Id: cmdtab.c,v 1.8 1999/09/28 15:36:05 dholland Exp $";
4f574c
+  "$Id: cmdtab.c,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $";
4f574c
 
4f574c
 #include <string.h>   /* for NULL */
4f574c
 #include "ftp_var.h"
4f574c
diff -uNr netkit-ftp-0.17/ftp/domacro.c netkit-ftp/ftp/domacro.c
4f574c
--- netkit-ftp-0.17/ftp/domacro.c	Thu Aug 15 02:27:28 1996
4f574c
+++ netkit-ftp/ftp/domacro.c	Fri Nov  3 21:18:15 2000
4f574c
@@ -35,7 +35,7 @@
4f574c
  * from: @(#)domacro.c	1.8 (Berkeley) 9/28/90
4f574c
  */
4f574c
 char domacro_rcsid[] = 
4f574c
-  "$Id: domacro.c,v 1.4 1996/08/14 23:27:28 dholland Exp $";
4f574c
+  "$Id: domacro.c,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $";
4f574c
 
4f574c
 #include <errno.h>
4f574c
 #include <ctype.h>
4f574c
diff -uNr netkit-ftp-0.17/ftp/ftp.1 netkit-ftp/ftp/ftp.1
4f574c
--- netkit-ftp-0.17/ftp/ftp.1	Mon Jul 31 02:56:59 2000
4f574c
+++ netkit-ftp/ftp/ftp.1	Fri Nov  3 21:18:15 2000
4f574c
@@ -30,7 +30,7 @@
4f574c
 .\" SUCH DAMAGE.
4f574c
 .\"
4f574c
 .\"	from: @(#)ftp.1	6.18 (Berkeley) 7/30/91
4f574c
-.\"	$Id: ftp.1,v 1.14 2000/07/30 23:56:59 dholland Exp $
4f574c
+.\"	$Id: ftp.1,v 1.1.1.1 2000/11/03 19:18:15 mk Exp $
4f574c
 .\"
4f574c
 .Dd August 15, 1999
4f574c
 .Dt FTP 1
4f574c
diff -uNr netkit-ftp-0.17/ftp/ftp.c netkit-ftp/ftp/ftp.c
4f574c
--- netkit-ftp-0.17/ftp/ftp.c	Mon Dec 13 22:33:20 1999
4f574c
+++ netkit-ftp/ftp/ftp.c	Sun Feb 11 14:26:59 2001
4f574c
@@ -1,3 +1,34 @@
4f574c
+/* $USAGI$ */
4f574c
+
4f574c
+/*
4f574c
+ * Copyright (C) 1997 and 1998 WIDE Project.
4f574c
+ * All rights reserved.
4f574c
+ * 
4f574c
+ * Redistribution and use in source and binary forms, with or without
4f574c
+ * modification, are permitted provided that the following conditions
4f574c
+ * are met:
4f574c
+ * 1. Redistributions of source code must retain the above copyright
4f574c
+ *    notice, this list of conditions and the following disclaimer.
4f574c
+ * 2. Redistributions in binary form must reproduce the above copyright
4f574c
+ *    notice, this list of conditions and the following disclaimer in the
4f574c
+ *    documentation and/or other materials provided with the distribution.
4f574c
+ * 3. Neither the name of the project nor the names of its contributors
4f574c
+ *    may be used to endorse or promote products derived from this software
4f574c
+ *    without specific prior written permission.
4f574c
+ * 
4f574c
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
4f574c
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4f574c
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4f574c
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
4f574c
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4f574c
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4f574c
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4f574c
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4f574c
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4f574c
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4f574c
+ * SUCH DAMAGE.
4f574c
+ */
4f574c
+
4f574c
 /*
4f574c
  * Copyright (c) 1985, 1989 Regents of the University of California.
4f574c
  * All rights reserved.
4f574c
@@ -35,7 +66,7 @@
4f574c
  * From: @(#)ftp.c	5.38 (Berkeley) 4/22/91
4f574c
  */
4f574c
 char ftp_rcsid[] = 
4f574c
-  "$Id: ftp.c,v 1.25 1999/12/13 20:33:20 dholland Exp $";
4f574c
+  "$Id: ftp.c,v 1.11 2001/02/11 12:26:59 yoshfuji Exp $";
4f574c
 
4f574c
 #include <sys/param.h>
4f574c
 #include <sys/stat.h>
4f574c
@@ -63,14 +94,38 @@
4f574c
 #include "ftp_var.h"
4f574c
 #include "cmds.h"
4f574c
 
4f574c
+#ifdef _USAGI
4f574c
+#include "version.h"
4f574c
+#else
4f574c
 #include "../version.h"
4f574c
+#endif
4f574c
+
4f574c
+union sockunion {
4f574c
+	struct sockinet {
4f574c
+		u_short	si_family;
4f574c
+		u_short	si_port;
4f574c
+	} su_si;
4f574c
+	struct	sockaddr		su_sa;
4f574c
+	struct	sockaddr_in  		su_sin;
4f574c
+#ifdef INET6
4f574c
+	struct	sockaddr_in6 		su_sin6;
4f574c
+#endif
4f574c
+};
4f574c
+#define	su_family	su_sa.sa_family
4f574c
+#define	su_port		su_si.si_port
4f574c
+
4f574c
+#ifdef INET6
4f574c
+#define ex_af2prot(a) (a == AF_INET ? 1 : (a == AF_INET6 ? 2 : 0))
4f574c
+#else
4f574c
+#define ex_af2prot(a) (a == AF_INET ? 1 : 0)
4f574c
+#endif
4f574c
 
4f574c
 int data = -1;
4f574c
 off_t restart_point = 0;
4f574c
 
4f574c
-static struct sockaddr_in hisctladdr;
4f574c
-static struct sockaddr_in data_addr;
4f574c
-static struct sockaddr_in myctladdr;
4f574c
+static union sockunion hisctladdr;
4f574c
+static union sockunion data_addr;
4f574c
+static union sockunion myctladdr;
4f574c
 static int ptflag = 0;
4f574c
 static sigjmp_buf recvabort;
4f574c
 static sigjmp_buf sendabort;
4f574c
@@ -96,79 +151,119 @@
4f574c
 static FILE *dataconn(const char *);
4f574c
 
4f574c
 char *
4f574c
-hookup(char *host, int port)
4f574c
+hookup(const char *host, const char *port)
4f574c
 {
4f574c
-	register struct hostent *hp = 0;
4f574c
-	int s, tos;
4f574c
+	int s, tos, error;
4f574c
 	socklen_t len;
4f574c
 	static char hostnamebuf[256];
4f574c
-
4f574c
+	struct addrinfo hints, *res, *res0;
4f574c
+	char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
4f574c
+	char *cause = "ftp: unknown";
4f574c
+
4f574c
+	if (port) {
4f574c
+		strncpy(pbuf, port, sizeof(pbuf) - 1);
4f574c
+		pbuf[sizeof(pbuf) - 1] = '\0';
4f574c
+	} else {
4f574c
+		sprintf(pbuf, "%d", ntohs(ftp_port));
4f574c
+	}
4f574c
 	memset(&hisctladdr, 0, sizeof(hisctladdr));
4f574c
-	if (inet_aton(host, &hisctladdr.sin_addr)) {
4f574c
-		hisctladdr.sin_family = AF_INET;
4f574c
-		strncpy(hostnamebuf, host, sizeof(hostnamebuf));
4f574c
-		hostnamebuf[sizeof(hostnamebuf)-1]=0;
4f574c
-	} 
4f574c
-	else {
4f574c
-		hp = gethostbyname(host);
4f574c
-		if (hp == NULL) {
4f574c
-			fprintf(stderr, "ftp: %s: ", host);
4f574c
-			herror((char *)NULL);
4f574c
-			code = -1;
4f574c
-			return((char *) 0);
4f574c
+	memset(&hints, 0, sizeof(hints));
4f574c
+	hints.ai_flags = AI_CANONNAME;
4f574c
+	hints.ai_socktype = SOCK_STREAM;
4f574c
+	error = getaddrinfo(host, pbuf, &hints, &res0);
4f574c
+	if (error) {
4f574c
+		if (port) {
4f574c
+			strcpy(hbuf, " ");
4f574c
+		} else {
4f574c
+			hbuf[0] = '\0';
4f574c
+			pbuf[0] = '\0';
4f574c
 		}
4f574c
-		hisctladdr.sin_family = hp->h_addrtype;
4f574c
-		if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
4f574c
-			hp->h_length = sizeof(hisctladdr.sin_addr);
4f574c
-		}
4f574c
-		memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);
4f574c
-		(void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
4f574c
-		hostnamebuf[sizeof(hostnamebuf)-1] = 0;
4f574c
-	}
4f574c
-	hostname = hostnamebuf;
4f574c
-	s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
4f574c
-	if (s < 0) {
4f574c
-		perror("ftp: socket");
4f574c
+		fprintf(stderr, "ftp: %s%s%s: %s\n", host, hbuf, pbuf,
4f574c
+						gai_strerror(error));
4f574c
 		code = -1;
4f574c
 		return (0);
4f574c
 	}
4f574c
-	hisctladdr.sin_port = port;
4f574c
-	while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
4f574c
-		if (hp && hp->h_addr_list[1]) {
4f574c
-			int oerrno = errno;
4f574c
-
4f574c
-			fprintf(stderr, "ftp: connect to address %s: ",
4f574c
-				inet_ntoa(hisctladdr.sin_addr));
4f574c
-			errno = oerrno;
4f574c
-			perror((char *) 0);
4f574c
-			hp->h_addr_list++;
4f574c
-			memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], 
4f574c
-			       hp->h_length);
4f574c
-			fprintf(stdout, "Trying %s...\n",
4f574c
-				inet_ntoa(hisctladdr.sin_addr));
4f574c
-			(void) close(s);
4f574c
-			s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
4f574c
-			if (s < 0) {
4f574c
-				perror("ftp: socket");
4f574c
-				code = -1;
4f574c
-				return (0);
4f574c
+
4f574c
+	if (res0->ai_canonname) {
4f574c
+		struct addrinfo h, *a;
4f574c
+		memset(&h, 0, sizeof(h));
4f574c
+		h.ai_family = PF_UNSPEC;
4f574c
+		h.ai_socktype = SOCK_STREAM;
4f574c
+		h.ai_flags = AI_NUMERICHOST;
4f574c
+		if (!getaddrinfo(res0->ai_canonname, NULL, &h, &a)) {
4f574c
+			strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
4f574c
+			freeaddrinfo(a);
4f574c
+		} else
4f574c
+			strncpy(hostnamebuf, host, sizeof(hostnamebuf));
4f574c
+	}
4f574c
+	else
4f574c
+		strncpy(hostnamebuf, host, sizeof(hostnamebuf));
4f574c
+	hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
4f574c
+	hostname = hostnamebuf;
4f574c
+	
4f574c
+	s = -1;
4f574c
+	for (res = res0; res; res = res->ai_next) {
4f574c
+		if (!ex_af2prot(res->ai_family)) {
4f574c
+			cause = "ftp: mismatch address family";
4f574c
+			errno = EPROTONOSUPPORT;
4f574c
+			continue;
4f574c
+		}
4f574c
+		if ((size_t)res->ai_addrlen > sizeof(hisctladdr)) {
4f574c
+			cause = "ftp: mismatch struct sockaddr size";
4f574c
+			errno = EPROTO;
4f574c
+			continue;
4f574c
+		}
4f574c
+		if (getnameinfo(res->ai_addr, res->ai_addrlen,
4f574c
+				hbuf, sizeof(hbuf), NULL, 0,
4f574c
+				NI_NUMERICHOST))
4f574c
+			strcpy(hbuf, "???");
4f574c
+		if (res0->ai_next)	/* if we have multiple possibilities */
4f574c
+			fprintf(stdout, "Trying %s...\n", hbuf);
4f574c
+		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4f574c
+		if (s < 0) {
4f574c
+			cause = "ftp: socket";
4f574c
+			continue;
4f574c
+		}
4f574c
+		while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
4f574c
+				&& errno == EINTR) {
4f574c
+			;
4f574c
+		}
4f574c
+		if (error) {
4f574c
+			/* this "if" clause is to prevent print warning twice */
4f574c
+			if (res->ai_next) {
4f574c
+				fprintf(stderr,
4f574c
+					"ftp: connect to address %s", hbuf);
4f574c
+				perror("");
4f574c
 			}
4f574c
+			cause = "ftp: connect";
4f574c
+			close(s);
4f574c
+			s = -1;
4f574c
 			continue;
4f574c
 		}
4f574c
-		perror("ftp: connect");
4f574c
+		/* finally we got one */
4f574c
+		break;
4f574c
+	}
4f574c
+	if (s < 0) {
4f574c
+		perror(cause);
4f574c
 		code = -1;
4f574c
-		goto bad;
4f574c
+		freeaddrinfo(res0);
4f574c
+		return NULL;
4f574c
 	}
4f574c
-	len = sizeof (myctladdr);
4f574c
+	len = res->ai_addrlen;
4f574c
+	memcpy(&hisctladdr, res->ai_addr, len);
4f574c
+	freeaddrinfo(res0);
4f574c
 	if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
4f574c
 		perror("ftp: getsockname");
4f574c
 		code = -1;
4f574c
 		goto bad;
4f574c
 	}
4f574c
 #ifdef IP_TOS
4f574c
+	if (hisctladdr.su_family == AF_INET)
4f574c
+	{
4f574c
 	tos = IPTOS_LOWDELAY;
4f574c
 	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
4f574c
 		perror("ftp: setsockopt TOS (ignored)");
4f574c
+	}
4f574c
 #endif
4f574c
 	cin = fdopen(s, "r");
4f574c
 	cout = fdopen(s, "w");
4f574c
@@ -182,7 +277,7 @@
4f574c
 		goto bad;
4f574c
 	}
4f574c
 	if (verbose)
4f574c
-		printf("Connected to %s.\n", hostname);
4f574c
+		printf("Connected to %s (%s).\n", hostname, hbuf);
4f574c
 	if (getreply(0) > 2) { 	/* read startup message from server */
4f574c
 		if (cin)
4f574c
 			(void) fclose(cin);
4f574c
@@ -392,8 +487,10 @@
4f574c
 			}
4f574c
 			if (dig < 4 && isdigit(c))
4f574c
 				code = code * 10 + (c - '0');
4f574c
-			if (!pflag && code == 227)
4f574c
+			if (!pflag && (code == 227 || code == 228))
4f574c
 				pflag = 1;
4f574c
+			else if (!pflag && code == 229)
4f574c
+				pflag = 100;
4f574c
 			if (dig > 4 && pflag == 1 && isdigit(c))
4f574c
 				pflag = 2;
4f574c
 			if (pflag == 2) {
4f574c
@@ -405,6 +502,8 @@
4f574c
 					pflag = 3;
4f574c
 				}
4f574c
 			}
4f574c
+			if (pflag == 100 && c == '(')
4f574c
+				pflag = 2;
4f574c
 			if (dig == 4 && c == '-') {
4f574c
 				if (continuation)
4f574c
 					code = 0;
4f574c
@@ -1083,15 +1182,25 @@
4f574c
 static int
4f574c
 initconn(void)
4f574c
 {
4f574c
-	register char *p, *a;
4f574c
+	u_char *p, *a;
4f574c
 	int result, tmpno = 0;
4f574c
 	socklen_t len;
4f574c
 	int on = 1;
4f574c
-	int tos;
4f574c
-	u_long a1,a2,a3,a4,p1,p2;
4f574c
-
4f574c
+	int tos, error = 0;
4f574c
+	u_int ad[16], po[2], af, alen, plen;
4f574c
+	char *pasvcmd = NULL;
4f574c
+	char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
4f574c
+
4f574c
+#ifdef INET6
4f574c
+	if (myctladdr.su_family == AF_INET6
4f574c
+	 && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
4f574c
+	  || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
4f574c
+		fprintf(stderr, "use of scoped address can be troublesome\n");
4f574c
+	}
4f574c
+#endif
4f574c
 	if (passivemode) {
4f574c
-		data = socket(AF_INET, SOCK_STREAM, 0);
4f574c
+		data_addr = hisctladdr;
4f574c
+		data = socket(data_addr.su_family, SOCK_STREAM, 0);
4f574c
 		if (data < 0) {
4f574c
 			perror("ftp: socket");
4f574c
 			return(1);
4f574c
@@ -1100,52 +1209,203 @@
4f574c
 		    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
4f574c
 			       sizeof (on)) < 0)
4f574c
 			perror("ftp: setsockopt (ignored)");
4f574c
-		if (command("PASV") != COMPLETE) {
4f574c
+		switch (data_addr.su_family) {
4f574c
+		case AF_INET:
4f574c
+#if 0
4f574c
+			if (try_epsv) {
4f574c
+				result = command(pasvcmd = "EPSV 1");
4f574c
+				if (code / 10 == 22 && code != 229) {
4f574c
+					fprintf(stderr,
4f574c
+				  "wrong server: return code must be 229\n");
4f574c
+					result = COMPLETE + 1;
4f574c
+				}
4f574c
+			} else {
4f574c
+#endif
4f574c
+			result = COMPLETE + 1;
4f574c
+
4f574c
+			if (result != COMPLETE) {
4f574c
+				try_epsv = 0;
4f574c
+				result = command(pasvcmd = "PASV");
4f574c
+			}
4f574c
+			break;
4f574c
+#ifdef INET6
4f574c
+		case AF_INET6:
4f574c
+			if (try_epsv) {
4f574c
+				result = command(pasvcmd = "EPSV 2");
4f574c
+				if (code / 10 == 22 && code != 229) {
4f574c
+					fprintf(stderr,
4f574c
+				  "wrong server: return code must be 229\n");
4f574c
+					result = COMPLETE + 1;
4f574c
+				}
4f574c
+			} else {
4f574c
+				result = COMPLETE + 1;
4f574c
+			}
4f574c
+			if (result != COMPLETE) {
4f574c
+				try_epsv = 0;
4f574c
+				result = command(pasvcmd = "LPSV");
4f574c
+			}
4f574c
+			break;
4f574c
+#endif
4f574c
+		default:
4f574c
+			result = COMPLETE + 1;
4f574c
+			break;
4f574c
+		}
4f574c
+		if (result != COMPLETE) {
4f574c
 			printf("Passive mode refused.\n");
4f574c
-			return(1);
4f574c
+			goto bad;
4f574c
 		}
4f574c
 
4f574c
+#define pack2(var) \
4f574c
+	(((var[0] & 0xff) << 8) | ((var[1] & 0xff) << 0))
4f574c
+#define pack4(var) \
4f574c
+	((((var)[0] & 0xff) << 24) | (((var)[1] & 0xff) << 16) | \
4f574c
+	 (((var)[2] & 0xff) << 8) | (((var)[3] & 0xff) << 0))
4f574c
+
4f574c
 		/*
4f574c
 		 * What we've got at this point is a string of comma separated
4f574c
 		 * one-byte unsigned integer values, separated by commas.
4f574c
-		 * The first four are the an IP address. The fifth is the MSB
4f574c
-		 * of the port number, the sixth is the LSB. From that we'll
4f574c
-		 * prepare a sockaddr_in.
4f574c
 		 */
4f574c
-
4f574c
-		if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",
4f574c
-			   &a1,&a2,&a3,&a4,&p1,&p2)
4f574c
-		    != 6) 
4f574c
-		{
4f574c
-			printf("Passive mode address scan failure. Shouldn't happen!\n");
4f574c
-			return(1);
4f574c
+		error = 0;
4f574c
+		if (strcmp(pasvcmd, "PASV") == 0) {
4f574c
+			if (data_addr.su_family != AF_INET) {
4f574c
+				error = 2;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			if (code / 10 == 22 && code != 227) {
4f574c
+				error = 227;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			if (sscanf(pasv, "%u,%u,%u,%u,%u,%u",
4f574c
+					&ad[0], &ad[1], &ad[2], &ad[3],
4f574c
+					&po[0], &po[1]) != 6) {
4f574c
+				error = 1;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			data_addr.su_sin.sin_addr.s_addr = htonl(pack4(ad));
4f574c
+			data_addr.su_port = htons(pack2(po));
4f574c
+		} else
4f574c
+		    if (strcmp(pasvcmd, "LPSV") == 0) {
4f574c
+			if (code / 10 == 22 && code != 228) {
4f574c
+				error = 228;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			switch (data_addr.su_family) {
4f574c
+			case AF_INET:
4f574c
+				if (sscanf(pasv, "%u,%u,%u,%u,%u,%u,%u,%u,%u",
4f574c
+						&af, &alen,
4f574c
+						&ad[0], &ad[1], &ad[2], &ad[3],
4f574c
+						&plen, &po[0], &po[1]) != 9) {
4f574c
+					error = 1;
4f574c
+					goto psv_done;
4f574c
+				}
4f574c
+				if (af != 4 || alen != 4 || plen != 2) {
4f574c
+					error = 2;
4f574c
+					goto psv_done;
4f574c
+				}
4f574c
+				data_addr.su_sin.sin_addr.s_addr =
4f574c
+							htonl(pack4(ad));
4f574c
+				data_addr.su_port = htons(pack2(po));
4f574c
+				break;
4f574c
+#ifdef INET6
4f574c
+			case AF_INET6:
4f574c
+				if (sscanf(pasv,
4f574c
+	"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
4f574c
+				  &af, &alen,
4f574c
+				  &ad[0], &ad[1], &ad[2], &ad[3],
4f574c
+				  &ad[4], &ad[5], &ad[6], &ad[7],
4f574c
+				  &ad[8], &ad[9], &ad[10], &ad[11],
4f574c
+				  &ad[12], &ad[13], &ad[14], &ad[15],
4f574c
+				  &plen, &po[0], &po[1]) != 21) {
4f574c
+					error = 1;
4f574c
+					goto psv_done;
4f574c
+				}
4f574c
+				if (af != 6 || alen != 16 || plen != 2) {
4f574c
+					error = 2;
4f574c
+					goto psv_done;
4f574c
+				}
4f574c
+				data_addr.su_sin6.sin6_addr.s6_addr32[0] =
4f574c
+							htonl(pack4(ad));
4f574c
+				data_addr.su_sin6.sin6_addr.s6_addr32[1] =
4f574c
+							htonl(pack4(ad+4));
4f574c
+				data_addr.su_sin6.sin6_addr.s6_addr32[2] =
4f574c
+							htonl(pack4(ad+8));
4f574c
+				data_addr.su_sin6.sin6_addr.s6_addr32[3] =
4f574c
+							htonl(pack4(ad+12));
4f574c
+				data_addr.su_port = htons(pack2(po));
4f574c
+				break;
4f574c
+#endif
4f574c
+			default:
4f574c
+				error = 1;
4f574c
+			}
4f574c
+		} else if (strncmp(pasvcmd, "EPSV", 4) == 0) {
4f574c
+			char delim[4];
4f574c
+			u_int epsvpo;
4f574c
+
4f574c
+			if (code / 10 == 22 && code != 229) {
4f574c
+				error = 229;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			if (sscanf(pasv, "%c%c%c%u%c", &delim[0], &delim[1],
4f574c
+					&delim[2], &epsvpo, &delim[3]) != 5) {
4f574c
+				error = 1;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			if (delim[0] != delim[1] || delim[0] != delim[2]
4f574c
+			 || delim[0] != delim[3]) {
4f574c
+				error = 1;
4f574c
+				goto psv_done;
4f574c
+			}
4f574c
+			data_addr.su_port = htons(epsvpo);
4f574c
+		} else {
4f574c
+			error = 1;
4f574c
+		}
4f574c
+psv_done:
4f574c
+		switch (error) {
4f574c
+		case 0:
4f574c
+			break;
4f574c
+		case 1:
4f574c
+			fprintf(stderr,
4f574c
+		  "Passive mode address scan failure. Shouldn't happen!\n");
4f574c
+			goto bad;
4f574c
+		case 2:
4f574c
+			fprintf(stderr,
4f574c
+			  "Passive mode AF mismatch. Shouldn't happen!\n");
4f574c
+			goto bad;
4f574c
+		case 227:
4f574c
+		case 228:
4f574c
+		case 229:
4f574c
+			fprintf(stderr,
4f574c
+			  "wrong server: return code must be %d\n", error);
4f574c
+			goto bad;
4f574c
+		default:
4f574c
+			fprintf(stderr, "Bug\n");
4f574c
 		}
4f574c
 
4f574c
-		data_addr.sin_family = AF_INET;
4f574c
-		data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
4f574c
-						  (a3 << 8) | a4);
4f574c
-		data_addr.sin_port = htons((p1 << 8) | p2);
4f574c
-
4f574c
 		if (connect(data, (struct sockaddr *) &data_addr,
4f574c
-		    sizeof(data_addr))<0) {
4f574c
+			    (data_addr.su_family == AF_INET ?
4f574c
+			     sizeof(data_addr.su_sin) :
4f574c
+			     sizeof(data_addr.su_sin6)))<0) {
4f574c
 			perror("ftp: connect");
4f574c
 			return(1);
4f574c
 		}
4f574c
 #ifdef IP_TOS
4f574c
+		if (data_addr.su_family == AF_INET)
4f574c
+		{
4f574c
 		tos = IPTOS_THROUGHPUT;
4f574c
 		if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
4f574c
 		    sizeof(tos)) < 0)
4f574c
 			perror("ftp: setsockopt TOS (ignored)");
4f574c
+		}
4f574c
 #endif
4f574c
 		return(0);
4f574c
 	}
4f574c
 noport:
4f574c
 	data_addr = myctladdr;
4f574c
 	if (sendport)
4f574c
-		data_addr.sin_port = 0;	/* let system pick one */ 
4f574c
+		data_addr.su_port = 0;	/* let system pick one */ 
4f574c
 	if (data != -1)
4f574c
 		(void) close(data);
4f574c
-	data = socket(AF_INET, SOCK_STREAM, 0);
4f574c
+	data = socket(data_addr.su_family, SOCK_STREAM, 0);
4f574c
 	if (data < 0) {
4f574c
 		perror("ftp: socket");
4f574c
 		if (tmpno)
4f574c
@@ -1172,13 +1432,47 @@
4f574c
 	if (listen(data, 1) < 0)
4f574c
 		perror("ftp: listen");
4f574c
 	if (sendport) {
4f574c
-		a = (char *)&data_addr.sin_addr;
4f574c
-		p = (char *)&data_addr.sin_port;
4f574c
-#define	UC(b)	(((int)b)&0xff)
4f574c
-		result =
4f574c
-		    command("PORT %d,%d,%d,%d,%d,%d",
4f574c
-		      UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
4f574c
-		      UC(p[0]), UC(p[1]));
4f574c
+		af = ex_af2prot(data_addr.su_family);
4f574c
+		if (try_eprt && af > 1) {      /* only IPv6 */
4f574c
+			if (getnameinfo((struct sockaddr *)&data_addr, len,
4f574c
+					hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
4f574c
+					NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
4f574c
+				result = command("EPRT |%d|%s|%s|",
4f574c
+							af, hbuf, pbuf);
4f574c
+				if (result != COMPLETE) {
4f574c
+					try_eprt = 0;
4f574c
+				}
4f574c
+			} else {
4f574c
+				result = ERROR;
4f574c
+			}
4f574c
+		} else {
4f574c
+			result = COMPLETE + 1;
4f574c
+		}
4f574c
+		if (result == COMPLETE)
4f574c
+			goto prt_done;
4f574c
+
4f574c
+		p = (u_char *)&data_addr.su_port;
4f574c
+		switch (data_addr.su_family) {
4f574c
+		case AF_INET:
4f574c
+			a = (u_char *)&data_addr.su_sin.sin_addr;
4f574c
+			result = command("PORT %u,%u,%u,%u,%u,%u",
4f574c
+				a[0], a[1], a[2], a[3], p[0], p[1]);
4f574c
+			break;
4f574c
+#ifdef INET6
4f574c
+		case AF_INET6:
4f574c
+			a = (u_char *)&data_addr.su_sin6.sin6_addr;
4f574c
+			result = command(
4f574c
+	"LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
4f574c
+				a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
4f574c
+				a[8], a[9],a[10],a[11],a[12],a[13],a[14],a[15],
4f574c
+				p[0], p[1]);
4f574c
+			break;
4f574c
+#endif
4f574c
+		default:
4f574c
+			result = COMPLETE + 1; /* xxx */
4f574c
+		}
4f574c
+
4f574c
+	prt_done:
4f574c
 		if (result == ERROR && sendport == -1) {
4f574c
 			sendport = 0;
4f574c
 			tmpno = 1;
4f574c
@@ -1189,9 +1483,12 @@
4f574c
 	if (tmpno)
4f574c
 		sendport = 1;
4f574c
 #ifdef IP_TOS
4f574c
+	if (data_addr.su_family == AF_INET)
4f574c
+	{
4f574c
 	on = IPTOS_THROUGHPUT;
4f574c
 	if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
4f574c
 		perror("ftp: setsockopt TOS (ignored)");
4f574c
+	}
4f574c
 #endif
4f574c
 	return (0);
4f574c
 bad:
4f574c
@@ -1204,7 +1501,7 @@
4f574c
 static FILE *
4f574c
 dataconn(const char *lmode)
4f574c
 {
4f574c
-	struct sockaddr_in from;
4f574c
+	union sockunion from;
4f574c
 	int s, tos;
4f574c
 	socklen_t fromlen = sizeof(from);
4f574c
 
4f574c
@@ -1220,9 +1517,12 @@
4f574c
 	(void) close(data);
4f574c
 	data = s;
4f574c
 #ifdef IP_TOS
4f574c
+	if (from.su_family == AF_INET)
4f574c
+	{
4f574c
 	tos = IPTOS_THROUGHPUT;
4f574c
 	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
4f574c
 		perror("ftp: setsockopt TOS (ignored)");
4f574c
+	}
4f574c
 #endif
4f574c
 	return (fdopen(data, lmode));
4f574c
 }
4f574c
@@ -1284,8 +1584,8 @@
4f574c
 	static struct comvars {
4f574c
 		int connect;
4f574c
 		char name[MAXHOSTNAMELEN];
4f574c
-		struct sockaddr_in mctl;
4f574c
-		struct sockaddr_in hctl;
4f574c
+		union sockunion mctl;
4f574c
+		union sockunion hctl;
4f574c
 		FILE *in;
4f574c
 		FILE *out;
4f574c
 		int tpe;
4f574c
@@ -1323,7 +1623,7 @@
4f574c
 	connected = op->connect;
4f574c
 	if (hostname) {
4f574c
 		(void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
4f574c
-		ip->name[strlen(ip->name)] = '\0';
4f574c
+		ip->name[sizeof(ip->name) - 1] = '\0';
4f574c
 	} 
4f574c
 	else {
4f574c
 		ip->name[0] = 0;
4f574c
@@ -1352,18 +1652,18 @@
4f574c
 	ip->ntflg = ntflag;
4f574c
 	ntflag = op->ntflg;
4f574c
 	(void) strncpy(ip->nti, ntin, 16);
4f574c
-	(ip->nti)[strlen(ip->nti)] = '\0';
4f574c
+	(ip->nti)[16] = '\0';		/* shouldn't use strlen */
4f574c
 	(void) strcpy(ntin, op->nti);
4f574c
 	(void) strncpy(ip->nto, ntout, 16);
4f574c
-	(ip->nto)[strlen(ip->nto)] = '\0';
4f574c
+	(ip->nto)[16] = '\0';
4f574c
 	(void) strcpy(ntout, op->nto);
4f574c
 	ip->mapflg = mapflag;
4f574c
 	mapflag = op->mapflg;
4f574c
 	(void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
4f574c
-	(ip->mi)[strlen(ip->mi)] = '\0';
4f574c
+	(ip->mi)[MAXPATHLEN - 1] = '\0';
4f574c
 	(void) strcpy(mapin, op->mi);
4f574c
 	(void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
4f574c
-	(ip->mo)[strlen(ip->mo)] = '\0';
4f574c
+	(ip->mo)[MAXPATHLEN - 1] = '\0';
4f574c
 	(void) strcpy(mapout, op->mo);
4f574c
 	(void) signal(SIGINT, oldintr);
4f574c
 	if (abrtflag) {
4f574c
diff -uNr netkit-ftp-0.17/ftp/ftp_var.h netkit-ftp/ftp/ftp_var.h
4f574c
--- netkit-ftp-0.17/ftp/ftp_var.h	Sat Oct  2 21:39:17 1999
4f574c
+++ netkit-ftp/ftp/ftp_var.h	Fri Jan 12 23:36:27 2001
4f574c
@@ -1,3 +1,5 @@
4f574c
+/* $USAGI$ */
4f574c
+
4f574c
 /*
4f574c
  * Copyright (c) 1985, 1989 Regents of the University of California.
4f574c
  * All rights reserved.
4f574c
@@ -31,7 +33,7 @@
4f574c
  * SUCH DAMAGE.
4f574c
  *
4f574c
  *	from: @(#)ftp_var.h	5.9 (Berkeley) 6/1/90
4f574c
- *	$Id: ftp_var.h,v 1.12 1999/10/02 18:39:17 dholland Exp $
4f574c
+ *	$Id: ftp_var.h,v 1.3 2001/01/12 21:36:27 sekiya Exp $
4f574c
  */
4f574c
 
4f574c
 /*
4f574c
@@ -112,6 +114,8 @@
4f574c
 Extern int	mflag;		/* flag: if != 0, then active multi command */
4f574c
 
4f574c
 Extern int	options;	/* used during socket creation */
4f574c
+Extern int	try_epsv;	/* try EPSV for this session */
4f574c
+Extern int	try_eprt;	/* try EPRT for this session */
4f574c
 
4f574c
 /*
4f574c
  * Format of command table.
4f574c
@@ -140,7 +144,7 @@
4f574c
 Extern char macbuf[4096];
4f574c
 #define MACBUF_SIZE 4096
4f574c
 
4f574c
-char *hookup(char *host, int port);
4f574c
+char *hookup(const char *host, const char *port);
4f574c
 struct cmd *getcmd(const char *);
4f574c
 char **makeargv(int *pargc, char **parg);
4f574c
 int dologin(const char *host);