diff options
author | Mike Heffner <mikeh@FreeBSD.org> | 2001-12-13 23:46:44 +0000 |
---|---|---|
committer | Mike Heffner <mikeh@FreeBSD.org> | 2001-12-13 23:46:44 +0000 |
commit | bfacd15a502c4a23f1a484c620b918b96111c2a0 (patch) | |
tree | b2b4624c2fb26f66d8f381a7fa80e22e726b9af6 /usr.bin/ftp | |
parent | 9446b36bab0d206dbf2fc39f2fc04a29b6b693be (diff) | |
download | src-test2-bfacd15a502c4a23f1a484c620b918b96111c2a0.tar.gz src-test2-bfacd15a502c4a23f1a484c620b918b96111c2a0.zip |
Notes
Diffstat (limited to 'usr.bin/ftp')
-rw-r--r-- | usr.bin/ftp/Makefile | 9 | ||||
-rw-r--r-- | usr.bin/ftp/cmds.c | 2214 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 230 | ||||
-rw-r--r-- | usr.bin/ftp/complete.c | 377 | ||||
-rw-r--r-- | usr.bin/ftp/domacro.c | 155 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 176 | ||||
-rw-r--r-- | usr.bin/ftp/fetch.c | 733 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 1456 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 1965 | ||||
-rw-r--r-- | usr.bin/ftp/ftp_var.h | 189 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 711 | ||||
-rw-r--r-- | usr.bin/ftp/pathnames.h | 41 | ||||
-rw-r--r-- | usr.bin/ftp/ruserpass.c | 306 | ||||
-rw-r--r-- | usr.bin/ftp/util.c | 897 |
14 files changed, 6 insertions, 9453 deletions
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile index 6a3e506bdeeb..c86e15361a2c 100644 --- a/usr.bin/ftp/Makefile +++ b/usr.bin/ftp/Makefile @@ -6,13 +6,16 @@ # #CFLAGS+=-DGATE_SERVER=\"ftp-gw.host\" # -DGATE_PORT=21 +LUKEMFTP= ${.CURDIR}/../../contrib/lukemftp +.PATH: ${LUKEMFTP}/src + PROG= ftp SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c ruserpass.c \ util.c -CFLAGS+=-DINET6 -LDADD+= -ledit -ltermcap -DPADD+= ${LIBEDIT} ${LIBTERMCAP} +CFLAGS+=-I${.CURDIR} -I${LUKEMFTP} +LDADD+= -ledit -ltermcap -lutil +DPADD+= ${LIBEDIT} ${LIBTERMCAP} ${LIBUTIL} LINKS= ${BINDIR}/ftp ${BINDIR}/pftp \ ${BINDIR}/ftp ${BINDIR}/gate-ftp diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c deleted file mode 100644 index 0c6c7fcf79d5..000000000000 --- a/usr.bin/ftp/cmds.c +++ /dev/null @@ -1,2214 +0,0 @@ -/* $NetBSD: cmds.c,v 1.30.2.1 1997/11/18 00:58:26 mellon Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: cmds.c,v 1.30.2.1 1997/11/18 00:58:26 mellon Exp $"); -#endif -#endif /* not lint */ - -/* - * FTP User Program -- Command Routines. - */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <arpa/ftp.h> - -#include <ctype.h> -#include <err.h> -#include <glob.h> -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "ftp_var.h" -#include "pathnames.h" - -jmp_buf jabort; -char *mname; -char *home = "/"; - -struct types { - char *t_name; - char *t_mode; - int t_type; - char *t_arg; -} types[] = { - { "ascii", "A", TYPE_A, 0 }, - { "binary", "I", TYPE_I, 0 }, - { "image", "I", TYPE_I, 0 }, - { "ebcdic", "E", TYPE_E, 0 }, - { "tenex", "L", TYPE_L, bytename }, - { NULL } -}; - -/* - * Set transfer type. - */ -void -settype(argc, argv) - int argc; - char *argv[]; -{ - struct types *p; - int comret; - - if (argc > 2) { - char *sep; - - printf("usage: %s [", argv[0]); - sep = " "; - for (p = types; p->t_name; p++) { - printf("%s%s", sep, p->t_name); - sep = " | "; - } - puts(" ]"); - code = -1; - return; - } - if (argc < 2) { - printf("Using %s mode to transfer files.\n", typename); - code = 0; - return; - } - for (p = types; p->t_name; p++) - if (strcmp(argv[1], p->t_name) == 0) - break; - if (p->t_name == 0) { - printf("%s: unknown mode.\n", argv[1]); - code = -1; - return; - } - if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) - comret = command("TYPE %s %s", p->t_mode, p->t_arg); - else - comret = command("TYPE %s", p->t_mode); - if (comret == COMPLETE) { - (void)strcpy(typename, p->t_name); - curtype = type = p->t_type; - } -} - -/* - * Internal form of settype; changes current type in use with server - * without changing our notion of the type for data transfers. - * Used to change to and from ascii for listings. - */ -void -changetype(newtype, show) - int newtype, show; -{ - struct types *p; - int comret, oldverbose = verbose; - - if (newtype == 0) - newtype = TYPE_I; - if (newtype == curtype) - return; - if (debug == 0 && show == 0) - verbose = 0; - for (p = types; p->t_name; p++) - if (newtype == p->t_type) - break; - if (p->t_name == 0) { - warnx("internal error: unknown type %d.", newtype); - return; - } - if (newtype == TYPE_L && bytename[0] != '\0') - comret = command("TYPE %s %s", p->t_mode, bytename); - else - comret = command("TYPE %s", p->t_mode); - if (comret == COMPLETE) - curtype = newtype; - verbose = oldverbose; -} - -char *stype[] = { - "type", - "", - 0 -}; - -/* - * Set binary transfer type. - */ -/*VARARGS*/ -void -setbinary(argc, argv) - int argc; - char *argv[]; -{ - - stype[1] = "binary"; - settype(2, stype); -} - -/* - * Set ascii transfer type. - */ -/*VARARGS*/ -void -setascii(argc, argv) - int argc; - char *argv[]; -{ - - stype[1] = "ascii"; - settype(2, stype); -} - -/* - * Set tenex transfer type. - */ -/*VARARGS*/ -void -settenex(argc, argv) - int argc; - char *argv[]; -{ - - stype[1] = "tenex"; - settype(2, stype); -} - -/* - * Set file transfer mode. - */ -/*ARGSUSED*/ -void -setftmode(argc, argv) - int argc; - char *argv[]; -{ - - printf("We only support %s mode, sorry.\n", modename); - code = -1; -} - -/* - * Set file transfer format. - */ -/*ARGSUSED*/ -void -setform(argc, argv) - int argc; - char *argv[]; -{ - - printf("We only support %s format, sorry.\n", formname); - code = -1; -} - -/* - * Set file transfer structure. - */ -/*ARGSUSED*/ -void -setstruct(argc, argv) - int argc; - char *argv[]; -{ - - printf("We only support %s structure, sorry.\n", structname); - code = -1; -} - -/* - * Send a single file. - */ -void -put(argc, argv) - int argc; - char *argv[]; -{ - char *cmd; - int loc = 0; - char *oldargv1, *oldargv2; - - if (argc == 2) { - argc++; - argv[2] = argv[1]; - loc++; - } - if (argc < 2 && !another(&argc, &argv, "local-file")) - goto usage; - if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) { -usage: - printf("usage: %s local-file [ remote-file ]\n", argv[0]); - code = -1; - return; - } - oldargv1 = argv[1]; - oldargv2 = argv[2]; - if (!globulize(&argv[1])) { - code = -1; - return; - } - /* - * If "globulize" modifies argv[1], and argv[2] is a copy of - * the old argv[1], make it a copy of the new argv[1]. - */ - if (argv[1] != oldargv1 && argv[2] == oldargv1) { - argv[2] = argv[1]; - } - cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); - if (loc && ntflag) { - argv[2] = dotrans(argv[2]); - } - if (loc && mapflag) { - argv[2] = domap(argv[2]); - } - sendrequest(cmd, argv[1], argv[2], - argv[1] != oldargv1 || argv[2] != oldargv2); - if (oldargv1 != argv[1]) /* free up after globulize() */ - free(argv[1]); -} - -/* - * Send multiple files. - */ -void -mput(argc, argv) - int argc; - char *argv[]; -{ - int i; - sig_t oldintr; - int ointer; - char *tp; - - if (argc < 2 && !another(&argc, &argv, "local-files")) { - printf("usage: %s local-files\n", argv[0]); - code = -1; - return; - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mabort); - (void)setjmp(jabort); - if (proxy) { - char *cp, *tp2, tmpbuf[MAXPATHLEN]; - - while ((cp = remglob(argv, 0, NULL)) != NULL) { - if (*cp == '\0') { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - tp = cp; - if (mcase) { - while (*tp && !islower((unsigned char)*tp)) { - tp++; - } - if (!*tp) { - tp = cp; - tp2 = tmpbuf; - while ((*tp2 = *tp) != '\0') { - if (isupper((unsigned char)*tp2)) - *tp2 = tolower((unsigned char)*tp2); - tp++; - tp2++; - } - } - tp = tmpbuf; - } - if (ntflag) { - tp = dotrans(tp); - } - if (mapflag) { - tp = domap(tp); - } - sendrequest((sunique) ? "STOU" : "STOR", - cp, tp, cp != tp || !interactive); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mput")) { - mflag++; - } - interactive = ointer; - } - } - } - (void)signal(SIGINT, oldintr); - mflag = 0; - return; - } - for (i = 1; i < argc; i++) { - char **cpp; - glob_t gl; - int flags; - - if (!doglob) { - if (mflag && confirm(argv[0], argv[i])) { - tp = (ntflag) ? dotrans(argv[i]) : argv[i]; - tp = (mapflag) ? domap(tp) : tp; - sendrequest((sunique) ? "STOU" : "STOR", - argv[i], tp, tp != argv[i] || !interactive); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mput")) { - mflag++; - } - interactive = ointer; - } - } - continue; - } - - memset(&gl, 0, sizeof(gl)); - flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; - if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) { - warnx("%s: not found", argv[i]); - globfree(&gl); - continue; - } - for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) { - if (mflag && confirm(argv[0], *cpp)) { - tp = (ntflag) ? dotrans(*cpp) : *cpp; - tp = (mapflag) ? domap(tp) : tp; - sendrequest((sunique) ? "STOU" : "STOR", - *cpp, tp, *cpp != tp || !interactive); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mput")) { - mflag++; - } - interactive = ointer; - } - } - } - globfree(&gl); - } - (void)signal(SIGINT, oldintr); - mflag = 0; -} - -void -reget(argc, argv) - int argc; - char *argv[]; -{ - - (void)getit(argc, argv, 1, "r+w"); -} - -void -get(argc, argv) - int argc; - char *argv[]; -{ - - (void)getit(argc, argv, 0, restart_point ? "r+w" : "w" ); -} - -/* - * Receive one file. - */ -int -getit(argc, argv, restartit, mode) - int argc; - char *argv[]; - int restartit; - const char *mode; -{ - int loc = 0; - int rval = 0; - char *oldargv1, *oldargv2, *globargv2; - - if (argc == 2) { - argc++; - argv[2] = argv[1]; - loc++; - } - if (argc < 2 && !another(&argc, &argv, "remote-file")) - goto usage; - if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) { -usage: - printf("usage: %s remote-file [ local-file ]\n", argv[0]); - code = -1; - return (0); - } - oldargv1 = argv[1]; - oldargv2 = argv[2]; - if (!globulize(&argv[2])) { - code = -1; - return (0); - } - globargv2 = argv[2]; - if (loc && mcase) { - char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; - - while (*tp && !islower((unsigned char)*tp)) { - tp++; - } - if (!*tp) { - tp = argv[2]; - tp2 = tmpbuf; - while ((*tp2 = *tp) != '\0') { - if (isupper((unsigned char)*tp2)) { - *tp2 = tolower((unsigned char)*tp2); - } - tp++; - tp2++; - } - argv[2] = tmpbuf; - } - } - if (loc && ntflag) - argv[2] = dotrans(argv[2]); - if (loc && mapflag) - argv[2] = domap(argv[2]); - if (restartit) { - struct stat stbuf; - int ret; - - ret = stat(argv[2], &stbuf); - if (restartit == 1) { - if (ret < 0) { - warn("local: %s", argv[2]); - goto freegetit; - } - restart_point = stbuf.st_size; - } else { - if (ret == 0) { - time_t mtime; - - mtime = remotemodtime(argv[1], 0); - if (mtime == -1) - goto freegetit; - if (stbuf.st_mtime >= mtime) { - rval = 1; - goto freegetit; - } - } - } - } - - recvrequest("RETR", argv[2], argv[1], mode, - argv[1] != oldargv1 || argv[2] != oldargv2, loc); - restart_point = 0; -freegetit: - if (oldargv2 != globargv2) /* free up after globulize() */ - free(globargv2); - return (rval); -} - -/* ARGSUSED */ -void -mabort(signo) - int signo; -{ - int ointer, oconf; - - alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); - if (mflag && fromatty) { - ointer = interactive; - oconf = confirmrest; - interactive = 1; - confirmrest = 0; - if (confirm("Continue with", mname)) { - interactive = ointer; - confirmrest = oconf; - longjmp(jabort, 0); - } - interactive = ointer; - confirmrest = oconf; - } - mflag = 0; - longjmp(jabort, 0); -} - -/* - * Get multiple files. - */ -void -mget(argc, argv) - int argc; - char *argv[]; -{ - sig_t oldintr; - int ch, ointer; - char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; - - if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); - code = -1; - return; - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mabort); - (void)setjmp(jabort); - while ((cp = remglob(argv, proxy, NULL)) != NULL) { - if (*cp == '\0') { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - tp = cp; - if (mcase) { - for (tp2 = tmpbuf; (ch = *tp++) != 0; ) - *tp2++ = isupper((unsigned char)ch) ? - tolower((unsigned char)ch) : - ch; - *tp2 = '\0'; - tp = tmpbuf; - } - if (ntflag) { - tp = dotrans(tp); - } - if (mapflag) { - tp = domap(tp); - } - recvrequest("RETR", tp, cp, "w", - tp != cp || !interactive, 1); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mget")) { - mflag++; - } - interactive = ointer; - } - } - } - (void)signal(SIGINT, oldintr); - mflag = 0; -} - -char * -onoff(bool) - int bool; -{ - - return (bool ? "on" : "off"); -} - -/* - * Show status. - */ -/*ARGSUSED*/ -void -status(argc, argv) - int argc; - char *argv[]; -{ - int i; - - if (connected) - printf("Connected %sto %s.\n", - connected == -1 ? "and logged in" : "", hostname); - else - puts("Not connected."); - if (!proxy) { - pswitch(1); - if (connected) { - printf("Connected for proxy commands to %s.\n", - hostname); - } - else { - puts("No proxy connection."); - } - pswitch(0); - } - printf("Gate ftp: %s, server %s, port %s.\n", onoff(gatemode), - *gateserver ? gateserver : "(none)", gateport); - printf("Passive mode: %s.\n", onoff(passivemode)); - printf("Mode: %s; Type: %s; Form: %s; Structure: %s.\n", - modename, typename, formname, structname); - printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s.\n", - onoff(verbose), onoff(bell), onoff(interactive), - onoff(doglob)); - printf("Store unique: %s; Receive unique: %s.\n", onoff(sunique), - onoff(runique)); - printf("Preserve modification times: %s.\n", onoff(preserve)); - printf("Case: %s; CR stripping: %s.\n", onoff(mcase), onoff(crflag)); - if (ntflag) { - printf("Ntrans: (in) %s (out) %s\n", ntin, ntout); - } - else { - puts("Ntrans: off."); - } - if (mapflag) { - printf("Nmap: (in) %s (out) %s\n", mapin, mapout); - } - else { - puts("Nmap: off."); - } - printf("Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n", - onoff(hash), mark, onoff(progress)); - printf("Use of PORT cmds: %s.\n", onoff(sendport)); -#ifndef SMALL - printf("Command line editing: %s.\n", onoff(editing)); -#endif /* !SMALL */ - if (macnum > 0) { - puts("Macros:"); - for (i=0; i<macnum; i++) { - printf("\t%s\n", macros[i].mac_name); - } - } - code = 0; -} - -/* - * Toggle a variable - */ -int -togglevar(argc, argv, var, mesg) - int argc; - char *argv[]; - int *var; - const char *mesg; -{ - if (argc < 2) { - *var = !*var; - } else if (argc == 2 && strcasecmp(argv[1], "on") == 0) { - *var = 1; - } else if (argc == 2 && strcasecmp(argv[1], "off") == 0) { - *var = 0; - } else { - printf("usage: %s [ on | off ]\n", argv[0]); - return (-1); - } - if (mesg) - printf("%s %s.\n", mesg, onoff(*var)); - return (*var); -} - -/* - * Set beep on cmd completed mode. - */ -/*VARARGS*/ -void -setbell(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &bell, "Bell mode"); -} - -#ifndef SMALL -/* - * Set command line editing - */ -/*VARARGS*/ -void -setedit(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &editing, "Editing mode"); - controlediting(); -} -#endif /* !SMALL */ - -/* - * Turn on packet tracing. - */ -/*VARARGS*/ -void -settrace(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &trace, "Packet tracing"); -} - -/* - * Toggle hash mark printing during transfers, or set hash mark bytecount. - */ -/*VARARGS*/ -void -sethash(argc, argv) - int argc; - char *argv[]; -{ - if (argc == 1) - hash = !hash; - else if (argc != 2) { - printf("usage: %s [ on | off | bytecount ]\n", argv[0]); - code = -1; - return; - } else if (strcasecmp(argv[1], "on") == 0) - hash = 1; - else if (strcasecmp(argv[1], "off") == 0) - hash = 0; - else { - int nmark; - char *ep; - - nmark = strtol(argv[1], &ep, 10); - if (nmark < 1 || *ep != '\0') { - printf("mark: bad bytecount value `%s'.\n", argv[1]); - code = -1; - return; - } - mark = nmark; - hash = 1; - } - printf("Hash mark printing %s", onoff(hash)); - if (hash) - printf(" (%d bytes/hash mark)", mark); - puts("."); - code = hash; -} - -/* - * Turn on printing of server echo's. - */ -/*VARARGS*/ -void -setverbose(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &verbose, "Verbose mode"); -} - -/* - * Toggle PORT cmd use before each data connection. - */ -/*VARARGS*/ -void -setport(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &sendport, "Use of PORT cmds"); -} - -/* - * Toggle transfer progress bar. - */ -/*VARARGS*/ -void -setprogress(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &progress, "Progress bar"); -} - -/* - * Turn on interactive prompting during mget, mput, and mdelete. - */ -/*VARARGS*/ -void -setprompt(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &interactive, "Interactive mode"); -} - -/* - * Toggle gate-ftp mode, or set gate-ftp server - */ -/*VARARGS*/ -void -setgate(argc, argv) - int argc; - char *argv[]; -{ - static char gsbuf[MAXHOSTNAMELEN]; - - if (argc > 3) { - printf("usage: %s [ on | off | gateserver [ port ] ]\n", - argv[0]); - code = -1; - return; - } else if (argc < 2) { - gatemode = !gatemode; - } else { - if (argc == 2 && strcasecmp(argv[1], "on") == 0) - gatemode = 1; - else if (argc == 2 && strcasecmp(argv[1], "off") == 0) - gatemode = 0; - else { - if (argc == 3) { - char *ep; - long port; - - port = strtol(argv[2], &ep, 10); - if (port < 0 || port > 0xffff || *ep != '\0') { - printf("%s: bad gateport value.\n", - argv[2]); - code = -1; - return; - } - if (gateport != NULL) - free(gateport); - asprintf(&gateport, "%ld", port); - } - strncpy(gsbuf, argv[1], sizeof(gsbuf) - 1); - gsbuf[sizeof(gsbuf) - 1] = '\0'; - gateserver = gsbuf; - gatemode = 1; - } - } - if (gatemode && (gateserver == NULL || *gateserver == '\0')) { - printf( - "Disabling gate-ftp mode - no gate-ftp server defined.\n"); - gatemode = 0; - } else { - printf("Gate ftp: %s, server %s, port %s.\n", onoff(gatemode), - *gateserver ? gateserver : "(none)", gateport); - } - code = gatemode; -} - -/* - * Toggle metacharacter interpretation on local file names. - */ -/*VARARGS*/ -void -setglob(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &doglob, "Globbing"); -} - -/* - * Toggle preserving modification times on retrieved files. - */ -/*VARARGS*/ -void -setpreserve(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &preserve, "Preserve modification times"); -} - -/* - * Set debugging mode on/off and/or set level of debugging. - */ -/*VARARGS*/ -void -setdebug(argc, argv) - int argc; - char *argv[]; -{ - if (argc > 2) { - printf("usage: %s [ on | off | debuglevel ]\n", argv[0]); - code = -1; - return; - } else if (argc == 2) { - if (strcasecmp(argv[1], "on") == 0) - debug = 1; - else if (strcasecmp(argv[1], "off") == 0) - debug = 0; - else { - char *ep; - long val; - - val = strtol(argv[1], &ep, 10); - if (val < 0 || val > INT_MAX || *ep != '\0') { - printf("%s: bad debugging value.\n", argv[1]); - code = -1; - return; - } - debug = (int)val; - } - } else - debug = !debug; - if (debug) - options |= SO_DEBUG; - else - options &= ~SO_DEBUG; - printf("Debugging %s (debug=%d).\n", onoff(debug), debug); - code = debug > 0; -} - -/* - * Set current working directory on remote machine. - */ -void -cd(argc, argv) - int argc; - char *argv[]; -{ - int r; - - if ((argc < 2 && !another(&argc, &argv, "remote-directory")) || - argc > 2) { - printf("usage: %s remote-directory\n", argv[0]); - code = -1; - return; - } - r = command("CWD %s", argv[1]); - if (r == ERROR && code == 500) { - if (verbose) - puts("CWD command not recognized, trying XCWD."); - r = command("XCWD %s", argv[1]); - } - if (r == COMPLETE) - dirchange = 1; -} - -/* - * Set current working directory on local machine. - */ -void -lcd(argc, argv) - int argc; - char *argv[]; -{ - char buf[MAXPATHLEN]; - char *oldargv1; - - if (argc < 2) - argc++, argv[1] = home; - if (argc != 2) { - printf("usage: %s local-directory\n", argv[0]); - code = -1; - return; - } - oldargv1 = argv[1]; - if (!globulize(&argv[1])) { - code = -1; - return; - } - if (chdir(argv[1]) < 0) { - warn("local: %s", argv[1]); - code = -1; - } else { - if (getcwd(buf, sizeof(buf)) != NULL) - printf("Local directory now %s\n", buf); - else - warn("getcwd: %s", argv[1]); - code = 0; - } - if (oldargv1 != argv[1]) /* free up after globulize() */ - free(argv[1]); -} - -/* - * Delete a single file. - */ -void -delete(argc, argv) - int argc; - char *argv[]; -{ - - if ((argc < 2 && !another(&argc, &argv, "remote-file")) || argc > 2) { - printf("usage: %s remote-file\n", argv[0]); - code = -1; - return; - } - (void)command("DELE %s", argv[1]); -} - -/* - * Delete multiple files. - */ -void -mdelete(argc, argv) - int argc; - char *argv[]; -{ - sig_t oldintr; - int ointer; - char *cp; - - if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); - code = -1; - return; - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mabort); - (void)setjmp(jabort); - while ((cp = remglob(argv, 0, NULL)) != NULL) { - if (*cp == '\0') { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - (void)command("DELE %s", cp); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mdelete")) { - mflag++; - } - interactive = ointer; - } - } - } - (void)signal(SIGINT, oldintr); - mflag = 0; -} - -/* - * Rename a remote file. - */ -void -renamefile(argc, argv) - int argc; - char *argv[]; -{ - - if (argc < 2 && !another(&argc, &argv, "from-name")) - goto usage; - if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) { -usage: - printf("usage: %s from-name to-name\n", argv[0]); - code = -1; - return; - } - if (command("RNFR %s", argv[1]) == CONTINUE) - (void)command("RNTO %s", argv[2]); -} - -/* - * Get a directory listing of remote files. - */ -void -ls(argc, argv) - int argc; - char *argv[]; -{ - const char *cmd; - char *oldargv2, *globargv2; - - if (argc < 2) - argc++, argv[1] = NULL; - if (argc < 3) - argc++, argv[2] = "-"; - if (argc > 3) { - printf("usage: %s remote-directory local-file\n", argv[0]); - code = -1; - return; - } - cmd = strcmp(argv[0], "nlist") == 0 ? "NLST" : "LIST"; - oldargv2 = argv[2]; - if (strcmp(argv[2], "-") && !globulize(&argv[2])) { - code = -1; - return; - } - globargv2 = argv[2]; - if (strcmp(argv[2], "-") && *argv[2] != '|') - if (!globulize(&argv[2]) || !confirm("output to local-file:", - argv[2])) { - code = -1; - goto freels; - } - recvrequest(cmd, argv[2], argv[1], "w", 0, 0); - - /* flush results in case commands are coming from a pipe */ - fflush(stdout); -freels: - if (argv[2] != globargv2) /* free up after globulize() */ - free(argv[2]); - if (globargv2 != oldargv2) - free(globargv2); -} - -/* - * Get a directory listing of multiple remote files. - */ -void -mls(argc, argv) - int argc; - char *argv[]; -{ - sig_t oldintr; - int ointer, i; - int dolist; - char mode[1], *dest, *odest; - - if (argc < 2 && !another(&argc, &argv, "remote-files")) - goto usage; - if (argc < 3 && !another(&argc, &argv, "local-file")) { -usage: - printf("usage: %s remote-files local-file\n", argv[0]); - code = -1; - return; - } - odest = dest = argv[argc - 1]; - argv[argc - 1] = NULL; - if (strcmp(dest, "-") && *dest != '|') - if (!globulize(&dest) || - !confirm("output to local-file:", dest)) { - code = -1; - return; - } - dolist = strcmp(argv[0], "mls"); - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mabort); - (void)setjmp(jabort); - for (i = 1; mflag && i < argc-1; ++i) { - *mode = (i == 1) ? 'w' : 'a'; - recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], mode, - 0, 0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", argv[0])) { - mflag ++; - } - interactive = ointer; - } - } - (void)signal(SIGINT, oldintr); - mflag = 0; - if (dest != odest) /* free up after globulize() */ - free(dest); -} - -/* - * Do a shell escape - */ -/*ARGSUSED*/ -void -shell(argc, argv) - int argc; - char *argv[]; -{ - pid_t pid; - sig_t old1, old2; - char shellnam[MAXPATHLEN], *shell, *namep; - int wait_status; - - old1 = signal (SIGINT, SIG_IGN); - old2 = signal (SIGQUIT, SIG_IGN); - if ((pid = fork()) == 0) { - for (pid = 3; pid < 20; pid++) - (void)close(pid); - (void)signal(SIGINT, SIG_DFL); - (void)signal(SIGQUIT, SIG_DFL); - shell = getenv("SHELL"); - if (shell == NULL) - shell = _PATH_BSHELL; - namep = strrchr(shell, '/'); - if (namep == NULL) - namep = shell; - shellnam[0] = '-'; - (void)strncpy(shellnam + 1, ++namep, sizeof(shellnam) - 2); - shellnam[sizeof(shellnam) - 1] = '\0'; - if (strcmp(namep, "sh") != 0) - shellnam[0] = '+'; - if (debug) { - puts(shell); - (void)fflush(stdout); - } - if (argc > 1) { - execl(shell, shellnam, "-c", altarg, (char *)0); - } - else { - execl(shell, shellnam, (char *)0); - } - warn("%s", shell); - code = -1; - exit(1); - } - if (pid > 0) - while (wait(&wait_status) != pid) - ; - (void)signal(SIGINT, old1); - (void)signal(SIGQUIT, old2); - if (pid == -1) { - warn("Try again later"); - code = -1; - } - else { - code = 0; - } -} - -/* - * Send new user information (re-login) - */ -void -user(argc, argv) - int argc; - char *argv[]; -{ - char acct[80]; - int n, aflag = 0; - - if (argc < 2) - (void)another(&argc, &argv, "username"); - if (argc < 2 || argc > 4) { - printf("usage: %s username [password] [account]\n", argv[0]); - code = -1; - return; - } - n = command("USER %s", argv[1]); - if (n == CONTINUE) { - if (argc < 3 ) - argv[2] = getpass("Password: "), argc++; - n = command("PASS %s", argv[2]); - } - if (n == CONTINUE) { - if (argc < 4) { - (void)fputs("Account: ", stdout); - (void)fflush(stdout); - (void)fgets(acct, sizeof(acct) - 1, stdin); - acct[strlen(acct) - 1] = '\0'; - argv[3] = acct; argc++; - } - n = command("ACCT %s", argv[3]); - aflag++; - } - if (n != COMPLETE) { - puts("Login failed."); - return; - } - if (!aflag && argc == 4) { - (void)command("ACCT %s", argv[3]); - } - connected = -1; -} - -/* - * Print working directory on remote machine. - */ -/*VARARGS*/ -void -pwd(argc, argv) - int argc; - char *argv[]; -{ - int oldverbose = verbose; - - /* - * If we aren't verbose, this doesn't do anything! - */ - verbose = 1; - if (command("PWD") == ERROR && code == 500) { - puts("PWD command not recognized, trying XPWD."); - (void)command("XPWD"); - } - verbose = oldverbose; -} - -/* - * Print working directory on local machine. - */ -void -lpwd(argc, argv) - int argc; - char *argv[]; -{ - char buf[MAXPATHLEN]; - - if (getcwd(buf, sizeof(buf)) != NULL) - printf("Local directory %s\n", buf); - else - warn("getcwd"); - code = 0; -} - -/* - * Make a directory. - */ -void -makedir(argc, argv) - int argc; - char *argv[]; -{ - - if ((argc < 2 && !another(&argc, &argv, "directory-name")) || - argc > 2) { - printf("usage: %s directory-name\n", argv[0]); - code = -1; - return; - } - if (command("MKD %s", argv[1]) == ERROR && code == 500) { - if (verbose) - puts("MKD command not recognized, trying XMKD."); - (void)command("XMKD %s", argv[1]); - } -} - -/* - * Remove a directory. - */ -void -removedir(argc, argv) - int argc; - char *argv[]; -{ - - if ((argc < 2 && !another(&argc, &argv, "directory-name")) || - argc > 2) { - printf("usage: %s directory-name\n", argv[0]); - code = -1; - return; - } - if (command("RMD %s", argv[1]) == ERROR && code == 500) { - if (verbose) - puts("RMD command not recognized, trying XRMD."); - (void)command("XRMD %s", argv[1]); - } -} - -/* - * Send a line, verbatim, to the remote machine. - */ -void -quote(argc, argv) - int argc; - char *argv[]; -{ - - if (argc < 2 && !another(&argc, &argv, "command line to send")) { - printf("usage: %s line-to-send\n", argv[0]); - code = -1; - return; - } - quote1("", argc, argv); -} - -/* - * Send a SITE command to the remote machine. The line - * is sent verbatim to the remote machine, except that the - * word "SITE" is added at the front. - */ -void -site(argc, argv) - int argc; - char *argv[]; -{ - - if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) { - printf("usage: %s line-to-send\n", argv[0]); - code = -1; - return; - } - quote1("SITE ", argc, argv); -} - -/* - * Turn argv[1..argc) into a space-separated string, then prepend initial text. - * Send the result as a one-line command and get response. - */ -void -quote1(initial, argc, argv) - const char *initial; - int argc; - char *argv[]; -{ - int i, len, len1; - char buf[BUFSIZ]; /* must be >= sizeof(line) */ - - len = snprintf(buf, sizeof(buf), "%s", initial); - if (len >= 0 && len < sizeof(buf)) { - for (i = 1; i < argc; i++) { - len1 = snprintf(&buf[len], sizeof(buf) - len, - i == 1 ? "%s" : " %s", argv[i]); - if (len1 < 0 || len1 > sizeof(buf) - len) - break; - len += len1; - } - } - if (command("%s", buf) == PRELIM) { - while (getreply(0) == PRELIM) - continue; - } -} - -void -do_chmod(argc, argv) - int argc; - char *argv[]; -{ - - if (argc < 2 && !another(&argc, &argv, "mode")) - goto usage; - if ((argc < 3 && !another(&argc, &argv, "file-name")) || argc > 3) { -usage: - printf("usage: %s mode file-name\n", argv[0]); - code = -1; - return; - } - (void)command("SITE CHMOD %s %s", argv[1], argv[2]); -} - -void -do_umask(argc, argv) - int argc; - char *argv[]; -{ - int oldverbose = verbose; - - verbose = 1; - (void)command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); - verbose = oldverbose; -} - -void -idle(argc, argv) - int argc; - char *argv[]; -{ - int oldverbose = verbose; - - verbose = 1; - (void)command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); - verbose = oldverbose; -} - -/* - * Ask the other side for help. - */ -void -rmthelp(argc, argv) - int argc; - char *argv[]; -{ - int oldverbose = verbose; - - verbose = 1; - (void)command(argc == 1 ? "HELP" : "HELP %s", argv[1]); - verbose = oldverbose; -} - -/* - * Terminate session and exit. - */ -/*VARARGS*/ -void -quit(argc, argv) - int argc; - char *argv[]; -{ - - if (connected) - disconnect(0, 0); - pswitch(1); - if (connected) { - disconnect(0, 0); - } - exit(0); -} - -/* - * Terminate session, but don't exit. - */ -void -disconnect(argc, argv) - int argc; - char *argv[]; -{ - - if (!connected) - return; - (void)command("QUIT"); - if (cout) { - (void)fclose(cout); - } - cout = NULL; - connected = 0; - data = -1; - if (!proxy) { - macnum = 0; - } -} - -void -account(argc, argv) - int argc; - char *argv[]; -{ - char *ap; - - if (argc > 2) { - printf("usage: %s [password]\n", argv[0]); - code = -1; - return; - } - else if (argc == 2) - ap = argv[1]; - else - ap = getpass("Account:"); - (void)command("ACCT %s", ap); -} - -jmp_buf abortprox; - -void -proxabort(notused) - int notused; -{ - - alarmtimer(0); - if (!proxy) { - pswitch(1); - } - if (connected) { - proxflag = 1; - } - else { - proxflag = 0; - } - pswitch(0); - longjmp(abortprox, 1); -} - -void -doproxy(argc, argv) - int argc; - char *argv[]; -{ - struct cmd *c; - int cmdpos; - sig_t oldintr; - - if (argc < 2 && !another(&argc, &argv, "command")) { - printf("usage: %s command\n", argv[0]); - code = -1; - return; - } - c = getcmd(argv[1]); - if (c == (struct cmd *) -1) { - puts("?Ambiguous command."); - (void)fflush(stdout); - code = -1; - return; - } - if (c == 0) { - puts("?Invalid command."); - (void)fflush(stdout); - code = -1; - return; - } - if (!c->c_proxy) { - puts("?Invalid proxy command."); - (void)fflush(stdout); - code = -1; - return; - } - if (setjmp(abortprox)) { - code = -1; - return; - } - oldintr = signal(SIGINT, proxabort); - pswitch(1); - if (c->c_conn && !connected) { - puts("Not connected."); - (void)fflush(stdout); - pswitch(0); - (void)signal(SIGINT, oldintr); - code = -1; - return; - } - cmdpos = strcspn(line, " \t"); - if (cmdpos > 0) /* remove leading "proxy " from input buffer */ - memmove(line, line + cmdpos + 1, strlen(line) - cmdpos + 1); - (*c->c_handler)(argc-1, argv+1); - if (connected) { - proxflag = 1; - } - else { - proxflag = 0; - } - pswitch(0); - (void)signal(SIGINT, oldintr); -} - -void -setcase(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &mcase, "Case mapping"); -} - -void -setcr(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &crflag, "Carriage Return stripping"); -} - -void -setntrans(argc, argv) - int argc; - char *argv[]; -{ - if (argc == 1) { - ntflag = 0; - puts("Ntrans off."); - code = ntflag; - return; - } - ntflag++; - code = ntflag; - (void)strncpy(ntin, argv[1], sizeof(ntin) - 1); - ntin[sizeof(ntin) - 1] = '\0'; - if (argc == 2) { - ntout[0] = '\0'; - return; - } - (void)strncpy(ntout, argv[2], sizeof(ntout) - 1); - ntout[sizeof(ntout) - 1] = '\0'; -} - -char * -dotrans(name) - char *name; -{ - static char new[MAXPATHLEN]; - char *cp1, *cp2 = new; - int i, ostop, found; - - for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++) - continue; - for (cp1 = name; *cp1; cp1++) { - found = 0; - for (i = 0; *(ntin + i) && i < 16; i++) { - if (*cp1 == *(ntin + i)) { - found++; - if (i < ostop) { - *cp2++ = *(ntout + i); - } - break; - } - } - if (!found) { - *cp2++ = *cp1; - } - } - *cp2 = '\0'; - return (new); -} - -void -setnmap(argc, argv) - int argc; - char *argv[]; -{ - char *cp; - - if (argc == 1) { - mapflag = 0; - puts("Nmap off."); - code = mapflag; - return; - } - if ((argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) { - printf("usage: %s [mapin mapout]\n", argv[0]); - code = -1; - return; - } - mapflag = 1; - code = 1; - cp = strchr(altarg, ' '); - if (proxy) { - while(*++cp == ' ') - continue; - altarg = cp; - cp = strchr(altarg, ' '); - } - *cp = '\0'; - (void)strncpy(mapin, altarg, MAXPATHLEN - 1); - while (*++cp == ' ') - continue; - (void)strncpy(mapout, cp, MAXPATHLEN - 1); -} - -char * -domap(name) - char *name; -{ - static char new[MAXPATHLEN]; - char *cp1 = name, *cp2 = mapin; - char *tp[9], *te[9]; - int i, toks[9], toknum = 0, match = 1; - - for (i=0; i < 9; ++i) { - toks[i] = 0; - } - while (match && *cp1 && *cp2) { - switch (*cp2) { - case '\\': - if (*++cp2 != *cp1) { - match = 0; - } - break; - case '$': - if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { - if (*cp1 != *(++cp2+1)) { - toks[toknum = *cp2 - '1']++; - tp[toknum] = cp1; - while (*++cp1 && *(cp2+1) - != *cp1); - te[toknum] = cp1; - } - cp2++; - break; - } - /* FALLTHROUGH */ - default: - if (*cp2 != *cp1) { - match = 0; - } - break; - } - if (match && *cp1) { - cp1++; - } - if (match && *cp2) { - cp2++; - } - } - if (!match && *cp1) /* last token mismatch */ - { - toks[toknum] = 0; - } - cp1 = new; - *cp1 = '\0'; - cp2 = mapout; - while (*cp2) { - match = 0; - switch (*cp2) { - case '\\': - if (*(cp2 + 1)) { - *cp1++ = *++cp2; - } - break; - case '[': -LOOP: - if (*++cp2 == '$' && - isdigit((unsigned char)*(cp2+1))) { - if (*++cp2 == '0') { - char *cp3 = name; - - while (*cp3) { - *cp1++ = *cp3++; - } - match = 1; - } - else if (toks[toknum = *cp2 - '1']) { - char *cp3 = tp[toknum]; - - while (cp3 != te[toknum]) { - *cp1++ = *cp3++; - } - match = 1; - } - } - else { - while (*cp2 && *cp2 != ',' && - *cp2 != ']') { - if (*cp2 == '\\') { - cp2++; - } - else if (*cp2 == '$' && - isdigit((unsigned char)*(cp2+1))) { - if (*++cp2 == '0') { - char *cp3 = name; - - while (*cp3) { - *cp1++ = *cp3++; - } - } - else if (toks[toknum = - *cp2 - '1']) { - char *cp3=tp[toknum]; - - while (cp3 != - te[toknum]) { - *cp1++ = *cp3++; - } - } - } - else if (*cp2) { - *cp1++ = *cp2++; - } - } - if (!*cp2) { - puts( -"nmap: unbalanced brackets."); - return (name); - } - match = 1; - cp2--; - } - if (match) { - while (*++cp2 && *cp2 != ']') { - if (*cp2 == '\\' && *(cp2 + 1)) { - cp2++; - } - } - if (!*cp2) { - puts( -"nmap: unbalanced brackets."); - return (name); - } - break; - } - switch (*++cp2) { - case ',': - goto LOOP; - case ']': - break; - default: - cp2--; - goto LOOP; - } - break; - case '$': - if (isdigit((unsigned char)*(cp2 + 1))) { - if (*++cp2 == '0') { - char *cp3 = name; - - while (*cp3) { - *cp1++ = *cp3++; - } - } - else if (toks[toknum = *cp2 - '1']) { - char *cp3 = tp[toknum]; - - while (cp3 != te[toknum]) { - *cp1++ = *cp3++; - } - } - break; - } - /* intentional drop through */ - default: - *cp1++ = *cp2; - break; - } - cp2++; - } - *cp1 = '\0'; - if (!*new) { - return (name); - } - return (new); -} - -void -setpassive(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &passivemode, - verbose ? "Passive mode" : NULL); -} - -void -setsunique(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &sunique, "Store unique"); -} - -void -setrunique(argc, argv) - int argc; - char *argv[]; -{ - - code = togglevar(argc, argv, &runique, "Receive unique"); -} - -/* change directory to parent directory */ -void -cdup(argc, argv) - int argc; - char *argv[]; -{ - int r; - - r = command("CDUP"); - if (r == ERROR && code == 500) { - if (verbose) - puts("CDUP command not recognized, trying XCUP."); - r = command("XCUP"); - } - if (r == COMPLETE) - dirchange = 1; -} - -/* - * Restart transfer at specific point - */ -void -restart(argc, argv) - int argc; - char *argv[]; -{ - - if (argc > 2) { - printf("usage: %s [restart_point]\n", argv[0]); - code = -1; - return; - } - if (argc == 2) { - quad_t rp; - char *ep; - - rp = strtoq(argv[1], &ep, 10); - if (rp < 0 || *ep != '\0') - printf("restart: Invalid offset `%s'\n", argv[1]); - else - restart_point = rp; - } - if (restart_point == 0) - puts("No restart point defined"); - else - printf("Restarting at %qd for next get, put or append\n", - (long long)restart_point); -} - -/* - * Show remote system type - */ -void -syst(argc, argv) - int argc; - char *argv[]; -{ - - (void)command("SYST"); -} - -void -macdef(argc, argv) - int argc; - char *argv[]; -{ - char *tmp; - int c; - - if (macnum == 16) { - puts("Limit of 16 macros have already been defined."); - code = -1; - return; - } - if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) { - printf("usage: %s macro_name\n", argv[0]); - code = -1; - return; - } - if (interactive) - puts( -"Enter macro line by line, terminating it with a null line."); - (void)strncpy(macros[macnum].mac_name, argv[1], - sizeof(macros[macnum].mac_name) - 1); - macros[macnum].mac_name[sizeof(macros[macnum].mac_name) - 1] = '\0'; - if (macnum == 0) - macros[macnum].mac_start = macbuf; - else - macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; - tmp = macros[macnum].mac_start; - while (tmp != macbuf+4096) { - if ((c = getchar()) == EOF) { - puts("macdef: end of file encountered."); - code = -1; - return; - } - if ((*tmp = c) == '\n') { - if (tmp == macros[macnum].mac_start) { - macros[macnum++].mac_end = tmp; - code = 0; - return; - } - if (*(tmp-1) == '\0') { - macros[macnum++].mac_end = tmp - 1; - code = 0; - return; - } - *tmp = '\0'; - } - tmp++; - } - while (1) { - while ((c = getchar()) != '\n' && c != EOF) - /* LOOP */; - if (c == EOF || getchar() == '\n') { - puts("Macro not defined - 4K buffer exceeded."); - code = -1; - return; - } - } -} - -/* - * Restrict FTP data port range to a high group of "safe" ports - */ -void -setrestrict(argc, argv) - int argc; - char *argv[]; -{ - code = togglevar(argc, argv, &restricted_data_ports, - verbose ? "Restricted data ports" : NULL); -} - -/* - * Get size of file on remote machine - */ -void -sizecmd(argc, argv) - int argc; - char *argv[]; -{ - off_t size; - - if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); - code = -1; - return; - } - size = remotesize(argv[1], 1); - if (size != -1) - printf("%s\t%qd\n", argv[1], (long long)size); - code = size; -} - -/* - * Get last modification time of file on remote machine - */ -void -modtime(argc, argv) - int argc; - char *argv[]; -{ - time_t mtime; - - if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); - code = -1; - return; - } - mtime = remotemodtime(argv[1], 1); - if (mtime != -1) - printf("%s\t%s", argv[1], asctime(localtime(&mtime))); - code = mtime; -} - -/* - * Show status on remote machine - */ -void -rmtstatus(argc, argv) - int argc; - char *argv[]; -{ - - (void)command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); -} - -/* - * Get file if modtime is more recent than current file - */ -void -newer(argc, argv) - int argc; - char *argv[]; -{ - - if (getit(argc, argv, -1, "w")) - printf("Local file \"%s\" is newer than remote file \"%s\".\n", - argv[2], argv[1]); -} - -/* - * Display one file through $PAGER (defaults to "more"). - */ -void -page(argc, argv) - int argc; - char *argv[]; -{ - int ohash, overbose; - char *p, *pager, *oldargv1; - - if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { - printf("usage: %s filename\n", argv[0]); - code = -1; - return; - } - oldargv1 = argv[1]; - if (!globulize(&argv[1])) { - code = -1; - return; - } - p = getenv("PAGER"); - if (p == NULL) - p = PAGER; - if ((pager = malloc(strlen(p) + 2)) == NULL) - errx(1, "Can't allocate memory for $PAGER"); - (void)sprintf(pager, "|%s", p); - - ohash = hash; - overbose = verbose; - hash = verbose = 0; - recvrequest("RETR", pager, argv[1], "r+w", 1, 0); - (void)free(pager); - hash = ohash; - verbose = overbose; - if (oldargv1 != argv[1]) /* free up after globulize() */ - free(argv[1]); -} diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c deleted file mode 100644 index e8d2d1b1c0a3..000000000000 --- a/usr.bin/ftp/cmdtab.c +++ /dev/null @@ -1,230 +0,0 @@ -/* $NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $"); -#endif -#endif /* not lint */ - -#include <stdio.h> -#include "ftp_var.h" - -/* - * User FTP -- Command Tables. - */ - -char accounthelp[] = "send account command to remote server"; -char appendhelp[] = "append to a file"; -char asciihelp[] = "set ascii transfer type"; -char beephelp[] = "beep when command completed"; -char binaryhelp[] = "set binary transfer type"; -char casehelp[] = "toggle mget upper/lower case id mapping"; -char cdhelp[] = "change remote working directory"; -char cduphelp[] = "change remote working directory to parent directory"; -char chmodhelp[] = "change file permissions of remote file"; -char connecthelp[] = "connect to remote ftp server"; -char crhelp[] = "toggle carriage return stripping on ascii gets"; -char debughelp[] = "toggle/set debugging mode"; -char deletehelp[] = "delete remote file"; -char dirhelp[] = "list contents of remote directory"; -char disconhelp[] = "terminate ftp session"; -char domachelp[] = "execute macro"; -#ifndef SMALL -char edithelp[] = "toggle command line editing"; -#endif /* !SMALL */ -char formhelp[] = "set file transfer format"; -char gatehelp[] = "toggle gate-ftp; specify host[:port] to change proxy"; -char globhelp[] = "toggle metacharacter expansion of local file names"; -char hashhelp[] = "toggle printing `#' marks; specify number to set size"; -char helphelp[] = "print local help information"; -char idlehelp[] = "get (set) idle timer on remote side"; -char lcdhelp[] = "change local working directory"; -char lpwdhelp[] = "print local working directory"; -char lshelp[] = "list contents of remote directory"; -char macdefhelp[] = "define a macro"; -char mdeletehelp[] = "delete multiple files"; -char mdirhelp[] = "list contents of multiple remote directories"; -char mgethelp[] = "get multiple files"; -char mkdirhelp[] = "make directory on the remote machine"; -char mlshelp[] = "list contents of multiple remote directories"; -char modehelp[] = "set file transfer mode"; -char modtimehelp[] = "show last modification time of remote file"; -char mputhelp[] = "send multiple files"; -char newerhelp[] = "get file if remote file is newer than local file "; -char nlisthelp[] = "nlist contents of remote directory"; -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 preservehelp[] ="toggle preservation of modification time of " - "retreived files"; -char progresshelp[] ="toggle transfer progress meter"; -char prompthelp[] = "force interactive prompting on multiple commands"; -char proxyhelp[] = "issue command on alternate connection"; -char pwdhelp[] = "print working directory on remote machine"; -char quithelp[] = "terminate ftp session and exit"; -char quotehelp[] = "send arbitrary ftp command"; -char receivehelp[] = "receive file"; -char regethelp[] = "get file restarting at end of local file"; -char remotehelp[] = "get help from remote server"; -char renamehelp[] = "rename file"; -char resethelp[] = "clear queued command replies"; -char restarthelp[]= "restart file transfer at bytecount"; -char restricthelp[]= "toggle restriction of data port range"; -char rmdirhelp[] = "remove directory on the remote machine"; -char rmtstatushelp[]="show status of remote machine"; -char runiquehelp[] = "toggle store unique for local files"; -char sendhelp[] = "send one file"; -char shellhelp[] = "escape to the shell"; -char sitehelp[] = "send site specific command to remote server\n" - "\t\tTry \"rhelp site\" or \"site help\" " - "for more information"; -char sizecmdhelp[] = "show size of remote file"; -char statushelp[] = "show current status"; -char structhelp[] = "set file transfer structure"; -char suniquehelp[] = "toggle store unique on remote machine"; -char systemhelp[] = "show remote system type"; -char tenexhelp[] = "set tenex file transfer type"; -char tracehelp[] = "toggle packet tracing"; -char typehelp[] = "set file transfer type"; -char umaskhelp[] = "get (set) umask on remote side"; -char userhelp[] = "send new user information"; -char verbosehelp[] = "toggle verbose mode"; - -#ifdef SMALL -#define CMPL(x) -#define CMPL0 -#else /* !SMALL */ -#define CMPL(x) __STRING(x), -#define CMPL0 "", -#endif /* !SMALL */ - -struct cmd cmdtab[] = { - { "!", shellhelp, 0, 0, 0, CMPL0 shell }, - { "$", domachelp, 1, 0, 0, CMPL0 domacro }, - { "account", accounthelp, 0, 1, 1, CMPL0 account}, - { "append", appendhelp, 1, 1, 1, CMPL(lr) put }, - { "ascii", asciihelp, 0, 1, 1, CMPL0 setascii }, - { "bell", beephelp, 0, 0, 0, CMPL0 setbell }, - { "binary", binaryhelp, 0, 1, 1, CMPL0 setbinary }, - { "bye", quithelp, 0, 0, 0, CMPL0 quit }, - { "case", casehelp, 0, 0, 1, CMPL0 setcase }, - { "cd", cdhelp, 0, 1, 1, CMPL(r) cd }, - { "cdup", cduphelp, 0, 1, 1, CMPL0 cdup }, - { "chmod", chmodhelp, 0, 1, 1, CMPL(nr) do_chmod }, - { "close", disconhelp, 0, 1, 1, CMPL0 disconnect }, - { "cr", crhelp, 0, 0, 0, CMPL0 setcr }, - { "debug", debughelp, 0, 0, 0, CMPL0 setdebug }, - { "delete", deletehelp, 0, 1, 1, CMPL(r) delete }, - { "dir", dirhelp, 1, 1, 1, CMPL(rl) ls }, - { "disconnect", disconhelp, 0, 1, 1, CMPL0 disconnect }, -#ifndef SMALL - { "edit", edithelp, 0, 0, 0, CMPL0 setedit }, -#endif /* !SMALL */ - { "exit", quithelp, 0, 0, 0, CMPL0 quit }, - { "form", formhelp, 0, 1, 1, CMPL0 setform }, - { "ftp", connecthelp, 0, 0, 1, CMPL0 setpeer }, - { "get", receivehelp, 1, 1, 1, CMPL(rl) get }, - { "gate", gatehelp, 0, 0, 0, CMPL0 setgate }, - { "glob", globhelp, 0, 0, 0, CMPL0 setglob }, - { "hash", hashhelp, 0, 0, 0, CMPL0 sethash }, - { "help", helphelp, 0, 0, 1, CMPL(C) help }, - { "idle", idlehelp, 0, 1, 1, CMPL0 idle }, - { "image", binaryhelp, 0, 1, 1, CMPL0 setbinary }, - { "lcd", lcdhelp, 0, 0, 0, CMPL(l) lcd }, - { "less", pagehelp, 1, 1, 1, CMPL(r) page }, - { "lpwd", lpwdhelp, 0, 0, 0, CMPL0 lpwd }, - { "ls", lshelp, 1, 1, 1, CMPL(rl) ls }, - { "macdef", macdefhelp, 0, 0, 0, CMPL0 macdef }, - { "mdelete", mdeletehelp, 1, 1, 1, CMPL(R) mdelete }, - { "mdir", mdirhelp, 1, 1, 1, CMPL(R) mls }, - { "mget", mgethelp, 1, 1, 1, CMPL(R) mget }, - { "mkdir", mkdirhelp, 0, 1, 1, CMPL(r) makedir }, - { "mls", mlshelp, 1, 1, 1, CMPL(R) mls }, - { "mode", modehelp, 0, 1, 1, CMPL0 setftmode }, - { "modtime", modtimehelp, 0, 1, 1, CMPL(r) modtime }, - { "more", pagehelp, 1, 1, 1, CMPL(r) page }, - { "mput", mputhelp, 1, 1, 1, CMPL(L) mput }, - { "msend", mputhelp, 1, 1, 1, CMPL(L) mput }, - { "newer", newerhelp, 1, 1, 1, CMPL(r) newer }, - { "nlist", nlisthelp, 1, 1, 1, CMPL(rl) ls }, - { "nmap", nmaphelp, 0, 0, 1, CMPL0 setnmap }, - { "ntrans", ntranshelp, 0, 0, 1, CMPL0 setntrans }, - { "open", connecthelp, 0, 0, 1, CMPL0 setpeer }, - { "page", pagehelp, 1, 1, 1, CMPL(r) page }, - { "passive", passivehelp, 0, 0, 0, CMPL0 setpassive }, - { "preserve", preservehelp, 0, 0, 0, CMPL0 setpreserve }, - { "progress", progresshelp, 0, 0, 0, CMPL0 setprogress }, - { "prompt", prompthelp, 0, 0, 0, CMPL0 setprompt }, - { "proxy", proxyhelp, 0, 0, 1, CMPL(c) doproxy }, - { "put", sendhelp, 1, 1, 1, CMPL(lr) put }, - { "pwd", pwdhelp, 0, 1, 1, CMPL0 pwd }, - { "quit", quithelp, 0, 0, 0, CMPL0 quit }, - { "quote", quotehelp, 1, 1, 1, CMPL0 quote }, - { "recv", receivehelp, 1, 1, 1, CMPL(rl) get }, - { "reget", regethelp, 1, 1, 1, CMPL(rl) reget }, - { "rename", renamehelp, 0, 1, 1, CMPL(rr) renamefile }, - { "reset", resethelp, 0, 1, 1, CMPL0 reset }, - { "restart", restarthelp, 1, 1, 1, CMPL0 restart }, - { "restrict", restricthelp, 0, 0, 0, CMPL0 setrestrict }, - { "rhelp", remotehelp, 0, 1, 1, CMPL0 rmthelp }, - { "rmdir", rmdirhelp, 0, 1, 1, CMPL(r) removedir }, - { "rstatus", rmtstatushelp, 0, 1, 1, CMPL(r) rmtstatus }, - { "runique", runiquehelp, 0, 0, 1, CMPL0 setrunique }, - { "send", sendhelp, 1, 1, 1, CMPL(lr) put }, - { "sendport", porthelp, 0, 0, 0, CMPL0 setport }, - { "site", sitehelp, 0, 1, 1, CMPL0 site }, - { "size", sizecmdhelp, 1, 1, 1, CMPL(r) sizecmd }, - { "status", statushelp, 0, 0, 1, CMPL0 status }, - { "struct", structhelp, 0, 1, 1, CMPL0 setstruct }, - { "sunique", suniquehelp, 0, 0, 1, CMPL0 setsunique }, - { "system", systemhelp, 0, 1, 1, CMPL0 syst }, - { "tenex", tenexhelp, 0, 1, 1, CMPL0 settenex }, - { "trace", tracehelp, 0, 0, 0, CMPL0 settrace }, - { "type", typehelp, 0, 1, 1, CMPL0 settype }, - { "umask", umaskhelp, 0, 1, 1, CMPL0 do_umask }, - { "user", userhelp, 0, 1, 1, CMPL0 user }, - { "verbose", verbosehelp, 0, 0, 0, CMPL0 setverbose }, - { "?", helphelp, 0, 0, 1, CMPL(C) help }, - { 0 }, -}; - -int NCMDS = (sizeof(cmdtab) / sizeof(cmdtab[0])) - 1; diff --git a/usr.bin/ftp/complete.c b/usr.bin/ftp/complete.c deleted file mode 100644 index 3125a5657455..000000000000 --- a/usr.bin/ftp/complete.c +++ /dev/null @@ -1,377 +0,0 @@ -/* $NetBSD: complete.c,v 1.11 1997/09/13 09:05:53 lukem Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Luke Mewburn. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#ifndef SMALL - -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: complete.c,v 1.11 1997/09/13 09:05:53 lukem Exp $"); -#endif /* not lint */ - -/* - * FTP user program - command and file completion routines - */ - -#include <sys/types.h> -#include <ctype.h> -#include <err.h> -#include <dirent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "ftp_var.h" - -static int -comparstr(a, b) - const void *a, *b; -{ - return (strcoll(*(char **)a, *(char **)b)); -} - -/* - * Determine if complete is ambiguous. If unique, insert. - * If no choices, error. If unambiguous prefix, insert that. - * Otherwise, list choices. words is assumed to be filtered - * to only contain possible choices. - * Args: - * word word which started the match - * list list by default - * words stringlist containing possible matches - */ -static unsigned char -complete_ambiguous(word, list, words) - char *word; - int list; - StringList *words; -{ - char insertstr[2 * MAXPATHLEN]; - char *lastmatch; - int i, j; - size_t matchlen, wordlen; - - wordlen = strlen(word); - if (words->sl_cur == 0) - return (CC_ERROR); /* no choices available */ - - if (words->sl_cur == 1) { /* only once choice available */ - for (i = 0, j = 0; words->sl_str[0][i] != '\0'; i++) { - if (isspace((u_char)words->sl_str[0][i])) - insertstr[j++] = '\\'; - insertstr[j++] = words->sl_str[0][i]; - } - insertstr[j] = '\0'; - if (el_insertstr(el, insertstr + wordlen) == -1) - return (CC_ERROR); - else - return (CC_REFRESH); - } - - if (!list) { - matchlen = 0; - lastmatch = words->sl_str[0]; - matchlen = strlen(lastmatch); - for (i = 1 ; i < words->sl_cur ; i++) { - for (j = wordlen ; j < strlen(words->sl_str[i]); j++) - if (lastmatch[j] != words->sl_str[i][j]) - break; - if (j < matchlen) - matchlen = j; - } - if (matchlen > wordlen) { - (void)strncpy(insertstr, lastmatch, matchlen); - insertstr[matchlen] = '\0'; - if (el_insertstr(el, insertstr + wordlen) == -1) - return (CC_ERROR); - else - /* - * XXX: really want CC_REFRESH_BEEP - */ - return (CC_REFRESH); - } - } - - putchar('\n'); - qsort(words->sl_str, words->sl_cur, sizeof(char *), comparstr); - list_vertical(words); - return (CC_REDISPLAY); -} - -/* - * Complete a command - */ -static unsigned char -complete_command(word, list) - char *word; - int list; -{ - struct cmd *c; - StringList *words; - size_t wordlen; - unsigned char rv; - - words = sl_init(); - wordlen = strlen(word); - - for (c = cmdtab; c->c_name != NULL; c++) { - if (wordlen > strlen(c->c_name)) - continue; - if (strncmp(word, c->c_name, wordlen) == 0) - sl_add(words, c->c_name); - } - - rv = complete_ambiguous(word, list, words); - sl_free(words, 0); - return (rv); -} - -/* - * Complete a local file - */ -static unsigned char -complete_local(word, list) - char *word; - int list; -{ - StringList *words; - char dir[MAXPATHLEN]; - char *file; - DIR *dd; - struct dirent *dp; - unsigned char rv; - - if ((file = strrchr(word, '/')) == NULL) { - dir[0] = '.'; - dir[1] = '\0'; - file = word; - } else { - if (file == word) { - dir[0] = '/'; - dir[1] = '\0'; - } else { - (void)strncpy(dir, word, file - word); - dir[file - word] = '\0'; - } - file++; - } - - if ((dd = opendir(dir)) == NULL) - return (CC_ERROR); - - words = sl_init(); - - for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - if (strlen(file) > dp->d_namlen) - continue; - if (strncmp(file, dp->d_name, strlen(file)) == 0) { - char *tcp; - - tcp = strdup(dp->d_name); - if (tcp == NULL) - errx(1, "Can't allocate memory for local dir"); - sl_add(words, tcp); - } - } - closedir(dd); - - rv = complete_ambiguous(file, list, words); - sl_free(words, 1); - return (rv); -} - -/* - * Complete a remote file - */ -static unsigned char -complete_remote(word, list) - char *word; - int list; -{ - static StringList *dirlist; - static char lastdir[MAXPATHLEN]; - StringList *words; - char dir[MAXPATHLEN]; - char *file, *cp; - int i; - unsigned char rv; - - char *dummyargv[] = { "complete", dir, NULL }; - - if ((file = strrchr(word, '/')) == NULL) { - dir[0] = '.'; - dir[1] = '\0'; - file = word; - } else { - cp = file; - while (*cp == '/' && cp > word) - cp--; - (void)strncpy(dir, word, cp - word + 1); - dir[cp - word + 1] = '\0'; - file++; - } - - if (dirchange || strcmp(dir, lastdir) != 0) { /* dir not cached */ - char *emesg; - - if (dirlist != NULL) - sl_free(dirlist, 1); - dirlist = sl_init(); - - mflag = 1; - emesg = NULL; - while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) { - char *tcp; - - if (!mflag) - continue; - if (*cp == '\0') { - mflag = 0; - continue; - } - tcp = strrchr(cp, '/'); - if (tcp) - tcp++; - else - tcp = cp; - tcp = strdup(tcp); - if (tcp == NULL) - errx(1, "Can't allocate memory for remote dir"); - sl_add(dirlist, tcp); - } - if (emesg != NULL) { - printf("\n%s\n", emesg); - return (CC_REDISPLAY); - } - (void)strcpy(lastdir, dir); - dirchange = 0; - } - - words = sl_init(); - for (i = 0; i < dirlist->sl_cur; i++) { - cp = dirlist->sl_str[i]; - if (strlen(file) > strlen(cp)) - continue; - if (strncmp(file, cp, strlen(file)) == 0) - sl_add(words, cp); - } - rv = complete_ambiguous(file, list, words); - sl_free(words, 0); - return (rv); -} - -/* - * Generic complete routine - */ -unsigned char -complete(el, ch) - EditLine *el; - int ch; -{ - static char word[FTPBUFLEN]; - static int lastc_argc, lastc_argo; - - struct cmd *c; - const LineInfo *lf; - int celems, dolist; - size_t len; - - lf = el_line(el); - len = lf->lastchar - lf->buffer; - if (len >= sizeof(line)) - return (CC_ERROR); - (void)strncpy(line, lf->buffer, len); - line[len] = '\0'; - cursor_pos = line + (lf->cursor - lf->buffer); - lastc_argc = cursor_argc; /* remember last cursor pos */ - lastc_argo = cursor_argo; - makeargv(); /* build argc/argv of current line */ - - if (cursor_argo >= sizeof(word)) - return (CC_ERROR); - - dolist = 0; - /* if cursor and word is same, list alternatives */ - if (lastc_argc == cursor_argc && lastc_argo == cursor_argo - && strncmp(word, margv[cursor_argc], cursor_argo) == 0) - dolist = 1; - else - (void)strncpy(word, margv[cursor_argc], cursor_argo); - word[cursor_argo] = '\0'; - - if (cursor_argc == 0) - return (complete_command(word, dolist)); - - c = getcmd(margv[0]); - if (c == (struct cmd *)-1 || c == 0) - return (CC_ERROR); - celems = strlen(c->c_complete); - - /* check for 'continuation' completes (which are uppercase) */ - if ((cursor_argc > celems) && (celems > 0) - && isupper((unsigned char)c->c_complete[celems-1])) - cursor_argc = celems; - - if (cursor_argc > celems) - return (CC_ERROR); - - switch (c->c_complete[cursor_argc - 1]) { - case 'l': /* local complete */ - case 'L': - return (complete_local(word, dolist)); - case 'r': /* remote complete */ - case 'R': - if (connected != -1) { - puts("\nMust be logged in to complete."); - return (CC_REDISPLAY); - } - return (complete_remote(word, dolist)); - case 'c': /* command complete */ - case 'C': - return (complete_command(word, dolist)); - case 'n': /* no complete */ - default: - return (CC_ERROR); - } - - return (CC_ERROR); -} - -#endif /* !SMALL */ diff --git a/usr.bin/ftp/domacro.c b/usr.bin/ftp/domacro.c deleted file mode 100644 index 448b9f020493..000000000000 --- a/usr.bin/ftp/domacro.c +++ /dev/null @@ -1,155 +0,0 @@ -/* $NetBSD: domacro.c,v 1.10 1997/07/20 09:45:45 lukem Exp $ */ - -/* - * Copyright (c) 1985, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: domacro.c,v 1.10 1997/07/20 09:45:45 lukem Exp $"); -#endif -#endif /* not lint */ - -#include <ctype.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> - -#include "ftp_var.h" - -void -domacro(argc, argv) - int argc; - char *argv[]; -{ - int i, j, count = 2, loopflg = 0; - char *cp1, *cp2, line2[200]; - struct cmd *c; - - if (argc < 2 && !another(&argc, &argv, "macro name")) { - printf("usage: %s macro_name\n", argv[0]); - code = -1; - return; - } - for (i = 0; i < macnum; ++i) { - if (!strncmp(argv[1], macros[i].mac_name, 9)) { - break; - } - } - if (i == macnum) { - printf("'%s' macro not found.\n", argv[1]); - code = -1; - return; - } - (void)strcpy(line2, line); -TOP: - cp1 = macros[i].mac_start; - while (cp1 != macros[i].mac_end) { - while (isascii(*cp1) && isspace(*cp1)) { - cp1++; - } - cp2 = line; - while (*cp1 != '\0') { - switch(*cp1) { - case '\\': - *cp2++ = *++cp1; - break; - case '$': - if (isdigit((unsigned char)*(cp1+1))) { - j = 0; - while (isdigit((unsigned char)*++cp1)) { - j = 10*j + *cp1 - '0'; - } - cp1--; - if (argc - 2 >= j) { - (void)strcpy(cp2, argv[j+1]); - cp2 += strlen(argv[j+1]); - } - break; - } - if (*(cp1+1) == 'i') { - loopflg = 1; - cp1++; - if (count < argc) { - (void)strcpy(cp2, argv[count]); - cp2 += strlen(argv[count]); - } - break; - } - /* intentional drop through */ - default: - *cp2++ = *cp1; - break; - } - if (*cp1 != '\0') { - cp1++; - } - } - *cp2 = '\0'; - makeargv(); - c = getcmd(margv[0]); - if (c == (struct cmd *)-1) { - puts("?Ambiguous command."); - code = -1; - } - else if (c == 0) { - puts("?Invalid command."); - code = -1; - } - else if (c->c_conn && !connected) { - puts("Not connected."); - code = -1; - } - else { - if (verbose) - puts(line); - (*c->c_handler)(margc, margv); - if (bell && c->c_bell) { - (void)putchar('\007'); - } - (void)strcpy(line, line2); - makeargv(); - argc = margc; - argv = margv; - } - if (cp1 != macros[i].mac_end) { - cp1++; - } - } - if (loopflg && ++count < argc) { - goto TOP; - } -} diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h deleted file mode 100644 index 54ccd79e812d..000000000000 --- a/usr.bin/ftp/extern.h +++ /dev/null @@ -1,176 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: extern.h,v 1.17.2.1 1997/11/18 00:59:50 mellon Exp $ */ - -/*- - * Copyright (c) 1994 The Regents of the University of California. - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)extern.h 8.3 (Berkeley) 10/9/94 - */ - -void abort_remote __P((FILE *)); -void abortpt __P((int)); -void abortrecv __P((int)); -void abortsend __P((int)); -void account __P((int, char **)); -void ai_unmapped __P((struct addrinfo *)); -void alarmtimer __P((int)); -int another __P((int *, char ***, const char *)); -int auto_fetch __P((int, char **)); -void blkfree __P((char **)); -void cd __P((int, char **)); -void cdup __P((int, char **)); -void changetype __P((int, int)); -void cmdabort __P((int)); -void cmdscanner __P((int)); -int command __P((const char *, ...)); -#ifndef SMALL -unsigned char complete __P((EditLine *, int)); -void controlediting __P((void)); -#endif /* !SMALL */ -int confirm __P((const char *, const char *)); -FILE *dataconn __P((const char *)); -void delete __P((int, char **)); -void disconnect __P((int, char **)); -void do_chmod __P((int, char **)); -void do_umask __P((int, char **)); -void domacro __P((int, char **)); -char *domap __P((char *)); -void doproxy __P((int, char **)); -char *dotrans __P((char *)); -int empty __P((fd_set *, int)); -void get __P((int, char **)); -struct cmd *getcmd __P((const char *)); -int getit __P((int, char **, int, const char *)); -int getreply __P((int)); -int globulize __P((char **)); -char *gunique __P((const char *)); -void help __P((int, char **)); -char *hookup __P((const char *, char *)); -void idle __P((int, char **)); -int initconn __P((void)); -void intr __P((void)); -int isipv6addr __P((const char *)); -void list_vertical __P((StringList *)); -void lcd __P((int, char **)); -int login __P((const char *, char *, char *)); -void lostpeer __P((void)); -void lpwd __P((int, char **)); -void ls __P((int, char **)); -void mabort __P((int)); -void macdef __P((int, char **)); -void makeargv __P((void)); -void makedir __P((int, char **)); -void mdelete __P((int, char **)); -void mget __P((int, char **)); -void mls __P((int, char **)); -void modtime __P((int, char **)); -void mput __P((int, char **)); -char *onoff __P((int)); -void newer __P((int, char **)); -void page __P((int, char **)); -void progressmeter __P((int)); -char *prompt __P((void)); -void proxabort __P((int)); -void proxtrans __P((const char *, const char *, const char *)); -void psabort __P((int)); -void psummary __P((int)); -void pswitch __P((int)); -void ptransfer __P((int)); -void put __P((int, char **)); -void pwd __P((int, char **)); -void quit __P((int, char **)); -void quote __P((int, char **)); -void quote1 __P((const char *, int, char **)); -void recvrequest __P((const char *, const char *, const char *, - const char *, int, int)); -void reget __P((int, char **)); -char *remglob __P((char **, int, char **)); -off_t remotesize __P((const char *, int)); -time_t remotemodtime __P((const char *, int)); -void removedir __P((int, char **)); -void renamefile __P((int, char **)); -void reset __P((int, char **)); -void restart __P((int, char **)); -void rmthelp __P((int, char **)); -void rmtstatus __P((int, char **)); -int ruserpass __P((const char *, char **, char **, char **)); -void sendrequest __P((const char *, const char *, const char *, int)); -void setascii __P((int, char **)); -void setbell __P((int, char **)); -void setbinary __P((int, char **)); -void setcase __P((int, char **)); -void setcr __P((int, char **)); -void setdebug __P((int, char **)); -void setedit __P((int, char **)); -void setform __P((int, char **)); -void setftmode __P((int, char **)); -void setgate __P((int, char **)); -void setglob __P((int, char **)); -void sethash __P((int, char **)); -void setnmap __P((int, char **)); -void setntrans __P((int, char **)); -void setpassive __P((int, char **)); -void setpeer __P((int, char **)); -void setport __P((int, char **)); -void setpreserve __P((int, char **)); -void setprogress __P((int, char **)); -void setprompt __P((int, char **)); -void setrestrict __P((int, char **)); -void setrunique __P((int, char **)); -void setstruct __P((int, char **)); -void setsunique __P((int, char **)); -void settenex __P((int, char **)); -void settrace __P((int, char **)); -void setttywidth __P((int)); -void settype __P((int, char **)); -void setverbose __P((int, char **)); -void shell __P((int, char **)); -void site __P((int, char **)); -void sizecmd __P((int, char **)); -char *slurpstring __P((void)); -void status __P((int, char **)); -void syst __P((int, char **)); -int togglevar __P((int, char **, int *, const char *)); -void usage __P((void)); -void user __P((int, char **)); - -extern struct cmd cmdtab[]; -extern FILE *cout; -extern int data; -extern char *home; -extern int family; -extern int proxy; -extern char reply_string[]; -extern int NCMDS; - -extern char *__progname; /* from crt0.o */ - diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c deleted file mode 100644 index 0c486af477e1..000000000000 --- a/usr.bin/ftp/fetch.c +++ /dev/null @@ -1,733 +0,0 @@ -/* $NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason Thorpe and Luke Mewburn. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: fetch.c,v 1.16.2.1 1997/11/18 01:00:22 mellon Exp $"); -#endif /* not lint */ - -/* - * FTP User Program -- Command line file retrieval - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> - -#include <arpa/ftp.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <vis.h> - -#include "ftp_var.h" - -/* wrapper for KAME-special getnameinfo() */ -#ifndef NI_WITHSCOPEID -#define NI_WITHSCOPEID 0 -#endif - -static int url_get __P((const char *, const char *)); -void aborthttp __P((int)); - - -#define FTP_URL "ftp://" /* ftp URL prefix */ -#define HTTP_URL "http://" /* http URL prefix */ -#define FTP_PROXY "ftp_proxy" /* env var with ftp proxy location */ -#define HTTP_PROXY "http_proxy" /* env var with http proxy location */ - - -#define EMPTYSTRING(x) ((x) == NULL || (*(x) == '\0')) - -jmp_buf httpabort; - -/* - * Retrieve URL, via the proxy in $proxyvar if necessary. - * Modifies the string argument given. - * Returns -1 on failure, 0 on success - */ -static int -url_get(origline, proxyenv) - const char *origline; - const char *proxyenv; -{ - struct addrinfo hints; - struct addrinfo *res0, *res; - char nameinfo[2 * INET6_ADDRSTRLEN + 1]; - int i, out, isftpurl; - char *port; - volatile int s; - size_t len; - char c, *cp, *ep, *http_buffer, *portnum, *path, *uri, buf[4096]; - const char *savefile; - char *line, *proxy, *host; - volatile sig_t oldintr; - off_t hashbytes; - int error; - - s = -1; - proxy = NULL; - isftpurl = 0; - res0 = NULL; - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&savefile; - (void)&proxy; - (void)&res0; -#endif - - line = strdup(origline); - if (line == NULL) - errx(1, "Can't allocate memory to parse URL"); - if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) - host = line + sizeof(HTTP_URL) - 1; - else if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { - host = line + sizeof(FTP_URL) - 1; - isftpurl = 1; - } else - errx(1, "url_get: Invalid URL '%s'", line); - - path = strchr(host, '/'); /* find path */ - if (EMPTYSTRING(path)) { - if (isftpurl) - goto noftpautologin; - warnx("Invalid URL (no `/' after host): %s", origline); - goto cleanup_url_get; - } - *path++ = '\0'; - if (EMPTYSTRING(path)) { - if (isftpurl) - goto noftpautologin; - warnx("Invalid URL (no file after host): %s", origline); - goto cleanup_url_get; - } - - savefile = strrchr(path, '/'); /* find savefile */ - if (savefile != NULL) - savefile++; - else - savefile = path; - if (EMPTYSTRING(savefile)) { - if (isftpurl) - goto noftpautologin; - warnx("Invalid URL (no file after directory): %s", origline); - goto cleanup_url_get; - } - - uri = (char *) calloc(strlen(path) * 4 + 1, sizeof(char)); - if (uri == NULL) - errx(1, "Can't allocate memory for URI."); - strvisx(uri, path, strlen(path), VIS_HTTPSTYLE); - - if (proxyenv != NULL) { /* use proxy */ - proxy = strdup(proxyenv); - if (proxy == NULL) - errx(1, "Can't allocate memory for proxy URL."); - if (strncasecmp(proxy, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) - host = proxy + sizeof(HTTP_URL) - 1; - else if (strncasecmp(proxy, FTP_URL, sizeof(FTP_URL) - 1) == 0) - host = proxy + sizeof(FTP_URL) - 1; - else { - warnx("Malformed proxy URL: %s", proxyenv); - goto cleanup_url_get; - } - if (EMPTYSTRING(host)) { - warnx("Malformed proxy URL: %s", proxyenv); - goto cleanup_url_get; - } - *--path = '/'; /* add / back to real path */ - path = strchr(host, '/'); /* remove trailing / on host */ - if (! EMPTYSTRING(path)) - *path++ = '\0'; - path = line; - } - - if (*host == '[' && (portnum = strrchr(host, ']'))) { /* IPv6 URL */ - *portnum++ = '\0'; - host++; - if (*portnum == ':') - portnum++; - else - portnum = NULL; - } else { - portnum = strrchr(host, ':'); /* find portnum */ - if (portnum != NULL) - *portnum++ = '\0'; - } - - if (debug) - printf("host %s, port %s, path %s, save as %s.\n", - host, portnum, uri, savefile); - - if (! EMPTYSTRING(portnum)) { - port = portnum; - } else - port = httpport; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - error = getaddrinfo(host, port, &hints, &res); - res0 = res; - if (error) { - warnx("%s: %s", host, gai_strerror(error)); - if (error == EAI_SYSTEM) - warnx("%s: %s", host, strerror(errno)); - goto cleanup_url_get; - } - - while (1) - { - ai_unmapped(res); - s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s == -1) { - res = res->ai_next; - if (res) - continue; - warn("Can't create socket"); - goto cleanup_url_get; - } - - if (dobind) { - struct addrinfo *bindres; - int binderr = -1; - - for (bindres = bindres0; - bindres != NULL; - bindres = bindres->ai_next) - if (bindres->ai_family == res->ai_family) - break; - if (bindres == NULL) - bindres = bindres0; - binderr = bind(s, bindres->ai_addr, bindres->ai_addrlen); - if (binderr == -1) - { - res = res->ai_next; - if (res) { - (void)close(s); - continue; - } - getnameinfo(bindres->ai_addr, bindres->ai_addrlen, - nameinfo, sizeof(nameinfo), NULL, 0, - NI_NUMERICHOST|NI_WITHSCOPEID); - /* XXX check error? */ - warn("Can't bind to %s", nameinfo); - goto cleanup_url_get; - } - } - - if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { - res = res->ai_next; - if (res) { - (void)close(s); - continue; - } - warn("Can't connect to %s", host); - goto cleanup_url_get; - } - - break; - } - freeaddrinfo(res0); - res0 = NULL; - - /* - * Construct and send the request. We're expecting a return - * status of "200". Proxy requests don't want leading /. - */ - if (!proxy) { - printf("Requesting %s\n", origline); - len = asprintf(&http_buffer, - "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", uri, host); - } else { - printf("Requesting %s (via %s)\n", origline, proxyenv); - len = asprintf(&http_buffer, - "GET %s HTTP/1.0\r\n\r\n", path); - } - free(uri); - if (len < 0) { - warnx("Failed to format HTTP request"); - goto cleanup_url_get; - } - if (write(s, http_buffer, len) < len) { - warn("Writing HTTP request"); - free(http_buffer); - goto cleanup_url_get; - } - free(http_buffer); - memset(buf, 0, sizeof(buf)); - for (cp = buf; cp < buf + sizeof(buf); ) { - if (read(s, cp, 1) != 1) - goto improper; - if (*cp == '\r') - continue; - if (*cp == '\n') - break; - cp++; - } - buf[sizeof(buf) - 1] = '\0'; /* sanity */ - cp = strchr(buf, ' '); - if (cp == NULL) - goto improper; - else - cp++; - if (strncmp(cp, "200", 3)) { - warnx("Error retrieving file: %s", cp); - goto cleanup_url_get; - } - - /* - * Read the rest of the header. - */ - memset(buf, 0, sizeof(buf)); - c = '\0'; - for (cp = buf; cp < buf + sizeof(buf); ) { - if (read(s, cp, 1) != 1) - goto improper; - if (*cp == '\r') - continue; - if (*cp == '\n' && c == '\n') - break; - c = *cp; - cp++; - } - buf[sizeof(buf) - 1] = '\0'; /* sanity */ - - /* - * Look for the "Content-length: " header. - */ -#define CONTENTLEN "Content-Length: " - for (cp = buf; *cp != '\0'; cp++) { - if (tolower((unsigned char)*cp) == 'c' && - strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0) - break; - } - if (*cp != '\0') { - cp += sizeof(CONTENTLEN) - 1; - ep = strchr(cp, '\n'); - if (ep == NULL) - goto improper; - else - *ep = '\0'; - filesize = strtoll(cp, &ep, 10); - if (filesize < 1 || *ep != '\0') - goto improper; - } else - filesize = -1; - - /* Open the output file. */ - out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (out < 0) { - warn("Can't open %s", savefile); - goto cleanup_url_get; - } - - /* Trap signals */ - oldintr = NULL; - if (setjmp(httpabort)) { - if (oldintr) - (void)signal(SIGINT, oldintr); - goto cleanup_url_get; - } - oldintr = signal(SIGINT, aborthttp); - - bytes = 0; - hashbytes = mark; - progressmeter(-1); - - /* Finally, suck down the file. */ - i = 0; - while ((len = read(s, buf, sizeof(buf))) > 0) { - bytes += len; - for (cp = buf; len > 0; len -= i, cp += i) { - if ((i = write(out, cp, len)) == -1) { - warn("Writing %s", savefile); - goto cleanup_url_get; - } - else if (i == 0) - break; - } - if (hash && !progress) { - while (bytes >= hashbytes) { - (void)putchar('#'); - hashbytes += mark; - } - (void)fflush(stdout); - } - } - if (hash && !progress && bytes > 0) { - if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); - } - if (len != 0) { - warn("Reading from socket"); - goto cleanup_url_get; - } - progressmeter(1); - if (verbose) - puts("Successfully retrieved file."); - (void)signal(SIGINT, oldintr); - - close(s); - close(out); - if (proxy) - free(proxy); - free(line); - return (0); - -noftpautologin: - warnx( - "Auto-login using ftp URLs isn't supported when using $ftp_proxy"); - goto cleanup_url_get; - -improper: - warnx("Improper response from %s", host); - -cleanup_url_get: - if (s != -1) - close(s); - if (proxy) - free(proxy); - free(line); - if (res0 != NULL) - freeaddrinfo(res0); - return (-1); -} - -/* - * Abort a http retrieval - */ -void -aborthttp(notused) - int notused; -{ - - alarmtimer(0); - puts("\nhttp fetch aborted."); - (void)fflush(stdout); - longjmp(httpabort, 1); -} - -/* - * Retrieve multiple files from the command line, transferring - * files of the form "host:path", "ftp://host/path" using the - * ftp protocol, and files of the form "http://host/path" using - * the http protocol. - * If path has a trailing "/", then return (-1); - * the path will be cd-ed into and the connection remains open, - * and the function will return -1 (to indicate the connection - * is alive). - * If an error occurs the return value will be the offset+1 in - * argv[] of the file that caused a problem (i.e, argv[x] - * returns x+1) - * Otherwise, 0 is returned if all files retrieved successfully. - */ -int -auto_fetch(argc, argv) - int argc; - char *argv[]; -{ - static char lasthost[MAXHOSTNAMELEN]; - char *xargv[5]; - char *cp, *line, *host, *dir, *file, *portnum; - char *user, *pass; - char *ftpproxy, *httpproxy; - int rval, xargc; - volatile int argpos; - int dirhasglob, filehasglob; - char rempath[MAXPATHLEN]; - - argpos = 0; - - if (setjmp(toplevel)) { - if (connected) - disconnect(0, NULL); - return (argpos + 1); - } - (void)signal(SIGINT, (sig_t)intr); - (void)signal(SIGPIPE, (sig_t)lostpeer); - - ftpproxy = getenv(FTP_PROXY); - httpproxy = getenv(HTTP_PROXY); - - /* - * Loop through as long as there's files to fetch. - */ - for (rval = 0; (rval == 0) && (argpos < argc); free(line), argpos++) { - if (strchr(argv[argpos], ':') == NULL) - break; - host = dir = file = portnum = user = pass = NULL; - - /* - * We muck with the string, so we make a copy. - */ - line = strdup(argv[argpos]); - if (line == NULL) - errx(1, "Can't allocate memory for auto-fetch."); - - /* - * Try HTTP URL-style arguments first. - */ - if (strncasecmp(line, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { - if (url_get(line, httpproxy) == -1) - rval = argpos + 1; - continue; - } - - /* - * Try FTP URL-style arguments next. If ftpproxy is - * set, use url_get() instead of standard ftp. - * Finally, try host:file. - */ - host = line; - if (strncasecmp(line, FTP_URL, sizeof(FTP_URL) - 1) == 0) { - if (ftpproxy) { - if (url_get(line, ftpproxy) == -1) - rval = argpos + 1; - continue; - } - host += sizeof(FTP_URL) - 1; - dir = strchr(host, '/'); - - /* look for [user:pass@]host[:port] */ - pass = strpbrk(host, ":@/"); - if (pass == NULL || *pass == '/') { - pass = NULL; - goto parsed_url; - } - if (pass == host || *pass == '@') { -bad_ftp_url: - warnx("Invalid URL: %s", argv[argpos]); - rval = argpos + 1; - continue; - } - *pass++ = '\0'; - cp = strpbrk(pass, ":@/"); - if (cp == NULL || *cp == '/') { - portnum = pass; - pass = NULL; - goto parsed_url; - } - if (EMPTYSTRING(cp) || *cp == ':') - goto bad_ftp_url; - *cp++ = '\0'; - user = host; - if (EMPTYSTRING(user)) - goto bad_ftp_url; - host = cp; - portnum = strchr(host, ':'); - if (portnum != NULL) - *portnum++ = '\0'; - } else { /* classic style `host:file' */ - char *end_brace; - - if (*host == '[' && - (end_brace = strrchr(host, ']')) != NULL) { - /*IPv6 addr in []*/ - host++; - *end_brace = '\0'; - dir = strchr(end_brace + 1, ':'); - } else - dir = strchr(host, ':'); - } -parsed_url: - if (EMPTYSTRING(host)) { - rval = argpos + 1; - continue; - } - - /* - * If dir is NULL, the file wasn't specified - * (URL looked something like ftp://host) - */ - if (dir != NULL) - *dir++ = '\0'; - - /* - * Extract the file and (if present) directory name. - */ - if (! EMPTYSTRING(dir)) { - cp = strrchr(dir, '/'); - if (cp != NULL) { - *cp++ = '\0'; - file = cp; - } else { - file = dir; - dir = NULL; - } - } - if (debug) - printf("user %s:%s host %s port %s dir %s file %s\n", - user, pass, host, portnum, dir, file); - - /* - * Set up the connection if we don't have one. - */ - if (strcmp(host, lasthost) != 0) { - int oautologin; - - (void)strcpy(lasthost, host); - if (connected) - disconnect(0, NULL); - xargv[0] = __progname; - xargv[1] = host; - xargv[2] = NULL; - xargc = 2; - if (! EMPTYSTRING(portnum)) { - xargv[2] = portnum; - xargv[3] = NULL; - xargc = 3; - } - oautologin = autologin; - if (user != NULL) - autologin = 0; - setpeer(xargc, xargv); - autologin = oautologin; - if ((connected == 0) - || ((connected == 1) && !login(host, user, pass)) ) { - warnx("Can't connect or login to host `%s'", - host); - rval = argpos + 1; - continue; - } - - /* Always use binary transfers. */ - setbinary(0, NULL); - } - /* cd back to '/' */ - xargv[0] = "cd"; - xargv[1] = "/"; - xargv[2] = NULL; - cd(2, xargv); - if (! dirchange) { - rval = argpos + 1; - continue; - } - - dirhasglob = filehasglob = 0; - if (doglob) { - if (! EMPTYSTRING(dir) && - strpbrk(dir, "*?[]{}") != NULL) - dirhasglob = 1; - if (! EMPTYSTRING(file) && - strpbrk(file, "*?[]{}") != NULL) - filehasglob = 1; - } - - /* Change directories, if necessary. */ - if (! EMPTYSTRING(dir) && !dirhasglob) { - xargv[0] = "cd"; - xargv[1] = dir; - xargv[2] = NULL; - cd(2, xargv); - if (! dirchange) { - rval = argpos + 1; - continue; - } - } - - if (EMPTYSTRING(file)) { - rval = -1; - continue; - } - - if (!verbose) - printf("Retrieving %s/%s\n", dir ? dir : "", file); - - if (dirhasglob) { - snprintf(rempath, sizeof(rempath), "%s/%s", dir, file); - file = rempath; - } - - /* Fetch the file(s). */ - xargv[0] = "get"; - xargv[1] = file; - xargv[2] = NULL; - if (dirhasglob || filehasglob) { - int ointeractive; - - ointeractive = interactive; - interactive = 0; - xargv[0] = "mget"; - mget(2, xargv); - interactive = ointeractive; - } else - get(2, xargv); - - if ((code / 100) != COMPLETE) - rval = argpos + 1; - } - if (connected && rval != -1) - disconnect(0, NULL); - return (rval); -} - -int -isurl(p) - const char *p; -{ - char *path, pton_buf[16]; - - if (strncasecmp(p, FTP_URL, sizeof(FTP_URL) - 1) == 0 - || strncasecmp(p, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) { - return 1; - } - if (*p == '[' && (path = strrchr(p, ']')) != NULL) /*IPv6 addr in []*/ - return (*(++path) == ':') ? 1 : 0; -#ifdef INET6 - if (inet_pton(AF_INET6, p, pton_buf) == 1) /* raw IPv6 addr */ - return 0; -#endif - if (strchr(p, ':') != NULL) /* else, if ':' exist */ - return 1; - return 0; -} diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1 deleted file mode 100644 index eac321020846..000000000000 --- a/usr.bin/ftp/ftp.1 +++ /dev/null @@ -1,1456 +0,0 @@ -.\" $FreeBSD$ -.\" $NetBSD: ftp.1,v 1.21 1997/06/10 21:59:58 lukem Exp $ -.\" -.\" Copyright (c) 1985, 1989, 1990, 1993 -.\" The Regents of the University of California. 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. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. -.\" -.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94 -.\" -.Dd January 27, 2000 -.Dt FTP 1 -.Os -.Sh NAME -.Nm ftp , pftp , gate-ftp -.Nd -.Tn ARPANET -file transfer program -.Sh SYNOPSIS -.Nm -.Op Fl 46adeginptUvV -.Op Fl P Ar port -.Op Fl s Ar src_addr -.Op Ar host Op Ar port -.Nm -ftp://[\fIuser\fR:\fIpassword\fR@]\fIhost\fR[:\fIport\fR]/\fIfile\fR[/] -.Nm -http://\fIhost\fR[:\fIport\fR]/\fIfile\fR -.Nm -\fIhost\fR:[/\fIpath\fR/]\fIfile\fR[/] -.Sh DESCRIPTION -.Nm -is the user interface to the -.Tn ARPANET -standard File Transfer Protocol. -The program allows a user to transfer files to and from a -remote network site. -The version supports IPv6 (Internet protocol version 6), as well as IPv4. -.Pp -The latter three usage formats will fetch a file using either the -HTTP or FTP protocols into the current directory. -This is ideal for scripts. -Refer to -.Sx AUTO-FETCHING FILES -below for more information. -.Pp -Options may be specified at the command line, or to the -command interpreter. -.Bl -tag -width Fl -.It Fl 4 -Forces -.Nm -to use IPv4 addresses only. -.It Fl 6 -Forces -.Nm -to use IPv6 addresses only. -.It Fl a -Causes -.Nm -to bypass normal login procedure, and use an anonymous login instead. -.It Fl d -Enables debugging. -.It Fl e -Disables command line editing. -.It Fl g -Disables file name globbing. -.It Fl i -Turns off interactive prompting during -multiple file transfers. -.It Fl n -Restrains -.Nm -from attempting -.Dq auto-login -upon initial connection. -If auto-login is enabled, -.Nm -will check the -.Pa .netrc -(see below) file in the user's home directory for an entry describing -an account on the remote machine. -If no entry exists, -.Nm -will prompt for the remote machine login name (default is the user -identity on the local machine), and, if necessary, prompt for a password -and an account with which to login. -.It Fl p -Enables passive mode operation for use behind connection filtering firewalls. -Using the -.Nm pftp -command has the same effect. -.It Fl P Ar port -Sets the port number to -.Ar port . -.It Fl s Ar src_addr -Sets the local IP address for all connections to -.Ar src_addr , -which can be an IP address or a host name. -.It Fl t -Enables packet tracing. -.It Fl U -Disable data port range restrictions. -.It Fl v -Enable verbose mode. -This is the default if input is from a terminal. -Forces -.Nm -to show all responses from the remote server, as well -as report on data transfer statistics. -.It Fl V -Disable verbose mode, overriding the default of enabled when input -is from a terminal. -.El -.Pp -The client host with which -.Nm -is to communicate may be specified on the command line. -If this is done, -.Nm -will immediately attempt to establish a connection to an -.Tn FTP -server on that host; otherwise, -.Nm -will enter its command interpreter and await instructions -from the user. -When -.Nm -is awaiting commands from the user the prompt -.Ql ftp> -is provided to the user. -The following commands are recognized -by -.Nm : -.Bl -tag -width Fl -.It Ic \&! Op Ar command Op Ar args -Invoke an interactive shell on the local machine. -If there are arguments, the first is taken to be a command to execute -directly, with the rest of the arguments as its arguments. -.It Ic \&$ Ar macro-name Op Ar args -Execute the macro -.Ar macro-name -that was defined with the -.Ic macdef -command. -Arguments are passed to the macro unglobbed. -.It Ic account Op Ar passwd -Supply a supplemental password required by a remote system for access -to resources once a login has been successfully completed. -If no argument is included, the user will be prompted for an account -password in a non-echoing input mode. -.It Ic append Ar local-file Op Ar remote-file -Append a local file to a file on the remote machine. -If -.Ar remote-file -is left unspecified, the local file name is used in naming the -remote file after being altered by any -.Ic ntrans -or -.Ic nmap -setting. -File transfer uses the current settings for -.Ic type , -.Ic format , -.Ic mode -and -.Ic structure . -.It Ic ascii -Set the file transfer -.Ic type -to network -.Tn ASCII . -This is the default type. -.It Ic bell -Arrange that a bell be sounded after each file transfer -command is completed. -.It Ic binary -Set the file transfer -.Ic type -to support binary image transfer. -.It Ic bye -Terminate the -.Tn FTP -session with the remote server -and exit -.Nm . -An end of file will also terminate the session and exit. -.It Ic case -Toggle remote computer file name case mapping during -.Ic mget -commands. -When -.Ic case -is on (default is off), remote computer file names with all letters in -upper case are written in the local directory with the letters mapped -to lower case. -.It Ic \&cd Ar remote-directory -Change the working directory on the remote machine -to -.Ar remote-directory . -.It Ic cdup -Change the remote machine working directory to the parent of the -current remote machine working directory. -.It Ic chmod Ar mode file-name -Change the permission modes of the file -.Ar file-name -on the remote -system to -.Ar mode . -.It Ic close -Terminate the -.Tn FTP -session with the remote server, and -return to the command interpreter. -Any defined macros are erased. -.It Ic \&cr -Toggle carriage return stripping during -ascii type file retrieval. -Records are denoted by a carriage return/linefeed sequence -during ascii type file transfer. -When -.Ic \&cr -is on (the default), carriage returns are stripped from this -sequence to conform with the -.Ux -single linefeed record -delimiter. -Records on -.Pf non\- Ns Ux -remote systems may contain single linefeeds; -when an ascii type transfer is made, these linefeeds may be -distinguished from a record delimiter only when -.Ic \&cr -is off. -.It Ic delete Ar remote-file -Delete the file -.Ar remote-file -on the remote machine. -.It Ic debug Op Ar debug-value -Toggle debugging mode. -If an optional -.Ar debug-value -is specified, it is used to set the debugging level. -When debugging is on, -.Nm -prints each command sent to the remote machine, preceded -by the string -.Ql \-\-> -.It Ic dir Op Ar remote-directory Op Ar local-file -Print a listing of the contents of a -directory on the remote machine. -The listing includes any system-dependent information that the server -chooses to include; for example, most -.Ux -systems will produce -output from the command -.Ql ls \-l . -(See also -.Ic ls . ) -If -.Ar remote-directory -is left unspecified, the current working directory is used. -If interactive prompting is on, -.Nm -will prompt the user to verify that the last argument is indeed the -target local file for receiving -.Ic dir -output. -If no local file is specified, or if -.Ar local-file -is -.Sq Fl , -the output is sent to the terminal. -.Pp -As this command provides extra information which is system-dependent, -you should use the -.Ic nlist -command instead if you only want a plain list of files. -.It Ic disconnect -A synonym for -.Ic close . -.It Ic edit -Toggle command line editing, and context sensitive command and file -completion. -This is automatically enabled if input is from a terminal, and -disabled otherwise. -.It Ic exit -A synonym for -.Ic bye . -.It Ic ftp Ar host Op Ar port -A synonym for -.Ic open . -.It Ic form Ar format -Set the file transfer -.Ic form -to -.Ar format . -The default format is \*(Lqfile\*(Rq. -.It Ic get Ar remote-file Op Ar local-file -Retrieve the -.Ar remote-file -and store it on the local machine. -If the local -file name is not specified, it is given the same -name it has on the remote machine, subject to -alteration by the current -.Ic case , -.Ic ntrans -and -.Ic nmap -settings. -The current settings for -.Ic type , -.Ic form , -.Ic mode -and -.Ic structure -are used while transferring the file. -.It Ic gate Op Ar host Op Ar port -Toggle gate-ftp mode. -This will not be permitted if the gate-ftp server hasn't been set -(either explicitly by the user, or from the -.Ev FTPSERVER -environment variable). -If -.Ar host -is given, -then gate-ftp mode will be enabled, and the gate-ftp server will be set to -.Ar host . -If -.Ar port -is also given, that will be used as the port to connect to on the -gate-ftp server. -.It Ic glob -Toggle filename expansion for -.Ic mdelete , -.Ic mget -and -.Ic mput . -If globbing is turned off with -.Ic glob , -the file name arguments -are taken literally and not expanded. -Globbing for -.Ic mput -is done as in -.Xr csh 1 . -For -.Ic mdelete -and -.Ic mget , -each remote file name is expanded -separately on the remote machine and the lists are not merged. -Expansion of a directory name is likely to be -different from expansion of the name of an ordinary file: -the exact result depends on the foreign operating system and ftp server, -and can be previewed by doing -.Ql mls remote-files \- -Note: -.Ic mget -and -.Ic mput -are not meant to transfer -entire directory subtrees of files. -That can be done by -transferring a -.Xr tar 1 -archive of the subtree (in binary mode). -.It Ic hash Op Ar size -Toggle hash-sign (``#'') printing for each data block -transferred. -The size of a data block defaults to 1024 bytes. -This can be changed by specifying -.Ar size -in bytes. -.It Ic help Op Ar command -Print an informative message about the meaning of -.Ar command . -If no argument is given, -.Nm -prints a list of the known commands. -.It Ic idle Op Ar seconds -Set the inactivity timer on the remote server to -.Ar seconds -seconds. -If -.Ar seconds -is omitted, the current inactivity timer is printed. -.It Ic lcd Op Ar directory -Change the working directory on the local machine. -If -no -.Ar directory -is specified, the user's home directory is used. -.It Ic less Ar file -A synonym for -.Ic page . -.It Ic lpwd -Print the working directory on the local machine. -.It Ic \&ls Op Ar remote-directory Op Ar local-file -A synonym for -.Ic dir . -.It Ic macdef Ar macro-name -Define a macro. -Subsequent lines are stored as the macro -.Ar macro-name ; -a null line (consecutive newline characters -in a file or -carriage returns from the terminal) terminates macro input mode. -There is a limit of 16 macros and 4096 total characters in all -defined macros. -Macros remain defined until a -.Ic close -command is executed. -The macro processor interprets `$' and `\e' as special characters. -A `$' followed by a number (or numbers) is replaced by the -corresponding argument on the macro invocation command line. -A `$' followed by an `i' signals that macro processor that the -executing macro is to be looped. -On the first pass `$i' is -replaced by the first argument on the macro invocation command line, -on the second pass it is replaced by the second argument, and so on. -A `\e' followed by any character is replaced by that character. -Use the `\e' to prevent special treatment of the `$'. -.It Ic mdelete Op Ar remote-files -Delete the -.Ar remote-files -on the remote machine. -.It Ic mdir Ar remote-files local-file -Like -.Ic dir , -except multiple remote files may be specified. -If interactive prompting is on, -.Nm -will prompt the user to verify that the last argument is indeed the -target local file for receiving -.Ic mdir -output. -.It Ic mget Ar remote-files -Expand the -.Ar remote-files -on the remote machine -and do a -.Ic get -for each file name thus produced. -See -.Ic glob -for details on the filename expansion. -Resulting file names will then be processed according to -.Ic case , -.Ic ntrans -and -.Ic nmap -settings. -Files are transferred into the local working directory, -which can be changed with -.Ql lcd directory ; -new local directories can be created with -.Ql "\&! mkdir directory" . -.It Ic mkdir Ar directory-name -Make a directory on the remote machine. -.It Ic mls Ar remote-files local-file -Like -.Ic ls , -except multiple remote files may be specified, -and the -.Ar local-file -must be specified. -If interactive prompting is on, -.Nm -will prompt the user to verify that the last argument is indeed the -target local file for receiving -.Ic mls -output. -.It Ic mode Op Ar mode-name -Set the file transfer -.Ic mode -to -.Ar mode-name . -The default mode is \*(Lqstream\*(Rq mode. -.It Ic modtime Ar file-name -Show the last modification time of the file on the remote machine. -.It Ic more Ar file -A synonym for -.Ic page . -.It Ic mput Ar local-files -Expand wild cards in the list of local files given as arguments -and do a -.Ic put -for each file in the resulting list. -See -.Ic glob -for details of filename expansion. -Resulting file names will then be processed according to -.Ic ntrans -and -.Ic nmap -settings. -.It Ic msend Ar local-files -A synonym for -.Ic mput . -.It Ic newer Ar file-name -Get the file only if the modification time of the remote file is more -recent that the file on the current system. -If the file does not -exist on the current system, the remote file is considered -.Ic newer . -Otherwise, this command is identical to -.Ar get . -.It Ic nlist Op Ar remote-directory Op Ar local-file -Print a list of the files in a -directory on the remote machine. -If -.Ar remote-directory -is left unspecified, the current working directory is used. -If interactive prompting is on, -.Nm -will prompt the user to verify that the last argument is indeed the -target local file for receiving -.Ic ls -output. -If no local file is specified, or if -.Ar local-file -is -.Fl , -the output is sent to the terminal. -.Pp -Note that this command only returns the filenames in the remote -directory. If you wish to see more information about the files (often -size, modification time, and so on), -you should use the -.Ic dir -command instead. -.It Ic nmap Op Ar inpattern outpattern -Set or unset the filename mapping mechanism. -If no arguments are specified, the filename mapping mechanism is unset. -If arguments are specified, remote filenames are mapped during -.Ic mput -commands and -.Ic put -commands issued without a specified remote target filename. -If arguments are specified, local filenames are mapped during -.Ic mget -commands and -.Ic get -commands issued without a specified local target filename. -This command is useful when connecting to a -.No non\- Ns Ux -remote computer -with different file naming conventions or practices. -The mapping follows the pattern set by -.Ar inpattern -and -.Ar outpattern . -.Op Ar Inpattern -is a template for incoming filenames (which may have already been -processed according to the -.Ic ntrans -and -.Ic case -settings). -Variable templating is accomplished by including the -sequences `$1', `$2', ..., `$9' in -.Ar inpattern . -Use `\\' to prevent this special treatment of the `$' character. -All other characters are treated literally, and are used to determine the -.Ic nmap -.Op Ar inpattern -variable values. -For example, given -.Ar inpattern -$1.$2 and the remote file name "mydata.data", $1 would have the value -"mydata", and $2 would have the value "data". -The -.Ar outpattern -determines the resulting mapped filename. -The sequences `$1', `$2', ...., `$9' are replaced by any value resulting -from the -.Ar inpattern -template. -The sequence `$0' is replace by the original filename. -Additionally, the sequence -.Ql Op Ar seq1 , Ar seq2 -is replaced by -.Op Ar seq1 -if -.Ar seq1 -is not a null string; otherwise it is replaced by -.Ar seq2 . -For example, the command -.Pp -.Bd -literal -offset indent -compact -nmap $1.$2.$3 [$1,$2].[$2,file] -.Ed -.Pp -would yield -the output filename "myfile.data" for input filenames "myfile.data" and -"myfile.data.old", "myfile.file" for the input filename "myfile", and -"myfile.myfile" for the input filename ".myfile". -Spaces may be included in -.Ar outpattern , -as in the example: `nmap $1 sed "s/ *$//" > $1' . -Use the `\e' character to prevent special treatment -of the `$','[',']' and `,' characters. -.It Ic ntrans Op Ar inchars Op Ar outchars -Set or unset the filename character translation mechanism. -If no arguments are specified, the filename character -translation mechanism is unset. -If arguments are specified, characters in -remote filenames are translated during -.Ic mput -commands and -.Ic put -commands issued without a specified remote target filename. -If arguments are specified, characters in -local filenames are translated during -.Ic mget -commands and -.Ic get -commands issued without a specified local target filename. -This command is useful when connecting to a -.No non\- Ns Ux -remote computer -with different file naming conventions or practices. -Characters in a filename matching a character in -.Ar inchars -are replaced with the corresponding character in -.Ar outchars . -If the character's position in -.Ar inchars -is longer than the length of -.Ar outchars , -the character is deleted from the file name. -.It Ic open Ar host Op Ar port -Establish a connection to the specified -.Ar host -.Tn FTP -server. -An optional port number may be supplied, -in which case, -.Nm -will attempt to contact an -.Tn FTP -server at that port. -If the -.Ic auto-login -option is on (default), -.Nm -will also attempt to automatically log the user in to -the -.Tn FTP -server (see below). -.It Ic page Ar file -Retrieve -.Ic file -and display with the program defined in -.Ev PAGER -(which defaults to -.Xr more 1 ) . -.It Ic passive -Toggle passive mode. If passive mode is turned on -(default is off), the ftp client will -send a -.Dv PASV -command for all data connections instead of the usual -.Dv PORT -command. The -.Dv PASV -command requests that the remote server open a port for the data connection -and return the address of that port. The remote server listens on that -port and the client connects to it. When using the more traditional -.Dv PORT -command, the client listens on a port and sends that address to the remote -server, who connects back to it. Passive mode is useful when using -.Nm -through a gateway router or host that controls the directionality of -traffic. -(Note that though ftp servers are required to support the -.Dv PASV -command by RFC 1123, some do not. -Please note that if you are connecting to IPv6 ftp server, -the program will use -.Dv EPSV/EPRT -pair and -.Dv LPSV/LPRT -pair, -instead of -.Dv PASV -and -.Dv PORT . -The meaning is the same.) -.It Ic preserve -Toggle preservation of modification times on retrieved files. -.It Ic progress -Toggle display of transfer progress bar. -The progress bar will be disabled for a transfer that has -.Ar local-file -as -.Sq Fl -or a command that starts with -.Sq \&| . -Refer to -.Sx FILE NAMING CONVENTIONS -for more information. -.It Ic prompt -Toggle interactive prompting. -Interactive prompting -occurs during multiple file transfers to allow the -user to selectively retrieve or store files. -If prompting is turned off (default is on), any -.Ic mget -or -.Ic mput -will transfer all files, and any -.Ic mdelete -will delete all files. -.Pp -When prompting is on, the following commands are available at a prompt: -.Bl -tag -width 2n -offset indent -.It Ic n -Do not transfer the file. -.It Ic a -Answer -.Sq yes -to the current file, and automatically answer -.Sq yes -to any remaining files for the current command. -.It Ic p -Answer -.Sq yes -to the current file, and turn off prompt mode -(as if -.Dq prompt off -had been given). -.El -.Pp -Any other reponse will answer -.Sq yes -to the current file. -.It Ic proxy Ar ftp-command -Execute an ftp command on a secondary control connection. -This command allows simultaneous connection to two remote ftp -servers for transferring files between the two servers. -The first -.Ic proxy -command should be an -.Ic open , -to establish the secondary control connection. -Enter the command "proxy ?" to see other ftp commands executable on the -secondary connection. -The following commands behave differently when prefaced by -.Ic proxy : -.Ic open -will not define new macros during the auto-login process, -.Ic close -will not erase existing macro definitions, -.Ic get -and -.Ic mget -transfer files from the host on the primary control connection -to the host on the secondary control connection, and -.Ic put , -.Ic mput -and -.Ic append -transfer files from the host on the secondary control connection -to the host on the primary control connection. -Third party file transfers depend upon support of the ftp protocol -.Dv PASV -command by the server on the secondary control connection. -.It Ic put Ar local-file Op Ar remote-file -Store a local file on the remote machine. -If -.Ar remote-file -is left unspecified, the local file name is used -after processing according to any -.Ic ntrans -or -.Ic nmap -settings -in naming the remote file. -File transfer uses the -current settings for -.Ic type , -.Ic format , -.Ic mode -and -.Ic structure . -.It Ic pwd -Print the name of the current working directory on the remote -machine. -.It Ic quit -A synonym for -.Ic bye . -.It Ic quote Ar arg1 arg2 ... -The arguments specified are sent, verbatim, to the remote -.Tn FTP -server. -.It Ic recv Ar remote-file Op Ar local-file -A synonym for -.Ic get . -.It Ic reget Ar remote-file Op Ar local-file -Reget acts like get, except that if -.Ar local-file -exists and is -smaller than -.Ar remote-file , -.Ar local-file -is presumed to be -a partially transferred copy of -.Ar remote-file -and the transfer -is continued from the apparent point of failure. -This command -is useful when transferring very large files over networks that -are prone to dropping connections. -.It Ic remotehelp Op Ar command-name -Request help from the remote -.Tn FTP -server. -If a -.Ar command-name -is specified it is supplied to the server as well. -.It Ic rstatus Op Ar file-name -With no arguments, show status of remote machine. -If -.Ar file-name -is specified, show status of -.Ar file-name -on remote machine. -.It Ic rename Op Ar from Op Ar to -Rename the file -.Ar from -on the remote machine, to the file -.Ar to . -.It Ic reset -Clear reply queue. -This command re-synchronizes command/reply sequencing with the remote -ftp server. -Resynchronization may be necessary following a violation of the ftp protocol -by the remote server. -.It Ic restart Ar marker -Restart the immediately following -.Ic get -or -.Ic put -at the -indicated -.Ar marker . -On -.Ux -systems, marker is usually a byte -offset into the file. -.It Ic restrict -Toggle data port range restrictions. -When not operating in passive mode, the -.Nm -client program requests that the remote server open a connection back -to the client host on a separate data port. In previous versions, that -remote port fell in the range 1024..4999. However, most firewall setups -filter that range of TCP ports because other services reside there. -The default behavior now is for the client to request that the server -connect back to the client using the port range 49152..65535. Firewall -administrators can chose to allow TCP connections in that range, if they -deem it to not be a security risk. -.It Ic rmdir Ar directory-name -Delete a directory on the remote machine. -.It Ic runique -Toggle storing of files on the local system with unique filenames. -If a file already exists with a name equal to the target -local filename for a -.Ic get -or -.Ic mget -command, a ".1" is appended to the name. -If the resulting name matches another existing file, -a ".2" is appended to the original name. -If this process continues up to ".99", an error -message is printed, and the transfer does not take place. -The generated unique filename will be reported. -Note that -.Ic runique -will not affect local files generated from a shell command -(see below). -The default value is off. -.It Ic send Ar local-file Op Ar remote-file -A synonym for -.Ic put . -.It Ic sendport -Toggle the use of -.Dv PORT -commands. -By default, -.Nm -will attempt to use a -.Dv PORT -command when establishing -a connection for each data transfer. -The use of -.Dv PORT -commands can prevent delays -when performing multiple file transfers. -If the -.Dv PORT -command fails, -.Nm -will use the default data port. -When the use of -.Dv PORT -commands is disabled, no attempt will be made to use -.Dv PORT -commands for each data transfer. -This is useful -for certain -.Tn FTP -implementations which do ignore -.Dv PORT -commands but, incorrectly, indicate they've been accepted. -.It Ic site Ar arg1 arg2 ... -The arguments specified are sent, verbatim, to the remote -.Tn FTP -server as a -.Dv SITE -command. -.It Ic size Ar file-name -Return size of -.Ar file-name -on remote machine. -.It Ic status -Show the current status of -.Nm . -.It Ic struct Op Ar struct-name -Set the file transfer -.Ar structure -to -.Ar struct-name . -By default \*(Lqstream\*(Rq structure is used. -.It Ic sunique -Toggle storing of files on remote machine under unique file names. -Remote ftp server must support ftp protocol -.Dv STOU -command for -successful completion. -The remote server will report unique name. -Default value is off. -.It Ic system -Show the type of operating system running on the remote machine. -.It Ic tenex -Set the file transfer type to that needed to -talk to -.Tn TENEX -machines. -.It Ic trace -Toggle packet tracing. -.It Ic type Op Ar type-name -Set the file transfer -.Ic type -to -.Ar type-name . -If no type is specified, the current type -is printed. -The default type is network -.Tn ASCII . -.It Ic umask Op Ar newmask -Set the default umask on the remote server to -.Ar newmask . -If -.Ar newmask -is omitted, the current umask is printed. -.It Xo -.Ic user Ar user-name -.Op Ar password Op Ar account -.Xc -Identify yourself to the remote -.Tn FTP -server. -If the -.Ar password -is not specified and the server requires it, -.Nm -will prompt the user for it (after disabling local echo). -If an -.Ar account -field is not specified, and the -.Tn FTP -server -requires it, the user will be prompted for it. -If an -.Ar account -field is specified, an account command will -be relayed to the remote server after the login sequence -is completed if the remote server did not require it -for logging in. -Unless -.Nm -is invoked with \*(Lqauto-login\*(Rq disabled, this -process is done automatically on initial connection to -the -.Tn FTP -server. -.It Ic verbose -Toggle verbose mode. -In verbose mode, all responses from -the -.Tn FTP -server are displayed to the user. -In addition, -if verbose is on, when a file transfer completes, statistics -regarding the efficiency of the transfer are reported. -By default, -verbose is on. -.It Ic \&? Op Ar command -A synonym for -.Ic help . -.El -.Pp -Command arguments which have embedded spaces may be quoted with -quote `"' marks. -.Pp -Commands which toggle settings can take an explicit -.Ic on -or -.Ic off -argument to force the setting appropriately. -.Pp -If -.Nm -receives a -.Dv SIGINFO -(see the -.Dq status -argument of -.Xr stty 1 ) -signal whilst a transfer is in progress, the current transfer rate -statistics will be written to the standard error output, in the -same format as the standard completion message. -.Sh AUTO-FETCHING FILES -In addition to standard commands, this version of -.Nm -supports an auto-fetch feature. -To enable auto-fetch, simply pass the list of hostnames/files -on the command line. -.Pp -The following formats are valid syntax for an auto-fetch element: -.Bl -tag -width "host:/file" -.It host:/file -.Dq Classic -ftp format -.It ftp://[user:password@]host[:port]/file -An ftp URL, retrieved using the ftp protocol if -.Ev ftp_proxy -isn't defined. -Otherwise, transfer using http via the proxy defined in -.Ev ftp_proxy . -If -.Ar user:password@ -is given and -.Ev ftp_proxy -isn't defined, login as -.Ar user -with a password of -.Ar password . -.It http://host[:port]/file -An HTTP URL, retrieved using the http protocol. -If -.Ev http_proxy -is defined, it is used as a URL to an HTTP proxy server. -.El -.Pp -If a classic format or a ftp URL format has a trailing -.Sq / , -then -.Nm -will connect to the site and -.Ic cd -to the directory given as the path, and leave the user in interactive -mode ready for further input. -.Pp -If successive auto-fetch ftp elements refer to the same host, then -the connection is maintained between transfers, reducing overhead on -connection creation and deletion. -.Pp -If -.Ic file -contains a glob character and globbing is enabled, -(see -.Ic glob ) , -then the equivalent of -.Ic "mget file" -is performed. -.Pp -If the directory component of -.Ic file -contains no globbing characters, -it is stored in the current directory as the -.Xr basename 1 -of -.Ic file . -Otherwise, the remote name is used as the local name. -.Sh ABORTING A FILE TRANSFER -To abort a file transfer, use the terminal interrupt key -(usually Ctrl-C). -Sending transfers will be immediately halted. -Receiving transfers will be halted by sending a ftp protocol -.Dv ABOR -command to the remote server, and discarding any further data received. -The speed at which this is accomplished depends upon the remote -server's support for -.Dv ABOR -processing. -If the remote server does not support the -.Dv ABOR -command, an -.Ql ftp> -prompt will not appear until the remote server has completed -sending the requested file. -.Pp -The terminal interrupt key sequence will be ignored when -.Nm -has completed any local processing and is awaiting a reply -from the remote server. -A long delay in this mode may result from the ABOR processing described -above, or from unexpected behavior by the remote server, including -violations of the ftp protocol. -If the delay results from unexpected remote server behavior, the local -.Nm -program must be killed by hand. -.Sh FILE NAMING CONVENTIONS -Files specified as arguments to -.Nm -commands are processed according to the following rules. -.Bl -enum -.It -If the file name -.Sq Fl -is specified, the -.Ar stdin -(for reading) or -.Ar stdout -(for writing) is used. -.It -If the first character of the file name is -.Sq \&| , -the -remainder of the argument is interpreted as a shell command. -.Nm -then forks a shell, using -.Xr popen 3 -with the argument supplied, and reads (writes) from the stdin -(stdout). -If the shell command includes spaces, the argument -must be quoted; e.g.\& -\*(Lq" ls -lt"\*(Rq. -A particularly -useful example of this mechanism is: \*(Lqdir \&|more\*(Rq. -.It -Failing the above checks, if -.Dq globbing -is enabled, -local file names are expanded -according to the rules used in the -.Xr csh 1 ; -c.f. the -.Ic glob -command. -If the -.Nm -command expects a single local file (e.g.\& -.Ic put ) , -only the first filename generated by the "globbing" operation is used. -.It -For -.Ic mget -commands and -.Ic get -commands with unspecified local file names, the local filename is -the remote filename, which may be altered by a -.Ic case , -.Ic ntrans , -or -.Ic nmap -setting. -The resulting filename may then be altered if -.Ic runique -is on. -.It -For -.Ic mput -commands and -.Ic put -commands with unspecified remote file names, the remote filename is -the local filename, which may be altered by a -.Ic ntrans -or -.Ic nmap -setting. -The resulting filename may then be altered by the remote server if -.Ic sunique -is on. -.El -.Sh FILE TRANSFER PARAMETERS -The FTP specification specifies many parameters which may -affect a file transfer. -The -.Ic type -may be one of \*(Lqascii\*(Rq, \*(Lqimage\*(Rq (binary), -\*(Lqebcdic\*(Rq and \*(Lqlocal byte size\*(Rq (for -.Tn PDP Ns -10's -and -.Tn PDP Ns -20's -mostly). -.Nm -supports the ascii and image types of file transfer, -plus local byte size 8 for -.Ic tenex -mode transfers. -.Pp -.Nm -supports only the default values for the remaining -file transfer parameters: -.Ic mode , -.Ic form -and -.Ic struct . -.Sh THE .netrc FILE -The -.Pa .netrc -file contains login and initialization information -used by the auto-login process. -It resides in the user's home directory. -The following tokens are recognized; they may be separated by spaces, -tabs, or new-lines: -.Bl -tag -width password -.It Ic machine Ar name -Identify a remote machine -.Ar name . -The auto-login process searches the -.Pa .netrc -file for a -.Ic machine -token that matches the remote machine specified on the -.Nm -command line or as an -.Ic open -command argument. -Once a match is made, the subsequent -.Pa .netrc -tokens are processed, -stopping when the end of file is reached or another -.Ic machine -or a -.Ic default -token is encountered. -.It Ic default -This is the same as -.Ic machine -.Ar name -except that -.Ic default -matches any name. -There can be only one -.Ic default -token, and it must be after all -.Ic machine -tokens. -This is normally used as: -.Pp -.Dl default login anonymous password user@site -.Pp -thereby giving the user -.Ar automatic -anonymous ftp login to -machines not specified in -.Pa .netrc . -This can be overridden -by using the -.Fl n -flag to disable auto-login. -.It Ic login Ar name -Identify a user on the remote machine. -If this token is present, the auto-login process will initiate -a login using the specified -.Ar name . -.It Ic password Ar string -Supply a password. -If this token is present, the auto-login process will supply the -specified string if the remote server requires a password as part -of the login process. -Note that if this token is present in the -.Pa .netrc -file for any user other -than -.Ar anonymous , -.Nm -will abort the auto-login process if the -.Pa .netrc -is readable by -anyone besides the user. -.It Ic account Ar string -Supply an additional account password. -If this token is present, the auto-login process will supply the -specified string if the remote server requires an additional -account password, or the auto-login process will initiate an -.Dv ACCT -command if it does not. -.It Ic macdef Ar name -Define a macro. -This token functions like the -.Nm -.Ic macdef -command functions. -A macro is defined with the specified name; its contents begin with the -next -.Pa .netrc -line and continue until a null line (consecutive new-line -characters) is encountered. -If a macro named -.Ic init -is defined, it is automatically executed as the last step in the -auto-login process. -.El -.Sh COMMAND LINE EDITING -.Nm -supports interactive command line editing, via the -.Xr editline 3 -library. -It is enabled with the -.Ic edit -command, and is enabled by default if input is from a tty. -Previous lines can be recalled and edited with the arrow keys, -and other GNU Emacs-style editing keys may be used as well. -.Pp -The -.Xr editline 3 -library is configured with a -.Pa .editrc -file - refer to -.Xr editrc 5 -for more information. -.Pp -An extra key binding is available to -.Nm -to provide context sensitive command and filename completion -(including remote file completion). -To use this, bind a key to the -.Xr editline 3 -command -.Ic ftp-complete . -By default, this is bound to the TAB key. -.Sh ENVIRONMENT -.Nm -utilizes the following environment variables. -.Bl -tag -width "FTP_PASSIVE_MODE" -.It Ev FTP_PASSIVE_MODE -If this variable is set to something else than -.Sq NO , -.Nm -will use passive mode by default. -.It Ev FTPSERVER -Host to use as gate-ftp server when -.Ic gate -is enabled. -.It Ev FTPSERVERPORT -Port to use when connecting to gate-ftp server when -.Ic gate -is enabled. -Default is port returned by a -.Fn getservbyname -lookup of -.Dq ftpgate/tcp . -.It Ev HOME -For default location of a -.Pa .netrc -file, if one exists. -.It Ev PAGER -Used by -.Ic page -to display files. -.It Ev SHELL -For default shell. -.It Ev ftp_proxy -URL of FTP proxy to use when making FTP URL requests -(if not defined, use the standard ftp protocol). -.It Ev http_proxy -URL of HTTP proxy to use when making HTTP URL requests. -.El -.Sh SEE ALSO -.Xr getservbyname 3 , -.Xr editrc 5 , -.Xr services 5 , -.Xr ftpd 8 -.Sh NOTES -The -.Xr pftp 1 -and -.Xr gate-ftp 1 -commands are links to -.Nm . -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . -.Pp -Various features such as command line editing, context sensitive -command and file completion, dynamic progress bar, automatic -fetching of files, ftp and http URLs, and modification time -preservation were implemented in -.Nx 1.3 -by Luke Mewburn, with assistance from Jason Thorpe. -.Pp -IPv6 support was added by WIDE/KAME Project. -.Sh BUGS -Correct execution of many commands depends upon proper behavior -by the remote server. -.Pp -An error in the treatment of carriage returns -in the -.Bx 4.2 -ascii-mode transfer code -has been corrected. -This correction may result in incorrect transfers of binary files -to and from -.Bx 4.2 -servers using the ascii type. -Avoid this problem by using the binary image type. -.Pp -Proxying functionalities, such as -.Ev ftp_proxy , -may not work for IPv6 connection. diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c deleted file mode 100644 index fc4f0b26fd68..000000000000 --- a/usr.bin/ftp/ftp.c +++ /dev/null @@ -1,1965 +0,0 @@ -/* $NetBSD: ftp.c,v 1.29.2.1 1997/11/18 01:01:04 mellon Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: ftp.c,v 1.29.2.1 1997/11/18 01:01:04 mellon Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/time.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <arpa/inet.h> -#include <arpa/ftp.h> -#include <arpa/telnet.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -#include "ftp_var.h" - -/* wrapper for KAME-special getnameinfo() */ -#ifndef NI_WITHSCOPEID -#define NI_WITHSCOPEID 0 -#endif - -int data = -1; -int abrtflag = 0; -jmp_buf ptabort; -int ptabflg; -int ptflag = 0; - -FILE *cin, *cout; - -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; - -char * -hookup(host0, port) - const char *host0; - char *port; -{ - int s, len, tos, error; - struct addrinfo hints, *res, *res0; - static char hostnamebuf[MAXHOSTNAMELEN]; - char *host; - - if (*host0 == '[' && strrchr(host0, ']') != NULL) { /*IPv6 addr in []*/ - strncpy(hostnamebuf, host0 + 1, strlen(host0) - 2); - hostnamebuf[strlen(host0) - 2] = '\0'; - } else { - strncpy(hostnamebuf, host0, strlen(host0)); - hostnamebuf[strlen(host0)] = '\0'; - } - host = hostnamebuf; - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - error = getaddrinfo(host, port, &hints, &res0); - if (error) { - warnx("%s: %s", host, gai_strerror(error)); - if (error == EAI_SYSTEM) - warnx("%s: %s", host, strerror(errno)); - code = -1; - return (0); - } - - res = res0; - if (res->ai_canonname) - (void) strncpy(hostnamebuf, res->ai_canonname, - sizeof(hostnamebuf)); - hostname = hostnamebuf; - while (1) { - /* - * make sure that ai_addr is NOT an IPv4 mapped address. - * IPv4 mapped address complicates too many things in FTP - * protocol handling, as FTP protocol is defined differently - * between IPv4 and IPv6. - */ - ai_unmapped(res); - s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s < 0) { - res = res->ai_next; - if (res) - continue; - warn("socket"); - code = -1; - return (0); - } - if (dobind) { - struct addrinfo *bindres; - int binderr = -1; - - for (bindres = bindres0; - bindres != NULL; - bindres = bindres->ai_next) - if (bindres->ai_family == res->ai_family) - break; - if (bindres == NULL) - bindres = bindres0; - binderr = bind(s, bindres->ai_addr, - bindres->ai_addrlen); - if (binderr == -1) - { - res = res->ai_next; - if (res) { - (void)close(s); - continue; - } - warn("bind"); - code = -1; - goto bad; - } - } - if (connect(s, res->ai_addr, res->ai_addrlen) == 0) - break; - if (res->ai_next) { - char hname[INET6_ADDRSTRLEN]; - getnameinfo(res->ai_addr, res->ai_addrlen, - hname, sizeof(hname) - 1, NULL, 0, - NI_NUMERICHOST|NI_WITHSCOPEID); - warn("connect to address %s", hname); - res = res->ai_next; - getnameinfo(res->ai_addr, res->ai_addrlen, - hname, sizeof(hname) - 1, NULL, 0, - NI_NUMERICHOST|NI_WITHSCOPEID); - printf("Trying %s...\n", hname); - (void)close(s); - continue; - } - warn("connect"); - code = -1; - goto bad; - } - memcpy(&hisctladdr, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res0); - len = sizeof(myctladdr); - if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { - warn("getsockname"); - code = -1; - goto bad; - } -#ifdef IP_TOS - if (myctladdr.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"); - if (cin == NULL || cout == NULL) { - warnx("fdopen failed."); - if (cin) - (void)fclose(cin); - if (cout) - (void)fclose(cout); - code = -1; - goto bad; - } - if (verbose) - printf("Connected to %s.\n", hostname); - if (getreply(0) > 2) { /* read startup message from server */ - if (cin) - (void)fclose(cin); - if (cout) - (void)fclose(cout); - code = -1; - goto bad; - } -#ifdef SO_OOBINLINE - { - int on = 1; - - if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) - < 0 && debug) { - warn("setsockopt"); - } - } -#endif /* SO_OOBINLINE */ - - return (hostname); -bad: - (void)close(s); - return ((char *)0); -} - -void -cmdabort(notused) - int notused; -{ - - alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); - abrtflag++; - if (ptflag) - longjmp(ptabort, 1); -} - -/*VARARGS*/ -int -#ifdef __STDC__ -command(const char *fmt, ...) -#else -command(va_alist) - va_dcl -#endif -{ - va_list ap; - int r; - sig_t oldintr; -#ifndef __STDC__ - const char *fmt; -#endif - - abrtflag = 0; - if (debug) { - fputs("---> ", stdout); -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); - fmt = va_arg(ap, const char *); -#endif - if (strncmp("PASS ", fmt, 5) == 0) - fputs("PASS XXXX", stdout); - else if (strncmp("ACCT ", fmt, 5) == 0) - fputs("ACCT XXXX", stdout); - else - vprintf(fmt, ap); - va_end(ap); - putchar('\n'); - (void)fflush(stdout); - } - if (cout == NULL) { - warnx("No control connection for command."); - code = -1; - return (0); - } - oldintr = signal(SIGINT, cmdabort); -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); - fmt = va_arg(ap, char *); -#endif - vfprintf(cout, fmt, ap); - va_end(ap); - fputs("\r\n", cout); - (void)fflush(cout); - cpend = 1; - r = getreply(!strcmp(fmt, "QUIT")); - if (abrtflag && oldintr != SIG_IGN) - (*oldintr)(SIGINT); - (void)signal(SIGINT, oldintr); - return (r); -} - -char reply_string[BUFSIZ]; /* first line of previous reply */ - -int -getreply(expecteof) - int expecteof; -{ - char current_line[BUFSIZ]; /* last line of previous reply */ - int c, n, line; - int dig; - int originalcode = 0, continuation = 0; - sig_t oldintr; - int pflag = 0; - char *cp, *pt = pasv; - - oldintr = signal(SIGINT, cmdabort); - for (line = 0 ;; line++) { - dig = n = code = 0; - cp = current_line; - while ((c = getc(cin)) != '\n') { - if (c == IAC) { /* handle telnet commands */ - switch (c = getc(cin)) { - case WILL: - case WONT: - c = getc(cin); - fprintf(cout, "%c%c%c", IAC, DONT, c); - (void)fflush(cout); - break; - case DO: - case DONT: - c = getc(cin); - fprintf(cout, "%c%c%c", IAC, WONT, c); - (void)fflush(cout); - break; - default: - break; - } - continue; - } - dig++; - if (c == EOF) { - if (expecteof) { - (void)signal(SIGINT, oldintr); - code = 221; - return (0); - } - lostpeer(); - if (verbose) { - puts( -"421 Service not available, remote server has closed connection."); - (void)fflush(stdout); - } - code = 421; - return (4); - } - if (c != '\r' && (verbose > 0 || - (verbose > -1 && n == '5' && dig > 4))) { - if (proxflag && - (dig == 1 || (dig == 5 && verbose == 0))) - printf("%s:", hostname); - (void)putchar(c); - } - if (dig < 4 && isdigit((unsigned char)c)) - code = code * 10 + (c - '0'); - switch (pflag) { - case 0: - if (code == 227 || code == 228) { - /* result for PASV/LPSV */ - pflag = 1; - /* fall through */ - } else if (code == 229) { - /* result for EPSV */ - pflag = 100; - break; - } else - break; - case 1: - if (!(dig > 4 && isdigit((unsigned char)c))) - break; - pflag = 2; - /* fall through */ - case 2: - if (c != '\r' && c != ')' && - pt < &pasv[sizeof(pasv)-1]) - *pt++ = c; - else { - *pt = '\0'; - pflag = 3; - } - break; - case 100: - if (dig > 4 && c == '(') - pflag = 2; - break; - } - if (dig == 4 && c == '-') { - if (continuation) - code = 0; - continuation++; - } - if (n == 0) - n = c; - if (cp < ¤t_line[sizeof(current_line) - 1]) - *cp++ = c; - } - if (verbose > 0 || (verbose > -1 && n == '5')) { - (void)putchar(c); - (void)fflush (stdout); - } - if (line == 0) { - size_t len = cp - current_line; - - if (len > sizeof(reply_string)) - len = sizeof(reply_string); - - (void)strncpy(reply_string, current_line, len); - reply_string[len] = '\0'; - } - if (continuation && code != originalcode) { - if (originalcode == 0) - originalcode = code; - continue; - } - *cp = '\0'; - if (n != '1') - cpend = 0; - (void)signal(SIGINT, oldintr); - if (code == 421 || originalcode == 421) - lostpeer(); - if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) - (*oldintr)(SIGINT); - return (n - '0'); - } -} - -int -empty(mask, sec) - fd_set *mask; - int sec; -{ - struct timeval t; - - t.tv_sec = (long) sec; - t.tv_usec = 0; - return (select(32, mask, (fd_set *) 0, (fd_set *) 0, &t)); -} - -jmp_buf sendabort; - -void -abortsend(notused) - int notused; -{ - - alarmtimer(0); - mflag = 0; - abrtflag = 0; - puts("\nsend aborted\nwaiting for remote to finish abort."); - (void)fflush(stdout); - longjmp(sendabort, 1); -} - -void -sendrequest(cmd, local, remote, printnames) - const char *cmd, *local, *remote; - int printnames; -{ - struct stat st; - int c, d; - FILE *fin, *dout; - int (*closefunc) __P((FILE *)); - sig_t oldinti, oldintr, oldintp; - volatile off_t hashbytes; - char *lmode, buf[BUFSIZ], *bufp; - int oprogress; - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&fin; - (void)&dout; - (void)&closefunc; - (void)&oldinti; - (void)&oldintr; - (void)&oldintp; - (void)&lmode; -#endif - - hashbytes = mark; - direction = "sent"; - dout = NULL; - bytes = 0; - filesize = -1; - oprogress = progress; - if (verbose && printnames) { - if (local && *local != '-') - printf("local: %s ", local); - if (remote) - printf("remote: %s\n", remote); - } - if (proxy) { - proxtrans(cmd, local, remote); - return; - } - if (curtype != type) - changetype(type, 0); - closefunc = NULL; - oldintr = NULL; - oldintp = NULL; - oldinti = NULL; - lmode = "w"; - if (setjmp(sendabort)) { - while (cpend) { - (void)getreply(0); - } - if (data >= 0) { - (void)close(data); - data = -1; - } - if (oldintr) - (void)signal(SIGINT, oldintr); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - if (oldinti) - (void)signal(SIGINFO, oldinti); - code = -1; - goto cleanupsend; - } - oldintr = signal(SIGINT, abortsend); - oldinti = signal(SIGINFO, psummary); - if (strcmp(local, "-") == 0) { - fin = stdin; - progress = 0; - } else if (*local == '|') { - oldintp = signal(SIGPIPE, SIG_IGN); - fin = popen(local + 1, "r"); - if (fin == NULL) { - warn("%s", local + 1); - (void)signal(SIGINT, oldintr); - (void)signal(SIGPIPE, oldintp); - (void)signal(SIGINFO, oldinti); - code = -1; - goto cleanupsend; - } - progress = 0; - closefunc = pclose; - } else { - fin = fopen(local, "r"); - if (fin == NULL) { - warn("local: %s", local); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - goto cleanupsend; - } - closefunc = fclose; - if (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) { - printf("%s: not a plain file.\n", local); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - fclose(fin); - code = -1; - goto cleanupsend; - } - filesize = st.st_size; - } - if (initconn()) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - code = -1; - if (closefunc != NULL) - (*closefunc)(fin); - goto cleanupsend; - } - if (setjmp(sendabort)) - goto abort; - - if (restart_point && - (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { - int rc; - - rc = -1; - switch (curtype) { - case TYPE_A: - rc = fseeko(fin, restart_point, SEEK_SET); - break; - case TYPE_I: - case TYPE_L: - rc = lseek(fileno(fin), restart_point, SEEK_SET); - break; - } - if (rc < 0) { - warn("local: %s", local); - if (closefunc != NULL) - (*closefunc)(fin); - goto cleanupsend; - } - if (command("REST %qd", (long long) restart_point) != - CONTINUE) { - if (closefunc != NULL) - (*closefunc)(fin); - goto cleanupsend; - } - lmode = "r+w"; - } - if (remote) { - if (command("%s %s", cmd, remote) != PRELIM) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - if (closefunc != NULL) - (*closefunc)(fin); - goto cleanupsend; - } - } else - if (command("%s", cmd) != PRELIM) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - if (closefunc != NULL) - (*closefunc)(fin); - goto cleanupsend; - } - dout = dataconn(lmode); - if (dout == NULL) - goto abort; - progressmeter(-1); - oldintp = signal(SIGPIPE, SIG_IGN); - switch (curtype) { - - case TYPE_I: - case TYPE_L: - errno = d = 0; - while ((c = read(fileno(fin), buf, sizeof(buf))) > 0) { - bytes += c; - for (bufp = buf; c > 0; c -= d, bufp += d) - if ((d = write(fileno(dout), bufp, c)) <= 0) - break; - if (hash && (!progress || filesize < 0) ) { - while (bytes >= hashbytes) { - (void)putchar('#'); - hashbytes += mark; - } - (void)fflush(stdout); - } - } - if (hash && (!progress || filesize < 0) && bytes > 0) { - if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); - } - if (c < 0) - warn("local: %s", local); - if (d < 0) { - if (errno != EPIPE) - warn("netout"); - bytes = -1; - } - break; - - case TYPE_A: - while ((c = getc(fin)) != EOF) { - if (c == '\n') { - while (hash && (!progress || filesize < 0) && - (bytes >= hashbytes)) { - (void)putchar('#'); - (void)fflush(stdout); - hashbytes += mark; - } - if (ferror(dout)) - break; - (void)putc('\r', dout); - bytes++; - } - (void)putc(c, dout); - bytes++; -#if 0 /* this violates RFC */ - if (c == '\r') { - (void)putc('\0', dout); - bytes++; - } -#endif - } - if (hash && (!progress || filesize < 0)) { - if (bytes < hashbytes) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); - } - if (ferror(fin)) - warn("local: %s", local); - if (ferror(dout)) { - if (errno != EPIPE) - warn("netout"); - bytes = -1; - } - break; - } - progressmeter(1); - if (closefunc != NULL) - (*closefunc)(fin); - (void)fclose(dout); - (void)getreply(0); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - if (bytes > 0) - ptransfer(0); - goto cleanupsend; -abort: - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - if (!cpend) { - code = -1; - return; - } - if (data >= 0) { - (void)close(data); - data = -1; - } - if (dout) - (void)fclose(dout); - (void)getreply(0); - code = -1; - if (closefunc != NULL && fin != NULL) - (*closefunc)(fin); - if (bytes > 0) - ptransfer(0); -cleanupsend: - progress = oprogress; - restart_point = 0; -} - -jmp_buf recvabort; - -void -abortrecv(notused) - int notused; -{ - - alarmtimer(0); - mflag = 0; - abrtflag = 0; - puts("\nreceive aborted\nwaiting for remote to finish abort."); - (void)fflush(stdout); - longjmp(recvabort, 1); -} - -void -recvrequest(cmd, local, remote, lmode, printnames, ignorespecial) - const char *cmd, *local, *remote, *lmode; - int printnames, ignorespecial; -{ - FILE *fout, *din; - int (*closefunc) __P((FILE *)); - sig_t oldinti, oldintr, oldintp; - int c, d; - volatile int is_retr, tcrflag, bare_lfs; - static size_t bufsize; - static char *buf; - volatile off_t hashbytes; - struct stat st; - time_t mtime; - struct timeval tval[2]; - int oprogress; - int opreserve; - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&local; - (void)&fout; - (void)&din; - (void)&closefunc; - (void)&oldinti; - (void)&oldintr; - (void)&oldintp; -#endif - - fout = NULL; - din = NULL; - oldinti = NULL; - hashbytes = mark; - direction = "received"; - bytes = 0; - bare_lfs = 0; - filesize = -1; - oprogress = progress; - opreserve = preserve; - is_retr = (strcmp(cmd, "RETR") == 0); - if (is_retr && verbose && printnames) { - if (local && (ignorespecial || *local != '-')) - printf("local: %s ", local); - if (remote) - printf("remote: %s\n", remote); - } - if (proxy && is_retr) { - proxtrans(cmd, local, remote); - return; - } - closefunc = NULL; - oldintr = NULL; - oldintp = NULL; - tcrflag = !crflag && is_retr; - if (setjmp(recvabort)) { - while (cpend) { - (void)getreply(0); - } - if (data >= 0) { - (void)close(data); - data = -1; - } - if (oldintr) - (void)signal(SIGINT, oldintr); - if (oldinti) - (void)signal(SIGINFO, oldinti); - progress = oprogress; - preserve = opreserve; - code = -1; - return; - } - oldintr = signal(SIGINT, abortrecv); - oldinti = signal(SIGINFO, psummary); - if (ignorespecial || (strcmp(local, "-") && *local != '|')) { - if (access(local, W_OK) < 0) { - char *dir = strrchr(local, '/'); - - if (errno != ENOENT && errno != EACCES) { - warn("local: %s", local); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - if (dir != NULL) - *dir = 0; - d = access(dir == local ? "/" : dir ? local : ".", W_OK); - if (dir != NULL) - *dir = '/'; - if (d < 0) { - warn("local: %s", local); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - if (!runique && errno == EACCES && - chmod(local, 0600) < 0) { - warn("local: %s", local); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - if (runique && errno == EACCES && - (local = gunique(local)) == NULL) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - } - else if (runique && (local = gunique(local)) == NULL) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - } - if (!is_retr) { - if (curtype != TYPE_A) - changetype(TYPE_A, 0); - } else { - if (curtype != type) - changetype(type, 0); - filesize = remotesize(remote, 0); - } - if (initconn()) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - code = -1; - return; - } - if (setjmp(recvabort)) - goto abort; - if (is_retr && restart_point && - command("REST %qd", (long long) restart_point) != CONTINUE) - return; - if (remote) { - if (command("%s %s", cmd, remote) != PRELIM) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - return; - } - } else { - if (command("%s", cmd) != PRELIM) { - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - return; - } - } - din = dataconn("r"); - if (din == NULL) - goto abort; - if (!ignorespecial && strcmp(local, "-") == 0) { - fout = stdout; - progress = 0; - preserve = 0; - } else if (!ignorespecial && *local == '|') { - oldintp = signal(SIGPIPE, SIG_IGN); - fout = popen(local + 1, "w"); - if (fout == NULL) { - warn("%s", local+1); - goto abort; - } - progress = 0; - preserve = 0; - closefunc = pclose; - } else { - fout = fopen(local, lmode); - if (fout == NULL) { - warn("local: %s", local); - goto abort; - } - closefunc = fclose; - } - if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) - st.st_blksize = BUFSIZ; - if (st.st_blksize > bufsize) { - if (buf) - (void)free(buf); - buf = malloc((unsigned)st.st_blksize); - if (buf == NULL) { - warn("malloc"); - bufsize = 0; - goto abort; - } - bufsize = st.st_blksize; - } - if (!S_ISREG(st.st_mode)) { - progress = 0; - preserve = 0; - } - progressmeter(-1); - switch (curtype) { - - case TYPE_I: - case TYPE_L: - if (is_retr && restart_point && - lseek(fileno(fout), restart_point, SEEK_SET) < 0) { - warn("local: %s", local); - progress = oprogress; - preserve = opreserve; - if (closefunc != NULL) - (*closefunc)(fout); - return; - } - errno = d = 0; - while ((c = read(fileno(din), buf, bufsize)) > 0) { - if ((d = write(fileno(fout), buf, c)) != c) - break; - bytes += c; - if (hash && (!progress || filesize < 0)) { - while (bytes >= hashbytes) { - (void)putchar('#'); - hashbytes += mark; - } - (void)fflush(stdout); - } - } - if (hash && (!progress || filesize < 0) && bytes > 0) { - if (bytes < mark) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); - } - if (c < 0) { - if (errno != EPIPE) - warn("netin"); - bytes = -1; - } - if (d < c) { - if (d < 0) - warn("local: %s", local); - else - warnx("%s: short write", local); - } - break; - - case TYPE_A: - if (is_retr && restart_point) { - int ch; - off_t i, n; - - if (fseeko(fout, (off_t)0, SEEK_SET) < 0) - goto done; - n = restart_point; - for (i = 0; i++ < n;) { - if ((ch = getc(fout)) == EOF) - goto done; - if (ch == '\n') - i++; - } - if (fseeko(fout, (off_t)0, SEEK_CUR) < 0) { -done: - warn("local: %s", local); - progress = oprogress; - preserve = opreserve; - if (closefunc != NULL) - (*closefunc)(fout); - return; - } - } - while ((c = getc(din)) != EOF) { - if (c == '\n') - bare_lfs++; - while (c == '\r') { - while (hash && (!progress || filesize < 0) && - (bytes >= hashbytes)) { - (void)putchar('#'); - (void)fflush(stdout); - hashbytes += mark; - } - bytes++; - if ((c = getc(din)) != '\n' || tcrflag) { - if (ferror(fout)) - goto break2; - (void)putc('\r', fout); - if (c == '\0') { - bytes++; - goto contin2; - } - if (c == EOF) - goto contin2; - } - } - (void)putc(c, fout); - bytes++; - contin2: ; - } -break2: - if (bare_lfs) { - printf( -"WARNING! %d bare linefeeds received in ASCII mode.\n", bare_lfs); - puts("File may not have transferred correctly."); - } - if (hash && (!progress || filesize < 0)) { - if (bytes < hashbytes) - (void)putchar('#'); - (void)putchar('\n'); - (void)fflush(stdout); - } - if (ferror(din)) { - if (errno != EPIPE) - warn("netin"); - bytes = -1; - } - if (ferror(fout)) - warn("local: %s", local); - break; - } - progressmeter(1); - progress = oprogress; - preserve = opreserve; - if (closefunc != NULL) - (*closefunc)(fout); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - if (oldintp) - (void)signal(SIGPIPE, oldintp); - (void)fclose(din); - (void)getreply(0); - if (bytes >= 0 && is_retr) { - if (bytes > 0) - ptransfer(0); - if (preserve && (closefunc == fclose)) { - mtime = remotemodtime(remote, 0); - if (mtime != -1) { - (void)gettimeofday(&tval[0], - (struct timezone *)0); - tval[1].tv_sec = mtime; - tval[1].tv_usec = 0; - if (utimes(local, tval) == -1) { - printf( - "Can't change modification time on %s to %s", - local, asctime(localtime(&mtime))); - } - } - } - } - return; - -abort: - -/* abort using RFC959 recommended IP,SYNC sequence */ - - progress = oprogress; - preserve = opreserve; - if (oldintp) - (void)signal(SIGPIPE, oldintp); - (void)signal(SIGINT, SIG_IGN); - if (!cpend) { - code = -1; - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); - return; - } - - abort_remote(din); - code = -1; - if (data >= 0) { - (void)close(data); - data = -1; - } - if (closefunc != NULL && fout != NULL) - (*closefunc)(fout); - if (din) - (void)fclose(din); - if (bytes > 0) - ptransfer(0); - (void)signal(SIGINT, oldintr); - (void)signal(SIGINFO, oldinti); -} - -/* - * Need to start a listen on the data channel before we send the command, - * otherwise the server's connect may fail. - */ -int -initconn() -{ - char *p, *a; - int result, len, tmpno = 0; - int on = 1; - int error, ports; - u_int af; - u_int hal, h[16]; - u_int pal, prt[2]; - char *pasvcmd; - -#ifdef INET6 - 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"); - } -#endif - - if (passivemode) { -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&pasvcmd; -#endif - data_addr = myctladdr; - data = socket(data_addr.su_family, SOCK_STREAM, 0); - if (data < 0) { - warn("socket"); - return (1); - } - if (dobind) { - struct addrinfo *bindres; - int binderr = -1; - - for (bindres = bindres0; - bindres != NULL; - bindres = bindres->ai_next) - if (bindres->ai_family == data_addr.su_family) - break; - if (bindres == NULL) - bindres = bindres0; - binderr = bind(data, bindres->ai_addr, - bindres->ai_addrlen); - if (binderr == -1) - { - warn("bind"); - goto bad; - } - } - if ((options & SO_DEBUG) && - setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, - sizeof(on)) < 0) - warn("setsockopt (ignored)"); - switch (data_addr.su_family) { - case AF_INET: - if (try_epsv) { - int overbose; - - overbose = verbose; - if (debug == 0) - verbose = -1; - result = command(pasvcmd = "EPSV"); - verbose = overbose; - if (code / 10 == 22 && code != 229) { - puts("wrong server: EPSV return code must be 229"); - result = COMPLETE + 1; - } - } else - result = COMPLETE + 1; - if (result != COMPLETE) { - try_epsv = 0; - result = command(pasvcmd = "PASV"); - } - break; -#ifdef INET6 - case AF_INET6: - result = command(pasvcmd = "EPSV"); - if (code / 10 == 22 && code != 229) { - puts("wrong server: EPSV return code must be 229"); - result = COMPLETE + 1; - } - if (result != COMPLETE) - result = command(pasvcmd = "LPSV"); - break; -#endif - default: - result = COMPLETE + 1; - } - if (result != COMPLETE) { - puts("Passive mode refused."); - goto bad; - } - -#define pack2(var, offset) \ - (((var[(offset) + 0] & 0xff) << 8) | ((var[(offset) + 1] & 0xff) << 0)) -#define pack4(var, offset) \ - (((var[(offset) + 0] & 0xff) << 24) | ((var[(offset) + 1] & 0xff) << 16) \ - | ((var[(offset) + 2] & 0xff) << 8) | ((var[(offset) + 3] & 0xff) << 0)) - /* - * What we've got at this point is a string of comma - * separated one-byte unsigned integer values. - * In PASV case, - * 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. - * In other case, the format is more complicated. - */ - if (strcmp(pasvcmd, "PASV") == 0) { - if (code / 10 == 22 && code != 227) { - puts("wrong server: return code must be 227"); - error = 1; - goto bad; - } - error = sscanf(pasv, "%d,%d,%d,%d,%d,%d", - &h[0], &h[1], &h[2], &h[3], - &prt[0], &prt[1]); - if (error == 6) { - error = 0; - data_addr.su_sin.sin_addr.s_addr = - htonl(pack4(h, 0)); - } else - error = 1; - } else if (strcmp(pasvcmd, "LPSV") == 0) { - if (code / 10 == 22 && code != 228) { - puts("wrong server: return code must be 228"); - error = 1; - goto bad; - } - switch (data_addr.su_family) { - case AF_INET: - error = sscanf(pasv, -"%d,%d,%d,%d,%d,%d,%d,%d,%d", - &af, &hal, - &h[0], &h[1], &h[2], &h[3], - &pal, &prt[0], &prt[1]); - if (error == 9 && af == 4 && hal == 4 && pal == 2) { - error = 0; - data_addr.su_sin.sin_addr.s_addr = - htonl(pack4(h, 0)); - } else - error = 1; - break; -#ifdef INET6 - case AF_INET6: - error = sscanf(pasv, -"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - &af, &hal, - &h[0], &h[1], &h[2], &h[3], - &h[4], &h[5], &h[6], &h[7], - &h[8], &h[9], &h[10], &h[11], - &h[12], &h[13], &h[14], &h[15], - &pal, &prt[0], &prt[1]); - if (error != 21 || af != 6 || hal != 16 || pal != 2) { - error = 1; - break; - } - - error = 0; - { - u_int32_t *p32; - p32 = (u_int32_t *)&data_addr.su_sin6.sin6_addr; - p32[0] = htonl(pack4(h, 0)); - p32[1] = htonl(pack4(h, 4)); - p32[2] = htonl(pack4(h, 8)); - p32[3] = htonl(pack4(h, 12)); - } - break; -#endif - default: - error = 1; - } - } else if (strcmp(pasvcmd, "EPSV") == 0) { - char delim[4]; - - prt[0] = 0; - if (code / 10 == 22 && code != 229) { - puts("wrong server: return code must be 229"); - error = 1; - goto bad; - } - error = sscanf(pasv, "%c%c%c%d%c", - &delim[0], &delim[1], &delim[2], - &prt[1], &delim[3]); - if (error != 5) { - error = 1; - goto epsv_done; - } - if (delim[0] != delim[1] || delim[0] != delim[2] - || delim[0] != delim[3]) { - error = 1; - goto epsv_done; - } - - data_addr = hisctladdr; - /* quickhack */ - prt[0] = (prt[1] & 0xff00) >> 8; - prt[1] &= 0xff; - error = 0; -epsv_done: - } else - error = 1; - - if (error) { - puts( -"Passive mode address scan failure. Shouldn't happen!"); - goto bad; - }; - - data_addr.su_port = htons(pack2(prt, 0)); - - if (connect(data, (struct sockaddr *)&data_addr, - data_addr.su_len) < 0) { - warn("connect"); - goto bad; - } -#ifdef 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); - } - -noport: - data_addr = myctladdr; - if (sendport) - data_addr.su_port = 0; /* let system pick one */ - if (data != -1) - (void)close(data); - data = socket(data_addr.su_family, SOCK_STREAM, 0); - if (data < 0) { - warn("socket"); - if (tmpno) - sendport = 1; - return (1); - } - if (!sendport) - if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, - sizeof(on)) < 0) { - warn("setsockopt (reuse address)"); - goto bad; - } -#ifdef IP_PORTRANGE - if (data_addr.su_family == AF_INET) - { - - ports = restricted_data_ports ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT; - if (setsockopt(data, IPPROTO_IP, IP_PORTRANGE, (char *)&ports, - sizeof(ports)) < 0) - warn("setsockopt PORTRANGE (ignored)"); - } -#endif -#ifdef INET6 -#ifdef IPV6_PORTRANGE - if (data_addr.su_family == AF_INET6) { - ports = restricted_data_ports ? IPV6_PORTRANGE_HIGH - : IPV6_PORTRANGE_DEFAULT; - if (setsockopt(data, IPPROTO_IPV6, IPV6_PORTRANGE, - (char *)&ports, sizeof(ports)) < 0) - warn("setsockopt PORTRANGE (ignored)"); - } -#endif -#endif - if (bind(data, (struct sockaddr *)&data_addr, data_addr.su_len) < 0) { - warn("bind"); - goto bad; - } - if (options & SO_DEBUG && - setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, - sizeof(on)) < 0) - warn("setsockopt (ignored)"); - len = sizeof(data_addr); - if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { - warn("getsockname"); - goto bad; - } - if (listen(data, 1) < 0) - warn("listen"); - if (sendport) { - char hname[INET6_ADDRSTRLEN]; - int af; - struct sockaddr_in data_addr4; - union sockunion *daddr; - -#ifdef INET6 - if (data_addr.su_family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&data_addr.su_sin6.sin6_addr)) { - memset(&data_addr4, 0, sizeof(data_addr4)); - data_addr4.sin_len = sizeof(struct sockaddr_in); - data_addr4.sin_family = AF_INET; - data_addr4.sin_port = data_addr.su_port; - memcpy((caddr_t)&data_addr4.sin_addr, - (caddr_t)&data_addr.su_sin6.sin6_addr.s6_addr[12], - sizeof(struct in_addr)); - daddr = (union sockunion *)&data_addr4; - } else -#endif - daddr = &data_addr; - - - -#define UC(b) (((int)b)&0xff) - - switch (daddr->su_family) { -#ifdef INET6 - case AF_INET6: -#endif - af = (daddr->su_family == AF_INET) ? 1 : 2; - if (getnameinfo((struct sockaddr *)daddr, - daddr->su_len, hname, - sizeof(hname) - 1, NULL, 0, - NI_NUMERICHOST)) { - result = ERROR; - } else { - result = command("EPRT |%d|%s|%d|", - af, hname, ntohs(daddr->su_port)); - } - break; - default: - result = COMPLETE + 1; - break; - } - if (result == COMPLETE) - goto skip_port; - - p = (char *)&daddr->su_port; - switch (daddr->su_family) { - case AF_INET: - a = (char *)&daddr->su_sin.sin_addr; - 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; -#ifdef INET6 - case AF_INET6: - a = (char *)&daddr->su_sin6.sin6_addr; - 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; -#endif - default: - result = COMPLETE + 1; /* xxx */ - } - skip_port: - - if (result == ERROR && sendport == -1) { - sendport = 0; - tmpno = 1; - goto noport; - } - return (result != COMPLETE); - } - if (tmpno) - sendport = 1; -#ifdef 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: - (void)close(data), data = -1; - if (tmpno) - sendport = 1; - return (1); -} - -FILE * -dataconn(lmode) - const char *lmode; -{ - union sockunion from; - int s, fromlen, tos; - - fromlen = myctladdr.su_len; - - if (passivemode) - return (fdopen(data, lmode)); - - s = accept(data, (struct sockaddr *) &from, &fromlen); - if (s < 0) { - warn("accept"); - (void)close(data), data = -1; - return (NULL); - } - (void)close(data); - data = s; -#ifdef IP_TOS - if (data_addr.su_family == AF_INET) - { - tos = IPTOS_THROUGHPUT; - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - warn("setsockopt TOS (ignored)"); - } -#endif - return (fdopen(data, lmode)); -} - -void -psummary(notused) - int notused; -{ - - if (bytes > 0) - ptransfer(1); -} - -void -psabort(notused) - int notused; -{ - - alarmtimer(0); - abrtflag++; -} - -void -pswitch(flag) - int flag; -{ - sig_t oldintr; - static struct comvars { - int connect; - char name[MAXHOSTNAMELEN]; - union sockunion mctl; - union sockunion hctl; - FILE *in; - FILE *out; - int tpe; - int curtpe; - int cpnd; - int sunqe; - int runqe; - int mcse; - int ntflg; - char nti[17]; - char nto[17]; - int mapflg; - char mi[MAXPATHLEN]; - char mo[MAXPATHLEN]; - } proxstruct, tmpstruct; - struct comvars *ip, *op; - - abrtflag = 0; - oldintr = signal(SIGINT, psabort); - if (flag) { - if (proxy) - return; - ip = &tmpstruct; - op = &proxstruct; - proxy++; - } else { - if (!proxy) - return; - ip = &proxstruct; - op = &tmpstruct; - proxy = 0; - } - ip->connect = connected; - connected = op->connect; - if (hostname) { - (void)strncpy(ip->name, hostname, sizeof(ip->name) - 1); - ip->name[sizeof(ip->name) - 1] = '\0'; - } else - ip->name[0] = '\0'; - hostname = op->name; - ip->hctl = hisctladdr; - hisctladdr = op->hctl; - ip->mctl = myctladdr; - myctladdr = op->mctl; - ip->in = cin; - cin = op->in; - ip->out = cout; - cout = op->out; - ip->tpe = type; - type = op->tpe; - ip->curtpe = curtype; - curtype = op->curtpe; - ip->cpnd = cpend; - cpend = op->cpnd; - ip->sunqe = sunique; - sunique = op->sunqe; - ip->runqe = runique; - runique = op->runqe; - ip->mcse = mcase; - mcase = op->mcse; - ip->ntflg = ntflag; - ntflag = op->ntflg; - (void)strncpy(ip->nti, ntin, sizeof(ip->nti) - 1); - (ip->nti)[sizeof(ip->nti) - 1] = '\0'; - (void)strcpy(ntin, op->nti); - (void)strncpy(ip->nto, ntout, sizeof(ip->nto) - 1); - (ip->nto)[sizeof(ip->nto) - 1] = '\0'; - (void)strcpy(ntout, op->nto); - ip->mapflg = mapflag; - mapflag = op->mapflg; - (void)strncpy(ip->mi, mapin, sizeof(ip->mi) - 1); - (ip->mi)[sizeof(ip->mi) - 1] = '\0'; - (void)strcpy(mapin, op->mi); - (void)strncpy(ip->mo, mapout, sizeof(ip->mo) - 1); - (ip->mo)[sizeof(ip->mo) - 1] = '\0'; - (void)strcpy(mapout, op->mo); - (void)signal(SIGINT, oldintr); - if (abrtflag) { - abrtflag = 0; - (*oldintr)(SIGINT); - } -} - -void -abortpt(notused) - int notused; -{ - - alarmtimer(0); - putchar('\n'); - (void)fflush(stdout); - ptabflg++; - mflag = 0; - abrtflag = 0; - longjmp(ptabort, 1); -} - -void -proxtrans(cmd, local, remote) - const char *cmd, *local, *remote; -{ - sig_t oldintr; - int prox_type, nfnd; - volatile int secndflag; - char *cmd2; - fd_set mask; - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&oldintr; - (void)&cmd2; -#endif - - oldintr = NULL; - secndflag = 0; - if (strcmp(cmd, "RETR")) - cmd2 = "RETR"; - else - cmd2 = runique ? "STOU" : "STOR"; - if ((prox_type = type) == 0) { - if (unix_server && unix_proxy) - prox_type = TYPE_I; - else - prox_type = TYPE_A; - } - if (curtype != prox_type) - changetype(prox_type, 1); - if (try_epsv && command("EPSV") != COMPLETE) - try_epsv = 0; - if (!try_epsv && command("PASV") != COMPLETE) { - puts("proxy server does not support third party transfers."); - return; - } - pswitch(0); - if (!connected) { - puts("No primary connection."); - pswitch(1); - code = -1; - return; - } - if (curtype != prox_type) - changetype(prox_type, 1); - if (command("PORT %s", pasv) != COMPLETE) { - pswitch(1); - return; - } - if (setjmp(ptabort)) - goto abort; - oldintr = signal(SIGINT, abortpt); - if (command("%s %s", cmd, remote) != PRELIM) { - (void)signal(SIGINT, oldintr); - pswitch(1); - return; - } - sleep(2); - pswitch(1); - secndflag++; - if (command("%s %s", cmd2, local) != PRELIM) - goto abort; - ptflag++; - (void)getreply(0); - pswitch(0); - (void)getreply(0); - (void)signal(SIGINT, oldintr); - pswitch(1); - ptflag = 0; - printf("local: %s remote: %s\n", local, remote); - return; -abort: - (void)signal(SIGINT, SIG_IGN); - ptflag = 0; - if (strcmp(cmd, "RETR") && !proxy) - pswitch(1); - else if (!strcmp(cmd, "RETR") && proxy) - pswitch(0); - if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ - if (command("%s %s", cmd2, local) != PRELIM) { - pswitch(0); - if (cpend) - abort_remote((FILE *) NULL); - } - pswitch(1); - if (ptabflg) - code = -1; - (void)signal(SIGINT, oldintr); - return; - } - if (cpend) - abort_remote((FILE *) NULL); - pswitch(!proxy); - if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ - if (command("%s %s", cmd2, local) != PRELIM) { - pswitch(0); - if (cpend) - abort_remote((FILE *) NULL); - pswitch(1); - if (ptabflg) - code = -1; - (void)signal(SIGINT, oldintr); - return; - } - } - if (cpend) - abort_remote((FILE *) NULL); - pswitch(!proxy); - if (cpend) { - FD_ZERO(&mask); - FD_SET(fileno(cin), &mask); - if ((nfnd = empty(&mask, 10)) <= 0) { - if (nfnd < 0) { - warn("abort"); - } - if (ptabflg) - code = -1; - lostpeer(); - } - (void)getreply(0); - (void)getreply(0); - } - if (proxy) - pswitch(0); - pswitch(1); - if (ptabflg) - code = -1; - (void)signal(SIGINT, oldintr); -} - -void -reset(argc, argv) - int argc; - char *argv[]; -{ - fd_set mask; - int nfnd = 1; - - FD_ZERO(&mask); - while (nfnd > 0) { - FD_SET(fileno(cin), &mask); - if ((nfnd = empty(&mask, 0)) < 0) { - warn("reset"); - code = -1; - lostpeer(); - } - else if (nfnd) { - (void)getreply(0); - } - } -} - -char * -gunique(local) - const char *local; -{ - static char new[MAXPATHLEN]; - char *cp = strrchr(local, '/'); - int d, count=0; - char ext = '1'; - - if (cp) - *cp = '\0'; - d = access(cp == local ? "/" : cp ? local : ".", W_OK); - if (cp) - *cp = '/'; - if (d < 0) { - warn("local: %s", local); - return ((char *) 0); - } - (void)strcpy(new, local); - cp = new + strlen(new); - *cp++ = '.'; - while (!d) { - if (++count == 100) { - puts("runique: can't find unique file name."); - return ((char *) 0); - } - *cp++ = ext; - *cp = '\0'; - if (ext == '9') - ext = '0'; - else - ext++; - if ((d = access(new, F_OK)) < 0) - break; - if (ext != '0') - cp--; - else if (*(cp - 2) == '.') - *(cp - 1) = '1'; - else { - *(cp - 2) = *(cp - 2) + 1; - cp--; - } - } - return (new); -} - -void -abort_remote(din) - FILE *din; -{ - char buf[BUFSIZ]; - int nfnd; - fd_set mask; - - if (cout == NULL) { - warnx("Lost control connection for abort."); - if (ptabflg) - code = -1; - lostpeer(); - return; - } - /* - * send IAC in urgent mode instead of DM because 4.3BSD places oob mark - * after urgent byte rather than before as is protocol now - */ - sprintf(buf, "%c%c%c", IAC, IP, IAC); - if (send(fileno(cout), buf, 3, MSG_OOB) != 3) - warn("abort"); - fprintf(cout, "%cABOR\r\n", DM); - (void)fflush(cout); - FD_ZERO(&mask); - FD_SET(fileno(cin), &mask); - if (din) { - FD_SET(fileno(din), &mask); - } - if ((nfnd = empty(&mask, 10)) <= 0) { - if (nfnd < 0) { - warn("abort"); - } - if (ptabflg) - code = -1; - lostpeer(); - } - if (din && FD_ISSET(fileno(din), &mask)) { - while (read(fileno(din), buf, BUFSIZ) > 0) - /* LOOP */; - } - if (getreply(0) == ERROR && code == 552) { - /* 552 needed for nic style abort */ - (void)getreply(0); - } - (void)getreply(0); -} - -void -ai_unmapped(ai) - struct addrinfo *ai; -{ - struct sockaddr_in6 *sin6; - struct sockaddr_in sin; - - if (ai->ai_family != AF_INET6) - return; - if (ai->ai_addrlen != sizeof(struct sockaddr_in6) || - sizeof(sin) > ai->ai_addrlen) - return; - sin6 = (struct sockaddr_in6 *)ai->ai_addr; - if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - return; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_len = sizeof(struct sockaddr_in); - memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], - sizeof(sin.sin_addr)); - sin.sin_port = sin6->sin6_port; - - ai->ai_family = AF_INET; - memcpy(ai->ai_addr, &sin, sin.sin_len); - ai->ai_addrlen = sin.sin_len; -} diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h deleted file mode 100644 index a906ca8e9b99..000000000000 --- a/usr.bin/ftp/ftp_var.h +++ /dev/null @@ -1,189 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ftp_var.h,v 1.20.2.1 1997/11/18 01:01:37 mellon Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)ftp_var.h 8.4 (Berkeley) 10/9/94 - */ - -/* - * FTP global variables. - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <setjmp.h> -#include <stringlist.h> -#include <netinet/in.h> -#include <netdb.h> - -#ifndef SMALL -#include <histedit.h> -#endif /* !SMALL */ - -#include "extern.h" - -#define HASHBYTES 1024 -#define FTPBUFLEN MAXPATHLEN + 200 - -#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */ - -#define FTP_PORT 21 /* default if ! getservbyname("ftp/tcp") */ -#define HTTP_PORT 80 /* default if ! getservbyname("http/tcp") */ -#ifndef GATE_PORT -#define GATE_PORT 21 /* default if ! getservbyname("ftpgate/tcp") */ -#endif -#ifndef GATE_SERVER -#define GATE_SERVER "" /* default server */ -#endif - -#define PAGER "more" /* default pager if $PAGER isn't set */ - -/* - * Options and other state info. - */ -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 verbose; /* print messages coming back from server */ -int connected; /* 1 = connected to server, -1 = logged in */ -int fromatty; /* input is from a terminal */ -int interactive; /* interactively prompt on m* cmds */ -int confirmrest; /* confirm rest of current m* cmd */ -int debug; /* debugging level */ -int bell; /* ring bell on cmd completion */ -int doglob; /* glob local file names */ -int autologin; /* establish user account on connection */ -int proxy; /* proxy server connection active */ -int proxflag; /* proxy connection exists */ -int gatemode; /* use gate-ftp */ -char *gateserver; /* server to use for gate-ftp */ -int sunique; /* store files on server with unique name */ -int runique; /* store local files with unique name */ -int mcase; /* map upper to lower case for mget names */ -int ntflag; /* use ntin ntout tables for name translation */ -int mapflag; /* use mapin mapout templates on file names */ -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[BUFSIZ]; /* passive port for proxy data connection */ -int passivemode; /* passive mode enabled */ -int restricted_data_ports; /* enable quarantine FTP area */ -char *altarg; /* argv[1] with no shell-like preprocessing */ -char ntin[17]; /* input translation table */ -char ntout[17]; /* output translation table */ -char mapin[MAXPATHLEN]; /* input map template */ -char mapout[MAXPATHLEN]; /* output map template */ -char typename[32]; /* name of file transfer type */ -int type; /* requested file transfer type */ -int curtype; /* current file transfer type */ -char structname[32]; /* name of file transfer structure */ -int stru; /* file transfer structure */ -char formname[32]; /* name of file transfer format */ -int form; /* file transfer format */ -char modename[32]; /* name of file transfer mode */ -int mode; /* file transfer mode */ -char bytename[32]; /* local byte size in ascii */ -int bytesize; /* local byte size in binary */ -int anonftp; /* automatic anonymous login */ -int dirchange; /* remote directory changed by cd command */ -int ttywidth; /* width of tty */ -char *tmpdir; /* temporary directory */ -int try_epsv; /* try EPSV for this session */ - -#ifndef SMALL -int editing; /* command line editing enabled */ -EditLine *el; /* editline(3) status structure */ -History *hist; /* editline(3) history structure */ -HistEvent he; /* editline(3) history structure */ -char *cursor_pos; /* cursor position we're looking for */ -size_t cursor_argc; /* location of cursor in margv */ -size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */ -#endif /* !SMALL */ - -off_t bytes; /* current # of bytes read */ -off_t filesize; /* size of file being transferred */ -char *direction; /* direction transfer is occurring */ -off_t restart_point; /* offset to restart transfer */ - -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 */ - -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 */ - -int dobind; /* bind to specific address */ -struct addrinfo * bindres0; /* addrinfo for address to bind to */ - -jmp_buf toplevel; /* non-local goto stuff for cmd scanner */ - -char line[FTPBUFLEN]; /* input line buffer */ -char *stringbase; /* current scan point in line buffer */ -char argbuf[FTPBUFLEN]; /* argument storage buffer */ -char *argbase; /* current storage point in arg buffer */ -StringList *marg_sl; /* stringlist containing margv */ -int margc; /* count of arguments on input line */ -#define margv (marg_sl->sl_str) /* args parsed from input line */ -int cpend; /* flag: if != 0, then pending server reply */ -int mflag; /* flag: if != 0, then active multi command */ - -int options; /* used during socket creation */ - -/* - * Format of command table. - */ -struct cmd { - char *c_name; /* name of command */ - char *c_help; /* help string */ - char c_bell; /* give bell when command completes */ - char c_conn; /* must be connected to use command */ - char c_proxy; /* proxy server may execute */ -#ifndef SMALL - char *c_complete; /* context sensitive completion list */ -#endif /* !SMALL */ - void (*c_handler) __P((int, char **)); /* function to call */ -}; - -struct macel { - char mac_name[9]; /* macro name */ - char *mac_start; /* start of macro in macbuf */ - char *mac_end; /* end of macro in macbuf */ -}; - -int macnum; /* number of defined macros */ -struct macel macros[16]; -char macbuf[4096]; diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c deleted file mode 100644 index b5bfc6f4b859..000000000000 --- a/usr.bin/ftp/main.c +++ /dev/null @@ -1,711 +0,0 @@ -/* $NetBSD: main.c,v 1.26 1997/10/14 16:31:22 christos Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\ -\tThe Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: main.c,v 1.26 1997/10/14 16:31:22 christos Exp $"); -#endif -#endif /* not lint */ - -/* - * FTP User Program -- Command Interface. - */ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <err.h> -#include <errno.h> -#include <locale.h> -#include <netdb.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "ftp_var.h" -#include "pathnames.h" - -int family = AF_UNSPEC; - -int main __P((int, char **)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int ch, top, rval; - struct passwd *pw = NULL; - char *cp, homedir[MAXPATHLEN], *s; - int dumbterm; - char *src_addr = NULL; - - (void) setlocale(LC_ALL, ""); - - ftpport = "ftp"; - httpport = "http"; - gateport = NULL; - cp = getenv("FTPSERVERPORT"); - if (cp != NULL) - asprintf(&gateport, "%s", cp); - if (!gateport) - asprintf(&gateport, "ftpgate"); - doglob = 1; - interactive = 1; - autologin = 1; - passivemode = 0; - restricted_data_ports = 1; - preserve = 1; - verbose = 0; - progress = 0; - gatemode = 0; -#ifndef SMALL - editing = 0; - el = NULL; - hist = NULL; -#endif - mark = HASHBYTES; - marg_sl = sl_init(); - if ((tmpdir = getenv("TMPDIR")) == NULL) - tmpdir = _PATH_TMP; - - cp = strrchr(argv[0], '/'); - cp = (cp == NULL) ? argv[0] : cp + 1; - if ((s = getenv("FTP_PASSIVE_MODE")) != NULL - && strcasecmp(s, "no") != 0) - passivemode = 1; - if (strcmp(cp, "pftp") == 0) - passivemode = 1; - else if (strcmp(cp, "gate-ftp") == 0) - gatemode = 1; - - gateserver = getenv("FTPSERVER"); - if (gateserver == NULL || *gateserver == '\0') - gateserver = GATE_SERVER; - if (gatemode) { - if (*gateserver == '\0') { - warnx( -"Neither $FTPSERVER nor GATE_SERVER is defined; disabling gate-ftp"); - gatemode = 0; - } - } - - cp = getenv("TERM"); - if (cp == NULL || strcmp(cp, "dumb") == 0) - dumbterm = 1; - else - dumbterm = 0; - fromatty = isatty(fileno(stdin)); - if (fromatty) { - verbose = 1; /* verbose if from a tty */ -#ifndef SMALL - if (! dumbterm) - editing = 1; /* editing mode on if tty is usable */ -#endif - } - if (isatty(fileno(stdout)) && !dumbterm) - progress = 1; /* progress bar on if tty is usable */ - - while ((ch = getopt(argc, argv, "46adeginpP:s:tUvV")) != -1) { - switch (ch) { - case '4': - family = AF_INET; - break; -#ifdef INET6 - case '6': - family = AF_INET6; - break; -#endif - case 'a': - anonftp = 1; - break; - - case 'd': - options |= SO_DEBUG; - debug++; - break; - - case 'e': -#ifndef SMALL - editing = 0; -#endif - break; - - case 'g': - doglob = 0; - break; - - case 'i': - interactive = 0; - break; - - case 'n': - autologin = 0; - break; - - case 'p': - passivemode = 1; - break; - - case 'P': - ftpport = optarg; - break; - - case 's': - dobind = 1; - src_addr = optarg; - break; - - case 't': - trace = 1; - break; - - case 'U': - restricted_data_ports = 0; - break; - - case 'v': - verbose = 1; - break; - - case 'V': - verbose = 0; - break; - - default: - usage(); - } - } - argc -= optind; - argv += optind; - - cpend = 0; /* no pending replies */ - proxy = 0; /* proxy not active */ - crflag = 1; /* strip c.r. on ascii gets */ - sendport = -1; /* not using ports */ - - if (dobind) { - struct addrinfo hints; - struct addrinfo *res; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - error = getaddrinfo(src_addr, NULL, &hints, &res); - if (error) { - warnx("%s: %s", src_addr, gai_strerror(error)); - if (error == EAI_SYSTEM) - warnx("%s", strerror(errno)); - exit(1); - } - bindres0 = res; - } - - /* - * Set up the home directory in case we're globbing. - */ - cp = getlogin(); - if (cp != NULL) { - pw = getpwnam(cp); - } - if (pw == NULL) - pw = getpwuid(getuid()); - if (pw != NULL) { - home = homedir; - (void)strcpy(home, pw->pw_dir); - } - - setttywidth(0); - (void)signal(SIGWINCH, setttywidth); - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&argc; - (void)&argv; -#endif - - if (argc > 0) { - if (strchr(argv[0], ':') != NULL && ! isipv6addr(argv[0])) { - anonftp = 1; /* Handle "automatic" transfers. */ - rval = auto_fetch(argc, argv); - if (rval >= 0) /* -1 == connected and cd-ed */ - exit(rval); - } else { - char *xargv[4], **xargp = xargv; - -#ifdef __GNUC__ /* XXX: to shut up gcc warnings */ - (void)&xargp; -#endif - if (setjmp(toplevel)) - exit(0); - (void)signal(SIGINT, (sig_t)intr); - (void)signal(SIGPIPE, (sig_t)lostpeer); - *xargp++ = __progname; - *xargp++ = argv[0]; /* host */ - if (argc > 1) - *xargp++ = argv[1]; /* port */ - *xargp = NULL; - setpeer(xargp-xargv, xargv); - } - } -#ifndef SMALL - controlediting(); -#endif /* !SMALL */ - top = setjmp(toplevel) == 0; - if (top) { - (void)signal(SIGINT, (sig_t)intr); - (void)signal(SIGPIPE, (sig_t)lostpeer); - } - for (;;) { - cmdscanner(top); - top = 1; - } -} - -void -intr() -{ - - alarmtimer(0); - longjmp(toplevel, 1); -} - -void -lostpeer() -{ - - alarmtimer(0); - if (connected) { - if (cout != NULL) { - (void)shutdown(fileno(cout), 1+1); - (void)fclose(cout); - cout = NULL; - } - if (data >= 0) { - (void)shutdown(data, 1+1); - (void)close(data); - data = -1; - } - connected = 0; - } - pswitch(1); - if (connected) { - if (cout != NULL) { - (void)shutdown(fileno(cout), 1+1); - (void)fclose(cout); - cout = NULL; - } - connected = 0; - } - proxflag = 0; - pswitch(0); -} - -/* - * Generate a prompt - */ -char * -prompt() -{ - return ("ftp> "); -} - -/* - * Command parser. - */ -void -cmdscanner(top) - int top; -{ - struct cmd *c; - int num; - - if (!top -#ifndef SMALL - && !editing -#endif /* !SMALL */ - ) - (void)putchar('\n'); - for (;;) { -#ifndef SMALL - if (!editing) { -#endif /* !SMALL */ - if (fromatty) - fputs(prompt(), stdout); - (void)fflush(stdout); - if (fgets(line, sizeof(line), stdin) == NULL) - quit(0, 0); - num = strlen(line); - if (num == 0) - break; - if (line[--num] == '\n') { - if (num == 0) - break; - line[num] = '\0'; - } else if (num == sizeof(line) - 2) { - puts("sorry, input line too long."); - while ((num = getchar()) != '\n' && num != EOF) - /* void */; - break; - } /* else it was a line without a newline */ -#ifndef SMALL - } else { - const char *buf; - cursor_pos = NULL; - - if ((buf = el_gets(el, &num)) == NULL || num == 0) - quit(0, 0); - if (buf[--num] == '\n') { - if (num == 0) - break; - } else if (num >= sizeof(line)) { - puts("sorry, input line too long."); - break; - } - memcpy(line, buf, num); - line[num] = '\0'; - history(hist, &he, H_ENTER, buf); - } -#endif /* !SMALL */ - - makeargv(); - if (margc == 0) - continue; -#if 0 && !defined(SMALL) /* XXX: don't want el_parse */ - /* - * el_parse returns -1 to signal that it's not been handled - * internally. - */ - if (el_parse(el, margc, margv) != -1) - continue; -#endif /* !SMALL */ - c = getcmd(margv[0]); - if (c == (struct cmd *)-1) { - puts("?Ambiguous command."); - continue; - } - if (c == 0) { - puts("?Invalid command."); - continue; - } - if (c->c_conn && !connected) { - puts("Not connected."); - continue; - } - confirmrest = 0; - (*c->c_handler)(margc, margv); - if (bell && c->c_bell) - (void)putchar('\007'); - if (c->c_handler != help) - break; - } - (void)signal(SIGINT, (sig_t)intr); - (void)signal(SIGPIPE, (sig_t)lostpeer); -} - -struct cmd * -getcmd(name) - const char *name; -{ - const char *p, *q; - struct cmd *c, *found; - int nmatches, longest; - - if (name == NULL) - return (0); - - longest = 0; - nmatches = 0; - found = 0; - for (c = cmdtab; (p = c->c_name) != NULL; c++) { - for (q = name; *q == *p++; q++) - if (*q == 0) /* exact match? */ - return (c); - if (!*q) { /* the name was a prefix */ - if (q - name > longest) { - longest = q - name; - nmatches = 1; - found = c; - } else if (q - name == longest) - nmatches++; - } - } - if (nmatches > 1) - return ((struct cmd *)-1); - return (found); -} - -/* - * Slice a string up into argc/argv. - */ - -int slrflag; - -void -makeargv() -{ - char *argp; - - stringbase = line; /* scan from first of buffer */ - argbase = argbuf; /* store from first of buffer */ - slrflag = 0; - marg_sl->sl_cur = 0; /* reset to start of marg_sl */ - for (margc = 0; ; margc++) { - argp = slurpstring(); - sl_add(marg_sl, argp); - if (argp == NULL) - break; - } -#ifndef SMALL - if (cursor_pos == line) { - cursor_argc = 0; - cursor_argo = 0; - } else if (cursor_pos != NULL) { - cursor_argc = margc; - cursor_argo = strlen(margv[margc-1]); - } -#endif /* !SMALL */ -} - -#ifdef SMALL -#define INC_CHKCURSOR(x) (x)++ -#else /* !SMALL */ -#define INC_CHKCURSOR(x) { (x)++ ; \ - if (x == cursor_pos) { \ - cursor_argc = margc; \ - cursor_argo = ap-argbase; \ - cursor_pos = NULL; \ - } } - -#endif /* !SMALL */ - -/* - * Parse string into argbuf; - * implemented with FSM to - * handle quoting and strings - */ -char * -slurpstring() -{ - int got_one = 0; - char *sb = stringbase; - char *ap = argbase; - char *tmp = argbase; /* will return this if token found */ - - if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */ - switch (slrflag) { /* and $ as token for macro invoke */ - case 0: - slrflag++; - INC_CHKCURSOR(stringbase); - return ((*sb == '!') ? "!" : "$"); - /* NOTREACHED */ - case 1: - slrflag++; - altarg = stringbase; - break; - default: - break; - } - } - -S0: - switch (*sb) { - - case '\0': - goto OUT; - - case ' ': - case '\t': - INC_CHKCURSOR(sb); - goto S0; - - default: - switch (slrflag) { - case 0: - slrflag++; - break; - case 1: - slrflag++; - altarg = sb; - break; - default: - break; - } - goto S1; - } - -S1: - switch (*sb) { - - case ' ': - case '\t': - case '\0': - goto OUT; /* end of token */ - - case '\\': - INC_CHKCURSOR(sb); - goto S2; /* slurp next character */ - - case '"': - INC_CHKCURSOR(sb); - goto S3; /* slurp quoted string */ - - default: - *ap = *sb; /* add character to token */ - ap++; - INC_CHKCURSOR(sb); - got_one = 1; - goto S1; - } - -S2: - switch (*sb) { - - case '\0': - goto OUT; - - default: - *ap = *sb; - ap++; - INC_CHKCURSOR(sb); - got_one = 1; - goto S1; - } - -S3: - switch (*sb) { - - case '\0': - goto OUT; - - case '"': - INC_CHKCURSOR(sb); - goto S1; - - default: - *ap = *sb; - ap++; - INC_CHKCURSOR(sb); - got_one = 1; - goto S3; - } - -OUT: - if (got_one) - *ap++ = '\0'; - argbase = ap; /* update storage pointer */ - stringbase = sb; /* update scan pointer */ - if (got_one) { - return (tmp); - } - switch (slrflag) { - case 0: - slrflag++; - break; - case 1: - slrflag++; - altarg = (char *) 0; - break; - default: - break; - } - return ((char *)0); -} - -/* - * Help command. - * Call each command handler with argc == 0 and argv[0] == name. - */ -void -help(argc, argv) - int argc; - char *argv[]; -{ - struct cmd *c; - - if (argc == 1) { - StringList *buf; - - buf = sl_init(); - printf("%sommands may be abbreviated. Commands are:\n\n", - proxy ? "Proxy c" : "C"); - for (c = cmdtab; c < &cmdtab[NCMDS]; c++) - if (c->c_name && (!proxy || c->c_proxy)) - sl_add(buf, c->c_name); - list_vertical(buf); - sl_free(buf, 0); - return; - } - -#define HELPINDENT ((int) sizeof("disconnect")) - - while (--argc > 0) { - char *arg; - - arg = *++argv; - c = getcmd(arg); - if (c == (struct cmd *)-1) - printf("?Ambiguous help command %s\n", arg); - else if (c == (struct cmd *)0) - printf("?Invalid help command %s\n", arg); - else - printf("%-*s\t%s\n", HELPINDENT, - c->c_name, c->c_help); - } -} - -void -usage() -{ - (void)fprintf(stderr, - "usage: %s [-46adeginptUvV] [-P port] [-s src_addr] [host [port]]\n" - " %s host:path[/]\n" - " %s ftp://host[:port]/path[/]\n" - " %s http://host[:port]/file\n", - __progname, __progname, __progname, __progname); - exit(1); -} diff --git a/usr.bin/ftp/pathnames.h b/usr.bin/ftp/pathnames.h deleted file mode 100644 index bf71177a33d4..000000000000 --- a/usr.bin/ftp/pathnames.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: pathnames.h,v 1.7 1997/01/09 20:19:40 tls Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 - */ - -#include <paths.h> - -#define TMPFILE "ftpXXXXXX" diff --git a/usr.bin/ftp/ruserpass.c b/usr.bin/ftp/ruserpass.c deleted file mode 100644 index 62a5c9c4305c..000000000000 --- a/usr.bin/ftp/ruserpass.c +++ /dev/null @@ -1,306 +0,0 @@ -/* $NetBSD: ruserpass.c,v 1.14.2.1 1997/11/18 01:02:05 mellon Exp $ */ - -/* - * Copyright (c) 1985, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95"; -#else -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: ruserpass.c,v 1.14.2.1 1997/11/18 01:02:05 mellon Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "ftp_var.h" - -static int token __P((void)); -static FILE *cfile; - -#define DEFAULT 1 -#define LOGIN 2 -#define PASSWD 3 -#define ACCOUNT 4 -#define MACDEF 5 -#define ID 10 -#define MACH 11 - -static char tokval[100]; - -static struct toktab { - char *tokstr; - int tval; -} toktab[]= { - { "default", DEFAULT }, - { "login", LOGIN }, - { "password", PASSWD }, - { "passwd", PASSWD }, - { "account", ACCOUNT }, - { "machine", MACH }, - { "macdef", MACDEF }, - { NULL, 0 } -}; - -int -ruserpass(host, aname, apass, aacct) - const char *host; - char **aname, **apass, **aacct; -{ - char *hdir, buf[BUFSIZ], *tmp; - char myname[MAXHOSTNAMELEN], *mydomain; - int t, i, c, usedefault = 0; - struct stat stb; - - hdir = getenv("HOME"); - if (hdir == NULL) - hdir = "."; - if (strlen(hdir) + sizeof(".netrc") < sizeof(buf)) { - (void)snprintf(buf, sizeof buf, "%s/.netrc", hdir); - } else { - warnx("%s/.netrc: %s", hdir, strerror(ENAMETOOLONG)); - return (0); - } - cfile = fopen(buf, "r"); - if (cfile == NULL) { - if (errno != ENOENT) - warn("%s", buf); - return (0); - } - if (gethostname(myname, sizeof(myname)) < 0) - myname[0] = '\0'; - if ((mydomain = strchr(myname, '.')) == NULL) - mydomain = ""; -next: - while ((t = token())) switch(t) { - - case DEFAULT: - usedefault = 1; - /* FALL THROUGH */ - - case MACH: - if (!usedefault) { - if (token() != ID) - continue; - /* - * Allow match either for user's input host name - * or official hostname. Also allow match of - * incompletely-specified host in local domain. - */ - if (strcasecmp(host, tokval) == 0) - goto match; - if (strcasecmp(hostname, tokval) == 0) - goto match; - if ((tmp = strchr(hostname, '.')) != NULL && - strcasecmp(tmp, mydomain) == 0 && - strncasecmp(hostname, tokval, tmp-hostname) == 0 && - tokval[tmp - hostname] == '\0') - goto match; - if ((tmp = strchr(host, '.')) != NULL && - strcasecmp(tmp, mydomain) == 0 && - strncasecmp(host, tokval, tmp - host) == 0 && - tokval[tmp - host] == '\0') - goto match; - continue; - } - match: - while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { - - case LOGIN: - if (token()) { - if (*aname == NULL) { - *aname = strdup(tokval); - if (*aname == NULL) - err(1, "can't strdup *aname"); - } else { - if (strcmp(*aname, tokval)) - goto next; - } - } - break; - case PASSWD: - if ((*aname == NULL || strcmp(*aname, "anonymous")) && - fstat(fileno(cfile), &stb) >= 0 && - (stb.st_mode & 077) != 0) { - warnx("Error: .netrc file is readable by others."); - warnx("Remove password or make file unreadable by others."); - goto bad; - } - if (token() && *apass == NULL) { - *apass = strdup(tokval); - if (*apass == NULL) - err(1, "can't strdup *apass"); - } - break; - case ACCOUNT: - if (fstat(fileno(cfile), &stb) >= 0 - && (stb.st_mode & 077) != 0) { - warnx("Error: .netrc file is readable by others."); - warnx("Remove account or make file unreadable by others."); - goto bad; - } - if (token() && *aacct == NULL) { - *aacct = strdup(tokval); - if (*aacct == NULL) - err(1, "can't strdup *aacct"); - } - break; - case MACDEF: - if (proxy) { - (void)fclose(cfile); - return (0); - } - while ((c=getc(cfile)) != EOF) - if (c != ' ' && c != '\t') - break; - if (c == EOF || c == '\n') { - puts("Missing macdef name argument."); - goto bad; - } - if (macnum == 16) { - puts( -"Limit of 16 macros have already been defined."); - goto bad; - } - tmp = macros[macnum].mac_name; - *tmp++ = c; - for (i=0; i < 8 && (c=getc(cfile)) != EOF && - (!isascii(c) || !isspace(c)); ++i) { - *tmp++ = c; - } - if (c == EOF) { - puts( -"Macro definition missing null line terminator."); - goto bad; - } - *tmp = '\0'; - if (c != '\n') { - while ((c=getc(cfile)) != EOF && c != '\n'); - } - if (c == EOF) { - puts( -"Macro definition missing null line terminator."); - goto bad; - } - if (macnum == 0) { - macros[macnum].mac_start = macbuf; - } - else { - macros[macnum].mac_start = - macros[macnum-1].mac_end + 1; - } - tmp = macros[macnum].mac_start; - while (tmp != macbuf + 4096) { - if ((c=getc(cfile)) == EOF) { - puts( -"Macro definition missing null line terminator."); - goto bad; - } - *tmp = c; - if (*tmp == '\n') { - if (*(tmp-1) == '\0') { - macros[macnum++].mac_end = tmp - 1; - break; - } - *tmp = '\0'; - } - tmp++; - } - if (tmp == macbuf + 4096) { - puts("4K macro buffer exceeded."); - goto bad; - } - break; - default: - warnx("Unknown .netrc keyword %s", tokval); - break; - } - goto done; - } -done: - (void)fclose(cfile); - return (0); -bad: - (void)fclose(cfile); - return (-1); -} - -static int -token() -{ - char *cp; - int c; - struct toktab *t; - - if (feof(cfile) || ferror(cfile)) - return (0); - while ((c = getc(cfile)) != EOF && - (c == '\n' || c == '\t' || c == ' ' || c == ',')) - continue; - if (c == EOF) - return (0); - cp = tokval; - if (c == '"') { - while ((c = getc(cfile)) != EOF && c != '"') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } else { - *cp++ = c; - while ((c = getc(cfile)) != EOF - && c != '\n' && c != '\t' && c != ' ' && c != ',') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } - *cp = 0; - if (tokval[0] == 0) - return (0); - for (t = toktab; t->tokstr; t++) - if (!strcmp(t->tokstr, tokval)) - return (t->tval); - return (ID); -} diff --git a/usr.bin/ftp/util.c b/usr.bin/ftp/util.c deleted file mode 100644 index 00bb9d2704dd..000000000000 --- a/usr.bin/ftp/util.c +++ /dev/null @@ -1,897 +0,0 @@ -/* $NetBSD: util.c,v 1.16.2.1 1997/11/18 01:02:33 mellon Exp $ */ - -/* - * Copyright (c) 1985, 1989, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$FreeBSD$"); -__RCSID_SOURCE("$NetBSD: util.c,v 1.16.2.1 1997/11/18 01:02:33 mellon Exp $"); -#endif /* not lint */ - -/* - * FTP User Program -- Misc support routines - */ -#include <sys/ioctl.h> -#include <sys/time.h> -#include <arpa/ftp.h> - -#include <ctype.h> -#include <err.h> -#include <fcntl.h> -#include <glob.h> -#include <limits.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#ifdef INET6 -#include <netdb.h> -#endif - -#include "ftp_var.h" -#include "pathnames.h" - -#ifndef SECSPERHOUR -#define SECSPERHOUR (60*60) -#endif - -/* - * Connect to peer server and - * auto-login, if possible. - */ -void -setpeer(argc, argv) - int argc; - char *argv[]; -{ - char *host; - char *port; - - if (connected) { - printf("Already connected to %s, use close first.\n", - hostname); - code = -1; - return; - } - if (argc < 2) - (void)another(&argc, &argv, "to"); - if (argc < 2 || argc > 3) { - printf("usage: %s host-name [port]\n", argv[0]); - code = -1; - return; - } - if (gatemode) - port = gateport; - else - port = ftpport; - if (argc > 2) - port = strdup(argv[2]); - - if (gatemode) { - if (gateserver == NULL || *gateserver == '\0') - errx(1, "gateserver not defined (shouldn't happen)"); - host = hookup(gateserver, port); - } else - host = hookup(argv[1], port); - - if (host) { - int overbose; - - if (gatemode) { - if (command("PASSERVE %s", argv[1]) != COMPLETE) - return; - if (verbose) - printf("Connected via pass-through server %s\n", - gateserver); - } - - connected = 1; - try_epsv = 1; - /* - * Set up defaults for FTP. - */ - (void)strcpy(typename, "ascii"), type = TYPE_A; - curtype = TYPE_A; - (void)strcpy(formname, "non-print"), form = FORM_N; - (void)strcpy(modename, "stream"), mode = MODE_S; - (void)strcpy(structname, "file"), stru = STRU_F; - (void)strcpy(bytename, "8"), bytesize = 8; - if (autologin) - (void)login(argv[1], NULL, NULL); - - overbose = verbose; - if (debug == 0) - verbose = -1; - if (command("SYST") == COMPLETE && overbose) { - char *cp, c; - c = 0; - cp = strchr(reply_string+4, ' '); - if (cp == NULL) - cp = strchr(reply_string+4, '\r'); - if (cp) { - if (cp[-1] == '.') - cp--; - c = *cp; - *cp = '\0'; - } - - printf("Remote system type is %s.\n", reply_string + 4); - if (cp) - *cp = c; - } - if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { - if (proxy) - unix_proxy = 1; - else - unix_server = 1; - /* - * Set type to 0 (not specified by user), - * meaning binary by default, but don't bother - * telling server. We can use binary - * for text files unless changed by the user. - */ - type = 0; - (void)strcpy(typename, "binary"); - if (overbose) - printf("Using %s mode to transfer files.\n", - typename); - } else { - if (proxy) - unix_proxy = 0; - else - unix_server = 0; - if (overbose && - !strncmp(reply_string, "215 TOPS20", 10)) - puts( -"Remember to set tenex mode when transferring binary files from this machine."); - } - verbose = overbose; - } -} - - -/* - * login to remote host, using given username & password if supplied - */ -int -login(host, user, pass) - const char *host; - char *user, *pass; -{ - char tmp[80]; - char *acct; - char anonpass[MAXLOGNAME + 1 + MAXHOSTNAMELEN]; /* "user@hostname" */ - char hostname[MAXHOSTNAMELEN]; - struct passwd *pw; - int n, aflag = 0; - - acct = NULL; - if (user == NULL) { - if (ruserpass(host, &user, &pass, &acct) < 0) { - code = -1; - return (0); - } - } - - /* - * Set up arguments for an anonymous FTP session, if necessary. - */ - if ((user == NULL || pass == NULL) && anonftp) { - memset(anonpass, 0, sizeof(anonpass)); - memset(hostname, 0, sizeof(hostname)); - - /* - * Set up anonymous login password. - */ - if ((user = getlogin()) == NULL) { - if ((pw = getpwuid(getuid())) == NULL) - user = "anonymous"; - else - user = pw->pw_name; - } - gethostname(hostname, MAXHOSTNAMELEN); -#ifndef DONT_CHEAT_ANONPASS - /* - * Every anonymous FTP server I've encountered - * will accept the string "username@", and will - * append the hostname itself. We do this by default - * since many servers are picky about not having - * a FQDN in the anonymous password. - thorpej@netbsd.org - */ - snprintf(anonpass, sizeof(anonpass) - 1, "%s@", - user); -#else - snprintf(anonpass, sizeof(anonpass) - 1, "%s@%s", - user, hp->h_name); -#endif - pass = anonpass; - user = "anonymous"; /* as per RFC 1635 */ - } - - while (user == NULL) { - char *myname = getlogin(); - - if (myname == NULL && (pw = getpwuid(getuid())) != NULL) - myname = pw->pw_name; - if (myname) - printf("Name (%s:%s): ", host, myname); - else - printf("Name (%s): ", host); - (void)fflush(stdout); - if (fgets(tmp, sizeof(tmp) - 1, stdin) == NULL) - return (0); - tmp[strlen(tmp) - 1] = '\0'; - if (*tmp == '\0') - user = myname; - else - user = tmp; - } - n = command("USER %s", user); - if (n == CONTINUE) { - if (pass == NULL) - pass = getpass("Password:"); - n = command("PASS %s", pass); - } - if (n == CONTINUE) { - aflag++; - if (acct == NULL) - acct = getpass("Account:"); - n = command("ACCT %s", acct); - } - if ((n != COMPLETE) || - (!aflag && acct != NULL && command("ACCT %s", acct) != COMPLETE)) { - warnx("Login failed."); - return (0); - } - if (proxy) - return (1); - connected = -1; - for (n = 0; n < macnum; ++n) { - if (!strcmp("init", macros[n].mac_name)) { - (void)strcpy(line, "$init"); - makeargv(); - domacro(margc, margv); - break; - } - } - return (1); -} - -/* - * `another' gets another argument, and stores the new argc and argv. - * It reverts to the top level (via main.c's intr()) on EOF/error. - * - * Returns false if no new arguments have been added. - */ -int -another(pargc, pargv, prompt) - int *pargc; - char ***pargv; - const char *prompt; -{ - int len = strlen(line), ret; - - if (len >= sizeof(line) - 3) { - puts("sorry, arguments too long."); - intr(); - } - printf("(%s) ", prompt); - line[len++] = ' '; - if (fgets(&line[len], sizeof(line) - len, stdin) == NULL) - intr(); - len += strlen(&line[len]); - if (len > 0 && line[len - 1] == '\n') - line[len - 1] = '\0'; - makeargv(); - ret = margc > *pargc; - *pargc = margc; - *pargv = margv; - return (ret); -} - -/* - * glob files given in argv[] from the remote server. - * if errbuf isn't NULL, store error messages there instead - * of writing to the screen. - */ -char * -remglob(argv, doswitch, errbuf) - char *argv[]; - int doswitch; - char **errbuf; -{ - char temp[MAXPATHLEN]; - static char buf[MAXPATHLEN]; - static FILE *ftemp = NULL; - static char **args; - int oldverbose, oldhash, fd; - char *cp, *mode; - - if (!mflag) { - if (!doglob) - args = NULL; - else { - if (ftemp) { - (void)fclose(ftemp); - ftemp = NULL; - } - } - return (NULL); - } - if (!doglob) { - if (args == NULL) - args = argv; - if ((cp = *++args) == NULL) - args = NULL; - return (cp); - } - if (ftemp == NULL) { - (void)snprintf(temp, sizeof(temp), "%s/%s", tmpdir, TMPFILE); - if ((fd = mkstemp(temp)) < 0) { - warn("unable to create temporary file %s", temp); - return (NULL); - } - close(fd); - oldverbose = verbose; - verbose = (errbuf != NULL) ? -1 : 0; - oldhash = hash; - hash = 0; - if (doswitch) - pswitch(!proxy); - for (mode = "w"; *++argv != NULL; mode = "a") - recvrequest("NLST", temp, *argv, mode, 0, 0); - if ((code / 100) != COMPLETE) { - if (errbuf != NULL) - *errbuf = reply_string; - } - if (doswitch) - pswitch(!proxy); - verbose = oldverbose; - hash = oldhash; - ftemp = fopen(temp, "r"); - (void)unlink(temp); - if (ftemp == NULL) { - if (errbuf == NULL) - puts("can't find list of remote files, oops."); - else - *errbuf = - "can't find list of remote files, oops."; - return (NULL); - } - } - if (fgets(buf, sizeof(buf), ftemp) == NULL) { - (void)fclose(ftemp); - ftemp = NULL; - return (NULL); - } - if ((cp = strchr(buf, '\n')) != NULL) - *cp = '\0'; - return (buf); -} - -int -confirm(cmd, file) - const char *cmd, *file; -{ - char line[BUFSIZ]; - - if (!interactive || confirmrest) - return (1); - printf("%s %s? ", cmd, file); - (void)fflush(stdout); - if (fgets(line, sizeof(line), stdin) == NULL) - return (0); - switch (tolower((unsigned char)*line)) { - case 'n': - return (0); - case 'p': - interactive = 0; - puts("Interactive mode: off."); - break; - case 'a': - confirmrest = 1; - printf("Prompting off for duration of %s.\n", cmd); - break; - } - return (1); -} - -/* - * Glob a local file name specification with - * the expectation of a single return value. - * Can't control multiple values being expanded - * from the expression, we return only the first. - */ -int -globulize(cpp) - char **cpp; -{ - glob_t gl; - int flags; - - if (!doglob) - return (1); - - flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; - memset(&gl, 0, sizeof(gl)); - if (glob(*cpp, flags, NULL, &gl) || - gl.gl_pathc == 0) { - warnx("%s: not found", *cpp); - globfree(&gl); - return (0); - } - /* XXX: caller should check if *cpp changed, and - * free(*cpp) if that is the case - */ - *cpp = strdup(gl.gl_pathv[0]); - globfree(&gl); - return (1); -} - -/* - * determine size of remote file - */ -off_t -remotesize(file, noisy) - const char *file; - int noisy; -{ - int overbose; - off_t size; - - overbose = verbose; - size = -1; - if (debug == 0) - verbose = -1; - if (command("SIZE %s", file) == COMPLETE) { - char *cp, *ep; - - cp = strchr(reply_string, ' '); - if (cp != NULL) { - cp++; - size = strtoq(cp, &ep, 10); - if (*ep != '\0' && !isspace((unsigned char)*ep)) - size = -1; - } - } else if (noisy && debug == 0) - puts(reply_string); - verbose = overbose; - return (size); -} - -/* - * determine last modification time (in GMT) of remote file - */ -time_t -remotemodtime(file, noisy) - const char *file; - int noisy; -{ - struct tm timebuf; - time_t rtime; - int len, month, ocode, overbose, y2kbug, year; - char *fmt; - char mtbuf[17]; - - overbose = verbose; - ocode = code; - rtime = -1; - if (debug == 0) - verbose = -1; - if (command("MDTM %s", file) == COMPLETE) { - memset(&timebuf, 0, sizeof(timebuf)); - /* - * Parse the time string, which is expected to be 14 - * characters long. Some broken servers send tm_year - * formatted with "19%02d", which produces an incorrect - * (but parsable) 15 characters for years >= 2000. - * Scan for invalid trailing junk by accepting up to 16 - * characters. - */ - if (sscanf(reply_string, "%*s %16s", mtbuf) == 1) { - fmt = NULL; - len = strlen(mtbuf); - y2kbug = 0; - if (len == 15 && strncmp(mtbuf, "19", 2) == 0) { - fmt = "19%03d%02d%02d%02d%02d%02d"; - y2kbug = 1; - } else if (len == 14) - fmt = "%04d%02d%02d%02d%02d%02d"; - if (fmt != NULL) { - if (sscanf(mtbuf, fmt, &year, &month, - &timebuf.tm_mday, &timebuf.tm_hour, - &timebuf.tm_min, &timebuf.tm_sec) == 6) { - timebuf.tm_isdst = -1; - timebuf.tm_mon = month - 1; - if (y2kbug) - timebuf.tm_year = year; - else - timebuf.tm_year = year - 1900; - rtime = mktime(&timebuf); - } - } - } - if (rtime == -1) { - if (noisy || debug != 0) - printf("Can't convert %s to a time.\n", mtbuf); - } else - rtime += timebuf.tm_gmtoff; /* conv. local -> GMT */ - } else if (noisy && debug == 0) - puts(reply_string); - verbose = overbose; - if (rtime == -1) - code = ocode; - return (rtime); -} - -void updateprogressmeter __P((int)); - -void -updateprogressmeter(dummy) - int dummy; -{ - static pid_t pgrp = -1; - int ctty_pgrp; - - if (pgrp == -1) - pgrp = getpgrp(); - - /* - * print progress bar only if we are foreground process. - */ - if (ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && - ctty_pgrp == (int)pgrp) - progressmeter(0); -} - -/* - * Display a transfer progress bar if progress is non-zero. - * SIGALRM is hijacked for use by this function. - * - Before the transfer, set filesize to size of file (or -1 if unknown), - * and call with flag = -1. This starts the once per second timer, - * and a call to updateprogressmeter() upon SIGALRM. - * - During the transfer, updateprogressmeter will call progressmeter - * with flag = 0 - * - After the transfer, call with flag = 1 - */ -static struct timeval start; - -void -progressmeter(flag) - int flag; -{ - /* - * List of order of magnitude prefixes. - * The last is `P', as 2^64 = 16384 Petabytes - */ - static const char prefixes[] = " KMGTP"; - - static struct timeval lastupdate; - static off_t lastsize; - struct timeval now, td, wait; - off_t cursize, abbrevsize; - double elapsed; - int ratio, barlength, i, len, n; - off_t remaining; - char buf[256]; - - len = 0; - - if (flag == -1) { - (void)gettimeofday(&start, (struct timezone *)0); - lastupdate = start; - lastsize = restart_point; - } - (void)gettimeofday(&now, (struct timezone *)0); - if (!progress || filesize <= 0) - return; - cursize = bytes + restart_point; - - ratio = cursize * 100 / filesize; - ratio = MAX(ratio, 0); - ratio = MIN(ratio, 100); - n = snprintf(buf + len, sizeof(buf) - len, "\r%3d%% ", ratio); - if (n > 0 && n < sizeof(buf) - len) - len += n; - - barlength = ttywidth - 30; - if (barlength > 0) { - if (barlength > 154) - barlength = 154; /* Number of '*'s below */ - i = barlength * ratio / 100; - n = snprintf(buf + len, sizeof(buf) - len, - "|%.*s%*s|", i, -"*****************************************************************************" -"*****************************************************************************", - barlength - i, ""); - if (n > 0 && n < sizeof(buf) - len) - len += n; - } - - i = 0; - abbrevsize = cursize; - while (abbrevsize >= 100000 && i < sizeof(prefixes)) { - i++; - abbrevsize >>= 10; - } - n = snprintf(buf + len, sizeof(buf) - len, - " %5qd %c%c ", (long long)abbrevsize, prefixes[i], - prefixes[i] == ' ' ? ' ' : 'B'); - if (n > 0 && n < sizeof(buf) - len) - len += n; - - timersub(&now, &lastupdate, &wait); - if (cursize > lastsize) { - lastupdate = now; - lastsize = cursize; - if (wait.tv_sec >= STALLTIME) { /* fudge out stalled time */ - start.tv_sec += wait.tv_sec; - start.tv_usec += wait.tv_usec; - } - wait.tv_sec = 0; - } - - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - - if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) { - n = snprintf(buf + len, sizeof(buf) - len, - " --:-- ETA"); - } else if (wait.tv_sec >= STALLTIME) { - n = snprintf(buf + len, sizeof(buf) - len, - " - stalled -"); - } else { - remaining = - ((filesize - restart_point) / (bytes / elapsed) - elapsed); - if (remaining >= 100 * SECSPERHOUR) - n = snprintf(buf + len, sizeof(buf) - len, - " --:-- ETA"); - else { - i = remaining / SECSPERHOUR; - if (i) - n = snprintf(buf + len, sizeof(buf) - len, - "%2d:", i); - else - n = snprintf(buf + len, sizeof(buf) - len, - " "); - if (n > 0 && n < sizeof(buf) - len) - len += n; - i = remaining % SECSPERHOUR; - n = snprintf(buf + len, sizeof(buf) - len, - "%02d:%02d ETA", i / 60, i % 60); - } - } - if (n > 0 && n < sizeof(buf) - len) - len += n; - (void)write(STDOUT_FILENO, buf, len); - - if (flag == -1) { - (void)signal(SIGALRM, updateprogressmeter); - alarmtimer(1); /* set alarm timer for 1 Hz */ - } else if (flag == 1) { - alarmtimer(0); - (void)putchar('\n'); - } - fflush(stdout); -} - -/* - * Display transfer statistics. - * Requires start to be initialised by progressmeter(-1), - * direction to be defined by xfer routines, and filesize and bytes - * to be updated by xfer routines - * If siginfo is nonzero, an ETA is displayed, and the output goes to STDERR - * instead of STDOUT. - */ -void -ptransfer(siginfo) - int siginfo; -{ - struct timeval now, td; - double elapsed; - off_t bs; - int meg, n, remaining, hh, len; - char buf[100]; - - if (!verbose && !siginfo) - return; - - (void)gettimeofday(&now, (struct timezone *)0); - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - bs = bytes / (elapsed == 0.0 ? 1 : elapsed); - meg = 0; - if (bs > (1024 * 1024)) - meg = 1; - len = 0; - n = snprintf(buf + len, sizeof(buf) - len, - "%qd byte%s %s in %.2f seconds (%.2f %sB/s)\n", - (long long)bytes, bytes == 1 ? "" : "s", direction, elapsed, - bs / (1024.0 * (meg ? 1024.0 : 1.0)), meg ? "M" : "K"); - if (n > 0 && n < sizeof(buf) - len) - len += n; - if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0 - && bytes + restart_point <= filesize) { - remaining = (int)((filesize - restart_point) / - (bytes / elapsed) - elapsed); - hh = remaining / SECSPERHOUR; - remaining %= SECSPERHOUR; - len--; /* decrement len to overwrite \n */ - n = snprintf(buf + len, sizeof(buf) - len, - " ETA: %02d:%02d:%02d\n", hh, remaining / 60, - remaining % 60); - if (n > 0 && n < sizeof(buf) - len) - len += n; - } - (void)write(siginfo ? STDERR_FILENO : STDOUT_FILENO, buf, len); -} - -/* - * List words in stringlist, vertically arranged - */ -void -list_vertical(sl) - StringList *sl; -{ - int i, j, w; - int columns, width, lines, items; - char *p; - - width = items = 0; - - for (i = 0 ; i < sl->sl_cur ; i++) { - w = strlen(sl->sl_str[i]); - if (w > width) - width = w; - } - width = (width + 8) &~ 7; - - columns = ttywidth / width; - if (columns == 0) - columns = 1; - lines = (sl->sl_cur + columns - 1) / columns; - for (i = 0; i < lines; i++) { - for (j = 0; j < columns; j++) { - p = sl->sl_str[j * lines + i]; - if (p) - fputs(p, stdout); - if (j * lines + i + lines >= sl->sl_cur) { - putchar('\n'); - break; - } - w = strlen(p); - while (w < width) { - w = (w + 8) &~ 7; - (void)putchar('\t'); - } - } - } -} - -/* - * Update the global ttywidth value, using TIOCGWINSZ. - */ -void -setttywidth(a) - int a; -{ - struct winsize winsize; - - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) - ttywidth = winsize.ws_col; - else - ttywidth = 80; -} - -/* - * Set the SIGALRM interval timer for wait seconds, 0 to disable. - */ -void -alarmtimer(wait) - int wait; -{ - struct itimerval itv; - - itv.it_value.tv_sec = wait; - itv.it_value.tv_usec = 0; - itv.it_interval = itv.it_value; - setitimer(ITIMER_REAL, &itv, NULL); -} - -/* - * Setup or cleanup EditLine structures - */ -#ifndef SMALL -void -controlediting() -{ - if (editing && el == NULL && hist == NULL) { - /* init editline */ - el = el_init(__progname, stdin, stdout, stderr); - hist = history_init(); /* init the builtin history */ - history(hist, &he, H_EVENT, 100); /* remember 100 events */ - el_set(el, EL_HIST, history, hist); /* use history */ - - el_set(el, EL_EDITOR, "emacs"); /* default editor is emacs */ - el_set(el, EL_PROMPT, prompt); /* set the prompt function */ - - /* add local file completion, bind to TAB */ - el_set(el, EL_ADDFN, "ftp-complete", - "Context sensitive argument completion", - complete); - el_set(el, EL_BIND, "^I", "ftp-complete", NULL); - - el_source(el, NULL); /* read ~/.editrc */ - el_set(el, EL_SIGNAL, 1); - } else if (!editing) { - if (hist) { - history_end(hist); - hist = NULL; - } - if (el) { - el_end(el); - el = NULL; - } - } -} -#endif /* !SMALL */ - -/* - * Determine if given string is an IPv6 address or not. - * Return 1 for yes, 0 for no - */ -int -isipv6addr(const char *addr) -{ - int rv = 0; -#ifdef INET6 - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET6; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(addr, "0", &hints, &res) != 0) - rv = 0; - else { - rv = 1; - freeaddrinfo(res); - } - if (debug) - printf("isipv6addr: got %d for %s\n", rv, addr); -#endif - return (rv == 1) ? 1 : 0; -} |