diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 1999-12-08 12:57:07 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 1999-12-08 12:57:07 +0000 |
commit | 608666bc5b614c4a821f9571e6e7516c490a1d2e (patch) | |
tree | 7d971c94c4313e37b84fb56089fcd487638af573 /usr.bin | |
parent | aa65718cad2b6a15bce9c1c4ec03903f42539558 (diff) |
ftp(1) from KAME, should be good for testing.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ftp/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/ftp/cmds.c | 51 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 6 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 34 | ||||
-rw-r--r-- | usr.bin/ftp/fetch.c | 123 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 499 | ||||
-rw-r--r-- | usr.bin/ftp/ftp_var.h | 41 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 77 | ||||
-rw-r--r-- | usr.bin/ftp/util.c | 11 |
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') |