summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>1999-12-08 12:57:07 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>1999-12-08 12:57:07 +0000
commit608666bc5b614c4a821f9571e6e7516c490a1d2e (patch)
tree7d971c94c4313e37b84fb56089fcd487638af573 /usr.bin
parentaa65718cad2b6a15bce9c1c4ec03903f42539558 (diff)
ftp(1) from KAME, should be good for testing.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ftp/Makefile5
-rw-r--r--usr.bin/ftp/cmds.c51
-rw-r--r--usr.bin/ftp/cmdtab.c6
-rw-r--r--usr.bin/ftp/extern.h34
-rw-r--r--usr.bin/ftp/fetch.c123
-rw-r--r--usr.bin/ftp/ftp.c499
-rw-r--r--usr.bin/ftp/ftp_var.h41
-rw-r--r--usr.bin/ftp/main.c77
-rw-r--r--usr.bin/ftp/util.c11
9 files changed, 604 insertions, 243 deletions
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile
index b8917deac29..5ac6c4f2dfa 100644
--- a/usr.bin/ftp/Makefile
+++ b/usr.bin/ftp/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.15 1998/07/24 00:10:54 millert Exp $
+# $OpenBSD: Makefile,v 1.16 1999/12/08 12:57:06 itojun Exp $
# Define SMALL to disable command line editing
#CFLAGS+=-DSMALL
@@ -15,6 +15,9 @@ PROG= ftp
SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c ruserpass.c \
stringlist.c util.c
+# not really used at this moment
+CPPFLAGS+= -DINET6
+
LDADD+= -ledit -lcurses
DPADD+= ${LIBEDIT} ${LIBCURSES}
diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c
index eb8a57073d1..e03c32c5149 100644
--- a/usr.bin/ftp/cmds.c
+++ b/usr.bin/ftp/cmds.c
@@ -1,7 +1,36 @@
-/* $OpenBSD: cmds.c,v 1.31 1999/06/29 14:33:23 aaron Exp $ */
+/* $OpenBSD: cmds.c,v 1.32 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: cmds.c,v 1.27 1997/08/18 10:20:15 lukem Exp $ */
/*
+ * Copyright (C) 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -38,7 +67,7 @@
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$OpenBSD: cmds.c,v 1.31 1999/06/29 14:33:23 aaron Exp $";
+static char rcsid[] = "$OpenBSD: cmds.c,v 1.32 1999/12/08 12:57:06 itojun Exp $";
#endif
#endif /* not lint */
@@ -653,8 +682,8 @@ status(argc, argv)
}
pswitch(0);
}
- fprintf(ttyout, "Gate ftp: %s, server %s, port %d.\n", onoff(gatemode),
- *gateserver ? gateserver : "(none)", ntohs(gateport));
+ fprintf(ttyout, "Gate ftp: %s, server %s, port %s.\n", onoff(gatemode),
+ *gateserver ? gateserver : "(none)", gateport);
fprintf(ttyout, "Passive mode: %s.\n", onoff(passivemode));
fprintf(ttyout, "Mode: %s; Type: %s; Form: %s; Structure: %s.\n",
modename, typename, formname, structname);
@@ -679,7 +708,7 @@ status(argc, argv)
}
fprintf(ttyout, "Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n",
onoff(hash), mark, onoff(progress));
- fprintf(ttyout, "Use of PORT cmds: %s.\n", onoff(sendport));
+ fprintf(ttyout, "Use of PORT/LPRT cmds: %s.\n", onoff(sendport));
#ifndef SMALL
fprintf(ttyout, "Command line editing: %s.\n", onoff(editing));
#endif /* !SMALL */
@@ -812,7 +841,7 @@ setverbose(argc, argv)
}
/*
- * Toggle PORT cmd use before each data connection.
+ * Toggle PORT/LPRT cmd use before each data connection.
*/
/*VARARGS*/
void
@@ -821,7 +850,7 @@ setport(argc, argv)
char *argv[];
{
- code = togglevar(argc, argv, &sendport, "Use of PORT cmds");
+ code = togglevar(argc, argv, &sendport, "Use of PORT/LPRT cmds");
}
/*
@@ -875,6 +904,7 @@ setgate(argc, argv)
gatemode = 0;
else {
if (argc == 3) {
+#if 0
char *ep;
long port;
@@ -887,6 +917,9 @@ setgate(argc, argv)
return;
}
gateport = htons(port);
+#else
+ gateport = strdup(argv[2]);
+#endif
}
strncpy(gsbuf, argv[1], sizeof(gsbuf) - 1);
gsbuf[sizeof(gsbuf) - 1] = '\0';
@@ -899,9 +932,9 @@ setgate(argc, argv)
"Disabling gate-ftp mode - no gate-ftp server defined.\n");
gatemode = 0;
} else {
- fprintf(ttyout, "Gate ftp: %s, server %s, port %d.\n",
+ fprintf(ttyout, "Gate ftp: %s, server %s, port %s.\n",
onoff(gatemode),
- *gateserver ? gateserver : "(none)", ntohs(gateport));
+ *gateserver ? gateserver : "(none)", gateport);
}
code = gatemode;
}
diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c
index 82fa7b02a43..792654fd70d 100644
--- a/usr.bin/ftp/cmdtab.c
+++ b/usr.bin/ftp/cmdtab.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmdtab.c,v 1.12 1998/12/24 17:00:12 aaron Exp $ */
+/* $OpenBSD: cmdtab.c,v 1.13 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$OpenBSD: cmdtab.c,v 1.12 1998/12/24 17:00:12 aaron Exp $";
+static char rcsid[] = "$OpenBSD: cmdtab.c,v 1.13 1999/12/08 12:57:06 itojun Exp $";
#endif
#endif /* not lint */
@@ -92,7 +92,7 @@ char nmaphelp[] = "set templates for default file name mapping";
char ntranshelp[] = "set translation table for default file name mapping";
char pagehelp[] = "view a remote file through your pager";
char passivehelp[] = "enter passive transfer mode";
-char porthelp[] = "toggle use of PORT cmd for each data connection";
+char porthelp[] = "toggle use of PORT/LPRT cmd for each data connection";
char preservehelp[] ="toggle preservation of modification time of "
"retrieved files";
char progresshelp[] ="toggle transfer progress meter";
diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h
index edf4ca71367..0c6fd13a007 100644
--- a/usr.bin/ftp/extern.h
+++ b/usr.bin/ftp/extern.h
@@ -1,6 +1,35 @@
-/* $OpenBSD: extern.h,v 1.18 1998/07/07 17:26:39 art Exp $ */
+/* $OpenBSD: extern.h,v 1.19 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: extern.h,v 1.17 1997/08/18 10:20:19 lukem Exp $ */
+/*
+ * Copyright (C) 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
/*-
* Copyright (c) 1994 The Regents of the University of California.
* All rights reserved.
@@ -76,10 +105,11 @@ int getreply __P((int));
int globulize __P((char **));
char *gunique __P((const char *));
void help __P((int, char **));
-char *hookup __P((const char *, in_port_t));
+char *hookup __P((char *, char *));
void idle __P((int, char **));
int initconn __P((void));
void intr __P((void));
+int isurl __P((const char *));
void list_vertical __P((StringList *));
void lcd __P((int, char **));
int login __P((const char *, char *, char *));
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index 27291212e16..ecae9647d83 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fetch.c,v 1.24 1999/02/09 03:43:48 deraadt Exp $ */
+/* $OpenBSD: fetch.c,v 1.25 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
/*-
@@ -38,7 +38,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: fetch.c,v 1.24 1999/02/09 03:43:48 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: fetch.c,v 1.25 1999/12/08 12:57:06 itojun Exp $";
#endif /* not lint */
/*
@@ -96,17 +96,17 @@ url_get(origline, proxyenv, outfile)
const char *proxyenv;
const char *outfile;
{
- struct sockaddr_in sin;
+ struct addrinfo hints, *res0, *res;
+ int error;
int i, out, isftpurl, isfileurl;
- in_port_t port;
volatile int s;
size_t len;
char c, *cp, *ep, *portnum, *path, buf[4096];
const char *savefile;
- char *line, *proxy, *host;
+ char *line, *proxy, *host, *port;
volatile sig_t oldintr;
off_t hashbytes;
- struct hostent *hp = NULL;
+ char *cause = "unknown";
s = -1;
proxy = NULL;
@@ -276,71 +276,43 @@ url_get(origline, proxyenv, outfile)
fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n",
host, portnum, path, savefile);
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
-
- if (isdigit(host[0])) {
- if (inet_aton(host, &sin.sin_addr) == 0) {
- warnx("Invalid IP address: %s", host);
- goto cleanup_url_get;
- }
- } else {
- hp = gethostbyname(host);
- if (hp == NULL) {
- warnx("%s: %s", host, hstrerror(h_errno));
- goto cleanup_url_get;
- }
- if (hp->h_addrtype != AF_INET) {
- warnx("%s: not an Internet address?", host);
- goto cleanup_url_get;
- }
- memcpy(&sin.sin_addr, hp->h_addr, (size_t)hp->h_length);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ port = portnum ? portnum : httpport;
+ error = getaddrinfo(host, port, &hints, &res0);
+ if (error) {
+ warnx("%s: %s", gai_strerror(error), host);
+ goto cleanup_url_get;
}
- if (! EMPTYSTRING(portnum)) {
- char *ep;
- long nport;
+ s = -1;
+ for (res = res0; res; res = res->ai_next) {
+ getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof(buf),
+ NULL, 0, NI_NUMERICHOST);
+ fprintf(ttyout, "Trying %s...\n", buf);
- nport = strtol(portnum, &ep, 10);
- if (nport < 1 || nport > USHRT_MAX || *ep != '\0') {
- warnx("Invalid port: %s", portnum);
- goto cleanup_url_get;
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s == -1) {
+ cause = "socket";
+ continue;
}
- port = htons((in_port_t)nport);
- } else
- port = httpport;
- sin.sin_port = port;
-
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s == -1) {
- warn("Can't create socket");
- goto cleanup_url_get;
- }
- while (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- if (errno == EINTR)
- continue;
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
- char *ia;
-
- ia = inet_ntoa(sin.sin_addr);
- errno = oerrno;
- warn("connect to address %s", ia);
- hp->h_addr_list++;
- memcpy(&sin.sin_addr, hp->h_addr_list[0],
- (size_t)hp->h_length);
- fprintf(ttyout, "Trying %s...\n",
- inet_ntoa(sin.sin_addr));
- (void)close(s);
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- warn("socket");
- goto cleanup_url_get;
- }
+again:
+ if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+ if (errno == EINTR)
+ goto again;
+ close(s);
+ s = -1;
+ cause = "connect";
continue;
}
- warn("connect");
+
+ break;
+ }
+ freeaddrinfo(res0);
+ if (s < 0) {
+ warn(cause);
goto cleanup_url_get;
}
@@ -648,7 +620,17 @@ bad_ftp_url:
if (EMPTYSTRING(user))
goto bad_ftp_url;
host = cp;
- portnum = strchr(host, ':');
+
+#if 0
+ /* look for IPv6 address URL */
+ if (host == '[' && (cp = strrchr(host, ']'))) {
+ host++;
+ *cp++ = '\0';
+ } else
+ cp = host;
+#endif
+
+ portnum = strrchr(cp, ':');
if (portnum != NULL)
*portnum++ = '\0';
} else { /* classic style `host:file' */
@@ -792,3 +774,14 @@ parsed_url:
disconnect(0, NULL);
return (rval);
}
+
+int
+isurl(p)
+ const char *p;
+{
+ if (strncasecmp(p, FTP_URL, sizeof(FTP_URL) - 1) == 0
+ || strncasecmp(p, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c
index 2d8896e6eeb..b4f81b67d92 100644
--- a/usr.bin/ftp/ftp.c
+++ b/usr.bin/ftp/ftp.c
@@ -1,7 +1,36 @@
-/* $OpenBSD: ftp.c,v 1.33 1998/12/13 21:01:29 millert Exp $ */
+/* $OpenBSD: ftp.c,v 1.34 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: ftp.c,v 1.27 1997/08/18 10:20:23 lukem Exp $ */
/*
+ * Copyright (C) 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -38,7 +67,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
-static char rcsid[] = "$OpenBSD: ftp.c,v 1.33 1998/12/13 21:01:29 millert Exp $";
+static char rcsid[] = "$OpenBSD: ftp.c,v 1.34 1999/12/08 12:57:06 itojun Exp $";
#endif
#endif /* not lint */
@@ -70,14 +99,29 @@ static char rcsid[] = "$OpenBSD: ftp.c,v 1.33 1998/12/13 21:01:29 millert Exp $"
#include "ftp_var.h"
-struct sockaddr_in hisctladdr;
-struct sockaddr_in data_addr;
+union sockunion {
+ struct sockinet {
+ u_char si_len;
+ u_char si_family;
+ u_short si_port;
+ } su_si;
+ struct sockaddr_in su_sin;
+ struct sockaddr_in6 su_sin6;
+};
+#define su_len su_si.si_len
+#define su_family su_si.si_family
+#define su_port su_si.si_port
+
+union sockunion myctladdr, hisctladdr, data_addr;
+
+union sockunion hisctladdr;
+union sockunion data_addr;
int data = -1;
int abrtflag = 0;
jmp_buf ptabort;
int ptabflg;
int ptflag = 0;
-struct sockaddr_in myctladdr;
+union sockunion myctladdr;
off_t restart_point = 0;
@@ -85,78 +129,94 @@ FILE *cin, *cout;
char *
hookup(host, port)
- const char *host;
- in_port_t port;
+ char *host;
+ char *port;
{
- struct hostent *hp = NULL;
- int s, len, tos;
+ int s, len, tos, error;
static char hostnamebuf[MAXHOSTNAMELEN];
-
- memset((void *)&hisctladdr, 0, sizeof(hisctladdr));
- if (inet_aton(host, &hisctladdr.sin_addr) != 0) {
- hisctladdr.sin_family = AF_INET;
- (void)strncpy(hostnamebuf, host, sizeof(hostnamebuf) - 1);
- hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
- } else {
- hp = gethostbyname(host);
- if (hp == NULL) {
- warnx("%s: %s", host, hstrerror(h_errno));
- code = -1;
- return ((char *) 0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
- (size_t)hp->h_length);
- (void)strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf) - 1);
- hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
- }
- hostname = hostnamebuf;
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s < 0) {
- warn("socket");
+ struct addrinfo hints, *res, *res0;
+ char hbuf[MAXHOSTNAMELEN];
+ char *cause = "unknown";
+
+ memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ error = getaddrinfo(host, port, &hints, &res0);
+ if (error) {
+ warn(gai_strerror(error));
code = -1;
return (0);
}
- hisctladdr.sin_port = port;
- while (connect(s, (struct sockaddr *)&hisctladdr,
- sizeof(hisctladdr)) < 0) {
- if (errno == EINTR)
+
+ if (res0->ai_canonname)
+ strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
+ else
+ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
+ hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
+ hostname = hostnamebuf;
+
+ s = -1;
+ for (res = res0; res; res = res->ai_next) {
+#if 0 /*old behavior*/
+ if (res != res0) /* not on the first address */
+#else
+ if (res0->ai_next) /* if we have multiple possibilities */
+#endif
+ {
+ getnameinfo(res->ai_addr, res->ai_addrlen,
+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
+ fprintf(ttyout, "Trying %s...\n", hbuf);
+ }
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0) {
+ cause = "socket";
continue;
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
- char *ia;
-
- ia = inet_ntoa(hisctladdr.sin_addr);
- errno = oerrno;
- warn("connect to address %s", ia);
- hp->h_addr_list++;
- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
- (size_t)hp->h_length);
- fprintf(ttyout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
- (void)close(s);
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s < 0) {
- warn("socket");
- code = -1;
- return (0);
+ }
+ while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
+ && errno == EINTR) {
+ ;
+ }
+ if (error) {
+ /* this "if" clause is to prevent print warning twice */
+ if (res->ai_next) {
+ getnameinfo(res->ai_addr, res->ai_addrlen,
+ hbuf, sizeof(hbuf), NULL, 0,
+ NI_NUMERICHOST);
+ warn("connect to address %s", hbuf);
}
+ cause = "connect";
+ close(s);
+ s = -1;
continue;
}
- warn("connect");
+
+ /* finally we got one */
+ break;
+ }
+ if (s < 0) {
+ warn(cause);
code = -1;
- goto bad;
+ freeaddrinfo(res0);
+ return 0;
}
- len = sizeof(myctladdr);
+ memcpy(&hisctladdr, res->ai_addr, res->ai_addrlen);
+ len = res->ai_addrlen;
+ freeaddrinfo(res0);
+ res0 = res = NULL;
if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
warn("getsockname");
code = -1;
goto bad;
}
-#ifdef IP_TOS
- tos = IPTOS_LOWDELAY;
- if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- warn("setsockopt TOS (ignored)");
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ if (hisctladdr.su_family == AF_INET) {
+ tos = IPTOS_LOWDELAY;
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
+ warn("setsockopt TOS (ignored)");
+ }
#endif
cin = fdopen(s, "r");
cout = fdopen(s, "w");
@@ -334,8 +394,10 @@ getreply(expecteof)
}
if (dig < 4 && isdigit(c))
code = code * 10 + (c - '0');
- if (!pflag && code == 227)
+ if (!pflag && (code == 227 || code == 228))
pflag = 1;
+ else if (!pflag && code == 229)
+ pflag = 100;
if (dig > 4 && pflag == 1 && isdigit(c))
pflag = 2;
if (pflag == 2) {
@@ -346,6 +408,8 @@ getreply(expecteof)
pflag = 3;
}
}
+ if (pflag == 100 && c == '(')
+ pflag = 2;
if (dig == 4 && c == '-') {
if (continuation)
code = 0;
@@ -1112,11 +1176,20 @@ initconn()
char *p, *a;
int result, len, tmpno = 0;
int on = 1;
- int a0, a1, a2, a3, p0, p1;
-
+ int error;
+ u_int addr[16], port[2];
+ u_int af, hal, pal;
+ char *pasvcmd = NULL;
+
+ if (myctladdr.su_family == AF_INET6
+ && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
+ || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
+ warnx("use of scoped address can be troublesome");
+ }
reinit:
if (passivemode) {
- data = socket(AF_INET, SOCK_STREAM, 0);
+ data_addr = myctladdr;
+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
if (data < 0) {
warn("socket");
return (1);
@@ -1125,7 +1198,34 @@ reinit:
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on)) < 0)
warn("setsockopt (ignored)");
- if (command("PASV") != COMPLETE) {
+ switch (data_addr.su_family) {
+ case AF_INET:
+ result = command(pasvcmd = "EPSV");
+ if (code / 10 == 22 && code != 229) {
+ fputs(
+"wrong server: return code must be 229\n",
+ ttyout);
+ result = COMPLETE + 1;
+ }
+ if (result != COMPLETE)
+ result = command(pasvcmd = "PASV");
+ break;
+ case AF_INET6:
+ result = command(pasvcmd = "EPSV");
+ if (code / 10 == 22 && code != 229) {
+ fputs(
+"wrong server: return code must be 229\n",
+ ttyout);
+ result = COMPLETE + 1;
+ }
+ if (result != COMPLETE)
+ result = command(pasvcmd = "LPSV");
+ break;
+ default:
+ result = COMPLETE + 1;
+ break;
+ }
+ if (result != COMPLETE) {
if (activefallback) {
(void)close(data);
data = -1;
@@ -1137,34 +1237,150 @@ reinit:
goto bad;
}
+#define pack2(var, off) \
+ (((var[(off) + 0] & 0xff) << 8) | ((var[(off) + 1] & 0xff) << 0))
+#define pack4(var, off) \
+ (((var[(off) + 0] & 0xff) << 24) | ((var[(off) + 1] & 0xff) << 16) | \
+ ((var[(off) + 2] & 0xff) << 8) | ((var[(off) + 3] & 0xff) << 0))
+
/*
- * What we've got at this point is a string of comma
- * separated one-byte unsigned integer values.
- * The first four are the an IP address. The fifth is
- * the MSB of the port number, the sixth is the LSB.
- * From that we'll prepare a sockaddr_in.
+ * What we've got at this point is a string of comma separated
+ * one-byte unsigned integer values, separated by commas.
*/
+ if (strcmp(pasvcmd, "PASV") == 0) {
+ if (data_addr.su_family != AF_INET) {
+ fputs(
+"Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
+ if (code / 10 == 22 && code != 227) {
+ fputs("wrong server: return code must be 227\n",
+ ttyout);
+ error = 1;
+ goto bad;
+ }
+ error = sscanf(pasv, "%u,%u,%u,%u,%u,%u",
+ &addr[0], &addr[1], &addr[2], &addr[3],
+ &port[0], &port[1]);
+ if (error != 6) {
+ fputs(
+"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
+ error = 0;
+ memset(&data_addr, 0, sizeof(data_addr));
+ data_addr.su_family = AF_INET;
+ data_addr.su_len = sizeof(struct sockaddr_in);
+ data_addr.su_sin.sin_addr.s_addr =
+ htonl(pack4(addr, 0));
+ data_addr.su_port = htons(pack2(port, 0));
+ } else if (strcmp(pasvcmd, "LPSV") == 0) {
+ if (code / 10 == 22 && code != 228) {
+ fputs("wrong server: return code must be 228\n",
+ ttyout);
+ error = 1;
+ goto bad;
+ }
+ switch (data_addr.su_family) {
+ case AF_INET:
+ error = sscanf(pasv,
+"%u,%u,%u,%u,%u,%u,%u,%u,%u",
+ &af, &hal,
+ &addr[0], &addr[1], &addr[2], &addr[3],
+ &pal, &port[0], &port[1]);
+ if (error != 9) {
+ fputs(
+"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
+ if (af != 4 || hal != 4 || pal != 2) {
+ fputs(
+"Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
- if (sscanf(pasv, "%d,%d,%d,%d,%d,%d",
- &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
- fputs(
+ error = 0;
+ memset(&data_addr, 0, sizeof(data_addr));
+ data_addr.su_family = AF_INET;
+ data_addr.su_len = sizeof(struct sockaddr_in);
+ data_addr.su_sin.sin_addr.s_addr =
+ htonl(pack4(addr, 0));
+ data_addr.su_port = htons(pack2(port, 0));
+ break;
+ case AF_INET6:
+ error = sscanf(pasv,
+"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
+ &af, &hal,
+ &addr[0], &addr[1], &addr[2], &addr[3],
+ &addr[4], &addr[5], &addr[6], &addr[7],
+ &addr[8], &addr[9], &addr[10],
+ &addr[11], &addr[12], &addr[13],
+ &addr[14], &addr[15],
+ &pal, &port[0], &port[1]);
+ if (error != 21) {
+ fputs(
"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
- goto bad;
- }
+ error = 1;
+ goto bad;
+ }
+ if (af != 6 || hal != 16 || pal != 2) {
+ fputs(
+"Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
- memset(&data_addr, 0, sizeof(data_addr));
- data_addr.sin_family = AF_INET;
- a = (char *)&data_addr.sin_addr.s_addr;
- a[0] = a0 & 0xff;
- a[1] = a1 & 0xff;
- a[2] = a2 & 0xff;
- a[3] = a3 & 0xff;
- p = (char *)&data_addr.sin_port;
- p[0] = p0 & 0xff;
- p[1] = p1 & 0xff;
+ error = 0;
+ memset(&data_addr, 0, sizeof(data_addr));
+ data_addr.su_family = AF_INET6;
+ data_addr.su_len = sizeof(struct sockaddr_in6);
+ {
+ u_int32_t *p32;
+ p32 = (u_int32_t *)&data_addr.su_sin6.sin6_addr;
+ p32[0] = htonl(pack4(addr, 0));
+ p32[1] = htonl(pack4(addr, 4));
+ p32[2] = htonl(pack4(addr, 8));
+ p32[3] = htonl(pack4(addr, 12));
+ }
+ data_addr.su_port = htons(pack2(port, 0));
+ break;
+ default:
+ error = 1;
+ }
+ } else if (strcmp(pasvcmd, "EPSV") == 0) {
+ char delim[4];
+
+ port[0] = 0;
+ if (code / 10 == 22 && code != 229) {
+ fputs("wrong server: return code must be 229\n",
+ ttyout);
+ error = 1;
+ goto bad;
+ }
+ if (sscanf(pasv, "%c%c%c%d%c", &delim[0],
+ &delim[1], &delim[2], &port[1],
+ &delim[3]) != 5) {
+ fputs("parse error!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
+ if (delim[0] != delim[1] || delim[0] != delim[2]
+ || delim[0] != delim[3]) {
+ fputs("parse error!\n", ttyout);
+ error = 1;
+ goto bad;
+ }
+ data_addr = hisctladdr;
+ data_addr.su_port = htons(port[1]);
+ } else
+ goto bad;
while (connect(data, (struct sockaddr *)&data_addr,
- sizeof(data_addr)) < 0) {
+ data_addr.su_len) < 0) {
if (errno == EINTR)
continue;
if (activefallback) {
@@ -1177,11 +1393,13 @@ reinit:
warn("connect");
goto bad;
}
-#ifdef IP_TOS
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
- sizeof(int)) < 0)
- warn("setsockopt TOS (ignored)");
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ if (data_addr.su_family == AF_INET) {
+ on = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
+ sizeof(int)) < 0)
+ warn("setsockopt TOS (ignored)");
+ }
#endif
return (0);
}
@@ -1189,10 +1407,10 @@ reinit:
noport:
data_addr = myctladdr;
if (sendport)
- data_addr.sin_port = 0; /* let system pick one */
+ data_addr.su_port = 0; /* let system pick one */
if (data != -1)
(void)close(data);
- data = socket(AF_INET, SOCK_STREAM, 0);
+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
if (data < 0) {
warn("socket");
if (tmpno)
@@ -1205,7 +1423,7 @@ noport:
warn("setsockopt (reuse address)");
goto bad;
}
- if (bind(data, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0) {
+ if (bind(data, (struct sockaddr *)&data_addr, data_addr.su_len) < 0) {
warn("bind");
goto bad;
}
@@ -1220,14 +1438,58 @@ noport:
}
if (listen(data, 1) < 0)
warn("listen");
- if (sendport) {
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
+
#define UC(b) (((int)b)&0xff)
- result =
- command("PORT %d,%d,%d,%d,%d,%d",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
- UC(p[0]), UC(p[1]));
+
+ if (sendport) {
+ char hname[INET6_ADDRSTRLEN];
+ int af;
+
+ switch (data_addr.su_family) {
+ case AF_INET:
+ case AF_INET6:
+ af = (data_addr.su_family == AF_INET) ? 1 : 2;
+ if (getnameinfo((struct sockaddr *)&data_addr,
+ data_addr.su_len, hname, sizeof(hname),
+ NULL, 0, NI_NUMERICHOST)) {
+ result = ERROR;
+ } else {
+ result = command("EPRT |%d|%s|%d|",
+ af, hname, ntohs(data_addr.su_port));
+ }
+ break;
+ default:
+ result = COMPLETE + 1;
+ break;
+ }
+ if (result == COMPLETE)
+ goto skip_port;
+
+ switch (data_addr.su_family) {
+ case AF_INET:
+ a = (char *)&data_addr.su_sin.sin_addr;
+ p = (char *)&data_addr.su_port;
+ result = command("PORT %d,%d,%d,%d,%d,%d",
+ UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
+ UC(p[0]), UC(p[1]));
+ break;
+ case AF_INET6:
+ a = (char *)&data_addr.su_sin6.sin6_addr;
+ p = (char *)&data_addr.su_port;
+ result = command(
+"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
+ 6, 16,
+ UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]),
+ UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]),
+ UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]),
+ UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]),
+ 2, UC(p[0]), UC(p[1]));
+ break;
+ default:
+ result = COMPLETE + 1; /* xxx */
+ }
+ skip_port:
+
if (result == ERROR && sendport == -1) {
sendport = 0;
tmpno = 1;
@@ -1237,10 +1499,13 @@ noport:
}
if (tmpno)
sendport = 1;
-#ifdef IP_TOS
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- warn("setsockopt TOS (ignored)");
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ if (data_addr.su_family == AF_INET) {
+ on = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
+ sizeof(int)) < 0)
+ warn("setsockopt TOS (ignored)");
+ }
#endif
return (0);
bad:
@@ -1254,10 +1519,8 @@ FILE *
dataconn(lmode)
const char *lmode;
{
- struct sockaddr_in from;
- int s, fromlen, tos;
-
- fromlen = sizeof(from);
+ union sockunion from;
+ int s, fromlen = myctladdr.su_len;
if (passivemode)
return (fdopen(data, lmode));
@@ -1270,10 +1533,14 @@ dataconn(lmode)
}
(void)close(data);
data = s;
-#ifdef IP_TOS
- tos = IPTOS_THROUGHPUT;
- if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- warn("setsockopt TOS (ignored)");
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ if (from.su_family == AF_INET) {
+ int tos = IPTOS_THROUGHPUT;
+ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
+ sizeof(int)) < 0) {
+ warn("setsockopt TOS (ignored)");
+ }
+ }
#endif
return (fdopen(data, lmode));
}
@@ -1306,8 +1573,8 @@ pswitch(flag)
static struct comvars {
int connect;
char name[MAXHOSTNAMELEN];
- struct sockaddr_in mctl;
- struct sockaddr_in hctl;
+ union sockunion mctl;
+ union sockunion hctl;
FILE *in;
FILE *out;
int tpe;
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index 04a30d0b020..635abee5728 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -1,7 +1,36 @@
-/* $OpenBSD: ftp_var.h,v 1.17 1997/12/17 16:03:04 millert Exp $ */
+/* $OpenBSD: ftp_var.h,v 1.18 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: ftp_var.h,v 1.18 1997/08/18 10:20:25 lukem Exp $ */
/*
+ * Copyright (C) 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -77,7 +106,7 @@ int fclose(FILE *);
int trace; /* trace packets exchanged */
int hash; /* print # for each buffer transferred */
int mark; /* number of bytes between hashes */
-int sendport; /* use PORT cmd for each data connection */
+int sendport; /* use PORT/LPRT cmd for each data connection */
int verbose; /* print messages coming back from server */
int connected; /* 1 = connected to server, -1 = logged in */
int fromatty; /* input is from a terminal */
@@ -100,7 +129,7 @@ int preserve; /* preserve modification time on files */
int progress; /* display transfer progress bar */
int code; /* return/reply code for ftp command */
int crflag; /* if 1, strip car. rets. on ascii gets */
-char pasv[64]; /* passive port for proxy data connection */
+char pasv[BUFSIZ]; /* passive port for proxy data connection */
int passivemode; /* passive mode enabled */
int activefallback; /* fall back to active mode if passive fails */
char *altarg; /* argv[1] with no shell-like preprocessing */
@@ -141,9 +170,9 @@ char *hostname; /* name of host connected to */
int unix_server; /* server is unix, can use binary for ascii */
int unix_proxy; /* proxy is unix, can use binary for ascii */
-in_port_t ftpport; /* port number to use for ftp connections */
-in_port_t httpport; /* port number to use for http connections */
-in_port_t gateport; /* port number to use for gateftp connections */
+char *ftpport; /* port number to use for ftp connections */
+char *httpport; /* port number to use for http connections */
+char *gateport; /* port number to use for gateftp connections */
jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index 6c7b3befdeb..859188ecb80 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -1,7 +1,36 @@
-/* $OpenBSD: main.c,v 1.43 1998/11/21 02:58:37 d Exp $ */
+/* $OpenBSD: main.c,v 1.44 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: main.c,v 1.24 1997/08/18 10:20:26 lukem Exp $ */
/*
+ * Copyright (C) 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -44,7 +73,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
#else
-static char rcsid[] = "$OpenBSD: main.c,v 1.43 1998/11/21 02:58:37 d Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.44 1999/12/08 12:57:06 itojun Exp $";
#endif
#endif /* not lint */
@@ -73,41 +102,17 @@ main(argc, argv)
int argc;
char *argv[];
{
- struct servent *sp;
int ch, top, rval;
- long port;
struct passwd *pw = NULL;
- char *cp, *ep, homedir[MAXPATHLEN];
+ char *cp, homedir[MAXPATHLEN];
char *outfile = NULL;
int dumb_terminal = 0;
- sp = getservbyname("ftp", "tcp");
- if (sp == 0)
- ftpport = htons(FTP_PORT); /* good fallback */
- else
- ftpport = sp->s_port;
- sp = getservbyname("http", "tcp");
- if (sp == 0)
- httpport = htons(HTTP_PORT); /* good fallback */
- else
- httpport = sp->s_port;
- gateport = 0;
- cp = getenv("FTPSERVERPORT");
- if (cp != NULL) {
- port = strtol(cp, &ep, 10);
- if (port < 1 || port > USHRT_MAX || *ep != '\0')
- warnx("bad FTPSERVERPORT port number: %s (ignored)",
- cp);
- else
- gateport = htons(port);
- }
- if (gateport == 0) {
- sp = getservbyname("ftpgate", "tcp");
- if (sp == 0)
- gateport = htons(GATE_PORT);
- else
- gateport = sp->s_port;
- }
+ ftpport = "ftp";
+ httpport = "http";
+ gateport = getenv("FTPSERVERPORT");
+ if (gateport == NULL)
+ gateport = "ftpgate";
doglob = 1;
interactive = 1;
autologin = 1;
@@ -221,11 +226,7 @@ main(argc, argv)
break;
case 'P':
- port = strtol(optarg, &ep, 10);
- if (port < 1 || port > USHRT_MAX || *ep != '\0')
- warnx("bad port number: %s (ignored)", optarg);
- else
- ftpport = htons((in_port_t)port);
+ ftpport = optarg;
break;
case 'r':
@@ -281,7 +282,7 @@ main(argc, argv)
#endif
if (argc > 0) {
- if (strchr(argv[0], ':') != NULL) {
+ if (isurl(argv[0])) {
anonftp = 1; /* Handle "automatic" transfers. */
rval = auto_fetch(argc, argv, outfile);
if (rval >= 0) /* -1 == connected and cd-ed */
diff --git a/usr.bin/ftp/util.c b/usr.bin/ftp/util.c
index a0a7cf15da7..db16b66f9dd 100644
--- a/usr.bin/ftp/util.c
+++ b/usr.bin/ftp/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.21 1998/09/22 04:42:49 deraadt Exp $ */
+/* $OpenBSD: util.c,v 1.22 1999/12/08 12:57:06 itojun Exp $ */
/* $NetBSD: util.c,v 1.12 1997/08/18 10:20:27 lukem Exp $ */
/*
@@ -35,7 +35,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: util.c,v 1.21 1998/09/22 04:42:49 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: util.c,v 1.22 1999/12/08 12:57:06 itojun Exp $";
#endif /* not lint */
/*
@@ -75,7 +75,7 @@ setpeer(argc, argv)
char *argv[];
{
char *host;
- in_port_t port;
+ char *port;
if (connected) {
fprintf(ttyout, "Already connected to %s, use close first.\n",
@@ -94,6 +94,7 @@ setpeer(argc, argv)
port = gateport;
else
port = ftpport;
+#if 0
if (argc > 2) {
char *ep;
long nport;
@@ -109,6 +110,10 @@ setpeer(argc, argv)
}
port = htons((in_port_t)nport);
}
+#else
+ if (argc > 2)
+ port = argv[2];
+#endif
if (gatemode) {
if (gateserver == NULL || *gateserver == '\0')