summaryrefslogtreecommitdiff
path: root/usr.bin/ftp
diff options
context:
space:
mode:
authorMike Heffner <mikeh@FreeBSD.org>2001-12-13 23:46:44 +0000
committerMike Heffner <mikeh@FreeBSD.org>2001-12-13 23:46:44 +0000
commitbfacd15a502c4a23f1a484c620b918b96111c2a0 (patch)
treeb2b4624c2fb26f66d8f381a7fa80e22e726b9af6 /usr.bin/ftp
parent9446b36bab0d206dbf2fc39f2fc04a29b6b693be (diff)
downloadsrc-test2-bfacd15a502c4a23f1a484c620b918b96111c2a0.tar.gz
src-test2-bfacd15a502c4a23f1a484c620b918b96111c2a0.zip
Notes
Diffstat (limited to 'usr.bin/ftp')
-rw-r--r--usr.bin/ftp/Makefile9
-rw-r--r--usr.bin/ftp/cmds.c2214
-rw-r--r--usr.bin/ftp/cmdtab.c230
-rw-r--r--usr.bin/ftp/complete.c377
-rw-r--r--usr.bin/ftp/domacro.c155
-rw-r--r--usr.bin/ftp/extern.h176
-rw-r--r--usr.bin/ftp/fetch.c733
-rw-r--r--usr.bin/ftp/ftp.11456
-rw-r--r--usr.bin/ftp/ftp.c1965
-rw-r--r--usr.bin/ftp/ftp_var.h189
-rw-r--r--usr.bin/ftp/main.c711
-rw-r--r--usr.bin/ftp/pathnames.h41
-rw-r--r--usr.bin/ftp/ruserpass.c306
-rw-r--r--usr.bin/ftp/util.c897
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 < &current_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;
-}