summaryrefslogtreecommitdiffstats
path: root/contrib/lukemftp/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/lukemftp/src')
-rw-r--r--contrib/lukemftp/src/Makefile28
-rw-r--r--contrib/lukemftp/src/Makefile.in43
-rw-r--r--contrib/lukemftp/src/cmds.c2753
-rw-r--r--contrib/lukemftp/src/cmdtab.c309
-rw-r--r--contrib/lukemftp/src/complete.c435
-rw-r--r--contrib/lukemftp/src/domacro.c143
-rw-r--r--contrib/lukemftp/src/extern.h257
-rw-r--r--contrib/lukemftp/src/fetch.c1834
-rw-r--r--contrib/lukemftp/src/ftp.12357
-rw-r--r--contrib/lukemftp/src/ftp.c2171
-rw-r--r--contrib/lukemftp/src/ftp_var.h337
-rw-r--r--contrib/lukemftp/src/main.c1052
-rw-r--r--contrib/lukemftp/src/progressbar.c464
-rw-r--r--contrib/lukemftp/src/progressbar.h99
-rw-r--r--contrib/lukemftp/src/ruserpass.c293
-rw-r--r--contrib/lukemftp/src/util.c1400
-rw-r--r--contrib/lukemftp/src/version.h44
17 files changed, 0 insertions, 14019 deletions
diff --git a/contrib/lukemftp/src/Makefile b/contrib/lukemftp/src/Makefile
deleted file mode 100644
index 79cc5a6..0000000
--- a/contrib/lukemftp/src/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# $NetBSD: Makefile,v 1.30 2005/02/11 15:13:28 jmc Exp $
-# from: @(#)Makefile 8.2 (Berkeley) 4/3/94
-
-.include <bsd.own.mk>
-
-PROG= ftp
-SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \
- progressbar.c ruserpass.c util.c
-
-# Uncomment the following to provide defaults for gate-ftp operation
-#
-#CPPFLAGS+=-DGATE_SERVER=\"ftp-gw.host\" # -DGATE_PORT=21
-
-.if defined(SMALLPROG)
-CPPFLAGS+=-DNO_EDITCOMPLETE -DNO_ABOUT -DNO_AUTH -DNO_HELP -DNO_STATUS
-.else
-LDADD+= -ledit -ltermcap
-DPADD+= ${LIBEDIT} ${LIBTERMCAP}
-.endif
-
-.if (!defined(SMALLPROG) || defined(SMALLPROG_INET6)) && (${USE_INET6} != "no")
-CPPFLAGS+= -DINET6
-.endif
-
-cmds.o fetch.o: version.h
-main.o: ftp_var.h
-
-.include <bsd.prog.mk>
diff --git a/contrib/lukemftp/src/Makefile.in b/contrib/lukemftp/src/Makefile.in
deleted file mode 100644
index bb60f10..0000000
--- a/contrib/lukemftp/src/Makefile.in
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# $Id: Makefile.in,v 1.8 2000/08/08 07:04:27 lukem Exp $
-#
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-SHELL = /bin/sh
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-mandir = @mandir@
-transform = @program_transform_name@
-
-mandircat1 = ${mandir}/cat1
-
-CC = @CC@
-CFLAGS = -I${srcdir} -I${srcdir}/.. -I. -I.. @INCLUDES@ @CFLAGS@
-LIBS = @LIBS@
-LDFLAGS = @LDFLAGS@
-
-INSTALL = @INSTALL@
-
-PROG = ftp
-OBJS = cmds.o cmdtab.o complete.o domacro.o fetch.o ftp.o main.o \
- ruserpass.o util.o
-
-all: ${PROG}
-
-install: all
- -mkdir -p ${bindir}
- ${INSTALL} -m 555 ${PROG} ${bindir}/`echo ${PROG}|sed '$(transform)'`
- -mkdir -p ${mandircat1}
- ${INSTALL} -m 444 ${srcdir}/${PROG}.cat1 ${mandircat1}/`echo ${PROG}|sed '$(transform)'`.1
-
-${PROG}: ${OBJS} @LIBDEPENDS@
- ${CC} ${CFLAGS} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBS}
-
-clean:
- rm -f core ${PROG} ${OBJS}
-
-distclean: clean
- rm -f Makefile
diff --git a/contrib/lukemftp/src/cmds.c b/contrib/lukemftp/src/cmds.c
deleted file mode 100644
index 69dbd18..0000000
--- a/contrib/lukemftp/src/cmds.c
+++ /dev/null
@@ -1,2753 +0,0 @@
-/* $NetBSD: cmds.c,v 1.112 2005/04/11 01:49:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Luke Mewburn.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center.
- *
- * 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.
- */
-
-/*
- * 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. 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.
- */
-
-/*
- * Copyright (C) 1997 and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
-#else
-__RCSID("$NetBSD: cmds.c,v 1.112 2005/04/11 01:49:31 lukem 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 <limits.h>
-#include <netdb.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <libutil.h>
-
-#include "ftp_var.h"
-#include "version.h"
-
-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 }
-};
-
-sigjmp_buf jabort;
-const char *mname;
-
-static int confirm(const char *, const char *);
-
-static const char *doprocess(char *, size_t, const char *, int, int, int);
-static const char *domap(char *, size_t, const char *);
-static const char *docase(char *, size_t, const char *);
-static const char *dotrans(char *, size_t, const char *);
-
-static int
-confirm(const char *cmd, const char *file)
-{
- char line[BUFSIZ];
-
- if (!interactive || confirmrest)
- return (1);
- while (1) {
- fprintf(ttyout, "%s %s [anpqy?]? ", cmd, file);
- (void)fflush(ttyout);
- if (fgets(line, sizeof(line), stdin) == NULL) {
- mflag = 0;
- fprintf(ttyout, "\nEOF received; %s aborted\n", mname);
- clearerr(stdin);
- return (0);
- }
- switch (tolower((unsigned char)*line)) {
- case 'a':
- confirmrest = 1;
- fprintf(ttyout,
- "Prompting off for duration of %s.\n", cmd);
- break;
- case 'p':
- interactive = 0;
- fputs("Interactive mode: off.\n", ttyout);
- break;
- case 'q':
- mflag = 0;
- fprintf(ttyout, "%s aborted.\n", mname);
- /* FALLTHROUGH */
- case 'n':
- return (0);
- case '?':
- fprintf(ttyout,
- " confirmation options:\n"
- "\ta answer `yes' for the duration of %s\n"
- "\tn answer `no' for this file\n"
- "\tp turn off `prompt' mode\n"
- "\tq stop the current %s\n"
- "\ty answer `yes' for this file\n"
- "\t? this help list\n",
- cmd, cmd);
- continue; /* back to while(1) */
- }
- return (1);
- }
- /* NOTREACHED */
-}
-
-/*
- * Set transfer type.
- */
-void
-settype(int argc, char *argv[])
-{
- struct types *p;
- int comret;
-
- if (argc == 0 || argc > 2) {
- char *sep;
-
- fprintf(ttyout, "usage: %s [", argv[0]);
- sep = " ";
- for (p = types; p->t_name; p++) {
- fprintf(ttyout, "%s%s", sep, p->t_name);
- sep = " | ";
- }
- fputs(" ]\n", ttyout);
- code = -1;
- return;
- }
- if (argc < 2) {
- fprintf(ttyout, "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) {
- fprintf(ttyout, "%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)strlcpy(typename, p->t_name, sizeof(typename));
- 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(int newtype, int 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(int argc, char *argv[])
-{
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- stype[1] = "binary";
- settype(2, stype);
-}
-
-/*
- * Set ascii transfer type.
- */
-/*VARARGS*/
-void
-setascii(int argc, char *argv[])
-{
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- stype[1] = "ascii";
- settype(2, stype);
-}
-
-/*
- * Set tenex transfer type.
- */
-/*VARARGS*/
-void
-settenex(int argc, char *argv[])
-{
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- stype[1] = "tenex";
- settype(2, stype);
-}
-
-/*
- * Set file transfer mode.
- */
-/*ARGSUSED*/
-void
-setftmode(int argc, char *argv[])
-{
-
- if (argc != 2) {
- fprintf(ttyout, "usage: %s mode-name\n", argv[0]);
- code = -1;
- return;
- }
- fprintf(ttyout, "We only support %s mode, sorry.\n", modename);
- code = -1;
-}
-
-/*
- * Set file transfer format.
- */
-/*ARGSUSED*/
-void
-setform(int argc, char *argv[])
-{
-
- if (argc != 2) {
- fprintf(ttyout, "usage: %s format\n", argv[0]);
- code = -1;
- return;
- }
- fprintf(ttyout, "We only support %s format, sorry.\n", formname);
- code = -1;
-}
-
-/*
- * Set file transfer structure.
- */
-/*ARGSUSED*/
-void
-setstruct(int argc, char *argv[])
-{
-
- if (argc != 2) {
- fprintf(ttyout, "usage: %s struct-mode\n", argv[0]);
- code = -1;
- return;
- }
- fprintf(ttyout, "We only support %s structure, sorry.\n", structname);
- code = -1;
-}
-
-/*
- * Send a single file.
- */
-void
-put(int argc, char *argv[])
-{
- char buf[MAXPATHLEN];
- char *cmd;
- int loc = 0;
- char *locfile;
- const char *remfile;
-
- if (argc == 2) {
- argc++;
- argv[2] = argv[1];
- loc++;
- }
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "local-file")))
- goto usage;
- if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
- usage:
- fprintf(ttyout, "usage: %s local-file [remote-file]\n",
- argv[0]);
- code = -1;
- return;
- }
- if ((locfile = globulize(argv[1])) == NULL) {
- code = -1;
- return;
- }
- remfile = argv[2];
- if (loc) /* If argv[2] is a copy of the old argv[1], update it */
- remfile = locfile;
- cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
- remfile = doprocess(buf, sizeof(buf), remfile,
- 0, loc && ntflag, loc && mapflag);
- sendrequest(cmd, locfile, remfile,
- locfile != argv[1] || remfile != argv[2]);
- free(locfile);
-}
-
-static const char *
-doprocess(char *dst, size_t dlen, const char *src,
- int casef, int transf, int mapf)
-{
- if (casef)
- src = docase(dst, dlen, src);
- if (transf)
- src = dotrans(dst, dlen, src);
- if (mapf)
- src = domap(dst, dlen, src);
- return src;
-}
-
-/*
- * Send multiple files.
- */
-void
-mput(int argc, char *argv[])
-{
- int i;
- sigfunc oldintr;
- int ointer;
- const char *tp;
-
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "local-files"))) {
- fprintf(ttyout, "usage: %s local-files\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = xsignal(SIGINT, mintr);
- if (sigsetjmp(jabort, 1))
- mabort();
- if (proxy) {
- char *cp;
-
- while ((cp = remglob(argv, 0, NULL)) != NULL) {
- if (*cp == '\0' || !connected) {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- char buf[MAXPATHLEN];
- tp = doprocess(buf, sizeof(buf), cp,
- mcase, ntflag, mapflag);
- sendrequest((sunique) ? "STOU" : "STOR",
- cp, tp, cp != tp || !interactive);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- goto cleanupmput;
- }
- for (i = 1; i < argc && connected; i++) {
- char **cpp;
- glob_t gl;
- int flags;
-
- if (!doglob) {
- if (mflag && confirm(argv[0], argv[i])) {
- char buf[MAXPATHLEN];
- tp = doprocess(buf, sizeof(buf), argv[i],
- 0, ntflag, mapflag);
- 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_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 && connected;
- cpp++) {
- if (mflag && confirm(argv[0], *cpp)) {
- char buf[MAXPATHLEN];
- tp = *cpp;
- tp = doprocess(buf, sizeof(buf), *cpp,
- 0, ntflag, mapflag);
- 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);
- }
- cleanupmput:
- (void)xsignal(SIGINT, oldintr);
- mflag = 0;
-}
-
-void
-reget(int argc, char *argv[])
-{
-
- (void)getit(argc, argv, 1, "r+");
-}
-
-void
-get(int argc, char *argv[])
-{
-
- (void)getit(argc, argv, 0, restart_point ? "r+" : "w" );
-}
-
-/*
- * Receive one file.
- * If restartit is 1, restart the xfer always.
- * If restartit is -1, restart the xfer only if the remote file is newer.
- */
-int
-getit(int argc, char *argv[], int restartit, const char *mode)
-{
- int loc, rval;
- char *remfile, *olocfile;
- const char *locfile;
- char buf[MAXPATHLEN];
-
- loc = rval = 0;
- if (argc == 2) {
- argc++;
- argv[2] = argv[1];
- loc++;
- }
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "remote-file")))
- goto usage;
- if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) {
- usage:
- fprintf(ttyout, "usage: %s remote-file [local-file]\n",
- argv[0]);
- code = -1;
- return (0);
- }
- remfile = argv[1];
- if ((olocfile = globulize(argv[2])) == NULL) {
- code = -1;
- return (0);
- }
- locfile = doprocess(buf, sizeof(buf), olocfile,
- loc && mcase, loc && ntflag, loc && mapflag);
- if (restartit) {
- struct stat stbuf;
- int ret;
-
- if (! features[FEAT_REST_STREAM]) {
- fprintf(ttyout,
- "Restart is not supported by the remote server.\n");
- return (0);
- }
- ret = stat(locfile, &stbuf);
- if (restartit == 1) {
- if (ret < 0) {
- warn("local: %s", locfile);
- 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", locfile, remfile, mode,
- remfile != argv[1] || locfile != argv[2], loc);
- restart_point = 0;
- freegetit:
- (void)free(olocfile);
- return (rval);
-}
-
-/* ARGSUSED */
-void
-mintr(int signo)
-{
-
- alarmtimer(0);
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- siglongjmp(jabort, 1);
-}
-
-void
-mabort(void)
-{
- int ointer, oconf;
-
- if (mflag && fromatty) {
- ointer = interactive;
- oconf = confirmrest;
- interactive = 1;
- confirmrest = 0;
- if (confirm("Continue with", mname)) {
- interactive = ointer;
- confirmrest = oconf;
- return;
- }
- interactive = ointer;
- confirmrest = oconf;
- }
- mflag = 0;
-}
-
-/*
- * Get multiple files.
- */
-void
-mget(int argc, char *argv[])
-{
- sigfunc oldintr;
- int ointer;
- char *cp;
- const char *tp;
- int restartit;
-
- if (argc == 0 ||
- (argc == 1 && !another(&argc, &argv, "remote-files"))) {
- fprintf(ttyout, "usage: %s remote-files\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- restart_point = 0;
- restartit = 0;
- if (strcmp(argv[0], "mreget") == 0) {
- if (! features[FEAT_REST_STREAM]) {
- fprintf(ttyout,
- "Restart is not supported by the remote server.\n");
- return;
- }
- restartit = 1;
- }
- oldintr = xsignal(SIGINT, mintr);
- if (sigsetjmp(jabort, 1))
- mabort();
- while ((cp = remglob(argv, proxy, NULL)) != NULL) {
- char buf[MAXPATHLEN];
- if (*cp == '\0' || !connected) {
- mflag = 0;
- continue;
- }
- if (! mflag)
- continue;
- if (! fileindir(cp, localcwd)) {
- fprintf(ttyout, "Skipping non-relative filename `%s'\n",
- cp);
- continue;
- }
- if (!confirm(argv[0], cp))
- continue;
- tp = doprocess(buf, sizeof(buf), cp, mcase, ntflag, mapflag);
- if (restartit) {
- struct stat stbuf;
-
- if (stat(tp, &stbuf) == 0)
- restart_point = stbuf.st_size;
- else
- warn("stat %s", tp);
- }
- recvrequest("RETR", tp, cp, restart_point ? "r+" : "w",
- tp != cp || !interactive, 1);
- restart_point = 0;
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mget"))
- mflag++;
- interactive = ointer;
- }
- }
- (void)xsignal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/*
- * Read list of filenames from a local file and get those
- */
-void
-fget(int argc, char *argv[])
-{
- char *buf, *mode;
- FILE *fp;
-
- if (argc != 2) {
- fprintf(ttyout, "usage: %s localfile\n", argv[0]);
- code = -1;
- return;
- }
-
- fp = fopen(argv[1], "r");
- if (fp == NULL) {
- fprintf(ttyout, "Cannot open source file %s\n", argv[1]);
- code = -1;
- return;
- }
-
- argv[0] = "get";
- mode = restart_point ? "r+" : "w";
-
- for (;
- (buf = fparseln(fp, NULL, NULL, "\0\0\0", 0)) != NULL;
- free(buf)) {
- if (buf[0] == '\0')
- continue;
- argv[1] = buf;
- (void)getit(argc, argv, 0, mode);
- }
- fclose(fp);
-}
-
-char *
-onoff(int bool)
-{
-
- return (bool ? "on" : "off");
-}
-
-/*
- * Show status.
- */
-/*ARGSUSED*/
-void
-status(int argc, char *argv[])
-{
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
-#ifndef NO_STATUS
- if (connected)
- fprintf(ttyout, "Connected %sto %s.\n",
- connected == -1 ? "and logged in" : "", hostname);
- else
- fputs("Not connected.\n", ttyout);
- if (!proxy) {
- pswitch(1);
- if (connected) {
- fprintf(ttyout, "Connected for proxy commands to %s.\n",
- hostname);
- }
- else {
- fputs("No proxy connection.\n", ttyout);
- }
- pswitch(0);
- }
- fprintf(ttyout, "Gate ftp: %s, server %s, port %s.\n", onoff(gatemode),
- *gateserver ? gateserver : "(none)", gateport);
- fprintf(ttyout, "Passive mode: %s; fallback to active mode: %s.\n",
- onoff(passivemode), onoff(activefallback));
- fprintf(ttyout, "Mode: %s; Type: %s; Form: %s; Structure: %s.\n",
- modename, typename, formname, structname);
- fprintf(ttyout, "Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s.\n",
- onoff(verbose), onoff(bell), onoff(interactive), onoff(doglob));
- fprintf(ttyout, "Store unique: %s; Receive unique: %s.\n",
- onoff(sunique), onoff(runique));
- fprintf(ttyout, "Preserve modification times: %s.\n", onoff(preserve));
- fprintf(ttyout, "Case: %s; CR stripping: %s.\n", onoff(mcase),
- onoff(crflag));
- if (ntflag) {
- fprintf(ttyout, "Ntrans: (in) %s (out) %s\n", ntin, ntout);
- }
- else {
- fputs("Ntrans: off.\n", ttyout);
- }
- if (mapflag) {
- fprintf(ttyout, "Nmap: (in) %s (out) %s\n", mapin, mapout);
- }
- else {
- fputs("Nmap: off.\n", ttyout);
- }
- fprintf(ttyout,
- "Hash mark printing: %s; Mark count: %d; Progress bar: %s.\n",
- onoff(hash), mark, onoff(progress));
- fprintf(ttyout,
- "Get transfer rate throttle: %s; maximum: %d; increment %d.\n",
- onoff(rate_get), rate_get, rate_get_incr);
- fprintf(ttyout,
- "Put transfer rate throttle: %s; maximum: %d; increment %d.\n",
- onoff(rate_put), rate_put, rate_put_incr);
- fprintf(ttyout,
- "Socket buffer sizes: send %d, receive %d.\n",
- sndbuf_size, rcvbuf_size);
- fprintf(ttyout, "Use of PORT cmds: %s.\n", onoff(sendport));
- fprintf(ttyout, "Use of EPSV/EPRT cmds for IPv4: %s%s.\n", onoff(epsv4),
- epsv4bad ? " (disabled for this connection)" : "");
- fprintf(ttyout, "Command line editing: %s.\n",
-#ifdef NO_EDITCOMPLETE
- "support not compiled in"
-#else /* !def NO_EDITCOMPLETE */
- onoff(editing)
-#endif /* !def NO_EDITCOMPLETE */
- );
- if (macnum > 0) {
- int i;
-
- fputs("Macros:\n", ttyout);
- for (i=0; i<macnum; i++) {
- fprintf(ttyout, "\t%s\n", macros[i].mac_name);
- }
- }
-#endif /* !def NO_STATUS */
- fprintf(ttyout, "Version: %s %s\n", FTP_PRODUCT, FTP_VERSION);
- code = 0;
-}
-
-/*
- * Toggle a variable
- */
-int
-togglevar(int argc, char *argv[], int *var, const char *mesg)
-{
- if (argc == 1) {
- *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 {
- fprintf(ttyout, "usage: %s [ on | off ]\n", argv[0]);
- return (-1);
- }
- if (mesg)
- fprintf(ttyout, "%s %s.\n", mesg, onoff(*var));
- return (*var);
-}
-
-/*
- * Set beep on cmd completed mode.
- */
-/*VARARGS*/
-void
-setbell(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &bell, "Bell mode");
-}
-
-/*
- * Set command line editing
- */
-/*VARARGS*/
-void
-setedit(int argc, char *argv[])
-{
-
-#ifdef NO_EDITCOMPLETE
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- if (verbose)
- fputs("Editing support not compiled in; ignoring command.\n",
- ttyout);
-#else /* !def NO_EDITCOMPLETE */
- code = togglevar(argc, argv, &editing, "Editing mode");
- controlediting();
-#endif /* !def NO_EDITCOMPLETE */
-}
-
-/*
- * Turn on packet tracing.
- */
-/*VARARGS*/
-void
-settrace(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(int argc, char *argv[])
-{
- if (argc == 1)
- hash = !hash;
- else if (argc != 2) {
- fprintf(ttyout, "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;
-
- nmark = strsuftoi(argv[1]);
- if (nmark < 1) {
- fprintf(ttyout, "mark: bad bytecount value `%s'.\n",
- argv[1]);
- code = -1;
- return;
- }
- mark = nmark;
- hash = 1;
- }
- fprintf(ttyout, "Hash mark printing %s", onoff(hash));
- if (hash)
- fprintf(ttyout, " (%d bytes/hash mark)", mark);
- fputs(".\n", ttyout);
- if (hash)
- progress = 0;
- code = hash;
-}
-
-/*
- * Turn on printing of server echo's.
- */
-/*VARARGS*/
-void
-setverbose(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &verbose, "Verbose mode");
-}
-
-/*
- * Toggle PORT/LPRT cmd use before each data connection.
- */
-/*VARARGS*/
-void
-setport(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &sendport, "Use of PORT/LPRT cmds");
-}
-
-/*
- * Toggle transfer progress bar.
- */
-/*VARARGS*/
-void
-setprogress(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &progress, "Progress bar");
- if (progress)
- hash = 0;
-}
-
-/*
- * Turn on interactive prompting during mget, mput, and mdelete.
- */
-/*VARARGS*/
-void
-setprompt(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &interactive, "Interactive mode");
-}
-
-/*
- * Toggle gate-ftp mode, or set gate-ftp server
- */
-/*VARARGS*/
-void
-setgate(int argc, char *argv[])
-{
- static char gsbuf[MAXHOSTNAMELEN];
-
- if (argc == 0 || argc > 3) {
- fprintf(ttyout,
- "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)
- gateport = xstrdup(argv[2]);
- (void)strlcpy(gsbuf, argv[1], sizeof(gsbuf));
- gateserver = gsbuf;
- gatemode = 1;
- }
- }
- if (gatemode && (gateserver == NULL || *gateserver == '\0')) {
- fprintf(ttyout,
- "Disabling gate-ftp mode - no gate-ftp server defined.\n");
- gatemode = 0;
- } else {
- fprintf(ttyout, "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(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &doglob, "Globbing");
-}
-
-/*
- * Toggle preserving modification times on retrieved files.
- */
-/*VARARGS*/
-void
-setpreserve(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(int argc, char *argv[])
-{
- if (argc == 0 || argc > 2) {
- fprintf(ttyout, "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 {
- int val;
-
- val = strsuftoi(argv[1]);
- if (val < 0) {
- fprintf(ttyout, "%s: bad debugging value.\n",
- argv[1]);
- code = -1;
- return;
- }
- debug = val;
- }
- } else
- debug = !debug;
- if (debug)
- options |= SO_DEBUG;
- else
- options &= ~SO_DEBUG;
- fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(debug), debug);
- code = debug > 0;
-}
-
-/*
- * Set current working directory on remote machine.
- */
-void
-cd(int argc, char *argv[])
-{
- int r;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "remote-directory"))) {
- fprintf(ttyout, "usage: %s remote-directory\n", argv[0]);
- code = -1;
- return;
- }
- r = command("CWD %s", argv[1]);
- if (r == ERROR && code == 500) {
- if (verbose)
- fputs("CWD command not recognized, trying XCWD.\n",
- ttyout);
- r = command("XCWD %s", argv[1]);
- }
- if (r == COMPLETE) {
- dirchange = 1;
- updateremotecwd();
- }
-}
-
-/*
- * Set current working directory on local machine.
- */
-void
-lcd(int argc, char *argv[])
-{
- char *locdir;
-
- code = -1;
- if (argc == 1) {
- argc++;
- argv[1] = localhome;
- }
- if (argc != 2) {
- fprintf(ttyout, "usage: %s [local-directory]\n", argv[0]);
- return;
- }
- if ((locdir = globulize(argv[1])) == NULL)
- return;
- if (chdir(locdir) == -1)
- warn("lcd %s", locdir);
- else {
- updatelocalcwd();
- if (localcwd[0]) {
- fprintf(ttyout, "Local directory now: %s\n", localcwd);
- code = 0;
- } else {
- fprintf(ttyout, "Unable to determine local directory\n");
- }
- }
- (void)free(locdir);
-}
-
-/*
- * Delete a single file.
- */
-void
-delete(int argc, char *argv[])
-{
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
- code = -1;
- return;
- }
- if (command("DELE %s", argv[1]) == COMPLETE)
- dirchange = 1;
-}
-
-/*
- * Delete multiple files.
- */
-void
-mdelete(int argc, char *argv[])
-{
- sigfunc oldintr;
- int ointer;
- char *cp;
-
- if (argc == 0 ||
- (argc == 1 && !another(&argc, &argv, "remote-files"))) {
- fprintf(ttyout, "usage: %s [remote-files]\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = xsignal(SIGINT, mintr);
- if (sigsetjmp(jabort, 1))
- mabort();
- while ((cp = remglob(argv, 0, NULL)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- if (command("DELE %s", cp) == COMPLETE)
- dirchange = 1;
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mdelete")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- (void)xsignal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/*
- * Rename a remote file.
- */
-void
-renamefile(int argc, char *argv[])
-{
-
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "from-name")))
- goto usage;
- if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) {
- usage:
- fprintf(ttyout, "usage: %s from-name to-name\n", argv[0]);
- code = -1;
- return;
- }
- if (command("RNFR %s", argv[1]) == CONTINUE &&
- command("RNTO %s", argv[2]) == COMPLETE)
- dirchange = 1;
-}
-
-/*
- * Get a directory listing of remote files.
- * Supports being invoked as:
- * cmd runs
- * --- ----
- * dir, ls LIST
- * mlsd MLSD
- * nlist NLST
- * pdir, pls LIST |$PAGER
- * mmlsd MLSD |$PAGER
- */
-void
-ls(int argc, char *argv[])
-{
- const char *cmd;
- char *remdir, *locfile;
- int freelocfile, pagecmd, mlsdcmd;
-
- remdir = NULL;
- locfile = "-";
- freelocfile = pagecmd = mlsdcmd = 0;
- /*
- * the only commands that start with `p' are
- * the `pager' versions.
- */
- if (argv[0][0] == 'p')
- pagecmd = 1;
- if (strcmp(argv[0] + pagecmd , "mlsd") == 0) {
- if (! features[FEAT_MLST]) {
- fprintf(ttyout,
- "MLSD is not supported by the remote server.\n");
- return;
- }
- mlsdcmd = 1;
- }
- if (argc == 0)
- goto usage;
-
- if (mlsdcmd)
- cmd = "MLSD";
- else if (strcmp(argv[0] + pagecmd, "nlist") == 0)
- cmd = "NLST";
- else
- cmd = "LIST";
-
- if (argc > 1)
- remdir = argv[1];
- if (argc > 2)
- locfile = argv[2];
- if (argc > 3 || ((pagecmd | mlsdcmd) && argc > 2)) {
- usage:
- if (pagecmd || mlsdcmd)
- fprintf(ttyout,
- "usage: %s [remote-path]\n", argv[0]);
- else
- fprintf(ttyout,
- "usage: %s [remote-path [local-file]]\n",
- argv[0]);
- code = -1;
- goto freels;
- }
-
- if (pagecmd) {
- char *p;
- int len;
-
- p = getoptionvalue("pager");
- if (EMPTYSTRING(p))
- p = DEFAULTPAGER;
- len = strlen(p) + 2;
- locfile = xmalloc(len);
- locfile[0] = '|';
- (void)strlcpy(locfile + 1, p, len - 1);
- freelocfile = 1;
- } else if ((strcmp(locfile, "-") != 0) && *locfile != '|') {
- mname = argv[0];
- if ((locfile = globulize(locfile)) == NULL ||
- !confirm("output to local-file:", locfile)) {
- code = -1;
- goto freels;
- }
- freelocfile = 1;
- }
- recvrequest(cmd, locfile, remdir, "w", 0, 0);
- freels:
- if (freelocfile && locfile)
- (void)free(locfile);
-}
-
-/*
- * Get a directory listing of multiple remote files.
- */
-void
-mls(int argc, char *argv[])
-{
- sigfunc oldintr;
- int ointer, i;
- int dolist;
- char *mode, *dest, *odest;
-
- if (argc == 0)
- goto usage;
- if (argc < 2 && !another(&argc, &argv, "remote-files"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "local-file")) {
- usage:
- fprintf(ttyout, "usage: %s remote-files local-file\n", argv[0]);
- code = -1;
- return;
- }
- odest = dest = argv[argc - 1];
- argv[argc - 1] = NULL;
- mname = argv[0];
- if (strcmp(dest, "-") && *dest != '|')
- if (((dest = globulize(dest)) == NULL) ||
- !confirm("output to local-file:", dest)) {
- code = -1;
- return;
- }
- dolist = strcmp(argv[0], "mls");
- mflag = 1;
- oldintr = xsignal(SIGINT, mintr);
- if (sigsetjmp(jabort, 1))
- mabort();
- for (i = 1; mflag && i < argc-1 && connected; 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)xsignal(SIGINT, oldintr);
- mflag = 0;
- if (dest != odest) /* free up after globulize() */
- free(dest);
-}
-
-/*
- * Do a shell escape
- */
-/*ARGSUSED*/
-void
-shell(int argc, char *argv[])
-{
- pid_t pid;
- sigfunc oldintr;
- char shellnam[MAXPATHLEN], *shell, *namep;
- int wait_status;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s [command [args]]\n", argv[0]);
- code = -1;
- return;
- }
- oldintr = xsignal(SIGINT, SIG_IGN);
- if ((pid = fork()) == 0) {
- for (pid = 3; pid < 20; pid++)
- (void)close(pid);
- (void)xsignal(SIGINT, SIG_DFL);
- shell = getenv("SHELL");
- if (shell == NULL)
- shell = _PATH_BSHELL;
- namep = strrchr(shell, '/');
- if (namep == NULL)
- namep = shell;
- else
- namep++;
- (void)strlcpy(shellnam, namep, sizeof(shellnam));
- if (debug) {
- fputs(shell, ttyout);
- putc('\n', ttyout);
- }
- 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)xsignal(SIGINT, oldintr);
- if (pid == -1) {
- warn("Try again later");
- code = -1;
- } else
- code = 0;
-}
-
-/*
- * Send new user information (re-login)
- */
-void
-user(int argc, char *argv[])
-{
- char acct[80];
- int n, aflag = 0;
-
- if (argc == 0)
- goto usage;
- if (argc < 2)
- (void)another(&argc, &argv, "username");
- if (argc < 2 || argc > 4) {
- usage:
- fprintf(ttyout, "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: ", ttyout);
- (void)fflush(ttyout);
- if (fgets(acct, sizeof(acct) - 1, stdin) == NULL) {
- fprintf(ttyout,
- "\nEOF received; login aborted.\n");
- clearerr(stdin);
- code = -1;
- return;
- }
- acct[strlen(acct) - 1] = '\0';
- argv[3] = acct; argc++;
- }
- n = command("ACCT %s", argv[3]);
- aflag++;
- }
- if (n != COMPLETE) {
- fputs("Login failed.\n", ttyout);
- return;
- }
- if (!aflag && argc == 4) {
- (void)command("ACCT %s", argv[3]);
- }
- connected = -1;
- getremoteinfo();
-}
-
-/*
- * Print working directory on remote machine.
- */
-/*VARARGS*/
-void
-pwd(int argc, char *argv[])
-{
-
- code = -1;
- if (argc != 1) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- return;
- }
- if (! remotecwd[0])
- updateremotecwd();
- if (! remotecwd[0])
- fprintf(ttyout, "Unable to determine remote directory\n");
- else {
- fprintf(ttyout, "Remote directory: %s\n", remotecwd);
- code = 0;
- }
-}
-
-/*
- * Print working directory on local machine.
- */
-void
-lpwd(int argc, char *argv[])
-{
-
- code = -1;
- if (argc != 1) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- return;
- }
- if (! localcwd[0])
- updatelocalcwd();
- if (! localcwd[0])
- fprintf(ttyout, "Unable to determine local directory\n");
- else {
- fprintf(ttyout, "Local directory: %s\n", localcwd);
- code = 0;
- }
-}
-
-/*
- * Make a directory.
- */
-void
-makedir(int argc, char *argv[])
-{
- int r;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "directory-name"))) {
- fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
- code = -1;
- return;
- }
- r = command("MKD %s", argv[1]);
- if (r == ERROR && code == 500) {
- if (verbose)
- fputs("MKD command not recognized, trying XMKD.\n",
- ttyout);
- r = command("XMKD %s", argv[1]);
- }
- if (r == COMPLETE)
- dirchange = 1;
-}
-
-/*
- * Remove a directory.
- */
-void
-removedir(int argc, char *argv[])
-{
- int r;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "directory-name"))) {
- fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
- code = -1;
- return;
- }
- r = command("RMD %s", argv[1]);
- if (r == ERROR && code == 500) {
- if (verbose)
- fputs("RMD command not recognized, trying XRMD.\n",
- ttyout);
- r = command("XRMD %s", argv[1]);
- }
- if (r == COMPLETE)
- dirchange = 1;
-}
-
-/*
- * Send a line, verbatim, to the remote machine.
- */
-void
-quote(int argc, char *argv[])
-{
-
- if (argc == 0 ||
- (argc == 1 && !another(&argc, &argv, "command line to send"))) {
- fprintf(ttyout, "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(int argc, char *argv[])
-{
-
- if (argc == 0 ||
- (argc == 1 && !another(&argc, &argv, "arguments to SITE command"))){
- fprintf(ttyout, "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(const char *initial, int argc, char *argv[])
-{
- int i;
- char buf[BUFSIZ]; /* must be >= sizeof(line) */
-
- (void)strlcpy(buf, initial, sizeof(buf));
- for (i = 1; i < argc; i++) {
- (void)strlcat(buf, argv[i], sizeof(buf));
- if (i < (argc - 1))
- (void)strlcat(buf, " ", sizeof(buf));
- }
- if (command("%s", buf) == PRELIM) {
- while (getreply(0) == PRELIM)
- continue;
- }
- dirchange = 1;
-}
-
-void
-do_chmod(int argc, char *argv[])
-{
-
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "mode")))
- goto usage;
- if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
- usage:
- fprintf(ttyout, "usage: %s mode remote-file\n", argv[0]);
- code = -1;
- return;
- }
- (void)command("SITE CHMOD %s %s", argv[1], argv[2]);
-}
-
-#define COMMAND_1ARG(argc, argv, cmd) \
- if (argc == 1) \
- command(cmd); \
- else \
- command(cmd " %s", argv[1])
-
-void
-do_umask(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s [umask]\n", argv[0]);
- code = -1;
- return;
- }
- verbose = 1;
- COMMAND_1ARG(argc, argv, "SITE UMASK");
- verbose = oldverbose;
-}
-
-void
-idlecmd(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc < 1 || argc > 2) {
- fprintf(ttyout, "usage: %s [seconds]\n", argv[0]);
- code = -1;
- return;
- }
- verbose = 1;
- COMMAND_1ARG(argc, argv, "SITE IDLE");
- verbose = oldverbose;
-}
-
-/*
- * Ask the other side for help.
- */
-void
-rmthelp(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- verbose = 1;
- COMMAND_1ARG(argc, argv, "HELP");
- verbose = oldverbose;
-}
-
-/*
- * Terminate session and exit.
- * May be called with 0, NULL.
- */
-/*VARARGS*/
-void
-quit(int argc, char *argv[])
-{
-
- /* this may be called with argc == 0, argv == NULL */
- if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- if (connected)
- disconnect(0, NULL);
- pswitch(1);
- if (connected)
- disconnect(0, NULL);
- exit(0);
-}
-
-/*
- * Terminate session, but don't exit.
- * May be called with 0, NULL.
- */
-void
-disconnect(int argc, char *argv[])
-{
-
- /* this may be called with argc == 0, argv == NULL */
- if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- if (!connected)
- return;
- (void)command("QUIT");
- cleanuppeer();
-}
-
-void
-account(int argc, char *argv[])
-{
- char *ap;
-
- if (argc == 0 || argc > 2) {
- fprintf(ttyout, "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);
-}
-
-sigjmp_buf abortprox;
-
-void
-proxabort(int notused)
-{
-
- sigint_raised = 1;
- alarmtimer(0);
- if (!proxy) {
- pswitch(1);
- }
- if (connected) {
- proxflag = 1;
- }
- else {
- proxflag = 0;
- }
- pswitch(0);
- siglongjmp(abortprox, 1);
-}
-
-void
-doproxy(int argc, char *argv[])
-{
- struct cmd *c;
- int cmdpos;
- sigfunc oldintr;
-
- if (argc == 0 || (argc == 1 && !another(&argc, &argv, "command"))) {
- fprintf(ttyout, "usage: %s command\n", argv[0]);
- code = -1;
- return;
- }
- c = getcmd(argv[1]);
- if (c == (struct cmd *) -1) {
- fputs("?Ambiguous command.\n", ttyout);
- code = -1;
- return;
- }
- if (c == 0) {
- fputs("?Invalid command.\n", ttyout);
- code = -1;
- return;
- }
- if (!c->c_proxy) {
- fputs("?Invalid proxy command.\n", ttyout);
- code = -1;
- return;
- }
- if (sigsetjmp(abortprox, 1)) {
- code = -1;
- return;
- }
- oldintr = xsignal(SIGINT, proxabort);
- pswitch(1);
- if (c->c_conn && !connected) {
- fputs("Not connected.\n", ttyout);
- pswitch(0);
- (void)xsignal(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);
- argv[1] = c->c_name;
- (*c->c_handler)(argc-1, argv+1);
- if (connected) {
- proxflag = 1;
- }
- else {
- proxflag = 0;
- }
- pswitch(0);
- (void)xsignal(SIGINT, oldintr);
-}
-
-void
-setcase(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &mcase, "Case mapping");
-}
-
-/*
- * convert the given name to lower case if it's all upper case, into
- * a static buffer which is returned to the caller
- */
-static const char *
-docase(char *dst, size_t dlen, const char *src)
-{
- size_t i;
- int dochange = 1;
-
- for (i = 0; src[i] != '\0' && i < dlen - 1; i++) {
- dst[i] = src[i];
- if (islower((unsigned char)dst[i]))
- dochange = 0;
- }
- dst[i] = '\0';
-
- if (dochange) {
- for (i = 0; dst[i] != '\0'; i++)
- if (isupper((unsigned char)dst[i]))
- dst[i] = tolower((unsigned char)dst[i]);
- }
- return dst;
-}
-
-void
-setcr(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &crflag, "Carriage Return stripping");
-}
-
-void
-setntrans(int argc, char *argv[])
-{
-
- if (argc == 0 || argc > 3) {
- fprintf(ttyout, "usage: %s [inchars [outchars]]\n", argv[0]);
- code = -1;
- return;
- }
- if (argc == 1) {
- ntflag = 0;
- fputs("Ntrans off.\n", ttyout);
- code = ntflag;
- return;
- }
- ntflag++;
- code = ntflag;
- (void)strlcpy(ntin, argv[1], sizeof(ntin));
- if (argc == 2) {
- ntout[0] = '\0';
- return;
- }
- (void)strlcpy(ntout, argv[2], sizeof(ntout));
-}
-
-static const char *
-dotrans(char *dst, size_t dlen, const char *src)
-{
- const char *cp1;
- char *cp2 = dst;
- size_t i, ostop;
-
- for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
- continue;
- for (cp1 = src; *cp1; cp1++) {
- int found = 0;
- for (i = 0; *(ntin + i) && i < 16; i++) {
- if (*cp1 == *(ntin + i)) {
- found++;
- if (i < ostop) {
- *cp2++ = *(ntout + i);
- if (cp2 - dst >= dlen - 1)
- goto out;
- }
- break;
- }
- }
- if (!found) {
- *cp2++ = *cp1;
- }
- }
-out:
- *cp2 = '\0';
- return dst;
-}
-
-void
-setnmap(int argc, char *argv[])
-{
- char *cp;
-
- if (argc == 1) {
- mapflag = 0;
- fputs("Nmap off.\n", ttyout);
- code = mapflag;
- return;
- }
- if (argc == 0 ||
- (argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) {
- fprintf(ttyout, "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)strlcpy(mapin, altarg, MAXPATHLEN);
- while (*++cp == ' ')
- continue;
- (void)strlcpy(mapout, cp, MAXPATHLEN);
-}
-
-static const char *
-domap(char *dst, size_t dlen, const char *src)
-{
- const char *cp1 = src;
- char *cp2 = mapin;
- const 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;
- }
- cp2 = dst;
- *cp2 = '\0';
- cp1 = mapout;
- while (*cp1) {
- match = 0;
- switch (*cp1) {
- case '\\':
- if (*(cp1 + 1)) {
- *cp2++ = *++cp1;
- }
- break;
- case '[':
-LOOP:
- if (*++cp1 == '$' &&
- isdigit((unsigned char)*(cp1+1))) {
- if (*++cp1 == '0') {
- const char *cp3 = src;
-
- while (*cp3) {
- *cp2++ = *cp3++;
- }
- match = 1;
- }
- else if (toks[toknum = *cp1 - '1']) {
- const char *cp3 = tp[toknum];
-
- while (cp3 != te[toknum]) {
- *cp2++ = *cp3++;
- }
- match = 1;
- }
- }
- else {
- while (*cp1 && *cp1 != ',' &&
- *cp1 != ']') {
- if (*cp1 == '\\') {
- cp1++;
- }
- else if (*cp1 == '$' &&
- isdigit((unsigned char)*(cp1+1))) {
- if (*++cp1 == '0') {
- const char *cp3 = src;
-
- while (*cp3) {
- *cp2++ = *cp3++;
- }
- }
- else if (toks[toknum =
- *cp1 - '1']) {
- const char *cp3=tp[toknum];
-
- while (cp3 !=
- te[toknum]) {
- *cp2++ = *cp3++;
- }
- }
- }
- else if (*cp1) {
- *cp2++ = *cp1++;
- }
- }
- if (!*cp1) {
- fputs(
- "nmap: unbalanced brackets.\n",
- ttyout);
- return (src);
- }
- match = 1;
- cp1--;
- }
- if (match) {
- while (*++cp1 && *cp1 != ']') {
- if (*cp1 == '\\' && *(cp1 + 1)) {
- cp1++;
- }
- }
- if (!*cp1) {
- fputs(
- "nmap: unbalanced brackets.\n",
- ttyout);
- return (src);
- }
- break;
- }
- switch (*++cp1) {
- case ',':
- goto LOOP;
- case ']':
- break;
- default:
- cp1--;
- goto LOOP;
- }
- break;
- case '$':
- if (isdigit((unsigned char)*(cp1 + 1))) {
- if (*++cp1 == '0') {
- const char *cp3 = src;
-
- while (*cp3) {
- *cp2++ = *cp3++;
- }
- }
- else if (toks[toknum = *cp1 - '1']) {
- const char *cp3 = tp[toknum];
-
- while (cp3 != te[toknum]) {
- *cp2++ = *cp3++;
- }
- }
- break;
- }
- /* intentional drop through */
- default:
- *cp2++ = *cp1;
- break;
- }
- cp1++;
- }
- *cp2 = '\0';
- return *dst ? dst : src;
-}
-
-void
-setpassive(int argc, char *argv[])
-{
-
- if (argc == 1) {
- passivemode = !passivemode;
- activefallback = passivemode;
- } else if (argc != 2) {
- passiveusage:
- fprintf(ttyout, "usage: %s [ on | off | auto ]\n", argv[0]);
- code = -1;
- return;
- } else if (strcasecmp(argv[1], "on") == 0) {
- passivemode = 1;
- activefallback = 0;
- } else if (strcasecmp(argv[1], "off") == 0) {
- passivemode = 0;
- activefallback = 0;
- } else if (strcasecmp(argv[1], "auto") == 0) {
- passivemode = 1;
- activefallback = 1;
- } else
- goto passiveusage;
- fprintf(ttyout, "Passive mode: %s; fallback to active mode: %s.\n",
- onoff(passivemode), onoff(activefallback));
- code = passivemode;
-}
-
-void
-setepsv4(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &epsv4,
- verbose ? "EPSV/EPRT on IPv4" : NULL);
- epsv4bad = 0;
-}
-
-void
-setsunique(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &sunique, "Store unique");
-}
-
-void
-setrunique(int argc, char *argv[])
-{
-
- code = togglevar(argc, argv, &runique, "Receive unique");
-}
-
-int
-parserate(int argc, char *argv[], int cmdlineopt)
-{
- int dir, max, incr, showonly;
- sigfunc oldusr1, oldusr2;
-
- if (argc > 4 || (argc < (cmdlineopt ? 3 : 2))) {
- usage:
- if (cmdlineopt)
- fprintf(ttyout,
- "usage: %s (all|get|put),maximum-bytes[,increment-bytes]]\n",
- argv[0]);
- else
- fprintf(ttyout,
- "usage: %s (all|get|put) [maximum-bytes [increment-bytes]]\n",
- argv[0]);
- return -1;
- }
- dir = max = incr = showonly = 0;
-#define RATE_GET 1
-#define RATE_PUT 2
-#define RATE_ALL (RATE_GET | RATE_PUT)
-
- if (strcasecmp(argv[1], "all") == 0)
- dir = RATE_ALL;
- else if (strcasecmp(argv[1], "get") == 0)
- dir = RATE_GET;
- else if (strcasecmp(argv[1], "put") == 0)
- dir = RATE_PUT;
- else
- goto usage;
-
- if (argc >= 3) {
- if ((max = strsuftoi(argv[2])) < 0)
- goto usage;
- } else
- showonly = 1;
-
- if (argc == 4) {
- if ((incr = strsuftoi(argv[3])) <= 0)
- goto usage;
- } else
- incr = DEFAULTINCR;
-
- oldusr1 = xsignal(SIGUSR1, SIG_IGN);
- oldusr2 = xsignal(SIGUSR2, SIG_IGN);
- if (dir & RATE_GET) {
- if (!showonly) {
- rate_get = max;
- rate_get_incr = incr;
- }
- if (!cmdlineopt || verbose)
- fprintf(ttyout,
- "Get transfer rate throttle: %s; maximum: %d; increment %d.\n",
- onoff(rate_get), rate_get, rate_get_incr);
- }
- if (dir & RATE_PUT) {
- if (!showonly) {
- rate_put = max;
- rate_put_incr = incr;
- }
- if (!cmdlineopt || verbose)
- fprintf(ttyout,
- "Put transfer rate throttle: %s; maximum: %d; increment %d.\n",
- onoff(rate_put), rate_put, rate_put_incr);
- }
- (void)xsignal(SIGUSR1, oldusr1);
- (void)xsignal(SIGUSR2, oldusr2);
- return 0;
-}
-
-void
-setrate(int argc, char *argv[])
-{
-
- code = parserate(argc, argv, 0);
-}
-
-/* change directory to parent directory */
-void
-cdup(int argc, char *argv[])
-{
- int r;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- r = command("CDUP");
- if (r == ERROR && code == 500) {
- if (verbose)
- fputs("CDUP command not recognized, trying XCUP.\n",
- ttyout);
- r = command("XCUP");
- }
- if (r == COMPLETE) {
- dirchange = 1;
- updateremotecwd();
- }
-}
-
-/*
- * Restart transfer at specific point
- */
-void
-restart(int argc, char *argv[])
-{
-
- if (argc == 0 || argc > 2) {
- fprintf(ttyout, "usage: %s [restart-point]\n", argv[0]);
- code = -1;
- return;
- }
- if (! features[FEAT_REST_STREAM]) {
- fprintf(ttyout,
- "Restart is not supported by the remote server.\n");
- return;
- }
- if (argc == 2) {
- off_t rp;
- char *ep;
-
- rp = STRTOLL(argv[1], &ep, 10);
- if (rp < 0 || *ep != '\0')
- fprintf(ttyout, "restart: Invalid offset `%s'\n",
- argv[1]);
- else
- restart_point = rp;
- }
- if (restart_point == 0)
- fputs("No restart point defined.\n", ttyout);
- else
- fprintf(ttyout,
- "Restarting at " LLF " for next get, put or append\n",
- (LLT)restart_point);
-}
-
-/*
- * Show remote system type
- */
-void
-syst(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- verbose = 1; /* If we aren't verbose, this doesn't do anything! */
- (void)command("SYST");
- verbose = oldverbose;
-}
-
-void
-macdef(int argc, char *argv[])
-{
- char *tmp;
- int c;
-
- if (argc == 0)
- goto usage;
- if (macnum == 16) {
- fputs("Limit of 16 macros have already been defined.\n",
- ttyout);
- code = -1;
- return;
- }
- if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) {
- usage:
- fprintf(ttyout, "usage: %s macro_name\n", argv[0]);
- code = -1;
- return;
- }
- if (interactive)
- fputs(
- "Enter macro line by line, terminating it with a null line.\n",
- ttyout);
- (void)strlcpy(macros[macnum].mac_name, argv[1],
- sizeof(macros[macnum].mac_name));
- 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) {
- fputs("macdef: end of file encountered.\n", ttyout);
- 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') {
- fputs("Macro not defined - 4K buffer exceeded.\n",
- ttyout);
- code = -1;
- return;
- }
- }
-}
-
-/*
- * Get size of file on remote machine
- */
-void
-sizecmd(int argc, char *argv[])
-{
- off_t size;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
- code = -1;
- return;
- }
- size = remotesize(argv[1], 1);
- if (size != -1)
- fprintf(ttyout,
- "%s\t" LLF "\n", argv[1], (LLT)size);
- code = (size > 0);
-}
-
-/*
- * Get last modification time of file on remote machine
- */
-void
-modtime(int argc, char *argv[])
-{
- time_t mtime;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
- code = -1;
- return;
- }
- mtime = remotemodtime(argv[1], 1);
- if (mtime != -1)
- fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime)));
- code = (mtime > 0);
-}
-
-/*
- * Show status on remote machine
- */
-void
-rmtstatus(int argc, char *argv[])
-{
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s [remote-file]\n", argv[0]);
- code = -1;
- return;
- }
- COMMAND_1ARG(argc, argv, "STAT");
-}
-
-/*
- * Get file if modtime is more recent than current file
- */
-void
-newer(int argc, char *argv[])
-{
-
- if (getit(argc, argv, -1, "w"))
- fprintf(ttyout,
- "Local file \"%s\" is newer than remote file \"%s\".\n",
- argv[2], argv[1]);
-}
-
-/*
- * Display one local file through $PAGER.
- */
-void
-lpage(int argc, char *argv[])
-{
- int len;
- char *p, *pager, *locfile;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "local-file"))) {
- fprintf(ttyout, "usage: %s local-file\n", argv[0]);
- code = -1;
- return;
- }
- if ((locfile = globulize(argv[1])) == NULL) {
- code = -1;
- return;
- }
- p = getoptionvalue("pager");
- if (EMPTYSTRING(p))
- p = DEFAULTPAGER;
- len = strlen(p) + strlen(locfile) + 2;
- pager = xmalloc(len);
- (void)strlcpy(pager, p, len);
- (void)strlcat(pager, " ", len);
- (void)strlcat(pager, locfile, len);
- system(pager);
- code = 0;
- (void)free(pager);
- (void)free(locfile);
-}
-
-/*
- * Display one remote file through $PAGER.
- */
-void
-page(int argc, char *argv[])
-{
- int ohash, orestart_point, overbose, len;
- char *p, *pager;
-
- if (argc == 0 || argc > 2 ||
- (argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
- code = -1;
- return;
- }
- p = getoptionvalue("pager");
- if (EMPTYSTRING(p))
- p = DEFAULTPAGER;
- len = strlen(p) + 2;
- pager = xmalloc(len);
- pager[0] = '|';
- (void)strlcpy(pager + 1, p, len - 1);
-
- ohash = hash;
- orestart_point = restart_point;
- overbose = verbose;
- hash = restart_point = verbose = 0;
- recvrequest("RETR", pager, argv[1], "r+", 1, 0);
- hash = ohash;
- restart_point = orestart_point;
- verbose = overbose;
- (void)free(pager);
-}
-
-/*
- * Set the socket send or receive buffer size.
- */
-void
-setxferbuf(int argc, char *argv[])
-{
- int size, dir;
-
- if (argc != 2) {
- usage:
- fprintf(ttyout, "usage: %s size\n", argv[0]);
- code = -1;
- return;
- }
- if (strcasecmp(argv[0], "sndbuf") == 0)
- dir = RATE_PUT;
- else if (strcasecmp(argv[0], "rcvbuf") == 0)
- dir = RATE_GET;
- else if (strcasecmp(argv[0], "xferbuf") == 0)
- dir = RATE_ALL;
- else
- goto usage;
-
- if ((size = strsuftoi(argv[1])) == -1)
- goto usage;
-
- if (size == 0) {
- fprintf(ttyout, "%s: size must be positive.\n", argv[0]);
- goto usage;
- }
-
- if (dir & RATE_PUT)
- sndbuf_size = size;
- if (dir & RATE_GET)
- rcvbuf_size = size;
- fprintf(ttyout, "Socket buffer sizes: send %d, receive %d.\n",
- sndbuf_size, rcvbuf_size);
- code = 0;
-}
-
-/*
- * Set or display options (defaults are provided by various env vars)
- */
-void
-setoption(int argc, char *argv[])
-{
- struct option *o;
-
- code = -1;
- if (argc == 0 || (argc != 1 && argc != 3)) {
- fprintf(ttyout, "usage: %s [option value]\n", argv[0]);
- return;
- }
-
-#define OPTIONINDENT ((int) sizeof("http_proxy"))
- if (argc == 1) {
- for (o = optiontab; o->name != NULL; o++) {
- fprintf(ttyout, "%-*s\t%s\n", OPTIONINDENT,
- o->name, o->value ? o->value : "");
- }
- } else {
- o = getoption(argv[1]);
- if (o == NULL) {
- fprintf(ttyout, "No such option `%s'.\n", argv[1]);
- return;
- }
- FREEPTR(o->value);
- o->value = xstrdup(argv[2]);
- if (verbose)
- fprintf(ttyout, "Setting `%s' to `%s'.\n",
- o->name, o->value);
- }
- code = 0;
-}
-
-/*
- * Unset an option
- */
-void
-unsetoption(int argc, char *argv[])
-{
- struct option *o;
-
- code = -1;
- if (argc == 0 || argc != 2) {
- fprintf(ttyout, "usage: %s option\n", argv[0]);
- return;
- }
-
- o = getoption(argv[1]);
- if (o == NULL) {
- fprintf(ttyout, "No such option `%s'.\n", argv[1]);
- return;
- }
- FREEPTR(o->value);
- fprintf(ttyout, "Unsetting `%s'.\n", o->name);
- code = 0;
-}
-
-/*
- * Display features supported by the remote host.
- */
-void
-feat(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- if (! features[FEAT_FEAT]) {
- fprintf(ttyout,
- "FEAT is not supported by the remote server.\n");
- return;
- }
- verbose = 1; /* If we aren't verbose, this doesn't do anything! */
- (void)command("FEAT");
- verbose = oldverbose;
-}
-
-void
-mlst(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc < 1 || argc > 2) {
- fprintf(ttyout, "usage: %s [remote-path]\n", argv[0]);
- code = -1;
- return;
- }
- if (! features[FEAT_MLST]) {
- fprintf(ttyout,
- "MLST is not supported by the remote server.\n");
- return;
- }
- verbose = 1; /* If we aren't verbose, this doesn't do anything! */
- COMMAND_1ARG(argc, argv, "MLST");
- verbose = oldverbose;
-}
-
-void
-opts(int argc, char *argv[])
-{
- int oldverbose = verbose;
-
- if (argc < 2 || argc > 3) {
- fprintf(ttyout, "usage: %s command [options]\n", argv[0]);
- code = -1;
- return;
- }
- if (! features[FEAT_FEAT]) {
- fprintf(ttyout,
- "OPTS is not supported by the remote server.\n");
- return;
- }
- verbose = 1; /* If we aren't verbose, this doesn't do anything! */
- if (argc == 2)
- command("OPTS %s", argv[1]);
- else
- command("OPTS %s %s", argv[1], argv[2]);
- verbose = oldverbose;
-}
diff --git a/contrib/lukemftp/src/cmdtab.c b/contrib/lukemftp/src/cmdtab.c
deleted file mode 100644
index 04efade..0000000
--- a/contrib/lukemftp/src/cmdtab.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* $NetBSD: cmdtab.c,v 1.44 2005/04/11 01:49:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2000 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.
- */
-
-/*
- * 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. 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("$NetBSD: cmdtab.c,v 1.44 2005/04/11 01:49:31 lukem Exp $");
-#endif
-#endif /* not lint */
-
-#include <stdio.h>
-#include "ftp_var.h"
-
-/*
- * User FTP -- Command Tables.
- */
-
-#define HSTR static const char
-
-#ifndef NO_HELP
-HSTR accounthelp[] = "send account command to remote server";
-HSTR appendhelp[] = "append to a file";
-HSTR asciihelp[] = "set ascii transfer type";
-HSTR beephelp[] = "beep when command completed";
-HSTR binaryhelp[] = "set binary transfer type";
-HSTR casehelp[] = "toggle mget upper/lower case id mapping";
-HSTR cdhelp[] = "change remote working directory";
-HSTR cduphelp[] = "change remote working directory to parent directory";
-HSTR chmodhelp[] = "change file permissions of remote file";
-HSTR connecthelp[] = "connect to remote ftp server";
-HSTR crhelp[] = "toggle carriage return stripping on ascii gets";
-HSTR debughelp[] = "toggle/set debugging mode";
-HSTR deletehelp[] = "delete remote file";
-HSTR disconhelp[] = "terminate ftp session";
-HSTR domachelp[] = "execute macro";
-HSTR edithelp[] = "toggle command line editing";
-HSTR epsv4help[] = "toggle use of EPSV/EPRT on IPv4 ftp";
-HSTR feathelp[] = "show FEATures supported by remote system";
-HSTR formhelp[] = "set file transfer format";
-HSTR gatehelp[] = "toggle gate-ftp; specify host[:port] to change proxy";
-HSTR globhelp[] = "toggle metacharacter expansion of local file names";
-HSTR hashhelp[] = "toggle printing `#' marks; specify number to set size";
-HSTR helphelp[] = "print local help information";
-HSTR idlehelp[] = "get (set) idle timer on remote side";
-HSTR lcdhelp[] = "change local working directory";
-HSTR lpagehelp[] = "view a local file through your pager";
-HSTR lpwdhelp[] = "print local working directory";
-HSTR lshelp[] = "list contents of remote path";
-HSTR macdefhelp[] = "define a macro";
-HSTR mdeletehelp[] = "delete multiple files";
-HSTR mgethelp[] = "get multiple files";
-HSTR mregethelp[] = "get multiple files restarting at end of local file";
-HSTR fgethelp[] = "get files using a localfile as a source of names";
-HSTR mkdirhelp[] = "make directory on the remote machine";
-HSTR mlshelp[] = "list contents of multiple remote directories";
-HSTR mlsdhelp[] = "list contents of remote directory in a machine "
- "parsable form";
-HSTR mlsthelp[] = "list remote path in a machine parsable form";
-HSTR modehelp[] = "set file transfer mode";
-HSTR modtimehelp[] = "show last modification time of remote file";
-HSTR mputhelp[] = "send multiple files";
-HSTR newerhelp[] = "get file if remote file is newer than local file ";
-HSTR nmaphelp[] = "set templates for default file name mapping";
-HSTR ntranshelp[] = "set translation table for default file name mapping";
-HSTR optshelp[] = "show or set options for remote commands";
-HSTR pagehelp[] = "view a remote file through your pager";
-HSTR passivehelp[] = "toggle use of passive transfer mode";
-HSTR plshelp[] = "list contents of remote path through your pager";
-HSTR pmlsdhelp[] = "list contents of remote directory in a machine "
- "parsable form through your pager";
-HSTR porthelp[] = "toggle use of PORT/LPRT cmd for each data connection";
-HSTR preservehelp[] ="toggle preservation of modification time of "
- "retrieved files";
-HSTR progresshelp[] ="toggle transfer progress meter";
-HSTR prompthelp[] = "force interactive prompting on multiple commands";
-HSTR proxyhelp[] = "issue command on alternate connection";
-HSTR pwdhelp[] = "print working directory on remote machine";
-HSTR quithelp[] = "terminate ftp session and exit";
-HSTR quotehelp[] = "send arbitrary ftp command";
-HSTR ratehelp[] = "set transfer rate limit (in bytes/second)";
-HSTR receivehelp[] = "receive file";
-HSTR regethelp[] = "get file restarting at end of local file";
-HSTR remotehelp[] = "get help from remote server";
-HSTR renamehelp[] = "rename file";
-HSTR resethelp[] = "clear queued command replies";
-HSTR restarthelp[]= "restart file transfer at bytecount";
-HSTR rmdirhelp[] = "remove directory on the remote machine";
-HSTR rmtstatushelp[]="show status of remote machine";
-HSTR runiquehelp[] = "toggle store unique for local files";
-HSTR sendhelp[] = "send one file";
-HSTR sethelp[] = "set or display options";
-HSTR shellhelp[] = "escape to the shell";
-HSTR sitehelp[] = "send site specific command to remote server\n"
- "\t\tTry \"rhelp site\" or \"site help\" "
- "for more information";
-HSTR sizecmdhelp[] = "show size of remote file";
-HSTR statushelp[] = "show current status";
-HSTR structhelp[] = "set file transfer structure";
-HSTR suniquehelp[] = "toggle store unique on remote machine";
-HSTR systemhelp[] = "show remote system type";
-HSTR tenexhelp[] = "set tenex file transfer type";
-HSTR tracehelp[] = "toggle packet tracing";
-HSTR typehelp[] = "set file transfer type";
-HSTR umaskhelp[] = "get (set) umask on remote side";
-HSTR unsethelp[] = "unset an option";
-HSTR usagehelp[] = "show command usage";
-HSTR userhelp[] = "send new user information";
-HSTR verbosehelp[] = "toggle verbose mode";
-HSTR xferbufhelp[] = "set socket send/receive buffer size";
-#endif
-
-HSTR empty[] = "";
-
-#ifdef NO_HELP
-#define H(x) empty
-#else
-#define H(x) x
-#endif
-
-#ifdef NO_EDITCOMPLETE
-#define CMPL(x)
-#define CMPL0
-#else /* !NO_EDITCOMPLETE */
-#define CMPL(x) #x,
-#define CMPL0 empty,
-#endif /* !NO_EDITCOMPLETE */
-
-struct cmd cmdtab[] = {
- { "!", H(shellhelp), 0, 0, 0, CMPL0 shell },
- { "$", H(domachelp), 1, 0, 0, CMPL0 domacro },
- { "account", H(accounthelp), 0, 1, 1, CMPL0 account},
- { "append", H(appendhelp), 1, 1, 1, CMPL(lr) put },
- { "ascii", H(asciihelp), 0, 1, 1, CMPL0 setascii },
- { "bell", H(beephelp), 0, 0, 0, CMPL0 setbell },
- { "binary", H(binaryhelp), 0, 1, 1, CMPL0 setbinary },
- { "bye", H(quithelp), 0, 0, 0, CMPL0 quit },
- { "case", H(casehelp), 0, 0, 1, CMPL0 setcase },
- { "cd", H(cdhelp), 0, 1, 1, CMPL(r) cd },
- { "cdup", H(cduphelp), 0, 1, 1, CMPL0 cdup },
- { "chmod", H(chmodhelp), 0, 1, 1, CMPL(nr) do_chmod },
- { "close", H(disconhelp), 0, 1, 1, CMPL0 disconnect },
- { "cr", H(crhelp), 0, 0, 0, CMPL0 setcr },
- { "debug", H(debughelp), 0, 0, 0, CMPL0 setdebug },
- { "delete", H(deletehelp), 0, 1, 1, CMPL(r) delete },
- { "dir", H(lshelp), 1, 1, 1, CMPL(rl) ls },
- { "disconnect", H(disconhelp), 0, 1, 1, CMPL0 disconnect },
- { "edit", H(edithelp), 0, 0, 0, CMPL0 setedit },
- { "epsv4", H(epsv4help), 0, 0, 0, CMPL0 setepsv4 },
- { "exit", H(quithelp), 0, 0, 0, CMPL0 quit },
- { "features", H(feathelp), 0, 1, 1, CMPL0 feat },
- { "fget", H(fgethelp), 1, 1, 1, CMPL(l) fget },
- { "form", H(formhelp), 0, 1, 1, CMPL0 setform },
- { "ftp", H(connecthelp), 0, 0, 1, CMPL0 setpeer },
- { "gate", H(gatehelp), 0, 0, 0, CMPL0 setgate },
- { "get", H(receivehelp), 1, 1, 1, CMPL(rl) get },
- { "glob", H(globhelp), 0, 0, 0, CMPL0 setglob },
- { "hash", H(hashhelp), 0, 0, 0, CMPL0 sethash },
- { "help", H(helphelp), 0, 0, 1, CMPL(C) help },
- { "idle", H(idlehelp), 0, 1, 1, CMPL0 idlecmd },
- { "image", H(binaryhelp), 0, 1, 1, CMPL0 setbinary },
- { "lcd", H(lcdhelp), 0, 0, 0, CMPL(l) lcd },
- { "less", H(pagehelp), 1, 1, 1, CMPL(r) page },
- { "lpage", H(lpagehelp), 0, 0, 0, CMPL(l) lpage },
- { "lpwd", H(lpwdhelp), 0, 0, 0, CMPL0 lpwd },
- { "ls", H(lshelp), 1, 1, 1, CMPL(rl) ls },
- { "macdef", H(macdefhelp), 0, 0, 0, CMPL0 macdef },
- { "mdelete", H(mdeletehelp), 1, 1, 1, CMPL(R) mdelete },
- { "mdir", H(mlshelp), 1, 1, 1, CMPL(R) mls },
- { "mget", H(mgethelp), 1, 1, 1, CMPL(R) mget },
- { "mkdir", H(mkdirhelp), 0, 1, 1, CMPL(r) makedir },
- { "mls", H(mlshelp), 1, 1, 1, CMPL(R) mls },
- { "mlsd", H(mlsdhelp), 1, 1, 1, CMPL(r) ls },
- { "mlst", H(mlsthelp), 1, 1, 1, CMPL(r) mlst },
- { "mode", H(modehelp), 0, 1, 1, CMPL0 setftmode },
- { "modtime", H(modtimehelp), 0, 1, 1, CMPL(r) modtime },
- { "more", H(pagehelp), 1, 1, 1, CMPL(r) page },
- { "mput", H(mputhelp), 1, 1, 1, CMPL(L) mput },
- { "mreget", H(mregethelp), 1, 1, 1, CMPL(R) mget },
- { "msend", H(mputhelp), 1, 1, 1, CMPL(L) mput },
- { "newer", H(newerhelp), 1, 1, 1, CMPL(r) newer },
- { "nlist", H(lshelp), 1, 1, 1, CMPL(rl) ls },
- { "nmap", H(nmaphelp), 0, 0, 1, CMPL0 setnmap },
- { "ntrans", H(ntranshelp), 0, 0, 1, CMPL0 setntrans },
- { "open", H(connecthelp), 0, 0, 1, CMPL0 setpeer },
- { "page", H(pagehelp), 1, 1, 1, CMPL(r) page },
- { "passive", H(passivehelp), 0, 0, 0, CMPL0 setpassive },
- { "pdir", H(plshelp), 1, 1, 1, CMPL(r) ls },
- { "pls", H(plshelp), 1, 1, 1, CMPL(r) ls },
- { "pmlsd", H(pmlsdhelp), 1, 1, 1, CMPL(r) ls },
- { "preserve", H(preservehelp),0, 0, 0, CMPL0 setpreserve },
- { "progress", H(progresshelp),0, 0, 0, CMPL0 setprogress },
- { "prompt", H(prompthelp), 0, 0, 0, CMPL0 setprompt },
- { "proxy", H(proxyhelp), 0, 0, 1, CMPL(c) doproxy },
- { "put", H(sendhelp), 1, 1, 1, CMPL(lr) put },
- { "pwd", H(pwdhelp), 0, 1, 1, CMPL0 pwd },
- { "quit", H(quithelp), 0, 0, 0, CMPL0 quit },
- { "quote", H(quotehelp), 1, 1, 1, CMPL0 quote },
- { "rate", H(ratehelp), 0, 0, 0, CMPL0 setrate },
- { "rcvbuf", H(xferbufhelp), 0, 0, 0, CMPL0 setxferbuf },
- { "recv", H(receivehelp), 1, 1, 1, CMPL(rl) get },
- { "reget", H(regethelp), 1, 1, 1, CMPL(rl) reget },
- { "remopts", H(optshelp), 0, 1, 1, CMPL0 opts },
- { "rename", H(renamehelp), 0, 1, 1, CMPL(rr) renamefile },
- { "reset", H(resethelp), 0, 1, 1, CMPL0 reset },
- { "restart", H(restarthelp), 1, 1, 1, CMPL0 restart },
- { "rhelp", H(remotehelp), 0, 1, 1, CMPL0 rmthelp },
- { "rmdir", H(rmdirhelp), 0, 1, 1, CMPL(r) removedir },
- { "rstatus", H(rmtstatushelp),0, 1, 1, CMPL(r) rmtstatus },
- { "runique", H(runiquehelp), 0, 0, 1, CMPL0 setrunique },
- { "send", H(sendhelp), 1, 1, 1, CMPL(lr) put },
- { "sendport", H(porthelp), 0, 0, 0, CMPL0 setport },
- { "set", H(sethelp), 0, 0, 0, CMPL(o) setoption },
- { "site", H(sitehelp), 0, 1, 1, CMPL0 site },
- { "size", H(sizecmdhelp), 1, 1, 1, CMPL(r) sizecmd },
- { "sndbuf", H(xferbufhelp), 0, 0, 0, CMPL0 setxferbuf },
- { "status", H(statushelp), 0, 0, 1, CMPL0 status },
- { "struct", H(structhelp), 0, 1, 1, CMPL0 setstruct },
- { "sunique", H(suniquehelp), 0, 0, 1, CMPL0 setsunique },
- { "system", H(systemhelp), 0, 1, 1, CMPL0 syst },
- { "tenex", H(tenexhelp), 0, 1, 1, CMPL0 settenex },
- { "throttle", H(ratehelp), 0, 0, 0, CMPL0 setrate },
- { "trace", H(tracehelp), 0, 0, 0, CMPL0 settrace },
- { "type", H(typehelp), 0, 1, 1, CMPL0 settype },
- { "umask", H(umaskhelp), 0, 1, 1, CMPL0 do_umask },
- { "unset", H(unsethelp), 0, 0, 0, CMPL(o) unsetoption },
- { "usage", H(usagehelp), 0, 0, 1, CMPL(C) help },
- { "user", H(userhelp), 0, 1, 1, CMPL0 user },
- { "verbose", H(verbosehelp), 0, 0, 0, CMPL0 setverbose },
- { "xferbuf", H(xferbufhelp), 0, 0, 0, CMPL0 setxferbuf },
- { "?", H(helphelp), 0, 0, 1, CMPL(C) help },
- { 0 },
-};
-
-struct option optiontab[] = {
- { "anonpass", NULL },
- { "ftp_proxy", NULL },
- { "http_proxy", NULL },
- { "no_proxy", NULL },
- { "pager", NULL },
- { "prompt", NULL },
- { "rprompt", NULL },
- { 0 },
-};
diff --git a/contrib/lukemftp/src/complete.c b/contrib/lukemftp/src/complete.c
deleted file mode 100644
index 8831bc1..0000000
--- a/contrib/lukemftp/src/complete.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* $NetBSD: complete.c,v 1.38 2000/05/01 10:35:17 lukem Exp $ */
-
-/*-
- * Copyright (c) 1997-2000 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__RCSID("$NetBSD: complete.c,v 1.38 2000/05/01 10:35:17 lukem Exp $");
-#endif /* not lint */
-
-/*
- * FTP user program - command and file completion routines
- */
-
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ftp_var.h"
-
-#ifndef NO_EDITCOMPLETE
-
-static int comparstr (const void *, const void *);
-static unsigned char complete_ambiguous (char *, int, StringList *);
-static unsigned char complete_command (char *, int);
-static unsigned char complete_local (char *, int);
-static unsigned char complete_option (char *, int);
-static unsigned char complete_remote (char *, int);
-
-static int
-comparstr(const void *a, const void *b)
-{
- return (strcmp(*(const char **)a, *(const 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
- * Returns a result as per el_set(EL_ADDFN, ...)
- */
-static unsigned char
-complete_ambiguous(char *word, int list, StringList *words)
-{
- char insertstr[MAXPATHLEN];
- char *lastmatch, *p;
- 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 */
- p = words->sl_str[0] + wordlen;
- if (*p == '\0') /* at end of word? */
- return (CC_REFRESH);
- ftpvis(insertstr, sizeof(insertstr), p, strlen(p));
- if (el_insertstr(el, insertstr) == -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) {
- ftpvis(insertstr, sizeof(insertstr),
- lastmatch + wordlen, matchlen - wordlen);
- if (el_insertstr(el, insertstr) == -1)
- return (CC_ERROR);
- else
- return (CC_REFRESH_BEEP);
- }
- }
-
- putc('\n', ttyout);
- qsort(words->sl_str, words->sl_cur, sizeof(char *), comparstr);
- list_vertical(words);
- return (CC_REDISPLAY);
-}
-
-/*
- * Complete a command
- */
-static unsigned char
-complete_command(char *word, int list)
-{
- struct cmd *c;
- StringList *words;
- size_t wordlen;
- unsigned char rv;
-
- words = xsl_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)
- xsl_add(words, c->c_name);
- }
-
- rv = complete_ambiguous(word, list, words);
- if (rv == CC_REFRESH) {
- if (el_insertstr(el, " ") == -1)
- rv = CC_ERROR;
- }
- sl_free(words, 0);
- return (rv);
-}
-
-/*
- * Complete a local file
- */
-static unsigned char
-complete_local(char *word, int list)
-{
- StringList *words;
- char dir[MAXPATHLEN];
- char *file;
- DIR *dd;
- struct dirent *dp;
- unsigned char rv;
- size_t len;
-
- if ((file = strrchr(word, '/')) == NULL) {
- dir[0] = '.';
- dir[1] = '\0';
- file = word;
- } else {
- if (file == word) {
- dir[0] = '/';
- dir[1] = '\0';
- } else
- (void)strlcpy(dir, word, file - word + 1);
- file++;
- }
- if (dir[0] == '~') {
- char *p;
-
- if ((p = globulize(dir)) == NULL)
- return (CC_ERROR);
- (void)strlcpy(dir, p, sizeof(dir));
- free(p);
- }
-
- if ((dd = opendir(dir)) == NULL)
- return (CC_ERROR);
-
- words = xsl_init();
- len = strlen(file);
-
- for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
- continue;
-
-#if defined(DIRENT_MISSING_D_NAMLEN)
- if (len > strlen(dp->d_name))
- continue;
-#else
- if (len > dp->d_namlen)
- continue;
-#endif
- if (strncmp(file, dp->d_name, len) == 0) {
- char *tcp;
-
- tcp = xstrdup(dp->d_name);
- xsl_add(words, tcp);
- }
- }
- closedir(dd);
-
- rv = complete_ambiguous(file, list, words);
- if (rv == CC_REFRESH) {
- struct stat sb;
- char path[MAXPATHLEN];
-
- (void)strlcpy(path, dir, sizeof(path));
- (void)strlcat(path, "/", sizeof(path));
- (void)strlcat(path, words->sl_str[0], sizeof(path));
-
- if (stat(path, &sb) >= 0) {
- char suffix[2] = " ";
-
- if (S_ISDIR(sb.st_mode))
- suffix[0] = '/';
- if (el_insertstr(el, suffix) == -1)
- rv = CC_ERROR;
- }
- }
- sl_free(words, 1);
- return (rv);
-}
-/*
- * Complete an option
- */
-static unsigned char
-complete_option(char *word, int list)
-{
- struct option *o;
- StringList *words;
- size_t wordlen;
- unsigned char rv;
-
- words = xsl_init();
- wordlen = strlen(word);
-
- for (o = optiontab; o->name != NULL; o++) {
- if (wordlen > strlen(o->name))
- continue;
- if (strncmp(word, o->name, wordlen) == 0)
- xsl_add(words, o->name);
- }
-
- rv = complete_ambiguous(word, list, words);
- if (rv == CC_REFRESH) {
- if (el_insertstr(el, " ") == -1)
- rv = CC_ERROR;
- }
- sl_free(words, 0);
- return (rv);
-}
-
-/*
- * Complete a remote file
- */
-static unsigned char
-complete_remote(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", NULL, NULL };
- dummyargv[1] = dir;
-
- if ((file = strrchr(word, '/')) == NULL) {
- dir[0] = '\0';
- file = word;
- } else {
- cp = file;
- while (*cp == '/' && cp > word)
- cp--;
- (void)strlcpy(dir, word, cp - word + 2);
- file++;
- }
-
- if (dirchange || dirlist == NULL ||
- strcmp(dir, lastdir) != 0) { /* dir not cached */
- char *emesg;
-
- if (dirlist != NULL)
- sl_free(dirlist, 1);
- dirlist = xsl_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 = xstrdup(tcp);
- xsl_add(dirlist, tcp);
- }
- if (emesg != NULL) {
- fprintf(ttyout, "\n%s\n", emesg);
- return (CC_REDISPLAY);
- }
- (void)strlcpy(lastdir, dir, sizeof(lastdir));
- dirchange = 0;
- }
-
- words = xsl_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)
- xsl_add(words, cp);
- }
- rv = complete_ambiguous(file, list, words);
- sl_free(words, 0);
- return (rv);
-}
-
-/*
- * Generic complete routine
- */
-unsigned char
-complete(EditLine *el, int ch)
-{
- static char word[FTPBUFLEN];
- static int lastc_argc, lastc_argo;
-
- struct cmd *c;
- const LineInfo *lf;
- int celems, dolist, cmpltype;
- size_t len;
-
- lf = el_line(el);
- len = lf->lastchar - lf->buffer;
- if (len >= sizeof(line))
- return (CC_ERROR);
- (void)strlcpy(line, lf->buffer, len + 1);
- 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] ? margv[cursor_argc] : "",
- cursor_argo) == 0)
- dolist = 1;
- else if (cursor_argc < margc)
- (void)strlcpy(word, margv[cursor_argc], cursor_argo + 1);
- 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);
-
- cmpltype = c->c_complete[cursor_argc - 1];
- switch (cmpltype) {
- case 'c': /* command complete */
- case 'C':
- return (complete_command(word, dolist));
- case 'l': /* local complete */
- case 'L':
- return (complete_local(word, dolist));
- case 'n': /* no complete */
- case 'N': /* no complete */
- return (CC_ERROR);
- case 'o': /* local complete */
- case 'O':
- return (complete_option(word, dolist));
- case 'r': /* remote complete */
- case 'R':
- if (connected != -1) {
- fputs("\nMust be logged in to complete.\n",
- ttyout);
- return (CC_REDISPLAY);
- }
- return (complete_remote(word, dolist));
- default:
- errx(1, "unknown complete type `%c'", cmpltype);
- return (CC_ERROR);
- }
- /* NOTREACHED */
-}
-
-#endif /* !NO_EDITCOMPLETE */
diff --git a/contrib/lukemftp/src/domacro.c b/contrib/lukemftp/src/domacro.c
deleted file mode 100644
index 2e10e1c..0000000
--- a/contrib/lukemftp/src/domacro.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* $NetBSD: domacro.c,v 1.20 2003/08/07 11:13:53 agc 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. 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("$NetBSD: domacro.c,v 1.20 2003/08/07 11:13:53 agc Exp $");
-#endif
-#endif /* not lint */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "ftp_var.h"
-
-void
-domacro(int argc, char *argv[])
-{
- int i, j, count = 2, loopflg = 0;
- char *cp1, *cp2, line2[FTPBUFLEN];
- struct cmd *c;
-
- if ((argc == 0 && argv != NULL) ||
- (argc < 2 && !another(&argc, &argv, "macro name"))) {
- fprintf(ttyout, "usage: %s macro_name [args]\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) {
- fprintf(ttyout, "'%s' macro not found.\n", argv[1]);
- code = -1;
- return;
- }
- (void)strlcpy(line2, line, sizeof(line2));
- TOP:
- cp1 = macros[i].mac_start;
- while (cp1 != macros[i].mac_end) {
- while (isspace((unsigned char)*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)strlcpy(cp2, argv[j+1],
- sizeof(line) - (cp2 - line));
- cp2 += strlen(argv[j+1]);
- }
- break;
- }
- if (*(cp1+1) == 'i') {
- loopflg = 1;
- cp1++;
- if (count < argc) {
- (void)strlcpy(cp2, argv[count],
- sizeof(line) - (cp2 - line));
- 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) {
- fputs("?Ambiguous command.\n", ttyout);
- code = -1;
- } else if (c == 0) {
- fputs("?Invalid command.\n", ttyout);
- code = -1;
- } else if (c->c_conn && !connected) {
- fputs("Not connected.\n", ttyout);
- code = -1;
- } else {
- if (verbose) {
- fputs(line, ttyout);
- putc('\n', ttyout);
- }
- margv[0] = c->c_name;
- (*c->c_handler)(margc, margv);
- if (bell && c->c_bell)
- (void)putc('\007', ttyout);
- (void)strlcpy(line, line2, sizeof(line));
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (cp1 != macros[i].mac_end)
- cp1++;
- }
- if (loopflg && ++count < argc)
- goto TOP;
-}
diff --git a/contrib/lukemftp/src/extern.h b/contrib/lukemftp/src/extern.h
deleted file mode 100644
index f2b802a..0000000
--- a/contrib/lukemftp/src/extern.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/* $NetBSD: extern.h,v 1.67 2005/05/14 15:26:43 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2005 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.
- */
-
-/*-
- * 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. 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
- */
-
-/*
- * Copyright (C) 1997 and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-struct sockaddr;
-struct tm;
-struct addrinfo;
-
-void abort_remote(FILE *);
-void abort_squared(int);
-void abortpt(int);
-void abortxfer(int);
-void account(int, char **);
-void ai_unmapped(struct addrinfo *);
-int another(int *, char ***, const char *);
-int auto_fetch(int, char **);
-int auto_put(int, char **, const char *);
-void blkfree(char **);
-void cd(int, char **);
-void cdup(int, char **);
-void changetype(int, int);
-void cleanuppeer(void);
-void cmdabort(int);
-void cmdtimeout(int);
-void cmdscanner(void);
-int command(const char *, ...)
- __attribute__((__format__(__printf__, 1, 2)));
-#ifndef NO_EDITCOMPLETE
-unsigned char complete(EditLine *, int);
-void controlediting(void);
-#endif /* !NO_EDITCOMPLETE */
-void crankrate(int);
-FILE *dataconn(const char *);
-void delete(int, char **);
-void disconnect(int, char **);
-void do_chmod(int, char **);
-void do_umask(int, char **);
-void domacro(int, char **);
-void doproxy(int, char **);
-void feat(int, char **);
-void fget(int, char **);
-int fileindir(const char *, const char *);
-int foregroundproc(void);
-void formatbuf(char *, size_t, const char *);
-void ftpvis(char *, size_t, const char *, size_t);
-int ftp_login(const char *, const char *, const char *);
-void get(int, char **);
-struct cmd *getcmd(const char *);
-int getit(int, char **, int, const char *);
-struct option *getoption(const char *);
-char *getoptionvalue(const char *);
-void getremoteinfo(void);
-int getreply(int);
-char *globulize(const char *);
-char *gunique(const char *);
-void help(int, char **);
-char *hookup(char *, char *);
-void idlecmd(int, char **);
-int initconn(void);
-void intr(int);
-int isipv6addr(const char *);
-void list_vertical(StringList *);
-void lcd(int, char **);
-void lostpeer(int);
-void lpage(int, char **);
-void lpwd(int, char **);
-void ls(int, char **);
-void mabort(void);
-void macdef(int, char **);
-void makeargv(void);
-void makedir(int, char **);
-void mdelete(int, char **);
-void mget(int, char **);
-void mintr(int);
-void mls(int, char **);
-void mlst(int, char **);
-void modtime(int, char **);
-void mput(int, char **);
-char *onoff(int);
-void opts(int, char **);
-void newer(int, char **);
-void page(int, char **);
-int parseport(const char *, int);
-int parserate(int, char **, int);
-char *prompt(void);
-void proxabort(int);
-void proxtrans(const char *, const char *, const char *);
-void psabort(int);
-void pswitch(int);
-void put(int, char **);
-void pwd(int, char **);
-void quit(int, char **);
-void quote(int, char **);
-void quote1(const char *, int, char **);
-void recvrequest(const char *, const char *, const char *,
- const char *, int, int);
-void reget(int, char **);
-char *remglob(char **, int, char **);
-time_t remotemodtime(const char *, int);
-off_t remotesize(const char *, int);
-void removedir(int, char **);
-void renamefile(int, char **);
-void reset(int, char **);
-void restart(int, char **);
-void rmthelp(int, char **);
-void rmtstatus(int, char **);
-char *rprompt(void);
-int ruserpass(const char *, const char **, const char **,
- const char **);
-void sendrequest(const char *, const char *, const char *, int);
-void setascii(int, char **);
-void setbell(int, char **);
-void setbinary(int, char **);
-void setcase(int, char **);
-void setcr(int, char **);
-void setdebug(int, char **);
-void setedit(int, char **);
-void setepsv4(int, char **);
-void setform(int, char **);
-void setftmode(int, char **);
-void setgate(int, char **);
-void setglob(int, char **);
-void sethash(int, char **);
-void setnmap(int, char **);
-void setntrans(int, char **);
-void setoption(int, char **);
-void setpassive(int, char **);
-void setpeer(int, char **);
-void setport(int, char **);
-void setpreserve(int, char **);
-void setprogress(int, char **);
-void setprompt(int, char **);
-void setrate(int, char **);
-void setrunique(int, char **);
-void setstruct(int, char **);
-void setsunique(int, char **);
-void settenex(int, char **);
-void settrace(int, char **);
-void setttywidth(int);
-void settype(int, char **);
-void setupsockbufsize(int);
-void setverbose(int, char **);
-void setxferbuf(int, char **);
-void shell(int, char **);
-void site(int, char **);
-void sizecmd(int, char **);
-char *slurpstring(void);
-void status(int, char **);
-int strsuftoi(const char *);
-void syst(int, char **);
-int togglevar(int, char **, int *, const char *);
-void unsetoption(int, char **);
-void updatelocalcwd(void);
-void updateremotecwd(void);
-void usage(void);
-void user(int, char **);
-int xconnect(int, const struct sockaddr *, socklen_t);
-int xlisten(int, int);
-int xpoll(struct pollfd *, int, int);
-void *xmalloc(size_t);
-StringList *xsl_init(void);
-void xsl_add(StringList *, char *);
-char *xstrdup(const char *);
diff --git a/contrib/lukemftp/src/fetch.c b/contrib/lukemftp/src/fetch.c
deleted file mode 100644
index e2acb01..0000000
--- a/contrib/lukemftp/src/fetch.c
+++ /dev/null
@@ -1,1834 +0,0 @@
-/* $NetBSD: fetch.c,v 1.158 2005/05/14 15:26:43 lukem Exp $ */
-
-/*-
- * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Luke Mewburn.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Scott Aaron Bamford.
- *
- * 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("$NetBSD: fetch.c,v 1.158 2005/05/14 15:26:43 lukem Exp $");
-#endif /* not lint */
-
-/*
- * FTP User Program -- Command line file retrieval
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#include <libutil.h>
-
-#include "ftp_var.h"
-#include "version.h"
-
-typedef enum {
- UNKNOWN_URL_T=-1,
- HTTP_URL_T,
- FTP_URL_T,
- FILE_URL_T,
- CLASSIC_URL_T
-} url_t;
-
-void aborthttp(int);
-#ifndef NO_AUTH
-static int auth_url(const char *, char **, const char *, const char *);
-static void base64_encode(const unsigned char *, size_t, unsigned char *);
-#endif
-static int go_fetch(const char *);
-static int fetch_ftp(const char *);
-static int fetch_url(const char *, const char *, char *, char *);
-static const char *match_token(const char **, const char *);
-static int parse_url(const char *, const char *, url_t *, char **,
- char **, char **, char **, in_port_t *, char **);
-static void url_decode(char *);
-
-static int redirect_loop;
-
-
-#define STRNEQUAL(a,b) (strncasecmp((a), (b), sizeof((b))-1) == 0)
-#define ISLWS(x) ((x)=='\r' || (x)=='\n' || (x)==' ' || (x)=='\t')
-#define SKIPLWS(x) do { while (ISLWS((*x))) x++; } while (0)
-
-
-#define ABOUT_URL "about:" /* propaganda */
-#define FILE_URL "file://" /* file URL prefix */
-#define FTP_URL "ftp://" /* ftp URL prefix */
-#define HTTP_URL "http://" /* http URL prefix */
-
-
-/*
- * Determine if token is the next word in buf (case insensitive).
- * If so, advance buf past the token and any trailing LWS, and
- * return a pointer to the token (in buf). Otherwise, return NULL.
- * token may be preceeded by LWS.
- * token must be followed by LWS or NUL. (I.e, don't partial match).
- */
-static const char *
-match_token(const char **buf, const char *token)
-{
- const char *p, *orig;
- size_t tlen;
-
- tlen = strlen(token);
- p = *buf;
- SKIPLWS(p);
- orig = p;
- if (strncasecmp(p, token, tlen) != 0)
- return NULL;
- p += tlen;
- if (*p != '\0' && !ISLWS(*p))
- return NULL;
- SKIPLWS(p);
- orig = *buf;
- *buf = p;
- return orig;
-}
-
-#ifndef NO_AUTH
-/*
- * Generate authorization response based on given authentication challenge.
- * Returns -1 if an error occurred, otherwise 0.
- * Sets response to a malloc(3)ed string; caller should free.
- */
-static int
-auth_url(const char *challenge, char **response, const char *guser,
- const char *gpass)
-{
- const char *cp, *scheme;
- char *ep, *clear, *realm;
- char user[BUFSIZ], *pass;
- int rval;
- size_t len, clen, rlen;
-
- *response = NULL;
- clear = realm = NULL;
- rval = -1;
- cp = challenge;
- scheme = "Basic"; /* only support Basic authentication */
-
- if (debug)
- fprintf(ttyout, "auth_url: challenge `%s'\n", challenge);
-
- if (! match_token(&cp, scheme)) {
- warnx("Unsupported authentication challenge - `%s'",
- challenge);
- goto cleanup_auth_url;
- }
-
-#define REALM "realm=\""
- if (STRNEQUAL(cp, REALM))
- cp += sizeof(REALM) - 1;
- else {
- warnx("Unsupported authentication challenge - `%s'",
- challenge);
- goto cleanup_auth_url;
- }
-/* XXX: need to improve quoted-string parsing to support \ quoting, etc. */
- if ((ep = strchr(cp, '\"')) != NULL) {
- size_t len = ep - cp;
-
- realm = (char *)xmalloc(len + 1);
- (void)strlcpy(realm, cp, len + 1);
- } else {
- warnx("Unsupported authentication challenge - `%s'",
- challenge);
- goto cleanup_auth_url;
- }
-
- fprintf(ttyout, "Username for `%s': ", realm);
- if (guser != NULL) {
- (void)strlcpy(user, guser, sizeof(user));
- fprintf(ttyout, "%s\n", user);
- } else {
- (void)fflush(ttyout);
- if (fgets(user, sizeof(user) - 1, stdin) == NULL) {
- clearerr(stdin);
- goto cleanup_auth_url;
- }
- user[strlen(user) - 1] = '\0';
- }
- if (gpass != NULL)
- pass = (char *)gpass;
- else
- pass = getpass("Password: ");
-
- clen = strlen(user) + strlen(pass) + 2; /* user + ":" + pass + "\0" */
- clear = (char *)xmalloc(clen);
- (void)strlcpy(clear, user, clen);
- (void)strlcat(clear, ":", clen);
- (void)strlcat(clear, pass, clen);
- if (gpass == NULL)
- memset(pass, 0, strlen(pass));
-
- /* scheme + " " + enc + "\0" */
- rlen = strlen(scheme) + 1 + (clen + 2) * 4 / 3 + 1;
- *response = (char *)xmalloc(rlen);
- (void)strlcpy(*response, scheme, rlen);
- len = strlcat(*response, " ", rlen);
- /* use `clen - 1' to not encode the trailing NUL */
- base64_encode((unsigned char *)clear, clen - 1,
- (unsigned char *)*response + len);
- memset(clear, 0, clen);
- rval = 0;
-
- cleanup_auth_url:
- FREEPTR(clear);
- FREEPTR(realm);
- return (rval);
-}
-
-/*
- * Encode len bytes starting at clear using base64 encoding into encoded,
- * which should be at least ((len + 2) * 4 / 3 + 1) in size.
- */
-static void
-base64_encode(const unsigned char *clear, size_t len, unsigned char *encoded)
-{
- static const unsigned char enc[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- unsigned char *cp;
- int i;
-
- cp = encoded;
- for (i = 0; i < len; i += 3) {
- *(cp++) = enc[((clear[i + 0] >> 2))];
- *(cp++) = enc[((clear[i + 0] << 4) & 0x30)
- | ((clear[i + 1] >> 4) & 0x0f)];
- *(cp++) = enc[((clear[i + 1] << 2) & 0x3c)
- | ((clear[i + 2] >> 6) & 0x03)];
- *(cp++) = enc[((clear[i + 2] ) & 0x3f)];
- }
- *cp = '\0';
- while (i-- > len)
- *(--cp) = '=';
-}
-#endif
-
-/*
- * Decode %xx escapes in given string, `in-place'.
- */
-static void
-url_decode(char *url)
-{
- unsigned char *p, *q;
-
- if (EMPTYSTRING(url))
- return;
- p = q = (unsigned char *)url;
-
-#define HEXTOINT(x) (x - (isdigit(x) ? '0' : (islower(x) ? 'a' : 'A') - 10))
- while (*p) {
- if (p[0] == '%'
- && p[1] && isxdigit((unsigned char)p[1])
- && p[2] && isxdigit((unsigned char)p[2])) {
- *q++ = HEXTOINT(p[1]) * 16 + HEXTOINT(p[2]);
- p+=3;
- } else
- *q++ = *p++;
- }
- *q = '\0';
-}
-
-
-/*
- * Parse URL of form:
- * <type>://[<user>[:<password>]@]<host>[:<port>][/<path>]
- * Returns -1 if a parse error occurred, otherwise 0.
- * It's the caller's responsibility to url_decode() the returned
- * user, pass and path.
- *
- * Sets type to url_t, each of the given char ** pointers to a
- * malloc(3)ed strings of the relevant section, and port to
- * the number given, or ftpport if ftp://, or httpport if http://.
- *
- * If <host> is surrounded by `[' and ']', it's parsed as an
- * IPv6 address (as per RFC 2732).
- *
- * XXX: this is not totally RFC 1738 compliant; <path> will have the
- * leading `/' unless it's an ftp:// URL, as this makes things easier
- * for file:// and http:// URLs. ftp:// URLs have the `/' between the
- * host and the URL-path removed, but any additional leading slashes
- * in the URL-path are retained (because they imply that we should
- * later do "CWD" with a null argument).
- *
- * Examples:
- * input URL output path
- * --------- -----------
- * "ftp://host" NULL
- * "http://host/" NULL
- * "file://host/dir/file" "dir/file"
- * "ftp://host/" ""
- * "ftp://host//" NULL
- * "ftp://host//dir/file" "/dir/file"
- */
-static int
-parse_url(const char *url, const char *desc, url_t *type,
- char **user, char **pass, char **host, char **port,
- in_port_t *portnum, char **path)
-{
- const char *origurl;
- char *cp, *ep, *thost, *tport;
- size_t len;
-
- if (url == NULL || desc == NULL || type == NULL || user == NULL
- || pass == NULL || host == NULL || port == NULL || portnum == NULL
- || path == NULL)
- errx(1, "parse_url: invoked with NULL argument!");
-
- origurl = url;
- *type = UNKNOWN_URL_T;
- *user = *pass = *host = *port = *path = NULL;
- *portnum = 0;
- tport = NULL;
-
- if (STRNEQUAL(url, HTTP_URL)) {
- url += sizeof(HTTP_URL) - 1;
- *type = HTTP_URL_T;
- *portnum = HTTP_PORT;
- tport = httpport;
- } else if (STRNEQUAL(url, FTP_URL)) {
- url += sizeof(FTP_URL) - 1;
- *type = FTP_URL_T;
- *portnum = FTP_PORT;
- tport = ftpport;
- } else if (STRNEQUAL(url, FILE_URL)) {
- url += sizeof(FILE_URL) - 1;
- *type = FILE_URL_T;
- } else {
- warnx("Invalid %s `%s'", desc, url);
- cleanup_parse_url:
- FREEPTR(*user);
- FREEPTR(*pass);
- FREEPTR(*host);
- FREEPTR(*port);
- FREEPTR(*path);
- return (-1);
- }
-
- if (*url == '\0')
- return (0);
-
- /* find [user[:pass]@]host[:port] */
- ep = strchr(url, '/');
- if (ep == NULL)
- thost = xstrdup(url);
- else {
- len = ep - url;
- thost = (char *)xmalloc(len + 1);
- (void)strlcpy(thost, url, len + 1);
- if (*type == FTP_URL_T) /* skip first / for ftp URLs */
- ep++;
- *path = xstrdup(ep);
- }
-
- cp = strchr(thost, '@'); /* look for user[:pass]@ in URLs */
- if (cp != NULL) {
- if (*type == FTP_URL_T)
- anonftp = 0; /* disable anonftp */
- *user = thost;
- *cp = '\0';
- thost = xstrdup(cp + 1);
- cp = strchr(*user, ':');
- if (cp != NULL) {
- *cp = '\0';
- *pass = xstrdup(cp + 1);
- }
- url_decode(*user);
- if (*pass)
- url_decode(*pass);
- }
-
-#ifdef INET6
- /*
- * Check if thost is an encoded IPv6 address, as per
- * RFC 2732:
- * `[' ipv6-address ']'
- */
- if (*thost == '[') {
- cp = thost + 1;
- if ((ep = strchr(cp, ']')) == NULL ||
- (ep[1] != '\0' && ep[1] != ':')) {
- warnx("Invalid address `%s' in %s `%s'",
- thost, desc, origurl);
- goto cleanup_parse_url;
- }
- len = ep - cp; /* change `[xyz]' -> `xyz' */
- memmove(thost, thost + 1, len);
- thost[len] = '\0';
- if (! isipv6addr(thost)) {
- warnx("Invalid IPv6 address `%s' in %s `%s'",
- thost, desc, origurl);
- goto cleanup_parse_url;
- }
- cp = ep + 1;
- if (*cp == ':')
- cp++;
- else
- cp = NULL;
- } else
-#endif /* INET6 */
- if ((cp = strchr(thost, ':')) != NULL)
- *cp++ = '\0';
- *host = thost;
-
- /* look for [:port] */
- if (cp != NULL) {
- long nport;
-
- nport = parseport(cp, -1);
- if (nport == -1) {
- warnx("Unknown port `%s' in %s `%s'",
- cp, desc, origurl);
- goto cleanup_parse_url;
- }
- *portnum = nport;
- tport = cp;
- }
-
- if (tport != NULL)
- *port = xstrdup(tport);
- if (*path == NULL)
- *path = xstrdup("/");
-
- if (debug)
- fprintf(ttyout,
- "parse_url: user `%s' pass `%s' host %s port %s(%d) "
- "path `%s'\n",
- *user ? *user : "<null>", *pass ? *pass : "<null>",
- *host ? *host : "<null>", *port ? *port : "<null>",
- *portnum ? *portnum : -1, *path ? *path : "<null>");
-
- return (0);
-}
-
-sigjmp_buf httpabort;
-
-/*
- * Retrieve URL, via a proxy if necessary, using HTTP.
- * If proxyenv is set, use that for the proxy, otherwise try ftp_proxy or
- * http_proxy as appropriate.
- * Supports HTTP redirects.
- * Returns 1 on failure, 0 on completed xfer, -1 if ftp connection
- * is still open (e.g, ftp xfer with trailing /)
- */
-static int
-fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
-{
- struct addrinfo hints, *res, *res0 = NULL;
- int error;
- char hbuf[NI_MAXHOST];
- volatile sigfunc oldintr, oldintp;
- volatile int s;
- struct stat sb;
- int ischunked, isproxy, rval, hcode;
- size_t len;
- static size_t bufsize;
- static char *xferbuf;
- const char *cp, *token;
- char *ep, *buf, *savefile;
- char *auth, *location, *message;
- char *user, *pass, *host, *port, *path, *decodedpath;
- char *puser, *ppass, *useragent;
- off_t hashbytes, rangestart, rangeend, entitylen;
- int (*closefunc)(FILE *);
- FILE *fin, *fout;
- time_t mtime;
- url_t urltype;
- in_port_t portnum;
-
- oldintr = oldintp = NULL;
- closefunc = NULL;
- fin = fout = NULL;
- s = -1;
- buf = savefile = NULL;
- auth = location = message = NULL;
- ischunked = isproxy = hcode = 0;
- rval = 1;
- user = pass = host = path = decodedpath = puser = ppass = NULL;
-
-#ifdef __GNUC__ /* shut up gcc warnings */
- (void)&closefunc;
- (void)&fin;
- (void)&fout;
- (void)&buf;
- (void)&savefile;
- (void)&rval;
- (void)&isproxy;
- (void)&hcode;
- (void)&ischunked;
- (void)&message;
- (void)&location;
- (void)&auth;
- (void)&decodedpath;
-#endif
-
- if (parse_url(url, "URL", &urltype, &user, &pass, &host, &port,
- &portnum, &path) == -1)
- goto cleanup_fetch_url;
-
- if (urltype == FILE_URL_T && ! EMPTYSTRING(host)
- && strcasecmp(host, "localhost") != 0) {
- warnx("No support for non local file URL `%s'", url);
- goto cleanup_fetch_url;
- }
-
- if (EMPTYSTRING(path)) {
- if (urltype == FTP_URL_T) {
- rval = fetch_ftp(url);
- goto cleanup_fetch_url;
- }
- if (urltype != HTTP_URL_T || outfile == NULL) {
- warnx("Invalid URL (no file after host) `%s'", url);
- goto cleanup_fetch_url;
- }
- }
-
- decodedpath = xstrdup(path);
- url_decode(decodedpath);
-
- if (outfile)
- savefile = xstrdup(outfile);
- else {
- cp = strrchr(decodedpath, '/'); /* find savefile */
- if (cp != NULL)
- savefile = xstrdup(cp + 1);
- else
- savefile = xstrdup(decodedpath);
- }
- if (EMPTYSTRING(savefile)) {
- if (urltype == FTP_URL_T) {
- rval = fetch_ftp(url);
- goto cleanup_fetch_url;
- }
- warnx("no file after directory (you must specify an "
- "output file) `%s'", url);
- goto cleanup_fetch_url;
- } else {
- if (debug)
- fprintf(ttyout, "savefile `%s'\n", savefile);
- }
-
- restart_point = 0;
- filesize = -1;
- rangestart = rangeend = entitylen = -1;
- mtime = -1;
- if (restartautofetch) {
- if (strcmp(savefile, "-") != 0 && *savefile != '|' &&
- stat(savefile, &sb) == 0)
- restart_point = sb.st_size;
- }
- if (urltype == FILE_URL_T) { /* file:// URLs */
- direction = "copied";
- fin = fopen(decodedpath, "r");
- if (fin == NULL) {
- warn("Cannot open file `%s'", decodedpath);
- goto cleanup_fetch_url;
- }
- if (fstat(fileno(fin), &sb) == 0) {
- mtime = sb.st_mtime;
- filesize = sb.st_size;
- }
- if (restart_point) {
- if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
- warn("Can't lseek to restart `%s'",
- decodedpath);
- goto cleanup_fetch_url;
- }
- }
- if (verbose) {
- fprintf(ttyout, "Copying %s", decodedpath);
- if (restart_point)
- fprintf(ttyout, " (restarting at " LLF ")",
- (LLT)restart_point);
- fputs("\n", ttyout);
- }
- } else { /* ftp:// or http:// URLs */
- char *leading;
- int hasleading;
-
- if (proxyenv == NULL) {
- if (urltype == HTTP_URL_T)
- proxyenv = getoptionvalue("http_proxy");
- else if (urltype == FTP_URL_T)
- proxyenv = getoptionvalue("ftp_proxy");
- }
- direction = "retrieved";
- if (! EMPTYSTRING(proxyenv)) { /* use proxy */
- url_t purltype;
- char *phost, *ppath;
- char *pport, *no_proxy;
-
- isproxy = 1;
-
- /* check URL against list of no_proxied sites */
- no_proxy = getoptionvalue("no_proxy");
- if (! EMPTYSTRING(no_proxy)) {
- char *np, *np_copy;
- long np_port;
- size_t hlen, plen;
-
- np_copy = xstrdup(no_proxy);
- hlen = strlen(host);
- while ((cp = strsep(&np_copy, " ,")) != NULL) {
- if (*cp == '\0')
- continue;
- if ((np = strrchr(cp, ':')) != NULL) {
- *np = '\0';
- np_port =
- strtol(np + 1, &ep, 10);
- if (*ep != '\0')
- continue;
- if (np_port != portnum)
- continue;
- }
- plen = strlen(cp);
- if (hlen < plen)
- continue;
- if (strncasecmp(host + hlen - plen,
- cp, plen) == 0) {
- isproxy = 0;
- break;
- }
- }
- FREEPTR(np_copy);
- if (isproxy == 0 && urltype == FTP_URL_T) {
- rval = fetch_ftp(url);
- goto cleanup_fetch_url;
- }
- }
-
- if (isproxy) {
- if (parse_url(proxyenv, "proxy URL", &purltype,
- &puser, &ppass, &phost, &pport, &portnum,
- &ppath) == -1)
- goto cleanup_fetch_url;
-
- if ((purltype != HTTP_URL_T
- && purltype != FTP_URL_T) ||
- EMPTYSTRING(phost) ||
- (! EMPTYSTRING(ppath)
- && strcmp(ppath, "/") != 0)) {
- warnx("Malformed proxy URL `%s'",
- proxyenv);
- FREEPTR(phost);
- FREEPTR(pport);
- FREEPTR(ppath);
- goto cleanup_fetch_url;
- }
- if (isipv6addr(host) &&
- strchr(host, '%') != NULL) {
- warnx(
-"Scoped address notation `%s' disallowed via web proxy",
- host);
- FREEPTR(phost);
- FREEPTR(pport);
- FREEPTR(ppath);
- goto cleanup_fetch_url;
- }
-
- FREEPTR(host);
- host = phost;
- FREEPTR(port);
- port = pport;
- FREEPTR(path);
- path = xstrdup(url);
- FREEPTR(ppath);
- }
- } /* ! EMPTYSTRING(proxyenv) */
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = 0;
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = 0;
- error = getaddrinfo(host, NULL, &hints, &res0);
- if (error) {
- warnx("%s", gai_strerror(error));
- goto cleanup_fetch_url;
- }
- if (res0->ai_canonname)
- host = res0->ai_canonname;
-
- s = -1;
- for (res = res0; res; res = res->ai_next) {
- /*
- * see comment in hookup()
- */
- ai_unmapped(res);
- if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
- strlcpy(hbuf, "invalid", sizeof(hbuf));
-
- if (verbose && res != res0)
- fprintf(ttyout, "Trying %s...\n", hbuf);
-
- ((struct sockaddr_in *)res->ai_addr)->sin_port =
- htons(portnum);
- s = socket(res->ai_family, SOCK_STREAM,
- res->ai_protocol);
- if (s < 0) {
- warn("Can't create socket");
- continue;
- }
-
- if (xconnect(s, res->ai_addr, res->ai_addrlen) < 0) {
- warn("Connect to address `%s'", hbuf);
- close(s);
- s = -1;
- continue;
- }
-
- /* success */
- break;
- }
-
- if (s < 0) {
- warn("Can't connect to %s", host);
- goto cleanup_fetch_url;
- }
-
- fin = fdopen(s, "r+");
- /*
- * Construct and send the request.
- */
- if (verbose)
- fprintf(ttyout, "Requesting %s\n", url);
- leading = " (";
- hasleading = 0;
- if (isproxy) {
- if (verbose) {
- fprintf(ttyout, "%svia %s:%s", leading,
- host, port);
- leading = ", ";
- hasleading++;
- }
- fprintf(fin, "GET %s HTTP/1.0\r\n", path);
- if (flushcache)
- fprintf(fin, "Pragma: no-cache\r\n");
- } else {
- fprintf(fin, "GET %s HTTP/1.1\r\n", path);
- if (strchr(host, ':')) {
- char *h, *p;
-
- /*
- * strip off IPv6 scope identifier, since it is
- * local to the node
- */
- h = xstrdup(host);
- if (isipv6addr(h) &&
- (p = strchr(h, '%')) != NULL) {
- *p = '\0';
- }
- fprintf(fin, "Host: [%s]", h);
- free(h);
- } else
- fprintf(fin, "Host: %s", host);
- if (portnum != HTTP_PORT)
- fprintf(fin, ":%u", portnum);
- fprintf(fin, "\r\n");
- fprintf(fin, "Accept: */*\r\n");
- fprintf(fin, "Connection: close\r\n");
- if (restart_point) {
- fputs(leading, ttyout);
- fprintf(fin, "Range: bytes=" LLF "-\r\n",
- (LLT)restart_point);
- fprintf(ttyout, "restarting at " LLF,
- (LLT)restart_point);
- leading = ", ";
- hasleading++;
- }
- if (flushcache)
- fprintf(fin, "Cache-Control: no-cache\r\n");
- }
- if ((useragent=getenv("FTPUSERAGENT")) != NULL) {
- fprintf(fin, "User-Agent: %s\r\n", useragent);
- } else {
- fprintf(fin, "User-Agent: %s/%s\r\n",
- FTP_PRODUCT, FTP_VERSION);
- }
- if (wwwauth) {
- if (verbose) {
- fprintf(ttyout, "%swith authorization",
- leading);
- leading = ", ";
- hasleading++;
- }
- fprintf(fin, "Authorization: %s\r\n", wwwauth);
- }
- if (proxyauth) {
- if (verbose) {
- fprintf(ttyout,
- "%swith proxy authorization", leading);
- leading = ", ";
- hasleading++;
- }
- fprintf(fin, "Proxy-Authorization: %s\r\n", proxyauth);
- }
- if (verbose && hasleading)
- fputs(")\n", ttyout);
- fprintf(fin, "\r\n");
- if (fflush(fin) == EOF) {
- warn("Writing HTTP request");
- goto cleanup_fetch_url;
- }
-
- /* Read the response */
- if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0)) == NULL) {
- warn("Receiving HTTP reply");
- goto cleanup_fetch_url;
- }
- while (len > 0 && (ISLWS(buf[len-1])))
- buf[--len] = '\0';
- if (debug)
- fprintf(ttyout, "received `%s'\n", buf);
-
- /* Determine HTTP response code */
- cp = strchr(buf, ' ');
- if (cp == NULL)
- goto improper;
- else
- cp++;
- hcode = strtol(cp, &ep, 10);
- if (*ep != '\0' && !isspace((unsigned char)*ep))
- goto improper;
- message = xstrdup(cp);
-
- /* Read the rest of the header. */
- while (1) {
- FREEPTR(buf);
- if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0))
- == NULL) {
- warn("Receiving HTTP reply");
- goto cleanup_fetch_url;
- }
- while (len > 0 && (ISLWS(buf[len-1])))
- buf[--len] = '\0';
- if (len == 0)
- break;
- if (debug)
- fprintf(ttyout, "received `%s'\n", buf);
-
- /*
- * Look for some headers
- */
-
- cp = buf;
-
- if (match_token(&cp, "Content-Length:")) {
- filesize = STRTOLL(cp, &ep, 10);
- if (filesize < 0 || *ep != '\0')
- goto improper;
- if (debug)
- fprintf(ttyout,
- "parsed len as: " LLF "\n",
- (LLT)filesize);
-
- } else if (match_token(&cp, "Content-Range:")) {
- if (! match_token(&cp, "bytes"))
- goto improper;
-
- if (*cp == '*')
- cp++;
- else {
- rangestart = STRTOLL(cp, &ep, 10);
- if (rangestart < 0 || *ep != '-')
- goto improper;
- cp = ep + 1;
- rangeend = STRTOLL(cp, &ep, 10);
- if (rangeend < 0 || rangeend < rangestart)
- goto improper;
- cp = ep;
- }
- if (*cp != '/')
- goto improper;
- cp++;
- if (*cp == '*')
- cp++;
- else {
- entitylen = STRTOLL(cp, &ep, 10);
- if (entitylen < 0)
- goto improper;
- cp = ep;
- }
- if (*cp != '\0')
- goto improper;
-
- if (debug) {
- fprintf(ttyout, "parsed range as: ");
- if (rangestart == -1)
- fprintf(ttyout, "*");
- else
- fprintf(ttyout, LLF "-" LLF,
- (LLT)rangestart,
- (LLT)rangeend);
- fprintf(ttyout, "/" LLF "\n", (LLT)entitylen);
- }
- if (! restart_point) {
- warnx(
- "Received unexpected Content-Range header");
- goto cleanup_fetch_url;
- }
-
- } else if (match_token(&cp, "Last-Modified:")) {
- struct tm parsed;
- char *t;
-
- /* RFC 1123 */
- if ((t = strptime(cp,
- "%a, %d %b %Y %H:%M:%S GMT",
- &parsed))
- /* RFC 850 */
- || (t = strptime(cp,
- "%a, %d-%b-%y %H:%M:%S GMT",
- &parsed))
- /* asctime */
- || (t = strptime(cp,
- "%a, %b %d %H:%M:%S %Y",
- &parsed))) {
- parsed.tm_isdst = -1;
- if (*t == '\0')
- mtime = timegm(&parsed);
- if (debug && mtime != -1) {
- fprintf(ttyout,
- "parsed date as: %s",
- ctime(&mtime));
- }
- }
-
- } else if (match_token(&cp, "Location:")) {
- location = xstrdup(cp);
- if (debug)
- fprintf(ttyout,
- "parsed location as `%s'\n", cp);
-
- } else if (match_token(&cp, "Transfer-Encoding:")) {
- if (match_token(&cp, "binary")) {
- warnx(
- "Bogus transfer encoding - `binary' (fetching anyway)");
- continue;
- }
- if (! (token = match_token(&cp, "chunked"))) {
- warnx(
- "Unsupported transfer encoding - `%s'",
- token);
- goto cleanup_fetch_url;
- }
- ischunked++;
- if (debug)
- fprintf(ttyout,
- "using chunked encoding\n");
-
- } else if (match_token(&cp, "Proxy-Authenticate:")
- || match_token(&cp, "WWW-Authenticate:")) {
- if (! (token = match_token(&cp, "Basic"))) {
- if (debug)
- fprintf(ttyout,
- "skipping unknown auth scheme `%s'\n",
- token);
- continue;
- }
- FREEPTR(auth);
- auth = xstrdup(token);
- if (debug)
- fprintf(ttyout,
- "parsed auth as `%s'\n", cp);
- }
-
- }
- /* finished parsing header */
- FREEPTR(buf);
-
- switch (hcode) {
- case 200:
- break;
- case 206:
- if (! restart_point) {
- warnx("Not expecting partial content header");
- goto cleanup_fetch_url;
- }
- break;
- case 300:
- case 301:
- case 302:
- case 303:
- case 305:
- if (EMPTYSTRING(location)) {
- warnx(
- "No redirection Location provided by server");
- goto cleanup_fetch_url;
- }
- if (redirect_loop++ > 5) {
- warnx("Too many redirections requested");
- goto cleanup_fetch_url;
- }
- if (hcode == 305) {
- if (verbose)
- fprintf(ttyout, "Redirected via %s\n",
- location);
- rval = fetch_url(url, location,
- proxyauth, wwwauth);
- } else {
- if (verbose)
- fprintf(ttyout, "Redirected to %s\n",
- location);
- rval = go_fetch(location);
- }
- goto cleanup_fetch_url;
-#ifndef NO_AUTH
- case 401:
- case 407:
- {
- char **authp;
- char *auser, *apass;
-
- if (hcode == 401) {
- authp = &wwwauth;
- auser = user;
- apass = pass;
- } else {
- authp = &proxyauth;
- auser = puser;
- apass = ppass;
- }
- if (verbose || *authp == NULL ||
- auser == NULL || apass == NULL)
- fprintf(ttyout, "%s\n", message);
- if (EMPTYSTRING(auth)) {
- warnx(
- "No authentication challenge provided by server");
- goto cleanup_fetch_url;
- }
- if (*authp != NULL) {
- char reply[10];
-
- fprintf(ttyout,
- "Authorization failed. Retry (y/n)? ");
- if (fgets(reply, sizeof(reply), stdin)
- == NULL) {
- clearerr(stdin);
- goto cleanup_fetch_url;
- }
- if (tolower((unsigned char)reply[0]) != 'y')
- goto cleanup_fetch_url;
- auser = NULL;
- apass = NULL;
- }
- if (auth_url(auth, authp, auser, apass) == 0) {
- rval = fetch_url(url, proxyenv,
- proxyauth, wwwauth);
- memset(*authp, 0, strlen(*authp));
- FREEPTR(*authp);
- }
- goto cleanup_fetch_url;
- }
-#endif
- default:
- if (message)
- warnx("Error retrieving file - `%s'", message);
- else
- warnx("Unknown error retrieving file");
- goto cleanup_fetch_url;
- }
- } /* end of ftp:// or http:// specific setup */
-
- /* Open the output file. */
- if (strcmp(savefile, "-") == 0) {
- fout = stdout;
- } else if (*savefile == '|') {
- oldintp = xsignal(SIGPIPE, SIG_IGN);
- fout = popen(savefile + 1, "w");
- if (fout == NULL) {
- warn("Can't run `%s'", savefile + 1);
- goto cleanup_fetch_url;
- }
- closefunc = pclose;
- } else {
- if ((rangeend != -1 && rangeend <= restart_point) ||
- (rangestart == -1 && filesize != -1 && filesize <= restart_point)) {
- /* already done */
- if (verbose)
- fprintf(ttyout, "already done\n");
- rval = 0;
- goto cleanup_fetch_url;
- }
- if (restart_point && rangestart != -1) {
- if (entitylen != -1)
- filesize = entitylen;
- if (rangestart != restart_point) {
- warnx(
- "Size of `%s' differs from save file `%s'",
- url, savefile);
- goto cleanup_fetch_url;
- }
- fout = fopen(savefile, "a");
- } else
- fout = fopen(savefile, "w");
- if (fout == NULL) {
- warn("Can't open `%s'", savefile);
- goto cleanup_fetch_url;
- }
- closefunc = fclose;
- }
-
- /* Trap signals */
- if (sigsetjmp(httpabort, 1))
- goto cleanup_fetch_url;
- (void)xsignal(SIGQUIT, psummary);
- oldintr = xsignal(SIGINT, aborthttp);
-
- if (rcvbuf_size > bufsize) {
- if (xferbuf)
- (void)free(xferbuf);
- bufsize = rcvbuf_size;
- xferbuf = xmalloc(bufsize);
- }
-
- bytes = 0;
- hashbytes = mark;
- progressmeter(-1);
-
- /* Finally, suck down the file. */
- do {
- long chunksize;
-
- chunksize = 0;
- /* read chunksize */
- if (ischunked) {
- if (fgets(xferbuf, bufsize, fin) == NULL) {
- warnx("Unexpected EOF reading chunksize");
- goto cleanup_fetch_url;
- }
- chunksize = strtol(xferbuf, &ep, 16);
-
- /*
- * XXX: Work around bug in Apache 1.3.9 and
- * 1.3.11, which incorrectly put trailing
- * space after the chunksize.
- */
- while (*ep == ' ')
- ep++;
-
- if (strcmp(ep, "\r\n") != 0) {
- warnx("Unexpected data following chunksize");
- goto cleanup_fetch_url;
- }
- if (debug)
- fprintf(ttyout, "got chunksize of " LLF "\n",
- (LLT)chunksize);
- if (chunksize == 0)
- break;
- }
- /* transfer file or chunk */
- while (1) {
- struct timeval then, now, td;
- off_t bufrem;
-
- if (rate_get)
- (void)gettimeofday(&then, NULL);
- bufrem = rate_get ? rate_get : bufsize;
- if (ischunked)
- bufrem = MIN(chunksize, bufrem);
- while (bufrem > 0) {
- len = fread(xferbuf, sizeof(char),
- MIN(bufsize, bufrem), fin);
- if (len <= 0)
- goto chunkdone;
- bytes += len;
- bufrem -= len;
- if (fwrite(xferbuf, sizeof(char), len, fout)
- != len) {
- warn("Writing `%s'", savefile);
- goto cleanup_fetch_url;
- }
- if (hash && !progress) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- if (ischunked) {
- chunksize -= len;
- if (chunksize <= 0)
- break;
- }
- }
- if (rate_get) {
- while (1) {
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec > 0)
- break;
- usleep(1000000 - td.tv_usec);
- }
- }
- if (ischunked && chunksize <= 0)
- break;
- }
- /* read CRLF after chunk*/
- chunkdone:
- if (ischunked) {
- if (fgets(xferbuf, bufsize, fin) == NULL)
- break;
- if (strcmp(xferbuf, "\r\n") != 0) {
- warnx("Unexpected data following chunk");
- goto cleanup_fetch_url;
- }
- }
- } while (ischunked);
- if (hash && !progress && bytes > 0) {
- if (bytes < mark)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- if (ferror(fin)) {
- warn("Reading file");
- goto cleanup_fetch_url;
- }
- progressmeter(1);
- (void)fflush(fout);
- if (closefunc == fclose && mtime != -1) {
- struct timeval tval[2];
-
- (void)gettimeofday(&tval[0], NULL);
- tval[1].tv_sec = mtime;
- tval[1].tv_usec = 0;
- (*closefunc)(fout);
- fout = NULL;
-
- if (utimes(savefile, tval) == -1) {
- fprintf(ttyout,
- "Can't change modification time to %s",
- asctime(localtime(&mtime)));
- }
- }
- if (bytes > 0)
- ptransfer(0);
- bytes = 0;
-
- rval = 0;
- goto cleanup_fetch_url;
-
- improper:
- warnx("Improper response from `%s'", host);
-
- cleanup_fetch_url:
- if (oldintr)
- (void)xsignal(SIGINT, oldintr);
- if (oldintp)
- (void)xsignal(SIGPIPE, oldintp);
- if (fin != NULL)
- fclose(fin);
- else if (s != -1)
- close(s);
- if (closefunc != NULL && fout != NULL)
- (*closefunc)(fout);
- if (res0)
- freeaddrinfo(res0);
- FREEPTR(savefile);
- FREEPTR(user);
- FREEPTR(pass);
- FREEPTR(host);
- FREEPTR(port);
- FREEPTR(path);
- FREEPTR(decodedpath);
- FREEPTR(puser);
- FREEPTR(ppass);
- FREEPTR(buf);
- FREEPTR(auth);
- FREEPTR(location);
- FREEPTR(message);
- return (rval);
-}
-
-/*
- * Abort a HTTP retrieval
- */
-void
-aborthttp(int notused)
-{
- char msgbuf[100];
- int len;
-
- sigint_raised = 1;
- alarmtimer(0);
- len = strlcpy(msgbuf, "\nHTTP fetch aborted.\n", sizeof(msgbuf));
- write(fileno(ttyout), msgbuf, len);
- siglongjmp(httpabort, 1);
-}
-
-/*
- * Retrieve ftp URL or classic ftp argument using FTP.
- * Returns 1 on failure, 0 on completed xfer, -1 if ftp connection
- * is still open (e.g, ftp xfer with trailing /)
- */
-static int
-fetch_ftp(const char *url)
-{
- char *cp, *xargv[5], rempath[MAXPATHLEN];
- char *host, *path, *dir, *file, *user, *pass;
- char *port;
- int dirhasglob, filehasglob, oautologin, rval, type, xargc;
- in_port_t portnum;
- url_t urltype;
-
- host = path = dir = file = user = pass = NULL;
- port = NULL;
- rval = 1;
- type = TYPE_I;
-
- if (STRNEQUAL(url, FTP_URL)) {
- if ((parse_url(url, "URL", &urltype, &user, &pass,
- &host, &port, &portnum, &path) == -1) ||
- (user != NULL && *user == '\0') ||
- EMPTYSTRING(host)) {
- warnx("Invalid URL `%s'", url);
- goto cleanup_fetch_ftp;
- }
- /*
- * Note: Don't url_decode(path) here. We need to keep the
- * distinction between "/" and "%2F" until later.
- */
-
- /* check for trailing ';type=[aid]' */
- if (! EMPTYSTRING(path) && (cp = strrchr(path, ';')) != NULL) {
- if (strcasecmp(cp, ";type=a") == 0)
- type = TYPE_A;
- else if (strcasecmp(cp, ";type=i") == 0)
- type = TYPE_I;
- else if (strcasecmp(cp, ";type=d") == 0) {
- warnx(
- "Directory listing via a URL is not supported");
- goto cleanup_fetch_ftp;
- } else {
- warnx("Invalid suffix `%s' in URL `%s'", cp,
- url);
- goto cleanup_fetch_ftp;
- }
- *cp = 0;
- }
- } else { /* classic style `[user@]host:[file]' */
- urltype = CLASSIC_URL_T;
- host = xstrdup(url);
- cp = strchr(host, '@');
- if (cp != NULL) {
- *cp = '\0';
- user = host;
- anonftp = 0; /* disable anonftp */
- host = xstrdup(cp + 1);
- }
- cp = strchr(host, ':');
- if (cp != NULL) {
- *cp = '\0';
- path = xstrdup(cp + 1);
- }
- }
- if (EMPTYSTRING(host))
- goto cleanup_fetch_ftp;
-
- /* Extract the file and (if present) directory name. */
- dir = path;
- if (! EMPTYSTRING(dir)) {
- /*
- * If we are dealing with classic `[user@]host:[path]' syntax,
- * then a path of the form `/file' (resulting from input of the
- * form `host:/file') means that we should do "CWD /" before
- * retrieving the file. So we set dir="/" and file="file".
- *
- * But if we are dealing with URLs like `ftp://host/path' then
- * a path of the form `/file' (resulting from a URL of the form
- * `ftp://host//file') means that we should do `CWD ' (with an
- * empty argument) before retrieving the file. So we set
- * dir="" and file="file".
- *
- * If the path does not contain / at all, we set dir=NULL.
- * (We get a path without any slashes if we are dealing with
- * classic `[user@]host:[file]' or URL `ftp://host/file'.)
- *
- * In all other cases, we set dir to a string that does not
- * include the final '/' that separates the dir part from the
- * file part of the path. (This will be the empty string if
- * and only if we are dealing with a path of the form `/file'
- * resulting from an URL of the form `ftp://host//file'.)
- */
- cp = strrchr(dir, '/');
- if (cp == dir && urltype == CLASSIC_URL_T) {
- file = cp + 1;
- dir = "/";
- } else if (cp != NULL) {
- *cp++ = '\0';
- file = cp;
- } else {
- file = dir;
- dir = NULL;
- }
- } else
- dir = NULL;
- if (urltype == FTP_URL_T && file != NULL) {
- url_decode(file);
- /* but still don't url_decode(dir) */
- }
- if (debug)
- fprintf(ttyout,
- "fetch_ftp: user `%s' pass `%s' host %s port %s "
- "path `%s' dir `%s' file `%s'\n",
- user ? user : "<null>", pass ? pass : "<null>",
- host ? host : "<null>", port ? port : "<null>",
- path ? path : "<null>",
- dir ? dir : "<null>", file ? file : "<null>");
-
- dirhasglob = filehasglob = 0;
- if (doglob && urltype == CLASSIC_URL_T) {
- if (! EMPTYSTRING(dir) && strpbrk(dir, "*?[]{}") != NULL)
- dirhasglob = 1;
- if (! EMPTYSTRING(file) && strpbrk(file, "*?[]{}") != NULL)
- filehasglob = 1;
- }
-
- /* Set up the connection */
- if (connected)
- disconnect(0, NULL);
- xargv[0] = (char *)getprogname(); /* XXX discards const */
- xargv[1] = host;
- xargv[2] = NULL;
- xargc = 2;
- if (port) {
- xargv[2] = port;
- xargv[3] = NULL;
- xargc = 3;
- }
- oautologin = autologin;
- /* don't autologin in setpeer(), use ftp_login() below */
- autologin = 0;
- setpeer(xargc, xargv);
- autologin = oautologin;
- if ((connected == 0) ||
- (connected == 1 && !ftp_login(host, user, pass))) {
- warnx("Can't connect or login to host `%s'", host);
- goto cleanup_fetch_ftp;
- }
-
- switch (type) {
- case TYPE_A:
- setascii(1, xargv);
- break;
- case TYPE_I:
- setbinary(1, xargv);
- break;
- default:
- errx(1, "fetch_ftp: unknown transfer type %d", type);
- }
-
- /*
- * Change directories, if necessary.
- *
- * Note: don't use EMPTYSTRING(dir) below, because
- * dir=="" means something different from dir==NULL.
- */
- if (dir != NULL && !dirhasglob) {
- char *nextpart;
-
- /*
- * If we are dealing with a classic `[user@]host:[path]'
- * (urltype is CLASSIC_URL_T) then we have a raw directory
- * name (not encoded in any way) and we can change
- * directories in one step.
- *
- * If we are dealing with an `ftp://host/path' URL
- * (urltype is FTP_URL_T), then RFC 1738 says we need to
- * send a separate CWD command for each unescaped "/"
- * in the path, and we have to interpret %hex escaping
- * *after* we find the slashes. It's possible to get
- * empty components here, (from multiple adjacent
- * slashes in the path) and RFC 1738 says that we should
- * still do `CWD ' (with a null argument) in such cases.
- *
- * Many ftp servers don't support `CWD ', so if there's an
- * error performing that command, bail out with a descriptive
- * message.
- *
- * Examples:
- *
- * host: dir="", urltype=CLASSIC_URL_T
- * logged in (to default directory)
- * host:file dir=NULL, urltype=CLASSIC_URL_T
- * "RETR file"
- * host:dir/ dir="dir", urltype=CLASSIC_URL_T
- * "CWD dir", logged in
- * ftp://host/ dir="", urltype=FTP_URL_T
- * logged in (to default directory)
- * ftp://host/dir/ dir="dir", urltype=FTP_URL_T
- * "CWD dir", logged in
- * ftp://host/file dir=NULL, urltype=FTP_URL_T
- * "RETR file"
- * ftp://host//file dir="", urltype=FTP_URL_T
- * "CWD ", "RETR file"
- * host:/file dir="/", urltype=CLASSIC_URL_T
- * "CWD /", "RETR file"
- * ftp://host///file dir="/", urltype=FTP_URL_T
- * "CWD ", "CWD ", "RETR file"
- * ftp://host/%2F/file dir="%2F", urltype=FTP_URL_T
- * "CWD /", "RETR file"
- * ftp://host/foo/file dir="foo", urltype=FTP_URL_T
- * "CWD foo", "RETR file"
- * ftp://host/foo/bar/file dir="foo/bar"
- * "CWD foo", "CWD bar", "RETR file"
- * ftp://host//foo/bar/file dir="/foo/bar"
- * "CWD ", "CWD foo", "CWD bar", "RETR file"
- * ftp://host/foo//bar/file dir="foo//bar"
- * "CWD foo", "CWD ", "CWD bar", "RETR file"
- * ftp://host/%2F/foo/bar/file dir="%2F/foo/bar"
- * "CWD /", "CWD foo", "CWD bar", "RETR file"
- * ftp://host/%2Ffoo/bar/file dir="%2Ffoo/bar"
- * "CWD /foo", "CWD bar", "RETR file"
- * ftp://host/%2Ffoo%2Fbar/file dir="%2Ffoo%2Fbar"
- * "CWD /foo/bar", "RETR file"
- * ftp://host/%2Ffoo%2Fbar%2Ffile dir=NULL
- * "RETR /foo/bar/file"
- *
- * Note that we don't need `dir' after this point.
- */
- do {
- if (urltype == FTP_URL_T) {
- nextpart = strchr(dir, '/');
- if (nextpart) {
- *nextpart = '\0';
- nextpart++;
- }
- url_decode(dir);
- } else
- nextpart = NULL;
- if (debug)
- fprintf(ttyout, "dir `%s', nextpart `%s'\n",
- dir ? dir : "<null>",
- nextpart ? nextpart : "<null>");
- if (urltype == FTP_URL_T || *dir != '\0') {
- xargv[0] = "cd";
- xargv[1] = dir;
- xargv[2] = NULL;
- dirchange = 0;
- cd(2, xargv);
- if (! dirchange) {
- if (*dir == '\0' && code == 500)
- fprintf(stderr,
-"\n"
-"ftp: The `CWD ' command (without a directory), which is required by\n"
-" RFC 1738 to support the empty directory in the URL pathname (`//'),\n"
-" conflicts with the server's conformance to RFC 959.\n"
-" Try the same URL without the `//' in the URL pathname.\n"
-"\n");
- goto cleanup_fetch_ftp;
- }
- }
- dir = nextpart;
- } while (dir != NULL);
- }
-
- if (EMPTYSTRING(file)) {
- rval = -1;
- goto cleanup_fetch_ftp;
- }
-
- if (dirhasglob) {
- (void)strlcpy(rempath, dir, sizeof(rempath));
- (void)strlcat(rempath, "/", sizeof(rempath));
- (void)strlcat(rempath, file, sizeof(rempath));
- file = rempath;
- }
-
- /* Fetch the file(s). */
- xargc = 2;
- xargv[0] = "get";
- xargv[1] = file;
- xargv[2] = NULL;
- if (dirhasglob || filehasglob) {
- int ointeractive;
-
- ointeractive = interactive;
- interactive = 0;
- if (restartautofetch)
- xargv[0] = "mreget";
- else
- xargv[0] = "mget";
- mget(xargc, xargv);
- interactive = ointeractive;
- } else {
- if (outfile == NULL) {
- cp = strrchr(file, '/'); /* find savefile */
- if (cp != NULL)
- outfile = cp + 1;
- else
- outfile = file;
- }
- xargv[2] = (char *)outfile;
- xargv[3] = NULL;
- xargc++;
- if (restartautofetch)
- reget(xargc, xargv);
- else
- get(xargc, xargv);
- }
-
- if ((code / 100) == COMPLETE)
- rval = 0;
-
- cleanup_fetch_ftp:
- FREEPTR(host);
- FREEPTR(path);
- FREEPTR(user);
- FREEPTR(pass);
- return (rval);
-}
-
-/*
- * Retrieve the given file to outfile.
- * Supports arguments of the form:
- * "host:path", "ftp://host/path" if $ftpproxy, call fetch_url() else
- * call fetch_ftp()
- * "http://host/path" call fetch_url() to use HTTP
- * "file:///path" call fetch_url() to copy
- * "about:..." print a message
- *
- * Returns 1 on failure, 0 on completed xfer, -1 if ftp connection
- * is still open (e.g, ftp xfer with trailing /)
- */
-static int
-go_fetch(const char *url)
-{
- char *proxy;
-
-#ifndef NO_ABOUT
- /*
- * Check for about:*
- */
- if (STRNEQUAL(url, ABOUT_URL)) {
- url += sizeof(ABOUT_URL) -1;
- if (strcasecmp(url, "ftp") == 0 ||
- strcasecmp(url, "tnftp") == 0) {
- fputs(
-"This version of ftp has been enhanced by Luke Mewburn <lukem@NetBSD.org>\n"
-"for the NetBSD project. Execute `man ftp' for more details.\n", ttyout);
- } else if (strcasecmp(url, "lukem") == 0) {
- fputs(
-"Luke Mewburn is the author of most of the enhancements in this ftp client.\n"
-"Please email feedback to <lukem@NetBSD.org>.\n", ttyout);
- } else if (strcasecmp(url, "netbsd") == 0) {
- fputs(
-"NetBSD is a freely available and redistributable UNIX-like operating system.\n"
-"For more information, see http://www.NetBSD.org/\n", ttyout);
- } else if (strcasecmp(url, "version") == 0) {
- fprintf(ttyout, "Version: %s %s%s\n",
- FTP_PRODUCT, FTP_VERSION,
-#ifdef INET6
- ""
-#else
- " (-IPv6)"
-#endif
- );
- } else {
- fprintf(ttyout, "`%s' is an interesting topic.\n", url);
- }
- fputs("\n", ttyout);
- return (0);
- }
-#endif
-
- /*
- * Check for file:// and http:// URLs.
- */
- if (STRNEQUAL(url, HTTP_URL) || STRNEQUAL(url, FILE_URL))
- return (fetch_url(url, NULL, NULL, NULL));
-
- /*
- * Try FTP URL-style and host:file arguments next.
- * If ftpproxy is set with an FTP URL, use fetch_url()
- * Othewise, use fetch_ftp().
- */
- proxy = getoptionvalue("ftp_proxy");
- if (!EMPTYSTRING(proxy) && STRNEQUAL(url, FTP_URL))
- return (fetch_url(url, NULL, NULL, NULL));
-
- return (fetch_ftp(url));
-}
-
-/*
- * Retrieve multiple files from the command line,
- * calling go_fetch() for each file.
- *
- * If an ftp path has a trailing "/", 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(int argc, char *argv[])
-{
- volatile int argpos;
- int rval;
-
- argpos = 0;
-
- if (sigsetjmp(toplevel, 1)) {
- if (connected)
- disconnect(0, NULL);
- if (rval > 0)
- rval = argpos + 1;
- return (rval);
- }
- (void)xsignal(SIGINT, intr);
- (void)xsignal(SIGPIPE, lostpeer);
-
- /*
- * Loop through as long as there's files to fetch.
- */
- for (rval = 0; (rval == 0) && (argpos < argc); argpos++) {
- if (strchr(argv[argpos], ':') == NULL)
- break;
- redirect_loop = 0;
- if (!anonftp)
- anonftp = 2; /* Handle "automatic" transfers. */
- rval = go_fetch(argv[argpos]);
- if (outfile != NULL && strcmp(outfile, "-") != 0
- && outfile[0] != '|')
- outfile = NULL;
- if (rval > 0)
- rval = argpos + 1;
- }
-
- if (connected && rval != -1)
- disconnect(0, NULL);
- return (rval);
-}
-
-
-int
-auto_put(int argc, char **argv, const char *uploadserver)
-{
- char *uargv[4], *path, *pathsep;
- int uargc, rval, len;
-
- uargc = 0;
- uargv[uargc++] = "mput";
- uargv[uargc++] = argv[0];
- uargv[2] = uargv[3] = NULL;
- pathsep = NULL;
- rval = 1;
-
- if (debug)
- fprintf(ttyout, "auto_put: target `%s'\n", uploadserver);
-
- path = xstrdup(uploadserver);
- len = strlen(path);
- if (path[len - 1] != '/' && path[len - 1] != ':') {
- /*
- * make sure we always pass a directory to auto_fetch
- */
- if (argc > 1) { /* more than one file to upload */
- int len;
-
- len = strlen(uploadserver) + 2; /* path + "/" + "\0" */
- free(path);
- path = (char *)xmalloc(len);
- (void)strlcpy(path, uploadserver, len);
- (void)strlcat(path, "/", len);
- } else { /* single file to upload */
- uargv[0] = "put";
- pathsep = strrchr(path, '/');
- if (pathsep == NULL) {
- pathsep = strrchr(path, ':');
- if (pathsep == NULL) {
- warnx("Invalid URL `%s'", path);
- goto cleanup_auto_put;
- }
- pathsep++;
- uargv[2] = xstrdup(pathsep);
- pathsep[0] = '/';
- } else
- uargv[2] = xstrdup(pathsep + 1);
- pathsep[1] = '\0';
- uargc++;
- }
- }
- if (debug)
- fprintf(ttyout, "auto_put: URL `%s' argv[2] `%s'\n",
- path, uargv[2] ? uargv[2] : "<null>");
-
- /* connect and cwd */
- rval = auto_fetch(1, &path);
- free(path);
- if(rval >= 0)
- goto cleanup_auto_put;
-
- /* XXX : is this the best way? */
- if (uargc == 3) {
- uargv[1] = argv[0];
- put(uargc, uargv);
- goto cleanup_auto_put;
- }
-
- for(; argv[0] != NULL; argv++) {
- uargv[1] = argv[0];
- mput(uargc, uargv);
- }
- rval = 0;
-
- cleanup_auto_put:
- FREEPTR(uargv[2]);
- return (rval);
-}
diff --git a/contrib/lukemftp/src/ftp.1 b/contrib/lukemftp/src/ftp.1
deleted file mode 100644
index 917980f..0000000
--- a/contrib/lukemftp/src/ftp.1
+++ /dev/null
@@ -1,2357 +0,0 @@
-.\" $NetBSD: ftp.1,v 1.109 2005/02/20 20:54:01 wiz Exp $
-.\"
-.\" Copyright (c) 1996-2004 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.
-.\"
-.\"
-.\" 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. 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 15, 2005
-.Dt FTP 1
-.Os
-.Sh NAME
-.Nm ftp
-.Nd
-Internet file transfer program
-.Sh SYNOPSIS
-.Nm
-.Op Fl 46AadefginpRtvV
-.Bk -words
-.Op Fl N Ar netrc
-.Ek
-.Bk -words
-.Op Fl o Ar output
-.Ek
-.Bk -words
-.Op Fl P Ar port
-.Ek
-.Bk -words
-.Op Fl q Ar quittime
-.Ek
-.Bk -words
-.Op Fl r Ar retry
-.Ek
-.Bk -words
-.\" [-T dir,max[,inc]]
-.Oo
-.Fl T Xo
-.Sm off
-.Ar dir ,
-.Ar max
-.Op , Ar inc
-.Sm on
-.Xc
-.Oc
-.Ek
-.Bk -words
-.\" [[user@]host [port]]
-.Oo
-.Oo Ar user Ns Li \&@ Oc Ns Ar host
-.Op Ar port
-.Oc
-.Ek
-.Bk -words
-.\" [[user@]host:[path][/]]
-.Sm off
-.Oo
-.Op Ar user Li \&@
-.Ar host Li \&:
-.Op Ar path
-.Op Li /
-.Oc
-.Sm on
-.Ek
-.Bk -words
-.\" [file:///path]
-.Sm off
-.Oo
-.Li file:/// Ar path
-.Oc
-.Sm on
-.Ek
-.Bk -words
-.\" [ftp://[user[:password]@]host[:port]/path[/]]
-.Sm off
-.Oo
-.Li ftp://
-.Oo Ar user
-.Op Li \&: Ar password
-.Li \&@ Oc
-.Ar host Oo Li \&: Ar port Oc
-.Li / Ar path
-.Op Li /
-.Op Li ;type= Ar X
-.Oc
-.Sm on
-.Ek
-.Bk -words
-.\" [http://[user[:password]@]host[:port]/path]
-.Sm off
-.Oo
-.Li http://
-.Oo Ar user
-.Op Li \&: Ar password
-.Li \&@ Oc
-.Ar host Oo Li \&: Ar port Oc
-.Li / Ar path
-.Oc
-.Sm on
-.Ek
-.Op Ar \&.\&.\&.
-.Nm
-.Bk -words
-.Fl u Ar URL Ar file
-.Ek
-.Op Ar \&.\&.\&.
-.Sh DESCRIPTION
-.Nm
-is the user interface to the Internet standard File Transfer Protocol.
-The program allows a user to transfer files to and from a
-remote network site.
-.Pp
-The last five arguments will fetch a file using the
-.Tn FTP
-or
-.Tn HTTP
-protocols, or by direct copying, 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 "port "
-.It Fl 4
-Forces
-.Nm
-to only use IPv4 addresses.
-.It Fl 6
-Forces
-.Nm
-to only use IPv6 addresses.
-.It Fl A
-Force active mode ftp.
-By default,
-.Nm
-will try to use passive mode ftp and fall back to active mode
-if passive is not supported by the server.
-This option causes
-.Nm
-to always use an active connection.
-It is only useful for connecting to very old servers that do not
-implement passive mode properly.
-.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.
-This is useful for Emacs ange-ftp mode.
-.It Fl f
-Forces a cache reload for transfers that go through the
-.Tn FTP
-or
-.Tn HTTP
-proxies.
-.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 for non auto-fetch transfers.
-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.
-To override the auto-login for auto-fetch transfers, specify the
-username (and optionally, password) as appropriate.
-.It Fl N Ar netrc
-Use
-.Ar netrc
-instead of
-.Pa ~/.netrc .
-Refer to
-.Sx THE .netrc FILE
-for more information.
-.It Fl o Ar output
-When auto-fetching files, save the contents in
-.Ar output .
-.Ar output
-is parsed according to the
-.Sx FILE NAMING CONVENTIONS
-below.
-If
-.Ar output
-is not
-.Sq -
-or doesn't start with
-.Sq \&| ,
-then only the first file specified will be retrieved into
-.Ar output ;
-all other files will be retrieved into the basename of their
-remote name.
-.It Fl p
-Enable passive mode operation for use behind connection filtering firewalls.
-This option has been deprecated as
-.Nm
-now tries to use passive mode by default, falling back to active mode
-if the server does not support passive connections.
-.It Fl P Ar port
-Sets the port number to
-.Ar port .
-.It Fl r Ar wait
-Retry the connection attempt if it failed, pausing for
-.Ar wait
-seconds.
-.It Fl q Ar quittime
-Quit if the connection has stalled for
-.Ar quittime
-seconds.
-.It Fl R
-Restart all non-proxied auto-fetches.
-.It Fl t
-Enables packet tracing.
-.It Xo
-.Fl T
-.Sm off
-.Ar direction ,
-.Ar maximum
-.Op , Ar increment
-.Sm on
-.Xc
-Set the maximum transfer rate for
-.Ar direction
-to
-.Ar maximum
-bytes/second,
-and if specified, the increment to
-.Ar increment
-bytes/second.
-Refer to
-.Ic rate
-for more information.
-.It Fl u Ar URL file Op \&.\&.\&.
-Upload files on the command line to
-.Ar URL
-where
-.Ar URL
-is one of the ftp URL types as supported by auto-fetch
-(with an optional target filename for single file uploads), and
-.Ar file
-is one or more local files to be uploaded.
-.It Fl v
-Enable
-.Ic verbose
-and
-.Ic progress .
-This is the default if output is to a terminal (and in the case of
-.Ic progress ,
-.Nm
-is the foreground process).
-Forces
-.Nm
-to show all responses from the remote server, as well
-as report on data transfer statistics.
-.It Fl V
-Disable
-.Ic verbose
-and
-.Ic progress ,
-overriding the default of enabled when output is to 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\*[Gt]
-is provided to the user.
-The following commands are recognized
-by
-.Nm ftp :
-.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 ftp .
-An end of file will also terminate the session and exit.
-.It Ic case
-Toggle remote computer file name case mapping during
-.Ic get ,
-.Ic mget
-and
-.Ic mput
-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 remote-file
-Change the permission modes of the file
-.Ar remote-file
-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 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 \-\-\*[Gt]
-.It Ic delete Ar remote-file
-Delete the file
-.Ar remote-file
-on the remote machine.
-.It Ic dir Op Ar remote-path 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 .
-If
-.Ar remote-path
-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.
-.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 epsv4
-Toggle the use of the extended
-.Dv EPSV
-and
-.Dv EPRT
-commands on IPv4 connections; first try
-.Dv EPSV /
-.Dv EPRT ,
-and then
-.Dv PASV /
-.Dv PORT .
-This is enabled by default.
-If an extended command fails then this option will be temporarily
-disabled for the duration of the current connection, or until
-.Ic epsv4
-is executed again.
-.It Ic exit
-A synonym for
-.Ic bye .
-.It Ic features
-Display what features the remote server supports (using the
-.Dv FEAT
-command).
-.It Ic fget Ar localfile
-Retrieve the files listed in
-.Ar localfile ,
-which has one line per filename.
-.It Ic form Ar format
-Set the file transfer
-.Ic form
-to
-.Ar format .
-The default (and only supported)
-format is
-.Dq non-print .
-.It Ic ftp Ar host Op Ar port
-A synonym for
-.Ic open .
-.It Ic gate Op Ar host Op Ar port
-Toggle gate-ftp mode, which used to connect through the
-TIS FWTK and Gauntlet ftp proxies.
-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 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 glob
-Toggle filename expansion for
-.Ic mdelete ,
-.Ic mget ,
-.Ic mput ,
-and
-.Ic mreget .
-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 ,
-.Ic mget ,
-and
-.Ic mreget ,
-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 ,
-.Ic mput
-and
-.Ic mreget
-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.
-Enabling
-.Ic hash
-disables
-.Ic progress .
-.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 image
-A synonym for
-.Ic binary .
-.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 lpage Ar local-file
-Display
-.Ar local-file
-with the program specified by the
-.Ic "set pager"
-option.
-.It Ic lpwd
-Print the working directory on the local machine.
-.It Ic \&ls Op Ar remote-path 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 mlsd Op Ar remote-path
-Display the contents of
-.Ar remote-path
-(which should default to the current directory if not given)
-in a machine-parsable form, using
-.Dv MLSD .
-The format of display can be changed with
-.Sq "remopts mlst ..." .
-.It Ic mlst Op Ar remote-path
-Display the details about
-.Ar remote-path
-(which should default to the current directory if not given)
-in a machine-parsable form, using
-.Dv MLST .
-The format of display can be changed with
-.Sq "remopts mlst ..." .
-.It Ic mode Ar mode-name
-Set the file transfer
-.Ic mode
-to
-.Ar mode-name .
-The default (and only supported)
-mode is
-.Dq stream .
-.It Ic modtime Ar remote-file
-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 mreget Ar remote-files
-As per
-.Ic mget ,
-but performs a
-.Ic reget
-instead of
-.Ic get .
-.It Ic msend Ar local-files
-A synonym for
-.Ic mput .
-.It Ic newer Ar remote-file Op Ar local-file
-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-path Op Ar local-file
-A synonym for
-.Ic ls .
-.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/ *$//" \*[Gt] $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 "set 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 specified by the
-.Ic "set pager"
-option.
-.It Ic passive Op Cm auto
-Toggle passive mode (if no arguments are given).
-If
-.Cm auto
-is given, act as if
-.Ev FTPMODE
-is set to
-.Sq auto .
-If passive mode is turned on (default),
-.Nm
-will send a
-.Dv PASV
-command for all data connections instead of a
-.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
-.Tn FTP
-servers are required to support the
-.Dv PASV
-command by
-.Li RFC 1123 ,
-some do not.)
-.It Ic pdir Op Ar remote-path
-Perform
-.Ic dir
-.Op Ar remote-path ,
-and display the result with the program specified by the
-.Ic "set pager"
-option.
-.It Ic pls Op Ar remote-path
-Perform
-.Ic ls
-.Op Ar remote-path ,
-and display the result with the program specified by the
-.Ic "set pager"
-option.
-.It Ic pmlsd Op Ar remote-path
-Perform
-.Ic mlsd
-.Op Ar remote-path ,
-and display the result with the program specified by the
-.Ic "set pager"
-option.
-.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.
-Enabling
-.Ic progress
-disables
-.Ic hash .
-.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 Cm a
-Answer
-.Sq yes
-to the current file, and automatically answer
-.Sq yes
-to any remaining files for the current command.
-.It Cm n
-Answer
-.Sq no ,
-and do not transfer the file.
-.It Cm p
-Answer
-.Sq yes
-to the current file, and turn off prompt mode
-(as is
-.Dq prompt off
-had been given).
-.It Cm q
-Terminate the current operation.
-.It Cm y
-Answer
-.Sq yes ,
-and transfer the file.
-.It Cm \&?
-Display a help message.
-.El
-.Pp
-Any other response 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
-.Tn 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
-.Tn 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
-.Tn 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 Xo
-.Ic rate Ar direction
-.Op Ar maximum Op Ar increment
-.Xc
-Throttle the maximum transfer rate to
-.Ar maximum
-bytes/second.
-If
-.Ar maximum
-is 0, disable the throttle.
-.Pp
-.Ar direction
-may be one of:
-.Bl -tag -width "all" -offset indent -compact
-.It Cm all
-Both directions.
-.It Cm get
-Incoming transfers.
-.It Cm put
-Outgoing transfers.
-.El
-.Pp
-.Ar maximum
-can be modified on the fly by
-.Ar increment
-bytes (default: 1024) each time a given signal is received:
-.B
-.Bl -tag -width "SIGUSR1" -offset indent
-.It Dv SIGUSR1
-Increment
-.Ar maximum
-by
-.Ar increment
-bytes.
-.It Dv SIGUSR2
-Decrement
-.Ar maximum
-by
-.Ar increment
-bytes.
-The result must be a positive number.
-.El
-.Pp
-If
-.Ar maximum
-is not supplied, the current throttle rates are displayed.
-.Pp
-Note:
-.Ic rate
-is not yet implemented for ascii mode transfers.
-.It Ic rcvbuf Ar size
-Set the size of the socket receive buffer to
-.Ar size .
-.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
-.Ic reget
-acts like
-.Ic 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 remopts Ar command Op Ar command-options
-Set options on the remote
-.Tn FTP
-server for
-.Ar command
-to
-.Ar command-options
-(whose absence is handled on a command-specific basis).
-Remote
-.Tn FTP
-commands known to support options include:
-.Sq MLST
-(used for
-.Dv MLSD
-and
-.Dv MLST ) .
-.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
-.Tn FTP
-server.
-Resynchronization may be necessary following a violation of the
-.Tn 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 rhelp 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 rmdir Ar directory-name
-Delete a directory on the remote machine.
-.It Ic rstatus Op Ar remote-file
-With no arguments, show status of remote machine.
-If
-.Ar remote-file
-is specified, show status of
-.Ar remote-file
-on 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 set Op Ar option Ar value
-Set
-.Ar option
-to
-.Ar value .
-If
-.Ar option
-and
-.Ar value
-are not given, display all of the options and their values.
-The currently supported options are:
-.Bl -tag -width "http_proxy" -offset indent
-.It Cm anonpass
-Defaults to
-.Ev $FTPANONPASS
-.It Cm ftp_proxy
-Defaults to
-.Ev $ftp_proxy .
-.It Cm http_proxy
-Defaults to
-.Ev $http_proxy .
-.It Cm no_proxy
-Defaults to
-.Ev $no_proxy .
-.It Cm pager
-Defaults to
-.Ev $PAGER .
-.It Cm prompt
-Defaults to
-.Ev $FTPPROMPT .
-.It Cm rprompt
-Defaults to
-.Ev $FTPRPROMPT .
-.El
-.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 remote-file
-Return size of
-.Ar remote-file
-on remote machine.
-.It Ic sndbuf Ar size
-Set the size of the socket send buffer to
-.Ar size .
-.It Ic status
-Show the current status of
-.Nm ftp .
-.It Ic struct Ar struct-name
-Set the file transfer
-.Ar structure
-to
-.Ar struct-name .
-The default (and only supported)
-structure is
-.Dq file .
-.It Ic sunique
-Toggle storing of files on remote machine under unique file names.
-The remote
-.Tn FTP
-server must support
-.Tn 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 throttle
-A synonym for
-.Ic rate .
-.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 Ic unset Ar option
-Unset
-.Ar option .
-Refer to
-.Ic set
-for more information.
-.It Ic usage Ar command
-Print the usage message for
-.Ar command .
-.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
-.Dq auto-login
-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 xferbuf Ar size
-Set the size of the socket send and receive buffers to
-.Ar size .
-.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
-Commands which take a byte count as an argument
-(e.g.,
-.Ic hash ,
-.Ic rate ,
-and
-.Ic xferbuf )
-support an optional suffix on the argument which changes the
-interpretation of the argument.
-Supported suffixes are:
-.Bl -tag -width 3n -offset indent -compact
-.It Li b
-Causes no modification.
-(Optional)
-.It Li k
-Kilo; multiply the argument by 1024
-.It Li m
-Mega; multiply the argument by 1048576
-.It Li g
-Giga; multiply the argument by 1073741824
-.El
-.Pp
-If
-.Nm
-receives a
-.Dv SIGINFO
-(see the
-.Dq status
-argument of
-.Xr stty 1 )
-or
-.Dv SIGQUIT
-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 "FOO "
-.\" [user@]host:[path][/]
-.It Xo
-.Sm off
-.Op Ar user Li \&@
-.Ar host Li \&:
-.Op Ar path
-.Op Li /
-.Sm on
-.Xc
-.Dq Classic
-.Tn FTP
-format.
-.Pp
-If
-.Ar path
-contains a glob character and globbing is enabled,
-(see
-.Ic glob ) ,
-then the equivalent of
-.Ql mget path
-is performed.
-.Pp
-If the directory component of
-.Ar path
-contains no globbing characters,
-it is stored locally with the name basename (see
-.Xr basename 1 )
-of
-.Ic path ,
-in the current directory.
-Otherwise, the full remote name is used as the local name,
-relative to the local root directory.
-.\" ftp://[user[:password]@]host[:port]/path[/][;type=X]
-.It Xo
-.Sm off
-.Li ftp://
-.Oo Ar user
-.Op Li \&: Ar password
-.Li \&@ Oc
-.Ar host Oo Li \&: Ar port Oc
-.Li / Ar path
-.Op Li /
-.Op Li ;type= Ar X
-.Sm on
-.Xc
-An
-.Tn FTP
-URL, retrieved using the
-.Tn FTP
-protocol if
-.Ic "set ftp_proxy"
-isn't defined.
-Otherwise, transfer the URL using
-.Tn HTTP
-via the proxy defined in
-.Ic "set ftp_proxy" .
-If
-.Ic "set ftp_proxy"
-isn't defined and
-.Ar user
-is given, login as
-.Ar user .
-In this case, use
-.Ar password
-if supplied, otherwise prompt the user for one.
-.Pp
-If a suffix of
-.Sq ;type=A
-or
-.Sq ;type=I
-is supplied, then the transfer type will take place as
-ascii or binary (respectively).
-The default transfer type is binary.
-.Pp
-In order to be compliant with
-.Li RFC 1738 ,
-.Nm
-interprets the
-.Ar path
-part of an
-.Dq ftp://
-auto-fetch URL as follows:
-.Bl -bullet
-.It
-The
-.Sq Li /
-immediately after the
-.Ar host Ns Oo Li \&: Ns Ar port Oc
-is interpreted as a separator before the
-.Ar path ,
-and not as part of the
-.Ar path
-itself.
-.It
-The
-.Ar path
-is interpreted as a
-.So Li / Sc Ns -separated
-list of name components.
-For all but the last such component,
-.Nm
-performs the equivalent of a
-.Ic cd
-command.
-For the last path component,
-.Nm
-performs the equivalent of a
-.Ic get
-command.
-.It
-Empty name components,
-which result from
-.Sq Li //
-within the
-.Ar path ,
-or from an extra
-.Sq Li /
-at the beginning of the
-.Ar path ,
-will cause the equivalent of a
-.Ic cd
-command without a directory name.
-This is unlikely to be useful.
-.It
-Any
-.Sq Li \&% Ns Ar XX
-codes
-(per
-.Li RFC 1738 )
-within the path components are decoded, with
-.Ar XX
-representing a character code in hexadecimal.
-This decoding takes place after the
-.Ar path
-has been split into components,
-but before each component is used in the equivalent of a
-.Ic cd
-or
-.Ic get
-command.
-Some often-used codes are
-.Sq Li \&%2F
-(which represents
-.Sq Li / )
-and
-.Sq Li \&%7E
-(which represents
-.Sq Li ~ ) .
-.El
-.Pp
-The above interpretation has the following consequences:
-.Bl -bullet
-.It
-The path is interpreted relative to the
-default login directory of the specified user or of the
-.Sq anonymous
-user.
-If the
-.Pa /
-directory is required, use a leading path of
-.Dq %2F .
-If a user's home directory is required (and the remote server supports
-the syntax), use a leading path of
-.Dq %7Euser/ .
-For example, to retrieve
-.Pa /etc/motd
-from
-.Sq localhost
-as the user
-.Sq myname
-with the password
-.Sq mypass ,
-use
-.Dq ftp://myname:mypass@localhost/%2fetc/motd
-.It
-The exact
-.Ic cd
-and
-.Ic get
-commands can be controlled by careful choice of
-where to use
-.Sq /
-and where to use
-.Sq %2F
-(or
-.Sq %2f ) .
-For example, the following URLs correspond to the
-equivalents of the indicated commands:
-.Bl -tag -width "ftp://host/%2Fdir1%2Fdir2%2Ffile"
-.It ftp://host/dir1/dir2/file
-.Dq "cd dir1" ,
-.Dq "cd dir2" ,
-.Dq "get file" .
-.It ftp://host/%2Fdir1/dir2/file
-.Dq "cd /dir1" ,
-.Dq "cd dir2" ,
-.Dq "get file" .
-.It ftp://host/dir1%2Fdir2/file
-.Dq "cd dir1/dir2" ,
-.Dq "get file" .
-.It ftp://host/%2Fdir1%2Fdir2/file
-.Dq "cd /dir1/dir2" ,
-.Dq "get file" .
-.It ftp://host/dir1%2Fdir2%2Ffile
-.Dq "get dir1/dir2/file" .
-.It ftp://host/%2Fdir1%2Fdir2%2Ffile
-.Dq "get /dir1/dir2/file" .
-.El
-.It
-You must have appropriate access permission for each of the
-intermediate directories that is used in the equivalent of a
-.Ic cd
-command.
-.El
-.\" http://[user[:password]@]host[:port]/path
-.It Xo
-.Sm off
-.Li http://
-.Oo Ar user
-.Op Li \&: Ar password
-.Li \&@ Oc
-.Ar host Oo Li \&: Ar port Oc
-.Li / Ar path
-.Sm on
-.Xc
-An
-.Tn HTTP
-URL, retrieved using the
-.Tn HTTP
-protocol.
-If
-.Ic "set http_proxy"
-is defined, it is used as a URL to an
-.Tn HTTP
-proxy server.
-If
-.Tn HTTP
-authorization is required to retrieve
-.Ar path ,
-and
-.Sq user
-(and optionally
-.Sq password )
-is in the URL, use them for the first attempt to authenticate.
-.\" file:///path
-.It Xo
-.Sm off
-.Li file:/// Ar path
-.Sm on
-.Xc
-A local URL, copied from
-.Pa / Ns Ar path
-on the local host.
-.El
-.Pp
-Unless noted otherwise above, and
-.Fl o Ar output
-is not given, the file is stored in the current directory as the
-.Xr basename 1
-of
-.Ar path .
-Note that if a
-.Tn HTTP
-redirect is received, the fetch is retried using the new target URL
-supplied by the server, with a corresponding new
-.Ar path .
-Using an explicit
-.Fl o Ar output
-is recommended, to avoid writing to unexpected file names.
-.Pp
-If a classic format or an
-.Tn FTP
-URL format has a trailing
-.Sq /
-or an empty
-.Ar path
-component, 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.
-This will not work if
-.Ic "set ftp_proxy"
-is being used.
-.Pp
-Direct
-.Tn HTTP
-transfers use HTTP 1.1.
-Proxied
-.Tn FTP
-and
-.Tn HTTP
-transfers use HTTP 1.0.
-.Pp
-If
-.Fl R
-is given, all auto-fetches that don't go via the
-.Tn FTP
-or
-.Tn HTTP
-proxies will be restarted.
-For
-.Tn FTP ,
-this is implemented by using
-.Nm reget
-instead of
-.Nm get .
-For
-.Tn HTTP ,
-this is implemented by using the
-.Sq "Range: bytes="
-.Tn "HTTP/1.1"
-directive.
-.Pp
-If WWW or proxy WWW authentication is required, you will be prompted
-to enter a username and password to authenticate with.
-.Pp
-When specifying IPv6 numeric addresses in a URL, you need to
-surround the address in square brackets.
-E.g.:
-.Dq ftp://[::1]:21/ .
-This is because colons are used in IPv6 numeric address as well as
-being the separator for the port number.
-.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 an
-.Tn 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, the prompt will not appear until the remote server has completed
-sending the requested file.
-.Pp
-If the terminal interrupt key sequence is used whilst
-.Nm
-is awaiting a reply from the remote server for the ABOR processing,
-then the connection will be closed.
-This is different from the traditional behaviour (which ignores the
-terminal interrupt during this phase), but is considered more useful.
-.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 stdout
-(stdin).
-If the shell command includes spaces, the argument
-must be quoted; e.g.
-.Dq Qq Li \&| ls\ \-lt .
-A particularly
-useful example of this mechanism is:
-.Dq Li dir \&"\&" \&|more .
-.It
-Failing the above checks, if ``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
-.Tn FTP
-specification specifies many parameters which may affect a file transfer.
-The
-.Ic type
-may be one of
-.Dq ascii ,
-.Dq image
-(binary),
-.Dq ebcdic ,
-and
-.Dq local byte size
-(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,
-unless overridden with the
-.Fl N Ar netrc
-option, or specified in the
-.Ev NETRC
-environment variable.
-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 an automatic anonymous
-.Tn 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 blank 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.
-For example,
-.Bd -literal -offset indent
-default
-macdef init
-epsv4 off
-.Ed
-.Pp
-followed by a blank line.
-.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 COMMAND LINE PROMPT
-By default,
-.Nm
-displays a command line prompt of
-.Dq "ftp\*[Gt] "
-to the user.
-This can be changed with the
-.Ic "set prompt"
-command.
-.Pp
-A prompt can be displayed on the right side of the screen (after the
-command input) with the
-.Ic "set rprompt"
-command.
-.Pp
-The following formatting sequences are replaced by the given
-information:
-.Bl -tag -width "%% " -offset indent
-.It Li \&%/
-The current remote working directory.
-.\" %c[[0]n], %.[[0]n]
-.It Xo
-.Sm off
-.Li \&%c
-.Op Oo Li 0 Oc Ar n Ns ,
-.Li \&%.
-.Op Oo Li 0 Oc Ar n
-.Sm on
-.Xc
-The trailing component of the current remote working directory, or
-.Em n
-trailing components if a digit
-.Em n
-is given.
-If
-.Em n
-begins with
-.Sq 0 ,
-the number of skipped components precede the trailing component(s) in
-the format
-.\" ``/<number>trailing''
-.Do
-.Sm off
-.Li / Li \*[Lt] Va number Li \*[Gt]
-.Va trailing
-.Sm on
-.Dc
-(for
-.Sq \&%c )
-or
-.\" ``...trailing''
-.Dq Li \&... Ns Va trailing
-(for
-.Sq \&%. ) .
-.It Li \&%M
-The remote host name.
-.It Li \&%m
-The remote host name, up to the first
-.Sq \&. .
-.It Li \&%n
-The remote user name.
-.It Li \&%%
-A single
-.Sq % .
-.El
-.Sh ENVIRONMENT
-.Nm
-uses the following environment variables.
-.Bl -tag -width "FTPSERVERPORT"
-.It Ev FTPANONPASS
-Password to send in an anonymous
-.Tn FTP
-transfer.
-Defaults to
-.Dq Li `whoami`@ .
-.It Ev FTPMODE
-Overrides the default operation mode.
-Support values are:
-.Bl -tag -width "passive"
-.It Cm active
-active mode
-.Tn FTP
-only
-.It Cm auto
-automatic determination of passive or active (this is the default)
-.It Cm gate
-gate-ftp mode
-.It Cm passive
-passive mode
-.Tn FTP
-only
-.El
-.It Ev FTPPROMPT
-Command-line prompt to use.
-Defaults to
-.Dq "ftp\*[Gt] " .
-Refer to
-.Sx COMMAND LINE PROMPT
-for more information.
-.It Ev FTPRPROMPT
-Command-line right side prompt to use.
-Defaults to
-.Dq "" .
-Refer to
-.Sx COMMAND LINE PROMPT
-for more information.
-.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 FTPUSERAGENT
-The value to send for the
-.Tn HTTP
-User-Agent
-header.
-.It Ev HOME
-For default location of a
-.Pa .netrc
-file, if one exists.
-.It Ev NETRC
-An alternate location of the
-.Pa .netrc
-file.
-.It Ev PAGER
-Used by various commands to display files.
-Defaults to
-.Xr more 1
-if empty or not set.
-.It Ev SHELL
-For default shell.
-.It Ev ftp_proxy
-URL of
-.Tn FTP
-proxy to use when making
-.Tn FTP
-URL requests
-(if not defined, use the standard
-.Tn FTP
-protocol).
-.Pp
-See
-.Ev http_proxy
-for further notes about proxy use.
-.It Ev http_proxy
-URL of
-.Tn HTTP
-proxy to use when making
-.Tn HTTP
-URL requests.
-If proxy authentication is required and there is a username and
-password in this URL, they will automatically be used in the first
-attempt to authenticate to the proxy.
-.Pp
-If
-.Dq unsafe
-URL characters are required in the username or password
-(for example
-.Sq @
-or
-.Sq / ) ,
-encode them with
-.Li RFC 1738
-.Sq Li \&% Ns Ar XX
-encoding.
-.Pp
-Note that the use of a username and password in
-.Ev ftp_proxy
-and
-.Ev http_proxy
-may be incompatible with other programs that use it
-(such as
-.Xr lynx 1 ) .
-.Pp
-.Em NOTE :
-this is not used for interactive sessions, only for command-line
-fetches.
-.It Ev no_proxy
-A space or comma separated list of hosts (or domains) for which
-proxying is not to be used.
-Each entry may have an optional trailing ":port", which restricts
-the matching to connections to that port.
-.El
-.Sh EXTENDED PASSIVE MODE AND FIREWALLS
-Some firewall configurations do not allow
-.Nm
-to use extended passive mode.
-If you find that even a simple
-.Ic ls
-appears to hang after printing a message such as this:
-.Pp
-.Dl 229 Entering Extended Passive Mode (|||58551|)
-.Pp
-then you will need to disable extended passive mode with
-.Ic epsv4 off .
-See the above section
-.Sx The .netrc File
-for an example of how to make this automatic.
-.Sh SEE ALSO
-.Xr getservbyname 3 ,
-.Xr editrc 5 ,
-.Xr services 5 ,
-.Xr ftpd 8
-.Sh STANDARDS
-.Nm
-attempts to be compliant with
-.Li RFC 959 ,
-.Li RFC 1123 ,
-.Li RFC 1738 ,
-.Li RFC 2068 ,
-.Li RFC 2389 ,
-.Li RFC 2428 ,
-.Li RFC 2732 ,
-and
-.Cm draft-ietf-ftpext-mlst-11 .
-.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 and URLs, modification time preservation,
-transfer rate throttling, configurable command line prompt,
-and other enhancements over the standard
-.Bx
-.Nm
-were implemented in
-.Nx 1.3
-and later releases
-by
-.An Luke Mewburn
-.Aq lukem@NetBSD.org .
-.Pp
-IPv6 support was added by the WIDE/KAME project
-(but may not be present in all non-NetBSD versions of this program, depending
-if the operating system supports IPv6 in a similar manner to KAME).
-.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
-.Nm
-assumes that all IPv4 mapped addresses
-.Po
-IPv6 addresses with a form like
-.Li ::ffff:10.1.1.1
-.Pc
-indicate IPv4 destinations which can be handled by
-.Dv AF_INET
-sockets.
-However, in certain IPv6 network configurations, this assumption is not true.
-In such an environment, IPv4 mapped addresses must be passed to
-.Dv AF_INET6
-sockets directly.
-For example, if your site uses a SIIT translator for IPv6-to-IPv4 translation,
-.Nm
-is unable to support your configuration.
diff --git a/contrib/lukemftp/src/ftp.c b/contrib/lukemftp/src/ftp.c
deleted file mode 100644
index dae6131..0000000
--- a/contrib/lukemftp/src/ftp.c
+++ /dev/null
@@ -1,2171 +0,0 @@
-/* $NetBSD: ftp.c,v 1.132 2005/05/14 15:26:43 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2005 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.
- */
-
-/*
- * 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. 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.
- */
-
-/*
- * Copyright (C) 1997 and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
-#else
-__RCSID("$NetBSD: ftp.c,v 1.132 2005/05/14 15:26:43 lukem 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 <fcntl.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include "ftp_var.h"
-
-volatile sig_atomic_t abrtflag;
-volatile sig_atomic_t timeoutflag;
-
-sigjmp_buf ptabort;
-int ptabflg;
-int ptflag = 0;
-char pasv[BUFSIZ]; /* passive port for proxy data connection */
-
-static int empty(FILE *, FILE *, int);
-
-struct sockinet {
- union sockunion {
- struct sockaddr_in su_sin;
-#ifdef INET6
- struct sockaddr_in6 su_sin6;
-#endif
- } si_su;
-#if !HAVE_SOCKADDR_SA_LEN
- int si_len;
-#endif
-};
-
-#if !HAVE_SOCKADDR_SA_LEN
-# define su_len si_len
-#else
-# define su_len si_su.su_sin.sin_len
-#endif
-#define su_family si_su.su_sin.sin_family
-#define su_port si_su.su_sin.sin_port
-
-struct sockinet myctladdr, hisctladdr, data_addr;
-
-char *
-hookup(char *host, char *port)
-{
- int s = -1, error, portnum;
- struct addrinfo hints, *res, *res0;
- char hbuf[MAXHOSTNAMELEN];
- static char hostnamebuf[MAXHOSTNAMELEN];
- char *cause = "unknown";
- socklen_t len;
- int on = 1;
-
- memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
- memset((char *)&myctladdr, 0, sizeof (myctladdr));
- memset(&hints, 0, sizeof(hints));
- portnum = parseport(port, FTP_PORT);
- hints.ai_flags = AI_CANONNAME;
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = 0;
- error = getaddrinfo(host, NULL, &hints, &res0);
- if (error) {
- warnx("%s", gai_strerror(error));
- code = -1;
- return (0);
- }
-
- if (res0->ai_canonname)
- (void)strlcpy(hostnamebuf, res0->ai_canonname,
- sizeof(hostnamebuf));
- else
- (void)strlcpy(hostnamebuf, host, sizeof(hostnamebuf));
- hostname = hostnamebuf;
-
- for (res = res0; res; res = res->ai_next) {
- /*
- * 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.
- *
- * This may not be the best way to handle this situation,
- * since the semantics of IPv4 mapped address is defined in
- * the kernel. There are configurations where we should use
- * IPv4 mapped address as native IPv6 address, not as
- * "an IPv6 address that embeds IPv4 address" (namely, SIIT).
- *
- * More complete solution would be to have an additional
- * getsockopt to grab "real" peername/sockname. "real"
- * peername/sockname will be AF_INET if IPv4 mapped address
- * is used to embed IPv4 address, and will be AF_INET6 if
- * we use it as native. What a mess!
- */
- ai_unmapped(res);
-#if 0 /*old behavior*/
- if (res != res0) /* not on the first address */
-#else
- if (res0->ai_next) /* if we have multiple possibilities */
-#endif
- {
- if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
- strlcpy(hbuf, "?", sizeof(hbuf));
- fprintf(ttyout, "Trying %s...\n", hbuf);
- }
- ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(portnum);
- s = socket(res->ai_family, SOCK_STREAM, res->ai_protocol);
- if (s < 0) {
- cause = "socket";
- continue;
- }
- error = xconnect(s, res->ai_addr, res->ai_addrlen);
- if (error) {
- /* this "if" clause is to prevent print warning twice */
- if (res->ai_next) {
- if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0,
- NI_NUMERICHOST))
- strlcpy(hbuf, "?", sizeof(hbuf));
- warn("connect to address %s", hbuf);
- }
- cause = "connect";
- close(s);
- s = -1;
- continue;
- }
-
- /* finally we got one */
- break;
- }
- if (s < 0) {
- warn("%s", cause);
- code = -1;
- freeaddrinfo(res0);
- return 0;
- }
- memcpy(&hisctladdr.si_su, res->ai_addr, res->ai_addrlen);
- hisctladdr.su_len = res->ai_addrlen;
- freeaddrinfo(res0);
- res0 = res = NULL;
-
- len = hisctladdr.su_len;
- if (getsockname(s, (struct sockaddr *)&myctladdr.si_su, &len) == -1) {
- warn("getsockname");
- code = -1;
- goto bad;
- }
- myctladdr.su_len = len;
-
-#ifdef IPTOS_LOWDELAY
- if (hisctladdr.su_family == AF_INET) {
- int tos = IPTOS_LOWDELAY;
- if (setsockopt(s, IPPROTO_IP, IP_TOS,
- (void *)&tos, sizeof(tos)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_LOWDELAY");
- }
- }
-#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)
- fprintf(ttyout, "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;
- }
-
- if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE,
- (void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_OOBINLINE");
- }
-
- return (hostname);
- bad:
- (void)close(s);
- return (NULL);
-}
-
-void
-cmdabort(int notused)
-{
- int oerrno = errno;
-
- sigint_raised = 1;
- alarmtimer(0);
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- abrtflag++;
- if (ptflag)
- siglongjmp(ptabort, 1);
- errno = oerrno;
-}
-
-void
-cmdtimeout(int notused)
-{
- int oerrno = errno;
-
- alarmtimer(0);
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- timeoutflag++;
- if (ptflag)
- siglongjmp(ptabort, 1);
- errno = oerrno;
-}
-
-/*VARARGS*/
-int
-command(const char *fmt, ...)
-{
- va_list ap;
- int r;
- sigfunc oldsigint;
-
- if (debug) {
- fputs("---> ", ttyout);
- va_start(ap, fmt);
- if (strncmp("PASS ", fmt, 5) == 0)
- fputs("PASS XXXX", ttyout);
- else if (strncmp("ACCT ", fmt, 5) == 0)
- fputs("ACCT XXXX", ttyout);
- else
- vfprintf(ttyout, fmt, ap);
- va_end(ap);
- putc('\n', ttyout);
- }
- if (cout == NULL) {
- warnx("No control connection for command.");
- code = -1;
- return (0);
- }
-
- abrtflag = 0;
-
- oldsigint = xsignal(SIGINT, cmdabort);
-
- va_start(ap, fmt);
- vfprintf(cout, fmt, ap);
- va_end(ap);
- fputs("\r\n", cout);
- (void)fflush(cout);
- cpend = 1;
- r = getreply(!strcmp(fmt, "QUIT"));
- if (abrtflag && oldsigint != SIG_IGN)
- (*oldsigint)(SIGINT);
- (void)xsignal(SIGINT, oldsigint);
- return (r);
-}
-
-int
-getreply(int expecteof)
-{
- char current_line[BUFSIZ]; /* last line of previous reply */
- int c, n, line;
- int dig;
- int originalcode = 0, continuation = 0;
- sigfunc oldsigint, oldsigalrm;
- int pflag = 0;
- char *cp, *pt = pasv;
-
- abrtflag = 0;
- timeoutflag = 0;
-
- oldsigint = xsignal(SIGINT, cmdabort);
- oldsigalrm = xsignal(SIGALRM, cmdtimeout);
-
- for (line = 0 ;; line++) {
- dig = n = code = 0;
- cp = current_line;
- while (alarmtimer(60),((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) {
- /*
- * these will get trashed by pswitch()
- * in lostpeer()
- */
- int reply_timeoutflag = timeoutflag;
- int reply_abrtflag = abrtflag;
-
- alarmtimer(0);
- if (expecteof && feof(cin)) {
- (void)xsignal(SIGINT, oldsigint);
- (void)xsignal(SIGALRM, oldsigalrm);
- code = 221;
- return (0);
- }
- cpend = 0;
- lostpeer(0);
- if (verbose) {
- if (reply_timeoutflag)
- fputs(
- "421 Service not available, remote server timed out. Connection closed\n",
- ttyout);
- else if (reply_abrtflag)
- fputs(
- "421 Service not available, user interrupt. Connection closed.\n",
- ttyout);
- else
- fputs(
- "421 Service not available, remote server has closed connection.\n",
- ttyout);
- (void)fflush(ttyout);
- }
- code = 421;
- (void)xsignal(SIGINT, oldsigint);
- (void)xsignal(SIGALRM, oldsigalrm);
- return (4);
- }
- if (c != '\r' && (verbose > 0 ||
- ((verbose > -1 && n == '5' && dig > 4) &&
- (((!n && c < '5') || (n && n < '5'))
- || !retry_connect)))) {
- if (proxflag &&
- (dig == 1 || (dig == 5 && verbose == 0)))
- fprintf(ttyout, "%s:", hostname);
- (void)putc(c, ttyout);
- }
- if (dig < 4 && isdigit(c))
- code = code * 10 + (c - '0');
- if (!pflag && (code == 227 || code == 228))
- pflag = 1;
- else if (!pflag && code == 229)
- pflag = 100;
- if (dig > 4 && pflag == 1 && isdigit(c))
- pflag = 2;
- if (pflag == 2) {
- if (c != '\r' && c != ')') {
- if (pt < &pasv[sizeof(pasv) - 1])
- *pt++ = c;
- } else {
- *pt = '\0';
- pflag = 3;
- }
- }
- if (pflag == 100 && c == '(')
- pflag = 2;
- 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') &&
- (n < '5' || !retry_connect))) {
- (void)putc(c, ttyout);
- (void)fflush (ttyout);
- }
- if (cp[-1] == '\r')
- cp[-1] = '\0';
- *cp = '\0';
- if (line == 0)
- (void)strlcpy(reply_string, current_line,
- sizeof(reply_string));
- if (line > 0 && code == 0 && reply_callback != NULL)
- (*reply_callback)(current_line);
- if (continuation && code != originalcode) {
- if (originalcode == 0)
- originalcode = code;
- continue;
- }
- if (n != '1')
- cpend = 0;
- alarmtimer(0);
- (void)xsignal(SIGINT, oldsigint);
- (void)xsignal(SIGALRM, oldsigalrm);
- if (code == 421 || originalcode == 421)
- lostpeer(0);
- if (abrtflag && oldsigint != cmdabort && oldsigint != SIG_IGN)
- (*oldsigint)(SIGINT);
- if (timeoutflag && oldsigalrm != cmdtimeout &&
- oldsigalrm != SIG_IGN)
- (*oldsigalrm)(SIGINT);
- return (n - '0');
- }
-}
-
-static int
-empty(FILE *cin, FILE *din, int sec)
-{
- int nr, nfd;
- struct pollfd pfd[2];
-
- nfd = 0;
- if (cin) {
- pfd[nfd].fd = fileno(cin);
- pfd[nfd++].events = POLLIN;
- }
-
- if (din) {
- pfd[nfd].fd = fileno(din);
- pfd[nfd++].events = POLLIN;
- }
-
- if ((nr = xpoll(pfd, nfd, sec * 1000)) <= 0)
- return nr;
-
- nr = 0;
- nfd = 0;
- if (cin)
- nr |= (pfd[nfd++].revents & POLLIN) ? 1 : 0;
- if (din)
- nr |= (pfd[nfd++].revents & POLLIN) ? 2 : 0;
- return nr;
-}
-
-sigjmp_buf xferabort;
-
-void
-abortxfer(int notused)
-{
- char msgbuf[100];
- size_t len;
-
- sigint_raised = 1;
- alarmtimer(0);
- mflag = 0;
- abrtflag = 0;
- switch (direction[0]) {
- case 'r':
- strlcpy(msgbuf, "\nreceive", sizeof(msgbuf));
- break;
- case 's':
- strlcpy(msgbuf, "\nsend", sizeof(msgbuf));
- break;
- default:
- errx(1, "abortxfer called with unknown direction `%s'",
- direction);
- }
- len = strlcat(msgbuf, " aborted. Waiting for remote to finish abort.\n",
- sizeof(msgbuf));
- write(fileno(ttyout), msgbuf, len);
- siglongjmp(xferabort, 1);
-}
-
-void
-sendrequest(const char *cmd, const char *local, const char *remote,
- int printnames)
-{
- struct stat st;
- int c, d;
- FILE *fin, *dout;
- int (*closefunc)(FILE *);
- sigfunc oldintr, oldintp;
- volatile off_t hashbytes;
- char *lmode, *bufp;
- static size_t bufsize;
- static char *buf;
- int oprogress;
-
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&fin;
- (void)&dout;
- (void)&closefunc;
- (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 != '-')
- fprintf(ttyout, "local: %s ", local);
- if (remote)
- fprintf(ttyout, "remote: %s\n", remote);
- }
- if (proxy) {
- proxtrans(cmd, local, remote);
- return;
- }
- if (curtype != type)
- changetype(type, 0);
- closefunc = NULL;
- oldintr = NULL;
- oldintp = NULL;
- lmode = "w";
- if (sigsetjmp(xferabort, 1)) {
- while (cpend)
- (void)getreply(0);
- code = -1;
- goto cleanupsend;
- }
- (void)xsignal(SIGQUIT, psummary);
- oldintr = xsignal(SIGINT, abortxfer);
- if (strcmp(local, "-") == 0) {
- fin = stdin;
- progress = 0;
- } else if (*local == '|') {
- oldintp = xsignal(SIGPIPE, SIG_IGN);
- fin = popen(local + 1, "r");
- if (fin == NULL) {
- warn("%s", local + 1);
- code = -1;
- goto cleanupsend;
- }
- progress = 0;
- closefunc = pclose;
- } else {
- fin = fopen(local, "r");
- if (fin == NULL) {
- warn("local: %s", local);
- code = -1;
- goto cleanupsend;
- }
- closefunc = fclose;
- if (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode)) {
- fprintf(ttyout, "%s: not a plain file.\n", local);
- code = -1;
- goto cleanupsend;
- }
- filesize = st.st_size;
- }
- if (initconn()) {
- code = -1;
- goto cleanupsend;
- }
- if (sigsetjmp(xferabort, 1))
- 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);
- goto cleanupsend;
- }
- if (command("REST " LLF, (LLT)restart_point) != CONTINUE)
- goto cleanupsend;
- lmode = "r+";
- }
- if (remote) {
- if (command("%s %s", cmd, remote) != PRELIM)
- goto cleanupsend;
- } else {
- if (command("%s", cmd) != PRELIM)
- goto cleanupsend;
- }
- dirchange = 1;
- dout = dataconn(lmode);
- if (dout == NULL)
- goto abort;
-
- if (sndbuf_size > bufsize) {
- if (buf)
- (void)free(buf);
- bufsize = sndbuf_size;
- buf = xmalloc(bufsize);
- }
-
- progressmeter(-1);
- oldintp = xsignal(SIGPIPE, SIG_IGN);
-
- switch (curtype) {
-
- case TYPE_I:
- case TYPE_L:
- if (rate_put) { /* rate limited */
- while (1) {
- struct timeval then, now, td;
- off_t bufrem;
-
- (void)gettimeofday(&then, NULL);
- errno = c = d = 0;
- bufrem = rate_put;
- while (bufrem > 0) {
- if ((c = read(fileno(fin), buf,
- MIN(bufsize, bufrem))) <= 0)
- goto senddone;
- bytes += c;
- bufrem -= c;
- for (bufp = buf; c > 0;
- c -= d, bufp += d)
- if ((d = write(fileno(dout),
- bufp, c)) <= 0)
- break;
- if (d < 0)
- goto senddone;
- if (hash &&
- (!progress || filesize < 0) ) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- while (1) {
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec > 0)
- break;
- usleep(1000000 - td.tv_usec);
- }
- }
- } else { /* simpler/faster; no rate limit */
- while (1) {
- errno = c = d = 0;
- if ((c = read(fileno(fin), buf, bufsize)) <= 0)
- goto senddone;
- bytes += c;
- for (bufp = buf; c > 0; c -= d, bufp += d)
- if ((d = write(fileno(dout), bufp, c))
- <= 0)
- break;
- if (d < 0)
- goto senddone;
- if (hash && (!progress || filesize < 0) ) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- }
- senddone:
- if (hash && (!progress || filesize < 0) && bytes > 0) {
- if (bytes < mark)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- 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)putc('#', ttyout);
- (void)fflush(ttyout);
- 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)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- 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);
- fin = NULL;
- }
- (void)fclose(dout);
- dout = NULL;
- (void)getreply(0);
- if (bytes > 0)
- ptransfer(0);
- goto cleanupsend;
-
- abort:
- (void)xsignal(SIGINT, oldintr);
- oldintr = NULL;
- if (!cpend) {
- code = -1;
- goto cleanupsend;
- }
- if (data >= 0) {
- (void)close(data);
- data = -1;
- }
- if (dout) {
- (void)fclose(dout);
- dout = NULL;
- }
- (void)getreply(0);
- code = -1;
- if (bytes > 0)
- ptransfer(0);
-
- cleanupsend:
- if (oldintr)
- (void)xsignal(SIGINT, oldintr);
- if (oldintp)
- (void)xsignal(SIGPIPE, oldintp);
- if (data >= 0) {
- (void)close(data);
- data = -1;
- }
- if (closefunc != NULL && fin != NULL)
- (*closefunc)(fin);
- if (dout)
- (void)fclose(dout);
- progress = oprogress;
- restart_point = 0;
- bytes = 0;
-}
-
-void
-recvrequest(const char *cmd, const char *local, const char *remote,
- const char *lmode, int printnames, int ignorespecial)
-{
- FILE *fout, *din;
- int (*closefunc)(FILE *);
- sigfunc 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__ /* to shut up gcc warnings */
- (void)&local;
- (void)&fout;
- (void)&din;
- (void)&closefunc;
- (void)&oldintr;
- (void)&oldintp;
-#endif
-
- fout = NULL;
- din = 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 != '-'))
- fprintf(ttyout, "local: %s ", local);
- if (remote)
- fprintf(ttyout, "remote: %s\n", remote);
- }
- if (proxy && is_retr) {
- proxtrans(cmd, local, remote);
- return;
- }
- closefunc = NULL;
- oldintr = NULL;
- oldintp = NULL;
- tcrflag = !crflag && is_retr;
- if (sigsetjmp(xferabort, 1)) {
- while (cpend)
- (void)getreply(0);
- code = -1;
- goto cleanuprecv;
- }
- (void)xsignal(SIGQUIT, psummary);
- oldintr = xsignal(SIGINT, abortxfer);
- if (ignorespecial || (strcmp(local, "-") && *local != '|')) {
- if (access(local, W_OK) < 0) {
- char *dir = strrchr(local, '/');
-
- if (errno != ENOENT && errno != EACCES) {
- warn("local: %s", local);
- code = -1;
- goto cleanuprecv;
- }
- if (dir != NULL)
- *dir = 0;
- d = access(dir == local ? "/" :
- dir ? local : ".", W_OK);
- if (dir != NULL)
- *dir = '/';
- if (d < 0) {
- warn("local: %s", local);
- code = -1;
- goto cleanuprecv;
- }
- if (!runique && errno == EACCES &&
- chmod(local, (S_IRUSR|S_IWUSR)) < 0) {
- warn("local: %s", local);
- code = -1;
- goto cleanuprecv;
- }
- if (runique && errno == EACCES &&
- (local = gunique(local)) == NULL) {
- code = -1;
- goto cleanuprecv;
- }
- }
- else if (runique && (local = gunique(local)) == NULL) {
- code = -1;
- goto cleanuprecv;
- }
- }
- if (!is_retr) {
- if (curtype != TYPE_A)
- changetype(TYPE_A, 0);
- } else {
- if (curtype != type)
- changetype(type, 0);
- filesize = remotesize(remote, 0);
- if (code == 421 || code == -1)
- goto cleanuprecv;
- }
- if (initconn()) {
- code = -1;
- goto cleanuprecv;
- }
- if (sigsetjmp(xferabort, 1))
- goto abort;
- if (is_retr && restart_point &&
- command("REST " LLF, (LLT) restart_point) != CONTINUE)
- goto cleanuprecv;
- if (! EMPTYSTRING(remote)) {
- if (command("%s %s", cmd, remote) != PRELIM)
- goto cleanuprecv;
- } else {
- if (command("%s", cmd) != PRELIM)
- goto cleanuprecv;
- }
- din = dataconn("r");
- if (din == NULL)
- goto abort;
- if (!ignorespecial && strcmp(local, "-") == 0) {
- fout = stdout;
- progress = 0;
- preserve = 0;
- } else if (!ignorespecial && *local == '|') {
- oldintp = xsignal(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) != -1 && !S_ISREG(st.st_mode)) {
- progress = 0;
- preserve = 0;
- }
- if (rcvbuf_size > bufsize) {
- if (buf)
- (void)free(buf);
- bufsize = rcvbuf_size;
- buf = xmalloc(bufsize);
- }
-
- 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);
- goto cleanuprecv;
- }
- if (rate_get) { /* rate limiting */
- while (1) {
- struct timeval then, now, td;
- off_t bufrem;
-
- (void)gettimeofday(&then, NULL);
- errno = c = d = 0;
- for (bufrem = rate_get; bufrem > 0; ) {
- if ((c = read(fileno(din), buf,
- MIN(bufsize, bufrem))) <= 0)
- goto recvdone;
- bytes += c;
- bufrem -=c;
- if ((d = write(fileno(fout), buf, c))
- != c)
- goto recvdone;
- if (hash &&
- (!progress || filesize < 0)) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- /* sleep until time is up */
- while (1) {
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec > 0)
- break;
- usleep(1000000 - td.tv_usec);
- }
- }
- } else { /* faster code (no limiting) */
- while (1) {
- errno = c = d = 0;
- if ((c = read(fileno(din), buf, bufsize)) <= 0)
- goto recvdone;
- bytes += c;
- if ((d = write(fileno(fout), buf, c)) != c)
- goto recvdone;
- if (hash && (!progress || filesize < 0)) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- }
- recvdone:
- if (hash && (!progress || filesize < 0) && bytes > 0) {
- if (bytes < mark)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- 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;
-
- if (fseeko(fout, (off_t)0, SEEK_SET) < 0)
- goto done;
- for (i = 0; i++ < restart_point;) {
- 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);
- goto cleanuprecv;
- }
- }
- while ((c = getc(din)) != EOF) {
- if (c == '\n')
- bare_lfs++;
- while (c == '\r') {
- while (hash && (!progress || filesize < 0) &&
- (bytes >= hashbytes)) {
- (void)putc('#', ttyout);
- (void)fflush(ttyout);
- 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 (hash && (!progress || filesize < 0)) {
- if (bytes < hashbytes)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- if (ferror(din)) {
- if (errno != EPIPE)
- warn("netin");
- bytes = -1;
- }
- if (ferror(fout))
- warn("local: %s", local);
- break;
- }
-
- progressmeter(1);
- if (closefunc != NULL) {
- (*closefunc)(fout);
- fout = NULL;
- }
- (void)fclose(din);
- din = NULL;
- (void)getreply(0);
- if (bare_lfs) {
- fprintf(ttyout,
- "WARNING! %d bare linefeeds received in ASCII mode.\n",
- bare_lfs);
- fputs("File may not have transferred correctly.\n", ttyout);
- }
- 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], NULL);
- tval[1].tv_sec = mtime;
- tval[1].tv_usec = 0;
- if (utimes(local, tval) == -1) {
- fprintf(ttyout,
- "Can't change modification time on %s to %s",
- local, asctime(localtime(&mtime)));
- }
- }
- }
- }
- goto cleanuprecv;
-
- abort:
- /*
- * abort using RFC 959 recommended IP,SYNC sequence
- */
- if (! sigsetjmp(xferabort, 1)) {
- /* this is the first call */
- (void)xsignal(SIGINT, abort_squared);
- if (!cpend) {
- code = -1;
- goto cleanuprecv;
- }
- abort_remote(din);
- }
- code = -1;
- if (bytes > 0)
- ptransfer(0);
-
- cleanuprecv:
- if (oldintr)
- (void)xsignal(SIGINT, oldintr);
- if (oldintp)
- (void)xsignal(SIGPIPE, oldintp);
- if (data >= 0) {
- (void)close(data);
- data = -1;
- }
- if (closefunc != NULL && fout != NULL)
- (*closefunc)(fout);
- if (din)
- (void)fclose(din);
- progress = oprogress;
- preserve = opreserve;
- bytes = 0;
-}
-
-/*
- * Need to start a listen on the data channel before we send the command,
- * otherwise the server's connect may fail.
- */
-int
-initconn(void)
-{
- char *p, *a;
- int result, tmpno = 0;
- int on = 1;
- int error;
- u_int addr[16], port[2];
- u_int af, hal, pal;
- socklen_t len;
- char *pasvcmd = NULL;
-
-#ifdef INET6
- if (myctladdr.su_family == AF_INET6 && debug &&
- (IN6_IS_ADDR_LINKLOCAL(&myctladdr.si_su.su_sin6.sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(&myctladdr.si_su.su_sin6.sin6_addr))) {
- warnx("use of scoped address can be troublesome");
- }
-#endif
- reinit:
- if (passivemode) {
- data_addr = myctladdr;
- data = socket(data_addr.su_family, SOCK_STREAM, 0);
- if (data < 0) {
- warn("socket");
- return (1);
- }
- if ((options & SO_DEBUG) &&
- setsockopt(data, SOL_SOCKET, SO_DEBUG,
- (void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_DEBUG");
- }
- result = COMPLETE + 1;
- switch (data_addr.su_family) {
- case AF_INET:
- if (epsv4 && !epsv4bad) {
- pasvcmd = "EPSV";
- result = command("EPSV");
- if (!connected)
- return (1);
- /*
- * this code is to be friendly with broken
- * BSDI ftpd
- */
- if (code / 10 == 22 && code != 229) {
- fputs(
-"wrong server: return code must be 229\n",
- ttyout);
- result = COMPLETE + 1;
- }
- if (result != COMPLETE) {
- epsv4bad = 1;
- if (debug)
- fputs(
- "disabling epsv4 for this connection\n",
- ttyout);
- }
- }
- if (result != COMPLETE) {
- pasvcmd = "PASV";
- result = command("PASV");
- if (!connected)
- return (1);
- }
- break;
-#ifdef INET6
- case AF_INET6:
- pasvcmd = "EPSV";
- result = command("EPSV");
- if (!connected)
- return (1);
- /* this code is to be friendly with broken BSDI ftpd */
- if (code / 10 == 22 && code != 229) {
- fputs(
-"wrong server: return code must be 229\n",
- ttyout);
- result = COMPLETE + 1;
- }
- if (result != COMPLETE) {
- pasvcmd = "LPSV";
- result = command("LPSV");
- }
- if (!connected)
- return (1);
- break;
-#endif
- default:
- result = COMPLETE + 1;
- break;
- }
- if (result != COMPLETE) {
- if (activefallback) {
- (void)close(data);
- data = -1;
- passivemode = 0;
-#if 0
- activefallback = 0;
-#endif
- goto reinit;
- }
- fputs("Passive mode refused.\n", ttyout);
- goto bad;
- }
-
-#define pack2(var, off) \
- (((var[(off) + 0] & 0xff) << 8) | ((var[(off) + 1] & 0xff) << 0))
-#define pack4(var, off) \
- (((var[(off) + 0] & 0xff) << 24) | ((var[(off) + 1] & 0xff) << 16) | \
- ((var[(off) + 2] & 0xff) << 8) | ((var[(off) + 3] & 0xff) << 0))
-#define UC(b) (((int)b)&0xff)
-
- /*
- * What we've got at this point is a string of comma separated
- * one-byte unsigned integer values, separated by commas.
- */
- if (strcmp(pasvcmd, "PASV") == 0) {
- if (data_addr.su_family != AF_INET) {
- fputs(
- "Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
- if (code / 10 == 22 && code != 227) {
- fputs("wrong server: return code must be 227\n",
- ttyout);
- error = 1;
- goto bad;
- }
- error = sscanf(pasv, "%u,%u,%u,%u,%u,%u",
- &addr[0], &addr[1], &addr[2], &addr[3],
- &port[0], &port[1]);
- if (error != 6) {
- fputs(
-"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
- error = 0;
- memset(&data_addr, 0, sizeof(data_addr));
- data_addr.su_family = AF_INET;
- data_addr.su_len = sizeof(struct sockaddr_in);
- data_addr.si_su.su_sin.sin_addr.s_addr =
- htonl(pack4(addr, 0));
- data_addr.su_port = htons(pack2(port, 0));
- } else if (strcmp(pasvcmd, "LPSV") == 0) {
- if (code / 10 == 22 && code != 228) {
- fputs("wrong server: return code must be 228\n",
- ttyout);
- error = 1;
- goto bad;
- }
- switch (data_addr.su_family) {
- case AF_INET:
- error = sscanf(pasv,
-"%u,%u,%u,%u,%u,%u,%u,%u,%u",
- &af, &hal,
- &addr[0], &addr[1], &addr[2], &addr[3],
- &pal, &port[0], &port[1]);
- if (error != 9) {
- fputs(
-"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
- if (af != 4 || hal != 4 || pal != 2) {
- fputs(
-"Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
-
- error = 0;
- memset(&data_addr, 0, sizeof(data_addr));
- data_addr.su_family = AF_INET;
- data_addr.su_len = sizeof(struct sockaddr_in);
- data_addr.si_su.su_sin.sin_addr.s_addr =
- htonl(pack4(addr, 0));
- data_addr.su_port = htons(pack2(port, 0));
- break;
-#ifdef INET6
- case AF_INET6:
- error = sscanf(pasv,
-"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
- &af, &hal,
- &addr[0], &addr[1], &addr[2], &addr[3],
- &addr[4], &addr[5], &addr[6], &addr[7],
- &addr[8], &addr[9], &addr[10],
- &addr[11], &addr[12], &addr[13],
- &addr[14], &addr[15],
- &pal, &port[0], &port[1]);
- if (error != 21) {
- fputs(
-"Passive mode address scan failure. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
- if (af != 6 || hal != 16 || pal != 2) {
- fputs(
-"Passive mode AF mismatch. Shouldn't happen!\n", ttyout);
- error = 1;
- goto bad;
- }
-
- error = 0;
- memset(&data_addr, 0, sizeof(data_addr));
- data_addr.su_family = AF_INET6;
- data_addr.su_len = sizeof(struct sockaddr_in6);
- {
- int i;
- for (i = 0; i < sizeof(struct in6_addr); i++) {
- data_addr.si_su.su_sin6.sin6_addr.s6_addr[i] =
- UC(addr[i]);
- }
- }
- data_addr.su_port = htons(pack2(port, 0));
- break;
-#endif
- default:
- error = 1;
- }
- } else if (strcmp(pasvcmd, "EPSV") == 0) {
- char delim[4];
-
- port[0] = 0;
- if (code / 10 == 22 && code != 229) {
- fputs("wrong server: return code must be 229\n",
- ttyout);
- error = 1;
- goto bad;
- }
- if (sscanf(pasv, "%c%c%c%d%c", &delim[0],
- &delim[1], &delim[2], &port[1],
- &delim[3]) != 5) {
- fputs("parse error!\n", ttyout);
- error = 1;
- goto bad;
- }
- if (delim[0] != delim[1] || delim[0] != delim[2]
- || delim[0] != delim[3]) {
- fputs("parse error!\n", ttyout);
- error = 1;
- goto bad;
- }
- data_addr = hisctladdr;
- data_addr.su_port = htons(port[1]);
- } else
- goto bad;
-
- while (xconnect(data, (struct sockaddr *)&data_addr.si_su,
- data_addr.su_len) < 0) {
- if (activefallback) {
- (void)close(data);
- data = -1;
- passivemode = 0;
-#if 0
- activefallback = 0;
-#endif
- goto reinit;
- }
- warn("connect for data channel");
- goto bad;
- }
-#ifdef IPTOS_THROUGHPUT
- if (data_addr.su_family == AF_INET) {
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS,
- (void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
- }
- }
-#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,
- (void *)&on, sizeof(on)) == -1) {
- warn("setsockopt %s", "SO_REUSEADDR");
- goto bad;
- }
- if (bind(data, (struct sockaddr *)&data_addr.si_su,
- data_addr.su_len) < 0) {
- warn("bind");
- goto bad;
- }
- if ((options & SO_DEBUG) &&
- setsockopt(data, SOL_SOCKET, SO_DEBUG,
- (void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_DEBUG");
- }
- len = sizeof(data_addr.si_su);
- memset((char *)&data_addr, 0, sizeof (data_addr));
- if (getsockname(data, (struct sockaddr *)&data_addr.si_su, &len) == -1) {
- warn("getsockname");
- goto bad;
- }
- data_addr.su_len = len;
- if (xlisten(data, 1) < 0)
- warn("listen");
-
- if (sendport) {
- char hname[NI_MAXHOST], sname[NI_MAXSERV];
- int af;
- struct sockinet tmp;
-
- switch (data_addr.su_family) {
- case AF_INET:
- if (!epsv4 || epsv4bad) {
- result = COMPLETE + 1;
- break;
- }
- /* FALLTHROUGH */
-#ifdef INET6
- case AF_INET6:
-#endif
- af = (data_addr.su_family == AF_INET) ? 1 : 2;
- tmp = data_addr;
-#ifdef INET6
- if (tmp.su_family == AF_INET6)
- tmp.si_su.su_sin6.sin6_scope_id = 0;
-#endif
- if (getnameinfo((struct sockaddr *)&tmp.si_su,
- tmp.su_len, hname, sizeof(hname), sname,
- sizeof(sname), NI_NUMERICHOST | NI_NUMERICSERV)) {
- result = ERROR;
- } else {
- result = command("EPRT |%d|%s|%s|", af, hname,
- sname);
- if (!connected)
- return (1);
- if (result != COMPLETE) {
- epsv4bad = 1;
- if (debug)
- fputs(
- "disabling epsv4 for this connection\n",
- ttyout);
- }
- }
- break;
- default:
- result = COMPLETE + 1;
- break;
- }
- if (result == COMPLETE)
- goto skip_port;
-
- switch (data_addr.su_family) {
- case AF_INET:
- a = (char *)&data_addr.si_su.su_sin.sin_addr;
- p = (char *)&data_addr.su_port;
- result = command("PORT %d,%d,%d,%d,%d,%d",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
- UC(p[0]), UC(p[1]));
- break;
-#ifdef INET6
- case AF_INET6:
- a = (char *)&data_addr.si_su.su_sin6.sin6_addr;
- p = (char *)&data_addr.su_port;
- result = command(
- "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
- 6, 16,
- UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]),
- UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]),
- UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]),
- UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]),
- 2, UC(p[0]), UC(p[1]));
- break;
-#endif
- default:
- result = COMPLETE + 1; /* xxx */
- }
- if (!connected)
- return (1);
- skip_port:
-
- if (result == ERROR && sendport == -1) {
- sendport = 0;
- tmpno = 1;
- goto noport;
- }
- return (result != COMPLETE);
- }
- if (tmpno)
- sendport = 1;
-#ifdef IPTOS_THROUGHPUT
- if (data_addr.su_family == AF_INET) {
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS,
- (void *)&on, sizeof(on)) == -1)
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
- }
-#endif
- return (0);
- bad:
- (void)close(data);
- data = -1;
- if (tmpno)
- sendport = 1;
- return (1);
-}
-
-FILE *
-dataconn(const char *lmode)
-{
- struct sockinet from;
- int s, flags, rv, timeout;
- struct timeval endtime, now, td;
- struct pollfd pfd[1];
- socklen_t fromlen;
-
- if (passivemode) /* passive data connection */
- return (fdopen(data, lmode));
-
- /* active mode data connection */
-
- if ((flags = fcntl(data, F_GETFL, 0)) == -1)
- goto dataconn_failed; /* get current socket flags */
- if (fcntl(data, F_SETFL, flags | O_NONBLOCK) == -1)
- goto dataconn_failed; /* set non-blocking connect */
-
- /* NOTE: we now must restore socket flags on successful exit */
-
- /* limit time waiting on listening socket */
- pfd[0].fd = data;
- pfd[0].events = POLLIN;
- (void)gettimeofday(&endtime, NULL); /* determine end time */
- endtime.tv_sec += (quit_time > 0) ? quit_time: 60;
- /* without -q, default to 60s */
- do {
- (void)gettimeofday(&now, NULL);
- timersub(&endtime, &now, &td);
- timeout = td.tv_sec * 1000 + td.tv_usec/1000;
- if (timeout < 0)
- timeout = 0;
- rv = xpoll(pfd, 1, timeout);
- } while (rv == -1 && errno == EINTR); /* loop until poll ! EINTR */
- if (rv == -1) {
- warn("poll waiting before accept");
- goto dataconn_failed;
- }
- if (rv == 0) {
- warn("poll timeout waiting before accept");
- goto dataconn_failed;
- }
-
- /* (non-blocking) accept the connection */
- fromlen = myctladdr.su_len;
- do {
- s = accept(data, (struct sockaddr *) &from.si_su, &fromlen);
- } while (s == -1 && errno == EINTR); /* loop until accept ! EINTR */
- if (s == -1) {
- warn("accept");
- goto dataconn_failed;
- }
-
- (void)close(data);
- data = s;
- if (fcntl(data, F_SETFL, flags) == -1) /* restore socket flags */
- goto dataconn_failed;
-
-#ifdef IPTOS_THROUGHPUT
- if (from.su_family == AF_INET) {
- int tos = IPTOS_THROUGHPUT;
- if (setsockopt(s, IPPROTO_IP, IP_TOS,
- (void *)&tos, sizeof(tos)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
- }
- }
-#endif
- return (fdopen(data, lmode));
-
- dataconn_failed:
- (void)close(data);
- data = -1;
- return (NULL);
-}
-
-void
-psabort(int notused)
-{
- int oerrno = errno;
-
- sigint_raised = 1;
- alarmtimer(0);
- abrtflag++;
- errno = oerrno;
-}
-
-void
-pswitch(int flag)
-{
- sigfunc oldintr;
- static struct comvars {
- int connect;
- char name[MAXHOSTNAMELEN];
- struct sockinet mctl;
- struct sockinet 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 = xsignal(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)strlcpy(ip->name, hostname, sizeof(ip->name));
- 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)strlcpy(ip->nti, ntin, sizeof(ip->nti));
- (void)strlcpy(ntin, op->nti, sizeof(ntin));
- (void)strlcpy(ip->nto, ntout, sizeof(ip->nto));
- (void)strlcpy(ntout, op->nto, sizeof(ntout));
- ip->mapflg = mapflag;
- mapflag = op->mapflg;
- (void)strlcpy(ip->mi, mapin, sizeof(ip->mi));
- (void)strlcpy(mapin, op->mi, sizeof(mapin));
- (void)strlcpy(ip->mo, mapout, sizeof(ip->mo));
- (void)strlcpy(mapout, op->mo, sizeof(mapout));
- (void)xsignal(SIGINT, oldintr);
- if (abrtflag) {
- abrtflag = 0;
- (*oldintr)(SIGINT);
- }
-}
-
-void
-abortpt(int notused)
-{
-
- sigint_raised = 1;
- alarmtimer(0);
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- ptabflg++;
- mflag = 0;
- abrtflag = 0;
- siglongjmp(ptabort, 1);
-}
-
-void
-proxtrans(const char *cmd, const char *local, const char *remote)
-{
- sigfunc oldintr;
- int prox_type, nfnd;
- volatile int secndflag;
- char *cmd2;
-
-#ifdef __GNUC__ /* 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 (command("PASV") != COMPLETE) {
- fputs("proxy server does not support third party transfers.\n",
- ttyout);
- return;
- }
- pswitch(0);
- if (!connected) {
- fputs("No primary connection.\n", ttyout);
- pswitch(1);
- code = -1;
- return;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
- if (command("PORT %s", pasv) != COMPLETE) {
- pswitch(1);
- return;
- }
- if (sigsetjmp(ptabort, 1))
- goto abort;
- oldintr = xsignal(SIGINT, abortpt);
- if ((restart_point &&
- (command("REST " LLF, (LLT) restart_point) != CONTINUE))
- || (command("%s %s", cmd, remote) != PRELIM)) {
- (void)xsignal(SIGINT, oldintr);
- pswitch(1);
- return;
- }
- sleep(2);
- pswitch(1);
- secndflag++;
- if ((restart_point &&
- (command("REST " LLF, (LLT) restart_point) != CONTINUE))
- || (command("%s %s", cmd2, local) != PRELIM))
- goto abort;
- ptflag++;
- (void)getreply(0);
- pswitch(0);
- (void)getreply(0);
- (void)xsignal(SIGINT, oldintr);
- pswitch(1);
- ptflag = 0;
- fprintf(ttyout, "local: %s remote: %s\n", local, remote);
- return;
- abort:
- if (sigsetjmp(xferabort, 1)) {
- (void)xsignal(SIGINT, oldintr);
- return;
- }
- (void)xsignal(SIGINT, abort_squared);
- 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(NULL);
- }
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void)xsignal(SIGINT, oldintr);
- return;
- }
- if (cpend)
- abort_remote(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(NULL);
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void)xsignal(SIGINT, oldintr);
- return;
- }
- }
- if (cpend)
- abort_remote(NULL);
- pswitch(!proxy);
- if (cpend) {
- if ((nfnd = empty(cin, NULL, 10)) <= 0) {
- if (nfnd < 0)
- warn("abort");
- if (ptabflg)
- code = -1;
- lostpeer(0);
- }
- (void)getreply(0);
- (void)getreply(0);
- }
- if (proxy)
- pswitch(0);
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void)xsignal(SIGINT, oldintr);
-}
-
-void
-reset(int argc, char *argv[])
-{
- int nfnd = 1;
-
- if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
- return;
- }
- while (nfnd > 0) {
- if ((nfnd = empty(cin, NULL, 0)) < 0) {
- warn("reset");
- code = -1;
- lostpeer(0);
- } else if (nfnd)
- (void)getreply(0);
- }
-}
-
-char *
-gunique(const char *local)
-{
- static char new[MAXPATHLEN];
- char *cp = strrchr(local, '/');
- int d, count=0, len;
- 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 (NULL);
- }
- len = strlcpy(new, local, sizeof(new));
- cp = &new[len];
- *cp++ = '.';
- while (!d) {
- if (++count == 100) {
- fputs("runique: can't find unique file name.\n",
- ttyout);
- return (NULL);
- }
- *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);
-}
-
-/*
- * abort_squared --
- * aborts abort_remote(). lostpeer() is called because if the user is
- * too impatient to wait or there's another problem then ftp really
- * needs to get back to a known state.
- */
-void
-abort_squared(int dummy)
-{
- char msgbuf[100];
- size_t len;
-
- sigint_raised = 1;
- alarmtimer(0);
- len = strlcpy(msgbuf, "\nremote abort aborted; closing connection.\n",
- sizeof(msgbuf));
- write(fileno(ttyout), msgbuf, len);
- lostpeer(0);
- siglongjmp(xferabort, 1);
-}
-
-void
-abort_remote(FILE *din)
-{
- char buf[BUFSIZ];
- int nfnd;
-
- if (cout == NULL) {
- warnx("Lost control connection for abort.");
- if (ptabflg)
- code = -1;
- lostpeer(0);
- 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
- */
- buf[0] = IAC;
- buf[1] = IP;
- buf[2] = IAC;
- if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
- warn("abort");
- fprintf(cout, "%cABOR\r\n", DM);
- (void)fflush(cout);
- if ((nfnd = empty(cin, din, 10)) <= 0) {
- if (nfnd < 0)
- warn("abort");
- if (ptabflg)
- code = -1;
- lostpeer(0);
- }
- if (din && (nfnd & 2)) {
- while (read(fileno(din), buf, BUFSIZ) > 0)
- continue;
- }
- if (getreply(0) == ERROR && code == 552) {
- /* 552 needed for nic style abort */
- (void)getreply(0);
- }
- (void)getreply(0);
-}
-
-void
-ai_unmapped(struct addrinfo *ai)
-{
-#ifdef INET6
- struct sockaddr_in6 *sin6;
- struct sockaddr_in sin;
- socklen_t len;
-
- 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;
- 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;
-#if HAVE_SOCKADDR_SA_LEN
- sin.sin_len = len;
-#endif
- memcpy(ai->ai_addr, &sin, len);
- ai->ai_addrlen = len;
-#endif
-}
diff --git a/contrib/lukemftp/src/ftp_var.h b/contrib/lukemftp/src/ftp_var.h
deleted file mode 100644
index 25f13d4..0000000
--- a/contrib/lukemftp/src/ftp_var.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $NetBSD: ftp_var.h,v 1.71 2005/04/11 01:49:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2005 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.
- */
-
-/*
- * 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. 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
- */
-
-/*
- * Copyright (C) 1997 and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * FTP global variables.
- */
-
-#ifdef SMALL
-#undef NO_EDITCOMPLETE
-#define NO_EDITCOMPLETE
-#undef NO_PROGRESS
-#define NO_PROGRESS
-#endif
-
-#include <sys/param.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <poll.h>
-
-#include <setjmp.h>
-#include <stringlist.h>
-
-#ifndef NO_EDITCOMPLETE
-#include <histedit.h>
-#endif /* !NO_EDITCOMPLETE */
-
-#include "extern.h"
-#include "progressbar.h"
-
-/*
- * Format of command table.
- */
-struct cmd {
- char *c_name; /* name of command */
- const 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 NO_EDITCOMPLETE
- const char *c_complete; /* context sensitive completion list */
-#endif /* !NO_EDITCOMPLETE */
- void (*c_handler)(int, char **); /* function to call */
-};
-
-/*
- * Format of macro table
- */
-struct macel {
- char mac_name[9]; /* macro name */
- char *mac_start; /* start of macro in macbuf */
- char *mac_end; /* end of macro in macbuf */
-};
-
-/*
- * Format of option table
- */
-struct option {
- char *name;
- char *value;
-};
-
-/*
- * Indices to features[]; an array containing status of remote server
- * features; -1 not known (FEAT failed), 0 absent, 1 present.
- */
-enum {
- FEAT_FEAT = 0, /* FEAT, OPTS */
- FEAT_MDTM, /* MDTM */
- FEAT_MLST, /* MLSD, MLST */
- FEAT_REST_STREAM, /* RESTart STREAM */
- FEAT_SIZE, /* SIZE */
- FEAT_TVFS, /* TVFS (not used) */
- FEAT_max
-};
-
-
-/*
- * Global defines
- */
-#define FTPBUFLEN MAXPATHLEN + 200
-#define MAX_IN_PORT_T 0xffffU
-
-#define HASHBYTES 1024 /* default mark for `hash' command */
-#define DEFAULTINCR 1024 /* default increment for `rate' command */
-
-#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 DEFAULTPAGER "more" /* default pager if $PAGER isn't set */
-#define DEFAULTPROMPT "ftp> " /* default prompt if `set prompt' is empty */
-#define DEFAULTRPROMPT "" /* default rprompt if `set rprompt' is empty */
-
-#define TMPFILE "ftpXXXXXXXXXX"
-
-
-#ifndef GLOBAL
-#define GLOBAL extern
-#endif
-
-/*
- * Options and other state info.
- */
-GLOBAL int trace; /* trace packets exchanged */
-GLOBAL int hash; /* print # for each buffer transferred */
-GLOBAL int mark; /* number of bytes between hashes */
-GLOBAL int sendport; /* use PORT/LPRT cmd for each data connection */
-GLOBAL int connected; /* 1 = connected to server, -1 = logged in */
-GLOBAL int interactive; /* interactively prompt on m* cmds */
-GLOBAL int confirmrest; /* confirm rest of current m* cmd */
-GLOBAL int debug; /* debugging level */
-GLOBAL int bell; /* ring bell on cmd completion */
-GLOBAL int doglob; /* glob local file names */
-GLOBAL int autologin; /* establish user account on connection */
-GLOBAL int proxy; /* proxy server connection active */
-GLOBAL int proxflag; /* proxy connection exists */
-GLOBAL int gatemode; /* use gate-ftp */
-GLOBAL char *gateserver; /* server to use for gate-ftp */
-GLOBAL int sunique; /* store files on server with unique name */
-GLOBAL int runique; /* store local files with unique name */
-GLOBAL int mcase; /* map upper to lower case for mget names */
-GLOBAL int ntflag; /* use ntin ntout tables for name translation */
-GLOBAL int mapflag; /* use mapin mapout templates on file names */
-GLOBAL int preserve; /* preserve modification time on files */
-GLOBAL int code; /* return/reply code for ftp command */
-GLOBAL int crflag; /* if 1, strip car. rets. on ascii gets */
-GLOBAL int passivemode; /* passive mode enabled */
-GLOBAL int activefallback; /* fall back to active mode if passive fails */
-GLOBAL char *altarg; /* argv[1] with no shell-like preprocessing */
-GLOBAL char ntin[17]; /* input translation table */
-GLOBAL char ntout[17]; /* output translation table */
-GLOBAL char mapin[MAXPATHLEN]; /* input map template */
-GLOBAL char mapout[MAXPATHLEN]; /* output map template */
-GLOBAL char typename[32]; /* name of file transfer type */
-GLOBAL int type; /* requested file transfer type */
-GLOBAL int curtype; /* current file transfer type */
-GLOBAL char structname[32]; /* name of file transfer structure */
-GLOBAL int stru; /* file transfer structure */
-GLOBAL char formname[32]; /* name of file transfer format */
-GLOBAL int form; /* file transfer format */
-GLOBAL char modename[32]; /* name of file transfer mode */
-GLOBAL int mode; /* file transfer mode */
-GLOBAL char bytename[32]; /* local byte size in ascii */
-GLOBAL int bytesize; /* local byte size in binary */
-GLOBAL int anonftp; /* automatic anonymous login */
-GLOBAL int dirchange; /* remote directory changed by cd command */
-GLOBAL int flushcache; /* set HTTP cache flush headers with request */
-GLOBAL int rate_get; /* maximum get xfer rate */
-GLOBAL int rate_get_incr; /* increment for get xfer rate */
-GLOBAL int rate_put; /* maximum put xfer rate */
-GLOBAL int rate_put_incr; /* increment for put xfer rate */
-GLOBAL int retry_connect; /* seconds between retrying connection */
-GLOBAL char *tmpdir; /* temporary directory */
-GLOBAL int epsv4; /* use EPSV/EPRT on IPv4 connections */
-GLOBAL int epsv4bad; /* EPSV doesn't work on the current server */
-GLOBAL int editing; /* command line editing enabled */
-GLOBAL int features[FEAT_max]; /* remote FEATures supported */
-
-#ifndef NO_EDITCOMPLETE
-GLOBAL EditLine *el; /* editline(3) status structure */
-GLOBAL History *hist; /* editline(3) history structure */
-GLOBAL char *cursor_pos; /* cursor position we're looking for */
-GLOBAL size_t cursor_argc; /* location of cursor in margv */
-GLOBAL size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */
-#endif /* !NO_EDITCOMPLETE */
-
-GLOBAL char *direction; /* direction transfer is occurring */
-
-GLOBAL char *hostname; /* name of host connected to */
-GLOBAL int unix_server; /* server is unix, can use binary for ascii */
-GLOBAL int unix_proxy; /* proxy is unix, can use binary for ascii */
-GLOBAL char localcwd[MAXPATHLEN]; /* local dir */
-GLOBAL char remotecwd[MAXPATHLEN]; /* remote dir */
-GLOBAL char *username; /* name of user logged in as. (dynamic) */
-
-GLOBAL sa_family_t family; /* address family to use for connections */
-GLOBAL char *ftpport; /* port number to use for FTP connections */
-GLOBAL char *httpport; /* port number to use for HTTP connections */
-GLOBAL char *gateport; /* port number to use for gateftp connections */
-
-GLOBAL char *outfile; /* filename to output URLs to */
-GLOBAL int restartautofetch; /* restart auto-fetch */
-
-GLOBAL char line[FTPBUFLEN]; /* input line buffer */
-GLOBAL char *stringbase; /* current scan point in line buffer */
-GLOBAL char argbuf[FTPBUFLEN]; /* argument storage buffer */
-GLOBAL char *argbase; /* current storage point in arg buffer */
-GLOBAL StringList *marg_sl; /* stringlist containing margv */
-GLOBAL int margc; /* count of arguments on input line */
-#define margv (marg_sl->sl_str) /* args parsed from input line */
-GLOBAL int cpend; /* flag: if != 0, then pending server reply */
-GLOBAL int mflag; /* flag: if != 0, then active multi command */
-
-GLOBAL int options; /* used during socket creation */
-
-GLOBAL int sndbuf_size; /* socket send buffer size */
-GLOBAL int rcvbuf_size; /* socket receive buffer size */
-
-GLOBAL int macnum; /* number of defined macros */
-GLOBAL struct macel macros[16];
-GLOBAL char macbuf[4096];
-
-GLOBAL char *localhome; /* local home directory */
-GLOBAL char *localname; /* local user name */
-GLOBAL char netrc[MAXPATHLEN]; /* path to .netrc file */
-GLOBAL char reply_string[BUFSIZ]; /* first line of previous reply */
-GLOBAL void (*reply_callback)(const char *);
- /*
- * function to call for each line in
- * the server's reply except for the
- * first (`xxx-') and last (`xxx ')
- */
-
-GLOBAL volatile sig_atomic_t sigint_raised;
-
-GLOBAL FILE *cin;
-GLOBAL FILE *cout;
-GLOBAL int data;
-
-extern struct cmd cmdtab[];
-extern struct option optiontab[];
-
-
-#define EMPTYSTRING(x) ((x) == NULL || (*(x) == '\0'))
-#define FREEPTR(x) if ((x) != NULL) { free(x); (x) = NULL; }
-
-#ifdef BSD4_4
-# define HAVE_SOCKADDR_SA_LEN 1
-#endif
-
-#ifdef NO_LONG_LONG
-# define STRTOLL(x,y,z) strtol(x,y,z)
-#else
-# define STRTOLL(x,y,z) strtoll(x,y,z)
-#endif
diff --git a/contrib/lukemftp/src/main.c b/contrib/lukemftp/src/main.c
deleted file mode 100644
index def05c5..0000000
--- a/contrib/lukemftp/src/main.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/* $NetBSD: main.c,v 1.94 2005/05/13 05:03:49 lukem Exp $ */
-
-/*-
- * Copyright (c) 1996-2004 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.
- */
-
-/*
- * 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. 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.
- */
-
-/*
- * Copyright (C) 1997 and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
-#else
-__RCSID("$NetBSD: main.c,v 1.94 2005/05/13 05:03:49 lukem Exp $");
-#endif
-#endif /* not lint */
-
-/*
- * FTP User Program -- Command Interface.
- */
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <err.h>
-#include <errno.h>
-#include <netdb.h>
-#include <paths.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <locale.h>
-
-#define GLOBAL /* force GLOBAL decls in ftp_var.h to be declared */
-#include "ftp_var.h"
-
-#define FTP_PROXY "ftp_proxy" /* env var with FTP proxy location */
-#define HTTP_PROXY "http_proxy" /* env var with HTTP proxy location */
-#define NO_PROXY "no_proxy" /* env var with list of non-proxied
- * hosts, comma or space separated */
-
-static void setupoption(char *, char *, char *);
-int main(int, char *[]);
-
-int
-main(int argc, char *argv[])
-{
- int ch, rval;
- struct passwd *pw;
- char *cp, *ep, *anonuser, *anonpass, *upload_path;
- int dumbterm, s, len, isupload;
- socklen_t slen;
-
- setlocale(LC_ALL, "");
- setprogname(argv[0]);
-
- sigint_raised = 0;
-
- ftpport = "ftp";
- httpport = "http";
- gateport = NULL;
- cp = getenv("FTPSERVERPORT");
- if (cp != NULL)
- gateport = cp;
- else
- gateport = "ftpgate";
- doglob = 1;
- interactive = 1;
- autologin = 1;
- passivemode = 1;
- activefallback = 1;
- preserve = 1;
- verbose = 0;
- progress = 0;
- gatemode = 0;
- data = -1;
- outfile = NULL;
- restartautofetch = 0;
-#ifndef NO_EDITCOMPLETE
- editing = 0;
- el = NULL;
- hist = NULL;
-#endif
- bytes = 0;
- mark = HASHBYTES;
- rate_get = 0;
- rate_get_incr = DEFAULTINCR;
- rate_put = 0;
- rate_put_incr = DEFAULTINCR;
-#ifdef INET6
- epsv4 = 1;
-#else
- epsv4 = 0;
-#endif
- epsv4bad = 0;
- upload_path = NULL;
- isupload = 0;
- reply_callback = NULL;
- family = AF_UNSPEC;
-
- netrc[0] = '\0';
- cp = getenv("NETRC");
- if (cp != NULL && strlcpy(netrc, cp, sizeof(netrc)) >= sizeof(netrc))
- errx(1, "$NETRC `%s': %s", cp, strerror(ENAMETOOLONG));
-
- /*
- * Get the default socket buffer sizes if we don't already have them.
- * It doesn't matter which socket we do this to, because on the first
- * call no socket buffer sizes will have been modified, so we are
- * guaranteed to get the system defaults.
- */
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s == -1)
- err(1, "can't create socket");
- slen = sizeof(rcvbuf_size);
- if (getsockopt(s, SOL_SOCKET, SO_RCVBUF,
- (void *)&rcvbuf_size, &slen) == -1)
- err(1, "unable to get default rcvbuf size");
- slen = sizeof(sndbuf_size);
- if (getsockopt(s, SOL_SOCKET, SO_SNDBUF,
- (void *)&sndbuf_size, &slen) == -1)
- err(1, "unable to get default sndbuf size");
- (void)close(s);
- /* sanity check returned buffer sizes */
- if (rcvbuf_size <= 0)
- rcvbuf_size = 8 * 1024;
- if (sndbuf_size <= 0)
- sndbuf_size = 8 * 1024;
-
- if (sndbuf_size > 8 * 1024 * 1024)
- sndbuf_size = 8 * 1024 * 1024;
- if (rcvbuf_size > 8 * 1024 * 1024)
- rcvbuf_size = 8 * 1024 * 1024;
-
- marg_sl = xsl_init();
- if ((tmpdir = getenv("TMPDIR")) == NULL)
- tmpdir = _PATH_TMP;
-
- /* Set default operation mode based on FTPMODE environment variable */
- if ((cp = getenv("FTPMODE")) != NULL) {
- if (strcasecmp(cp, "passive") == 0) {
- passivemode = 1;
- activefallback = 0;
- } else if (strcasecmp(cp, "active") == 0) {
- passivemode = 0;
- activefallback = 0;
- } else if (strcasecmp(cp, "gate") == 0) {
- gatemode = 1;
- } else if (strcasecmp(cp, "auto") == 0) {
- passivemode = 1;
- activefallback = 1;
- } else
- warnx("unknown $FTPMODE '%s'; using defaults", cp);
- }
-
- if (strcmp(getprogname(), "pftp") == 0) {
- passivemode = 1;
- activefallback = 0;
- } else if (strcmp(getprogname(), "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));
- ttyout = stdout;
- if (isatty(fileno(ttyout))) {
- verbose = 1; /* verbose if to a tty */
- if (! dumbterm) {
-#ifndef NO_EDITCOMPLETE
- if (fromatty) /* editing mode on if tty is usable */
- editing = 1;
-#endif
-#ifndef NO_PROGRESS
- if (foregroundproc())
- progress = 1; /* progress bar on if fg */
-#endif
- }
- }
-
- while ((ch = getopt(argc, argv, "46AadefginN:o:pP:q:r:RtT:u:vV")) != -1) {
- switch (ch) {
- case '4':
- family = AF_INET;
- break;
-
- case '6':
-#ifdef INET6
- family = AF_INET6;
-#else
- warnx("INET6 support is not available; ignoring -6");
-#endif
- break;
-
- case 'A':
- activefallback = 0;
- passivemode = 0;
- break;
-
- case 'a':
- anonftp = 1;
- break;
-
- case 'd':
- options |= SO_DEBUG;
- debug++;
- break;
-
- case 'e':
-#ifndef NO_EDITCOMPLETE
- editing = 0;
-#endif
- break;
-
- case 'f':
- flushcache = 1;
- break;
-
- case 'g':
- doglob = 0;
- break;
-
- case 'i':
- interactive = 0;
- break;
-
- case 'n':
- autologin = 0;
- break;
-
- case 'N':
- if (strlcpy(netrc, optarg, sizeof(netrc))
- >= sizeof(netrc))
- errx(1, "%s: %s", optarg,
- strerror(ENAMETOOLONG));
- break;
-
- case 'o':
- outfile = optarg;
- if (strcmp(outfile, "-") == 0)
- ttyout = stderr;
- break;
-
- case 'p':
- passivemode = 1;
- activefallback = 0;
- break;
-
- case 'P':
- ftpport = optarg;
- break;
-
- case 'q':
- quit_time = strtol(optarg, &ep, 10);
- if (quit_time < 1 || *ep != '\0')
- errx(1, "bad quit value: %s", optarg);
- break;
-
- case 'r':
- retry_connect = strtol(optarg, &ep, 10);
- if (retry_connect < 1 || *ep != '\0')
- errx(1, "bad retry value: %s", optarg);
- break;
-
- case 'R':
- restartautofetch = 1;
- break;
-
- case 't':
- trace = 1;
- break;
-
- case 'T':
- {
- int targc;
- char *targv[6], *oac;
-
- /* look for `dir,max[,incr]' */
- targc = 0;
- targv[targc++] = "-T";
- oac = xstrdup(optarg);
-
- while ((cp = strsep(&oac, ",")) != NULL) {
- if (*cp == '\0') {
- warnx("bad throttle value: %s", optarg);
- usage();
- /* NOTREACHED */
- }
- targv[targc++] = cp;
- if (targc >= 5)
- break;
- }
- if (parserate(targc, targv, 1) == -1)
- usage();
- free(oac);
- break;
- }
-
- case 'u':
- {
- isupload = 1;
- interactive = 0;
- upload_path = xstrdup(optarg);
-
- break;
- }
-
- case 'v':
- progress = verbose = 1;
- break;
-
- case 'V':
- progress = verbose = 0;
- break;
-
- default:
- usage();
- }
- }
- /* set line buffering on ttyout */
- setvbuf(ttyout, NULL, _IOLBF, 0);
- 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 */
-
- /*
- * Cache the user name and home directory.
- */
- localhome = NULL;
- localname = NULL;
- anonuser = "anonymous";
- cp = getenv("HOME");
- if (! EMPTYSTRING(cp))
- localhome = xstrdup(cp);
- pw = NULL;
- cp = getlogin();
- if (cp != NULL)
- pw = getpwnam(cp);
- if (pw == NULL)
- pw = getpwuid(getuid());
- if (pw != NULL) {
- if (localhome == NULL && !EMPTYSTRING(pw->pw_dir))
- localhome = xstrdup(pw->pw_dir);
- localname = xstrdup(pw->pw_name);
- anonuser = localname;
- }
- if (netrc[0] == '\0' && localhome != NULL) {
- if (strlcpy(netrc, localhome, sizeof(netrc)) >= sizeof(netrc) ||
- strlcat(netrc, "/.netrc", sizeof(netrc)) >= sizeof(netrc)) {
- warnx("%s/.netrc: %s", localhome,
- strerror(ENAMETOOLONG));
- netrc[0] = '\0';
- }
- }
- if (localhome == NULL)
- localhome = xstrdup("/");
-
- /*
- * 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
- */
- len = strlen(anonuser) + 2;
- anonpass = xmalloc(len);
- (void)strlcpy(anonpass, anonuser, len);
- (void)strlcat(anonpass, "@", len);
-
- /*
- * set all the defaults for options defined in
- * struct option optiontab[] declared in cmdtab.c
- */
- setupoption("anonpass", getenv("FTPANONPASS"), anonpass);
- setupoption("ftp_proxy", getenv(FTP_PROXY), "");
- setupoption("http_proxy", getenv(HTTP_PROXY), "");
- setupoption("no_proxy", getenv(NO_PROXY), "");
- setupoption("pager", getenv("PAGER"), DEFAULTPAGER);
- setupoption("prompt", getenv("FTPPROMPT"), DEFAULTPROMPT);
- setupoption("rprompt", getenv("FTPRPROMPT"), DEFAULTRPROMPT);
-
- free(anonpass);
-
- setttywidth(0);
-#ifdef SIGINFO
- (void)xsignal(SIGINFO, psummary);
-#endif
- (void)xsignal(SIGQUIT, psummary);
- (void)xsignal(SIGUSR1, crankrate);
- (void)xsignal(SIGUSR2, crankrate);
- (void)xsignal(SIGWINCH, setttywidth);
-
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&argc;
- (void)&argv;
-#endif
-
- if (argc > 0) {
- if (isupload) {
- rval = auto_put(argc, argv, upload_path);
- sigint_or_rval_exit:
- if (sigint_raised) {
- (void)xsignal(SIGINT, SIG_DFL);
- raise(SIGINT);
- }
- exit(rval);
- } else if (strchr(argv[0], ':') != NULL
- && ! isipv6addr(argv[0])) {
- rval = auto_fetch(argc, argv);
- if (rval >= 0) /* -1 == connected and cd-ed */
- goto sigint_or_rval_exit;
- } else {
- char *xargv[4], *user, *host;
-
- if ((rval = sigsetjmp(toplevel, 1)))
- goto sigint_or_rval_exit;
- (void)xsignal(SIGINT, intr);
- (void)xsignal(SIGPIPE, lostpeer);
- user = NULL;
- host = argv[0];
- cp = strchr(host, '@');
- if (cp) {
- *cp = '\0';
- user = host;
- host = cp + 1;
- }
- /* XXX discards const */
- xargv[0] = (char *)getprogname();
- xargv[1] = host;
- xargv[2] = argv[1];
- xargv[3] = NULL;
- do {
- int oautologin;
-
- oautologin = autologin;
- if (user != NULL) {
- anonftp = 0;
- autologin = 0;
- }
- setpeer(argc+1, xargv);
- autologin = oautologin;
- if (connected == 1 && user != NULL)
- (void)ftp_login(host, user, NULL);
- if (!retry_connect)
- break;
- if (!connected) {
- macnum = 0;
- fprintf(ttyout,
- "Retrying in %d seconds...\n",
- retry_connect);
- sleep(retry_connect);
- }
- } while (!connected);
- retry_connect = 0; /* connected, stop hiding msgs */
- }
- }
- if (isupload)
- usage();
-
-#ifndef NO_EDITCOMPLETE
- controlediting();
-#endif /* !NO_EDITCOMPLETE */
-
- (void)sigsetjmp(toplevel, 1);
- (void)xsignal(SIGINT, intr);
- (void)xsignal(SIGPIPE, lostpeer);
- for (;;)
- cmdscanner();
-}
-
-/*
- * Generate a prompt
- */
-char *
-prompt(void)
-{
- static char **prompt;
- static char buf[MAXPATHLEN];
-
- if (prompt == NULL) {
- struct option *o;
-
- o = getoption("prompt");
- if (o == NULL)
- errx(1, "no such option `prompt'");
- prompt = &(o->value);
- }
- formatbuf(buf, sizeof(buf), *prompt ? *prompt : DEFAULTPROMPT);
- return (buf);
-}
-
-/*
- * Generate an rprompt
- */
-char *
-rprompt(void)
-{
- static char **rprompt;
- static char buf[MAXPATHLEN];
-
- if (rprompt == NULL) {
- struct option *o;
-
- o = getoption("rprompt");
- if (o == NULL)
- errx(1, "no such option `rprompt'");
- rprompt = &(o->value);
- }
- formatbuf(buf, sizeof(buf), *rprompt ? *rprompt : DEFAULTRPROMPT);
- return (buf);
-}
-
-/*
- * Command parser.
- */
-void
-cmdscanner(void)
-{
- struct cmd *c;
- char *p;
- int num;
-
- for (;;) {
-#ifndef NO_EDITCOMPLETE
- if (!editing) {
-#endif /* !NO_EDITCOMPLETE */
- if (fromatty) {
- fputs(prompt(), ttyout);
- p = rprompt();
- if (*p)
- fprintf(ttyout, "%s ", p);
- (void)fflush(ttyout);
- }
- if (fgets(line, sizeof(line), stdin) == NULL) {
- if (fromatty)
- putc('\n', ttyout);
- quit(0, NULL);
- }
- num = strlen(line);
- if (num == 0)
- break;
- if (line[--num] == '\n') {
- if (num == 0)
- break;
- line[num] = '\0';
- } else if (num == sizeof(line) - 2) {
- fputs("Sorry, input line is too long.\n",
- ttyout);
- while ((num = getchar()) != '\n' && num != EOF)
- /* void */;
- break;
- } /* else it was a line without a newline */
-#ifndef NO_EDITCOMPLETE
- } else {
- const char *buf;
- HistEvent ev;
- cursor_pos = NULL;
-
- buf = el_gets(el, &num);
- if (buf == NULL || num == 0) {
- if (fromatty)
- putc('\n', ttyout);
- quit(0, NULL);
- }
- if (num >= sizeof(line)) {
- fputs("Sorry, input line is too long.\n",
- ttyout);
- break;
- }
- memcpy(line, buf, num);
- if (line[--num] == '\n') {
- line[num] = '\0';
- if (num == 0)
- break;
- }
- history(hist, &ev, H_ENTER, buf);
- }
-#endif /* !NO_EDITCOMPLETE */
-
- makeargv();
- if (margc == 0)
- continue;
- c = getcmd(margv[0]);
- if (c == (struct cmd *)-1) {
- fputs("?Ambiguous command.\n", ttyout);
- continue;
- }
- if (c == NULL) {
-#if !defined(NO_EDITCOMPLETE)
- /*
- * attempt to el_parse() unknown commands.
- * any command containing a ':' would be parsed
- * as "[prog:]cmd ...", and will result in a
- * false positive if prog != "ftp", so treat
- * such commands as invalid.
- */
- if (strchr(margv[0], ':') != NULL ||
- !editing ||
- el_parse(el, margc, (const char **)margv) != 0)
-#endif /* !NO_EDITCOMPLETE */
- fputs("?Invalid command.\n", ttyout);
- continue;
- }
- if (c->c_conn && !connected) {
- fputs("Not connected.\n", ttyout);
- continue;
- }
- confirmrest = 0;
- margv[0] = c->c_name;
- (*c->c_handler)(margc, margv);
- if (bell && c->c_bell)
- (void)putc('\007', ttyout);
- if (c->c_handler != help)
- break;
- }
- (void)xsignal(SIGINT, intr);
- (void)xsignal(SIGPIPE, lostpeer);
-}
-
-struct cmd *
-getcmd(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(void)
-{
- 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();
- xsl_add(marg_sl, argp);
- if (argp == NULL)
- break;
- }
-#ifndef NO_EDITCOMPLETE
- 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 /* !NO_EDITCOMPLETE */
-}
-
-#ifdef NO_EDITCOMPLETE
-#define INC_CHKCURSOR(x) (x)++
-#else /* !NO_EDITCOMPLETE */
-#define INC_CHKCURSOR(x) { (x)++ ; \
- if (x == cursor_pos) { \
- cursor_argc = margc; \
- cursor_argo = ap-argbase; \
- cursor_pos = NULL; \
- } }
-
-#endif /* !NO_EDITCOMPLETE */
-
-/*
- * Parse string into argbuf;
- * implemented with FSM to
- * handle quoting and strings
- */
-char *
-slurpstring(void)
-{
- 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 = NULL;
- break;
- default:
- break;
- }
- return (NULL);
-}
-
-/*
- * Help/usage command.
- * Call each command handler with argc == 0 and argv[0] == name.
- */
-void
-help(int argc, char *argv[])
-{
- struct cmd *c;
- char *nargv[1], *p, *cmd;
- int isusage;
-
- cmd = argv[0];
- isusage = (strcmp(cmd, "usage") == 0);
- if (argc == 0 || (isusage && argc == 1)) {
- fprintf(ttyout, "usage: %s [command [...]]\n", cmd);
- return;
- }
- if (argc == 1) {
- StringList *buf;
-
- buf = xsl_init();
- fprintf(ttyout,
- "%sommands may be abbreviated. Commands are:\n\n",
- proxy ? "Proxy c" : "C");
- for (c = cmdtab; (p = c->c_name) != NULL; c++)
- if (!proxy || c->c_proxy)
- xsl_add(buf, p);
- 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)
- fprintf(ttyout, "?Ambiguous %s command `%s'\n",
- cmd, arg);
- else if (c == NULL)
- fprintf(ttyout, "?Invalid %s command `%s'\n",
- cmd, arg);
- else {
- if (isusage) {
- nargv[0] = c->c_name;
- (*c->c_handler)(0, nargv);
- } else
- fprintf(ttyout, "%-*s\t%s\n", HELPINDENT,
- c->c_name, c->c_help);
- }
- }
-}
-
-struct option *
-getoption(const char *name)
-{
- const char *p;
- struct option *c;
-
- if (name == NULL)
- return (NULL);
- for (c = optiontab; (p = c->name) != NULL; c++) {
- if (strcasecmp(p, name) == 0)
- return (c);
- }
- return (NULL);
-}
-
-char *
-getoptionvalue(const char *name)
-{
- struct option *c;
-
- if (name == NULL)
- errx(1, "getoptionvalue() invoked with NULL name");
- c = getoption(name);
- if (c != NULL)
- return (c->value);
- errx(1, "getoptionvalue() invoked with unknown option `%s'", name);
- /* NOTREACHED */
-}
-
-static void
-setupoption(char *name, char *value, char *defaultvalue)
-{
- char *nargv[3];
- int overbose;
-
- nargv[0] = "setupoption()";
- nargv[1] = name;
- nargv[2] = (value ? value : defaultvalue);
- overbose = verbose;
- verbose = 0;
- setoption(3, nargv);
- verbose = overbose;
-}
-
-void
-usage(void)
-{
- const char *progname = getprogname();
-
- (void)fprintf(stderr,
-"usage: %s [-46AadefginpRtvV] [-N netrc] [-o outfile] [-P port] [-q quittime]\n"
-" [-r retry] [-T dir,max[,inc][[user@]host [port]]] [host:path[/]]\n"
-" [file:///file] [ftp://[user[:pass]@]host[:port]/path[/]]\n"
-" [http://[user[:pass]@]host[:port]/path] [...]\n"
-" %s -u URL file [...]\n", progname, progname);
- exit(1);
-}
diff --git a/contrib/lukemftp/src/progressbar.c b/contrib/lukemftp/src/progressbar.c
deleted file mode 100644
index d0bd35f..0000000
--- a/contrib/lukemftp/src/progressbar.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/* $NetBSD: progressbar.c,v 1.7 2005/04/11 01:49:31 lukem Exp $ */
-
-/*-
- * Copyright (c) 1997-2003 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__RCSID("$NetBSD: progressbar.c,v 1.7 2005/04/11 01:49:31 lukem Exp $");
-#endif /* not lint */
-
-/*
- * FTP User Program -- Misc support routines
- */
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-
-#include <err.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "progressbar.h"
-
-#define SECSPERHOUR (60 * 60)
-#define SECSPERDAY ((long)60 * 60 * 24)
-
-#if !defined(NO_PROGRESS)
-/*
- * return non-zero if we're the current foreground process
- */
-int
-foregroundproc(void)
-{
- static pid_t pgrp = -1;
-
- if (pgrp == -1)
- pgrp = getpgrp();
-
- return (tcgetpgrp(fileno(ttyout)) == pgrp);
-}
-#endif /* !defined(NO_PROGRESS) */
-
-
-static void updateprogressmeter(int);
-
-/*
- * SIGALRM handler to update the progress meter
- */
-static void
-updateprogressmeter(int dummy)
-{
- int oerrno = errno;
-
- progressmeter(0);
- errno = oerrno;
-}
-
-/*
- * List of order of magnitude prefixes.
- * The last is `P', as 2^64 = 16384 Petabytes
- */
-static const char prefixes[] = " KMGTP";
-
-/*
- * 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;
-static struct timeval lastupdate;
-
-#define BUFLEFT (sizeof(buf) - len)
-
-void
-progressmeter(int flag)
-{
- static off_t lastsize;
- off_t cursize;
- struct timeval now, wait;
-#ifndef NO_PROGRESS
- struct timeval td;
- off_t abbrevsize, bytespersec;
- double elapsed;
- int ratio, barlength, i, remaining;
-
- /*
- * Work variables for progress bar.
- *
- * XXX: if the format of the progress bar changes
- * (especially the number of characters in the
- * `static' portion of it), be sure to update
- * these appropriately.
- */
-#endif
- int len;
- char buf[256]; /* workspace for progress bar */
-#ifndef NO_PROGRESS
-#define BAROVERHEAD 43 /* non `*' portion of progress bar */
- /*
- * stars should contain at least
- * sizeof(buf) - BAROVERHEAD entries
- */
- static const char stars[] =
-"*****************************************************************************"
-"*****************************************************************************"
-"*****************************************************************************";
-
-#endif
-
- if (flag == -1) {
- (void)gettimeofday(&start, NULL);
- lastupdate = start;
- lastsize = restart_point;
- }
-
- (void)gettimeofday(&now, NULL);
- cursize = bytes + restart_point;
- timersub(&now, &lastupdate, &wait);
- if (cursize > lastsize) {
- lastupdate = now;
- lastsize = cursize;
- wait.tv_sec = 0;
- } else {
-#ifndef STANDALONE_PROGRESS
- if (quit_time > 0 && wait.tv_sec > quit_time) {
- len = snprintf(buf, sizeof(buf), "\r\n%s: "
- "transfer aborted because stalled for %lu sec.\r\n",
- getprogname(), (unsigned long)wait.tv_sec);
- (void)write(fileno(ttyout), buf, len);
- (void)xsignal(SIGALRM, SIG_DFL);
- alarmtimer(0);
- siglongjmp(toplevel, 1);
- }
-#endif /* !STANDALONE_PROGRESS */
- }
- /*
- * Always set the handler even if we are not the foreground process.
- */
-#ifdef STANDALONE_PROGRESS
- if (progress) {
-#else
- if (quit_time > 0 || progress) {
-#endif /* !STANDALONE_PROGRESS */
- if (flag == -1) {
- (void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
- alarmtimer(1); /* set alarm timer for 1 Hz */
- } else if (flag == 1) {
- (void)xsignal(SIGALRM, SIG_DFL);
- alarmtimer(0);
- }
- }
-#ifndef NO_PROGRESS
- if (!progress)
- return;
- len = 0;
-
- /*
- * print progress bar only if we are foreground process.
- */
- if (! foregroundproc())
- return;
-
- len += snprintf(buf + len, BUFLEFT, "\r");
- if (prefix)
- len += snprintf(buf + len, BUFLEFT, "%s", prefix);
- if (filesize > 0) {
- ratio = (int)((double)cursize * 100.0 / (double)filesize);
- ratio = MAX(ratio, 0);
- ratio = MIN(ratio, 100);
- len += snprintf(buf + len, BUFLEFT, "%3d%% ", ratio);
-
- /*
- * calculate the length of the `*' bar, ensuring that
- * the number of stars won't exceed the buffer size
- */
- barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
- if (prefix)
- barlength -= strlen(prefix);
- if (barlength > 0) {
- i = barlength * ratio / 100;
- len += snprintf(buf + len, BUFLEFT,
- "|%.*s%*s|", i, stars, barlength - i, "");
- }
- }
-
- abbrevsize = cursize;
- for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++)
- abbrevsize >>= 10;
- len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ",
- (LLT)abbrevsize,
- prefixes[i],
- i == 0 ? ' ' : 'B');
-
- timersub(&now, &start, &td);
- elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
-
- bytespersec = 0;
- if (bytes > 0) {
- bytespersec = bytes;
- if (elapsed > 0.0)
- bytespersec /= elapsed;
- }
- for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
- bytespersec >>= 10;
- len += snprintf(buf + len, BUFLEFT,
- " " LLFP("3") ".%02d %cB/s ",
- (LLT)(bytespersec / 1024),
- (int)((bytespersec % 1024) * 100 / 1024),
- prefixes[i]);
-
- if (filesize > 0) {
- if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
- len += snprintf(buf + len, BUFLEFT, " --:-- ETA");
- } else if (wait.tv_sec >= STALLTIME) {
- len += snprintf(buf + len, BUFLEFT, " - stalled -");
- } else {
- remaining = (int)
- ((filesize - restart_point) / (bytes / elapsed) -
- elapsed);
- if (remaining >= 100 * SECSPERHOUR)
- len += snprintf(buf + len, BUFLEFT,
- " --:-- ETA");
- else {
- i = remaining / SECSPERHOUR;
- if (i)
- len += snprintf(buf + len, BUFLEFT,
- "%2d:", i);
- else
- len += snprintf(buf + len, BUFLEFT,
- " ");
- i = remaining % SECSPERHOUR;
- len += snprintf(buf + len, BUFLEFT,
- "%02d:%02d ETA", i / 60, i % 60);
- }
- }
- }
- if (flag == 1)
- len += snprintf(buf + len, BUFLEFT, "\n");
- (void)write(fileno(ttyout), buf, len);
-
-#endif /* !NO_PROGRESS */
-}
-
-#ifndef STANDALONE_PROGRESS
-/*
- * 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 ttyout.
- */
-void
-ptransfer(int siginfo)
-{
- struct timeval now, td, wait;
- double elapsed;
- off_t bytespersec;
- int remaining, hh, i, len;
-
- char buf[256]; /* Work variable for transfer status. */
-
- if (!verbose && !progress && !siginfo)
- return;
-
- (void)gettimeofday(&now, NULL);
- timersub(&now, &start, &td);
- elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
- bytespersec = 0;
- if (bytes > 0) {
- bytespersec = bytes;
- if (elapsed > 0.0)
- bytespersec /= elapsed;
- }
- len = 0;
- len += snprintf(buf + len, BUFLEFT, LLF " byte%s %s in ",
- (LLT)bytes, bytes == 1 ? "" : "s", direction);
- remaining = (int)elapsed;
- if (remaining > SECSPERDAY) {
- int days;
-
- days = remaining / SECSPERDAY;
- remaining %= SECSPERDAY;
- len += snprintf(buf + len, BUFLEFT,
- "%d day%s ", days, days == 1 ? "" : "s");
- }
- hh = remaining / SECSPERHOUR;
- remaining %= SECSPERHOUR;
- if (hh)
- len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
- len += snprintf(buf + len, BUFLEFT,
- "%02d:%02d ", remaining / 60, remaining % 60);
-
- for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
- bytespersec >>= 10;
- len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)",
- (LLT)(bytespersec / 1024),
- (int)((bytespersec % 1024) * 100 / 1024),
- prefixes[i]);
-
- 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 += snprintf(buf + len, BUFLEFT, " ETA: ");
- if (hh)
- len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
- len += snprintf(buf + len, BUFLEFT, "%02d:%02d",
- remaining / 60, remaining % 60);
- timersub(&now, &lastupdate, &wait);
- if (wait.tv_sec >= STALLTIME)
- len += snprintf(buf + len, BUFLEFT, " (stalled)");
- }
- len += snprintf(buf + len, BUFLEFT, "\n");
- (void)write(siginfo ? STDERR_FILENO : fileno(ttyout), buf, len);
-}
-
-/*
- * SIG{INFO,QUIT} handler to print transfer stats if a transfer is in progress
- */
-void
-psummary(int notused)
-{
- int oerrno = errno;
-
- if (bytes > 0) {
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- ptransfer(1);
- }
- errno = oerrno;
-}
-#endif /* !STANDALONE_PROGRESS */
-
-
-/*
- * Set the SIGALRM interval timer for wait seconds, 0 to disable.
- */
-void
-alarmtimer(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);
-}
-
-
-/*
- * Install a POSIX signal handler, allowing the invoker to set whether
- * the signal should be restartable or not
- */
-sigfunc
-xsignal_restart(int sig, sigfunc func, int restartable)
-{
- struct sigaction act, oact;
- act.sa_handler = func;
-
- sigemptyset(&act.sa_mask);
-#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */
- act.sa_flags = restartable ? SA_RESTART : 0;
-#elif defined(SA_INTERRUPT) /* SunOS 4.x */
- act.sa_flags = restartable ? 0 : SA_INTERRUPT;
-#else
-#error "system must have SA_RESTART or SA_INTERRUPT"
-#endif
- if (sigaction(sig, &act, &oact) < 0)
- return (SIG_ERR);
- return (oact.sa_handler);
-}
-
-/*
- * Install a signal handler with the `restartable' flag set dependent upon
- * which signal is being set. (This is a wrapper to xsignal_restart())
- */
-sigfunc
-xsignal(int sig, sigfunc func)
-{
- int restartable;
-
- /*
- * Some signals print output or change the state of the process.
- * There should be restartable, so that reads and writes are
- * not affected. Some signals should cause program flow to change;
- * these signals should not be restartable, so that the system call
- * will return with EINTR, and the program will go do something
- * different. If the signal handler calls longjmp() or siglongjmp(),
- * it doesn't matter if it's restartable.
- */
-
- switch(sig) {
-#ifdef SIGINFO
- case SIGINFO:
-#endif
- case SIGQUIT:
- case SIGUSR1:
- case SIGUSR2:
- case SIGWINCH:
- restartable = 1;
- break;
-
- case SIGALRM:
- case SIGINT:
- case SIGPIPE:
- restartable = 0;
- break;
-
- default:
- /*
- * This is unpleasant, but I don't know what would be better.
- * Right now, this "can't happen"
- */
- errx(1, "xsignal_restart called with signal %d", sig);
- }
-
- return(xsignal_restart(sig, func, restartable));
-}
diff --git a/contrib/lukemftp/src/progressbar.h b/contrib/lukemftp/src/progressbar.h
deleted file mode 100644
index 9e004f4..0000000
--- a/contrib/lukemftp/src/progressbar.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* $NetBSD: progressbar.h,v 1.5 2005/02/10 16:00:38 jmc Exp $ */
-
-/*-
- * Copyright (c) 1996-2003 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 STANDALONE_PROGRESS
-#include <setjmp.h>
-#endif /* !STANDALONE_PROGRESS */
-
-#ifndef GLOBAL
-#define GLOBAL extern
-#endif
-
-
-#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */
-
-typedef void (*sigfunc)(int);
-
-
-GLOBAL FILE *ttyout; /* stdout, or stderr if retrieving to stdout */
-
-GLOBAL int progress; /* display transfer progress bar */
-GLOBAL int ttywidth; /* width of tty */
-
-GLOBAL off_t bytes; /* current # of bytes read */
-GLOBAL off_t filesize; /* size of file being transferred */
-GLOBAL off_t restart_point; /* offset to restart transfer */
-GLOBAL char *prefix; /* Text written left of progress bar */
-
-
-#ifndef STANDALONE_PROGRESS
-GLOBAL int fromatty; /* input is from a terminal */
-GLOBAL int verbose; /* print messages coming back from server */
-GLOBAL int quit_time; /* maximum time to wait if stalled */
-
-GLOBAL char *direction; /* direction transfer is occurring */
-
-GLOBAL sigjmp_buf toplevel; /* non-local goto stuff for cmd scanner */
-#endif /* !STANDALONE_PROGRESS */
-
-int foregroundproc(void);
-void alarmtimer(int);
-void progressmeter(int);
-sigfunc xsignal(int, sigfunc);
-sigfunc xsignal_restart(int, sigfunc, int);
-
-#ifndef STANDALONE_PROGRESS
-void psummary(int);
-void ptransfer(int);
-#endif /* !STANDALONE_PROGRESS */
-
-#ifdef NO_LONG_LONG
-# define LLF "%ld"
-# define LLFP(x) "%" x "ld"
-# define LLT long
-# define ULLF "%lu"
-# define ULLFP(x) "%" x "lu"
-# define ULLT unsigned long
-#else
-# define LLF "%lld"
-# define LLFP(x) "%" x "lld"
-# define LLT long long
-# define ULLF "%llu"
-# define ULLFP(x) "%" x "llu"
-# define ULLT unsigned long long
-#endif
diff --git a/contrib/lukemftp/src/ruserpass.c b/contrib/lukemftp/src/ruserpass.c
deleted file mode 100644
index 9cb318a..0000000
--- a/contrib/lukemftp/src/ruserpass.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* $NetBSD: ruserpass.c,v 1.29 2003/08/07 11:13:57 agc 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. 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("$NetBSD: ruserpass.c,v 1.29 2003/08/07 11:13:57 agc Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/stat.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>
-
-#include "ftp_var.h"
-
-static int token(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(const char *host, const char **aname, const char **apass,
- const char **aacct)
-{
- char *tmp;
- char myname[MAXHOSTNAMELEN + 1], *mydomain;
- int t, i, c, usedefault = 0;
- struct stat stb;
-
- if (netrc[0] == '\0')
- return (0);
- cfile = fopen(netrc, "r");
- if (cfile == NULL) {
- if (errno != ENOENT)
- warn("%s", netrc);
- return (0);
- }
- if (gethostname(myname, sizeof(myname)) < 0)
- myname[0] = '\0';
- myname[sizeof(myname) - 1] = '\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 = xstrdup(tokval);
- 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 = xstrdup(tokval);
- 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 = xstrdup(tokval);
- 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') {
- fputs("Missing macdef name argument.\n",
- ttyout);
- goto bad;
- }
- if (macnum == 16) {
- fputs(
- "Limit of 16 macros have already been defined.\n",
- ttyout);
- goto bad;
- }
- tmp = macros[macnum].mac_name;
- *tmp++ = c;
- for (i = 0; i < 8 && (c = getc(cfile)) != EOF &&
- !isspace(c); ++i) {
- *tmp++ = c;
- }
- if (c == EOF) {
- fputs(
- "Macro definition missing null line terminator.\n",
- ttyout);
- goto bad;
- }
- *tmp = '\0';
- if (c != '\n') {
- while ((c = getc(cfile)) != EOF && c != '\n');
- }
- if (c == EOF) {
- fputs(
- "Macro definition missing null line terminator.\n",
- ttyout);
- 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) {
- fputs(
- "Macro definition missing null line terminator.\n",
- ttyout);
- 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) {
- fputs("4K macro buffer exceeded.\n",
- ttyout);
- 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(void)
-{
- 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/contrib/lukemftp/src/util.c b/contrib/lukemftp/src/util.c
deleted file mode 100644
index 6f94bb0..0000000
--- a/contrib/lukemftp/src/util.c
+++ /dev/null
@@ -1,1400 +0,0 @@
-/* $NetBSD: util.c,v 1.123 2005/05/14 18:56:45 dsl Exp $ */
-
-/*-
- * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Luke Mewburn.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center.
- *
- * 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.
- */
-
-/*
- * 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. 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("$NetBSD: util.c,v 1.123 2005/05/14 18:56:45 dsl Exp $");
-#endif /* not lint */
-
-/*
- * FTP User Program -- Misc support routines
- */
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <arpa/ftp.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <glob.h>
-#include <signal.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "ftp_var.h"
-
-#define TM_YEAR_BASE 1900
-
-/*
- * Connect to peer server and auto-login, if possible.
- */
-void
-setpeer(int argc, char *argv[])
-{
- char *host;
- char *port;
-
- if (argc == 0)
- goto usage;
- if (connected) {
- fprintf(ttyout, "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) {
- usage:
- fprintf(ttyout, "usage: %s host-name [port]\n", argv[0]);
- code = -1;
- return;
- }
- if (gatemode)
- port = gateport;
- else
- port = ftpport;
- if (argc > 2)
- port = 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) {
- if (gatemode && verbose) {
- fprintf(ttyout,
- "Connecting via pass-through server %s\n",
- gateserver);
- }
-
- connected = 1;
- /*
- * Set up defaults for FTP.
- */
- (void)strlcpy(typename, "ascii", sizeof(typename));
- type = TYPE_A;
- curtype = TYPE_A;
- (void)strlcpy(formname, "non-print", sizeof(formname));
- form = FORM_N;
- (void)strlcpy(modename, "stream", sizeof(modename));
- mode = MODE_S;
- (void)strlcpy(structname, "file", sizeof(structname));
- stru = STRU_F;
- (void)strlcpy(bytename, "8", sizeof(bytename));
- bytesize = 8;
- if (autologin)
- (void)ftp_login(argv[1], NULL, NULL);
- }
-}
-
-static void
-parse_feat(const char *line)
-{
-
- /*
- * work-around broken ProFTPd servers that can't
- * even obey RFC 2389.
- */
- while (*line && isspace((int)*line))
- line++;
-
- if (strcasecmp(line, "MDTM") == 0)
- features[FEAT_MDTM] = 1;
- else if (strncasecmp(line, "MLST", sizeof("MLST") - 1) == 0) {
- features[FEAT_MLST] = 1;
- } else if (strcasecmp(line, "REST STREAM") == 0)
- features[FEAT_REST_STREAM] = 1;
- else if (strcasecmp(line, "SIZE") == 0)
- features[FEAT_SIZE] = 1;
- else if (strcasecmp(line, "TVFS") == 0)
- features[FEAT_TVFS] = 1;
-}
-
-/*
- * Determine the remote system type (SYST) and features (FEAT).
- * Call after a successful login (i.e, connected = -1)
- */
-void
-getremoteinfo(void)
-{
- int overbose, i;
-
- overbose = verbose;
- if (debug == 0)
- verbose = -1;
-
- /* determine remote system type */
- if (command("SYST") == COMPLETE) {
- if (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';
- }
-
- fprintf(ttyout, "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)strlcpy(typename, "binary", sizeof(typename));
- if (overbose)
- fprintf(ttyout,
- "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))
- fputs(
-"Remember to set tenex mode when transferring binary files from this machine.\n",
- ttyout);
- }
- }
-
- /* determine features (if any) */
- for (i = 0; i < FEAT_max; i++)
- features[i] = -1;
- reply_callback = parse_feat;
- if (command("FEAT") == COMPLETE) {
- for (i = 0; i < FEAT_max; i++) {
- if (features[i] == -1)
- features[i] = 0;
- }
- features[FEAT_FEAT] = 1;
- } else
- features[FEAT_FEAT] = 0;
- if (debug) {
-#define DEBUG_FEAT(x) fprintf(ttyout, "features[" #x "] = %d\n", features[(x)])
- DEBUG_FEAT(FEAT_FEAT);
- DEBUG_FEAT(FEAT_MDTM);
- DEBUG_FEAT(FEAT_MLST);
- DEBUG_FEAT(FEAT_REST_STREAM);
- DEBUG_FEAT(FEAT_SIZE);
- DEBUG_FEAT(FEAT_TVFS);
-#undef DEBUG_FEAT
- }
- reply_callback = NULL;
-
- verbose = overbose;
-}
-
-/*
- * Reset the various variables that indicate connection state back to
- * disconnected settings.
- * The caller is responsible for issuing any commands to the remote server
- * to perform a clean shutdown before this is invoked.
- */
-void
-cleanuppeer(void)
-{
-
- if (cout)
- (void)fclose(cout);
- cout = NULL;
- connected = 0;
- unix_server = 0;
- unix_proxy = 0;
- /*
- * determine if anonftp was specifically set with -a
- * (1), or implicitly set by auto_fetch() (2). in the
- * latter case, disable after the current xfer
- */
- if (anonftp == 2)
- anonftp = 0;
- data = -1;
- epsv4bad = 0;
- if (username)
- free(username);
- username = NULL;
- if (!proxy)
- macnum = 0;
-}
-
-/*
- * Top-level signal handler for interrupted commands.
- */
-void
-intr(int signo)
-{
-
- sigint_raised = 1;
- alarmtimer(0);
- if (fromatty)
- write(fileno(ttyout), "\n", 1);
- siglongjmp(toplevel, 1);
-}
-
-/*
- * Signal handler for lost connections; cleanup various elements of
- * the connection state, and call cleanuppeer() to finish it off.
- */
-void
-lostpeer(int dummy)
-{
- int oerrno = errno;
-
- 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);
- cleanuppeer();
- errno = oerrno;
-}
-
-
-/*
- * Login to remote host, using given username & password if supplied.
- * Return non-zero if successful.
- */
-int
-ftp_login(const char *host, const char *user, const char *pass)
-{
- char tmp[80];
- const char *acct;
- int n, aflag, rval, freeuser, freepass, freeacct;
-
- acct = NULL;
- aflag = rval = freeuser = freepass = freeacct = 0;
-
- if (debug)
- fprintf(ttyout, "ftp_login: user `%s' pass `%s' host `%s'\n",
- user ? user : "<null>", pass ? pass : "<null>",
- host ? host : "<null>");
-
-
- /*
- * Set up arguments for an anonymous FTP session, if necessary.
- */
- if (anonftp) {
- user = "anonymous"; /* as per RFC 1635 */
- pass = getoptionvalue("anonpass");
- }
-
- if (user == NULL)
- freeuser = 1;
- if (pass == NULL)
- freepass = 1;
- freeacct = 1;
- if (ruserpass(host, &user, &pass, &acct) < 0) {
- code = -1;
- goto cleanup_ftp_login;
- }
-
- while (user == NULL) {
- if (localname)
- fprintf(ttyout, "Name (%s:%s): ", host, localname);
- else
- fprintf(ttyout, "Name (%s): ", host);
- *tmp = '\0';
- if (fgets(tmp, sizeof(tmp) - 1, stdin) == NULL) {
- fprintf(ttyout, "\nEOF received; login aborted.\n");
- clearerr(stdin);
- code = -1;
- goto cleanup_ftp_login;
- }
- tmp[strlen(tmp) - 1] = '\0';
- freeuser = 0;
- if (*tmp == '\0')
- user = localname;
- else
- user = tmp;
- }
-
- if (gatemode) {
- char *nuser;
- int len;
-
- len = strlen(user) + 1 + strlen(host) + 1;
- nuser = xmalloc(len);
- (void)strlcpy(nuser, user, len);
- (void)strlcat(nuser, "@", len);
- (void)strlcat(nuser, host, len);
- freeuser = 1;
- user = nuser;
- }
-
- n = command("USER %s", user);
- if (n == CONTINUE) {
- if (pass == NULL) {
- freepass = 0;
- pass = getpass("Password:");
- }
- n = command("PASS %s", pass);
- }
- if (n == CONTINUE) {
- aflag++;
- if (acct == NULL) {
- freeacct = 0;
- acct = getpass("Account:");
- }
- if (acct[0] == '\0') {
- warnx("Login failed.");
- goto cleanup_ftp_login;
- }
- n = command("ACCT %s", acct);
- }
- if ((n != COMPLETE) ||
- (!aflag && acct != NULL && command("ACCT %s", acct) != COMPLETE)) {
- warnx("Login failed.");
- goto cleanup_ftp_login;
- }
- rval = 1;
- username = xstrdup(user);
- if (proxy)
- goto cleanup_ftp_login;
-
- connected = -1;
- getremoteinfo();
- for (n = 0; n < macnum; ++n) {
- if (!strcmp("init", macros[n].mac_name)) {
- (void)strlcpy(line, "$init", sizeof(line));
- makeargv();
- domacro(margc, margv);
- break;
- }
- }
- updatelocalcwd();
- updateremotecwd();
-
- cleanup_ftp_login:
- if (user != NULL && freeuser)
- free((char *)user);
- if (pass != NULL && freepass)
- free((char *)pass);
- if (acct != NULL && freeacct)
- free((char *)acct);
- return (rval);
-}
-
-/*
- * `another' gets another argument, and stores the new argc and argv.
- * It reverts to the top level (via intr()) on EOF/error.
- *
- * Returns false if no new arguments have been added.
- */
-int
-another(int *pargc, char ***pargv, const char *prompt)
-{
- int len = strlen(line), ret;
-
- if (len >= sizeof(line) - 3) {
- fputs("sorry, arguments too long.\n", ttyout);
- intr(0);
- }
- fprintf(ttyout, "(%s) ", prompt);
- line[len++] = ' ';
- if (fgets(&line[len], sizeof(line) - len, stdin) == NULL) {
- clearerr(stdin);
- intr(0);
- }
- 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(char *argv[], int doswitch, char **errbuf)
-{
- char temp[MAXPATHLEN];
- static char buf[MAXPATHLEN];
- static FILE *ftemp = NULL;
- static char **args;
- int oldverbose, oldhash, oldprogress, fd, len;
- char *cp, *mode;
-
- if (!mflag || !connected) {
- 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) {
- len = strlcpy(temp, tmpdir, sizeof(temp));
- if (temp[len - 1] != '/')
- (void)strlcat(temp, "/", sizeof(temp));
- (void)strlcat(temp, TMPFILE, sizeof(temp));
- 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;
- oldprogress = progress;
- hash = 0;
- progress = 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;
- progress = oldprogress;
- ftemp = fopen(temp, "r");
- (void)unlink(temp);
- if (ftemp == NULL) {
- if (errbuf == NULL)
- fputs(
- "can't find list of remote files, oops.\n",
- ttyout);
- 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);
-}
-
-/*
- * 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.
- * Returns NULL on error, or a pointer to a buffer containing the filename
- * that's the caller's responsiblity to free(3) when finished with.
- */
-char *
-globulize(const char *pattern)
-{
- glob_t gl;
- int flags;
- char *p;
-
- if (!doglob)
- return (xstrdup(pattern));
-
- flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
- memset(&gl, 0, sizeof(gl));
- if (glob(pattern, flags, NULL, &gl) || gl.gl_pathc == 0) {
- warnx("%s: not found", pattern);
- globfree(&gl);
- return (NULL);
- }
- p = xstrdup(gl.gl_pathv[0]);
- globfree(&gl);
- return (p);
-}
-
-/*
- * determine size of remote file
- */
-off_t
-remotesize(const char *file, int noisy)
-{
- int overbose, r;
- off_t size;
-
- overbose = verbose;
- size = -1;
- if (debug == 0)
- verbose = -1;
- if (! features[FEAT_SIZE]) {
- if (noisy)
- fprintf(ttyout,
- "SIZE is not supported by remote server.\n");
- goto cleanup_remotesize;
- }
- r = command("SIZE %s", file);
- if (r == COMPLETE) {
- char *cp, *ep;
-
- cp = strchr(reply_string, ' ');
- if (cp != NULL) {
- cp++;
- size = STRTOLL(cp, &ep, 10);
- if (*ep != '\0' && !isspace((unsigned char)*ep))
- size = -1;
- }
- } else {
- if (r == ERROR && code == 500 && features[FEAT_SIZE] == -1)
- features[FEAT_SIZE] = 0;
- if (noisy && debug == 0) {
- fputs(reply_string, ttyout);
- putc('\n', ttyout);
- }
- }
- cleanup_remotesize:
- verbose = overbose;
- return (size);
-}
-
-/*
- * determine last modification time (in GMT) of remote file
- */
-time_t
-remotemodtime(const char *file, int noisy)
-{
- int overbose, ocode, r;
- time_t rtime;
-
- overbose = verbose;
- ocode = code;
- rtime = -1;
- if (debug == 0)
- verbose = -1;
- if (! features[FEAT_MDTM]) {
- if (noisy)
- fprintf(ttyout,
- "MDTM is not supported by remote server.\n");
- goto cleanup_parse_time;
- }
- r = command("MDTM %s", file);
- if (r == COMPLETE) {
- struct tm timebuf;
- char *timestr, *frac;
- int yy, mo, day, hour, min, sec;
-
- /*
- * time-val = 14DIGIT [ "." 1*DIGIT ]
- * YYYYMMDDHHMMSS[.sss]
- * mdtm-response = "213" SP time-val CRLF / error-response
- */
- timestr = reply_string + 4;
-
- /*
- * parse fraction.
- * XXX: ignored for now
- */
- frac = strchr(timestr, '\r');
- if (frac != NULL)
- *frac = '\0';
- frac = strchr(timestr, '.');
- if (frac != NULL)
- *frac++ = '\0';
- if (strlen(timestr) == 15 && strncmp(timestr, "191", 3) == 0) {
- /*
- * XXX: Workaround for lame ftpd's that return
- * `19100' instead of `2000'
- */
- fprintf(ttyout,
- "Y2K warning! Incorrect time-val `%s' received from server.\n",
- timestr);
- timestr++;
- timestr[0] = '2';
- timestr[1] = '0';
- fprintf(ttyout, "Converted to `%s'\n", timestr);
- }
- if (strlen(timestr) != 14 ||
- sscanf(timestr, "%04d%02d%02d%02d%02d%02d",
- &yy, &mo, &day, &hour, &min, &sec) != 6) {
- bad_parse_time:
- fprintf(ttyout, "Can't parse time `%s'.\n", timestr);
- goto cleanup_parse_time;
- }
- memset(&timebuf, 0, sizeof(timebuf));
- timebuf.tm_sec = sec;
- timebuf.tm_min = min;
- timebuf.tm_hour = hour;
- timebuf.tm_mday = day;
- timebuf.tm_mon = mo - 1;
- timebuf.tm_year = yy - TM_YEAR_BASE;
- timebuf.tm_isdst = -1;
- rtime = timegm(&timebuf);
- if (rtime == -1) {
- if (noisy || debug != 0)
- goto bad_parse_time;
- else
- goto cleanup_parse_time;
- } else if (debug)
- fprintf(ttyout, "parsed date as: %s", ctime(&rtime));
- } else {
- if (r == ERROR && code == 500 && features[FEAT_MDTM] == -1)
- features[FEAT_MDTM] = 0;
- if (noisy && debug == 0) {
- fputs(reply_string, ttyout);
- putc('\n', ttyout);
- }
- }
- cleanup_parse_time:
- verbose = overbose;
- if (rtime == -1)
- code = ocode;
- return (rtime);
-}
-
-/*
- * Update global `localcwd', which contains the state of the local cwd
- */
-void
-updatelocalcwd(void)
-{
-
- if (getcwd(localcwd, sizeof(localcwd)) == NULL)
- localcwd[0] = '\0';
- if (debug)
- fprintf(ttyout, "got localcwd as `%s'\n", localcwd);
-}
-
-/*
- * Update global `remotecwd', which contains the state of the remote cwd
- */
-void
-updateremotecwd(void)
-{
- int overbose, ocode, i;
- char *cp;
-
- overbose = verbose;
- ocode = code;
- if (debug == 0)
- verbose = -1;
- if (command("PWD") != COMPLETE)
- goto badremotecwd;
- cp = strchr(reply_string, ' ');
- if (cp == NULL || cp[0] == '\0' || cp[1] != '"')
- goto badremotecwd;
- cp += 2;
- for (i = 0; *cp && i < sizeof(remotecwd) - 1; i++, cp++) {
- if (cp[0] == '"') {
- if (cp[1] == '"')
- cp++;
- else
- break;
- }
- remotecwd[i] = *cp;
- }
- remotecwd[i] = '\0';
- if (debug)
- fprintf(ttyout, "got remotecwd as `%s'\n", remotecwd);
- goto cleanupremotecwd;
- badremotecwd:
- remotecwd[0]='\0';
- cleanupremotecwd:
- verbose = overbose;
- code = ocode;
-}
-
-/*
- * Ensure file is in or under dir.
- * Returns 1 if so, 0 if not (or an error occurred).
- */
-int
-fileindir(const char *file, const char *dir)
-{
- char realfile[PATH_MAX+1];
- size_t dirlen;
-
- if (realpath(file, realfile) == NULL) {
- warn("Unable to determine real path of `%s'", file);
- return 0;
- }
- if (realfile[0] != '/') /* relative result */
- return 1;
- dirlen = strlen(dir);
-#if 0
-printf("file %s realfile %s dir %s [%d]\n", file, realfile, dir, dirlen);
-#endif
- if (strncmp(realfile, dir, dirlen) == 0 && realfile[dirlen] == '/')
- return 1;
- return 0;
-}
-
-/*
- * List words in stringlist, vertically arranged
- */
-void
-list_vertical(StringList *sl)
-{
- int i, j, w;
- int columns, width, lines;
- char *p;
-
- width = 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, ttyout);
- if (j * lines + i + lines >= sl->sl_cur) {
- putc('\n', ttyout);
- break;
- }
- w = strlen(p);
- while (w < width) {
- w = (w + 8) &~ 7;
- (void)putc('\t', ttyout);
- }
- }
- }
-}
-
-/*
- * Update the global ttywidth value, using TIOCGWINSZ.
- */
-void
-setttywidth(int a)
-{
- struct winsize winsize;
- int oerrno = errno;
-
- if (ioctl(fileno(ttyout), TIOCGWINSZ, &winsize) != -1 &&
- winsize.ws_col != 0)
- ttywidth = winsize.ws_col;
- else
- ttywidth = 80;
- errno = oerrno;
-}
-
-/*
- * Change the rate limit up (SIGUSR1) or down (SIGUSR2)
- */
-void
-crankrate(int sig)
-{
-
- switch (sig) {
- case SIGUSR1:
- if (rate_get)
- rate_get += rate_get_incr;
- if (rate_put)
- rate_put += rate_put_incr;
- break;
- case SIGUSR2:
- if (rate_get && rate_get > rate_get_incr)
- rate_get -= rate_get_incr;
- if (rate_put && rate_put > rate_put_incr)
- rate_put -= rate_put_incr;
- break;
- default:
- err(1, "crankrate invoked with unknown signal: %d", sig);
- }
-}
-
-
-/*
- * Setup or cleanup EditLine structures
- */
-#ifndef NO_EDITCOMPLETE
-void
-controlediting(void)
-{
- if (editing && el == NULL && hist == NULL) {
- HistEvent ev;
- int editmode;
-
- el = el_init(getprogname(), stdin, ttyout, stderr);
- /* init editline */
- hist = history_init(); /* init the builtin history */
- history(hist, &ev, H_SETSIZE, 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 functions */
- el_set(el, EL_RPROMPT, rprompt);
-
- /* 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 */
- if ((el_get(el, EL_EDITMODE, &editmode) != -1) && editmode == 0)
- editing = 0; /* the user doesn't want editing,
- * so disable, and let statement
- * below cleanup */
- else
- el_set(el, EL_SIGNAL, 1);
- }
- if (!editing) {
- if (hist) {
- history_end(hist);
- hist = NULL;
- }
- if (el) {
- el_end(el);
- el = NULL;
- }
- }
-}
-#endif /* !NO_EDITCOMPLETE */
-
-/*
- * Convert the string `arg' to an int, which may have an optional SI suffix
- * (`b', `k', `m', `g'). Returns the number for success, -1 otherwise.
- */
-int
-strsuftoi(const char *arg)
-{
- char *cp;
- long val;
-
- if (!isdigit((unsigned char)arg[0]))
- return (-1);
-
- val = strtol(arg, &cp, 10);
- if (cp != NULL) {
- if (cp[0] != '\0' && cp[1] != '\0')
- return (-1);
- switch (tolower((unsigned char)cp[0])) {
- case '\0':
- case 'b':
- break;
- case 'k':
- val <<= 10;
- break;
- case 'm':
- val <<= 20;
- break;
- case 'g':
- val <<= 30;
- break;
- default:
- return (-1);
- }
- }
- if (val < 0 || val > INT_MAX)
- return (-1);
-
- return (val);
-}
-
-/*
- * Set up socket buffer sizes before a connection is made.
- */
-void
-setupsockbufsize(int sock)
-{
-
- if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
- (void *)&sndbuf_size, sizeof(sndbuf_size)) == -1)
- warn("unable to set sndbuf size %d", sndbuf_size);
-
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
- (void *)&rcvbuf_size, sizeof(rcvbuf_size)) == -1)
- warn("unable to set rcvbuf size %d", rcvbuf_size);
-}
-
-/*
- * Copy characters from src into dst, \ quoting characters that require it
- */
-void
-ftpvis(char *dst, size_t dstlen, const char *src, size_t srclen)
-{
- int di, si;
-
- for (di = si = 0;
- src[si] != '\0' && di < dstlen && si < srclen;
- di++, si++) {
- switch (src[si]) {
- case '\\':
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- case '"':
- dst[di++] = '\\';
- if (di >= dstlen)
- break;
- /* FALLTHROUGH */
- default:
- dst[di] = src[si];
- }
- }
- dst[di] = '\0';
-}
-
-/*
- * Copy src into buf (which is len bytes long), expanding % sequences.
- */
-void
-formatbuf(char *buf, size_t len, const char *src)
-{
- const char *p;
- char *p2, *q;
- int i, op, updirs, pdirs;
-
-#define ADDBUF(x) do { \
- if (i >= len - 1) \
- goto endbuf; \
- buf[i++] = (x); \
- } while (0)
-
- p = src;
- for (i = 0; *p; p++) {
- if (*p != '%') {
- ADDBUF(*p);
- continue;
- }
- p++;
-
- switch (op = *p) {
-
- case '/':
- case '.':
- case 'c':
- p2 = connected ? remotecwd : "";
- updirs = pdirs = 0;
-
- /* option to determine fixed # of dirs from path */
- if (op == '.' || op == 'c') {
- int skip;
-
- q = p2;
- while (*p2) /* calc # of /'s */
- if (*p2++ == '/')
- updirs++;
- if (p[1] == '0') { /* print <x> or ... */
- pdirs = 1;
- p++;
- }
- if (p[1] >= '1' && p[1] <= '9') {
- /* calc # to skip */
- skip = p[1] - '0';
- p++;
- } else
- skip = 1;
-
- updirs -= skip;
- while (skip-- > 0) {
- while ((p2 > q) && (*p2 != '/'))
- p2--; /* back up */
- if (skip && p2 > q)
- p2--;
- }
- if (*p2 == '/' && p2 != q)
- p2++;
- }
-
- if (updirs > 0 && pdirs) {
- if (i >= len - 5)
- break;
- if (op == '.') {
- ADDBUF('.');
- ADDBUF('.');
- ADDBUF('.');
- } else {
- ADDBUF('/');
- ADDBUF('<');
- if (updirs > 9) {
- ADDBUF('9');
- ADDBUF('+');
- } else
- ADDBUF('0' + updirs);
- ADDBUF('>');
- }
- }
- for (; *p2; p2++)
- ADDBUF(*p2);
- break;
-
- case 'M':
- case 'm':
- for (p2 = connected && username ? username : "-";
- *p2 ; p2++) {
- if (op == 'm' && *p2 == '.')
- break;
- ADDBUF(*p2);
- }
- break;
-
- case 'n':
- for (p2 = connected ? username : "-"; *p2 ; p2++)
- ADDBUF(*p2);
- break;
-
- case '%':
- ADDBUF('%');
- break;
-
- default: /* display unknown codes literally */
- ADDBUF('%');
- ADDBUF(op);
- break;
-
- }
- }
- endbuf:
- buf[i] = '\0';
-}
-
-/*
- * Parse `port' into a TCP port number, defaulting to `defport' if `port' is
- * an unknown service name. If defport != -1, print a warning upon bad parse.
- */
-int
-parseport(const char *port, int defport)
-{
- int rv;
- long nport;
- char *p, *ep;
-
- p = xstrdup(port);
- nport = strtol(p, &ep, 10);
- if (*ep != '\0' && ep == p) {
- struct servent *svp;
-
- svp = getservbyname(port, "tcp");
- if (svp == NULL) {
- badparseport:
- if (defport != -1)
- warnx("Unknown port `%s', using port %d",
- port, defport);
- rv = defport;
- } else
- rv = ntohs(svp->s_port);
- } else if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0')
- goto badparseport;
- else
- rv = nport;
- free(p);
- return (rv);
-}
-
-/*
- * 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)
- fprintf(ttyout, "isipv6addr: got %d for %s\n", rv, addr);
-#endif
- return (rv == 1) ? 1 : 0;
-}
-
-
-/*
- * Internal version of connect(2); sets socket buffer sizes first and
- * supports a connection timeout using a non-blocking connect(2) with
- * a poll(2).
- * Socket fcntl flags are temporarily updated to include O_NONBLOCK;
- * these will not be reverted on connection failure.
- * Returns -1 upon failure (with errno set to the problem), or 0 on success.
- */
-int
-xconnect(int sock, const struct sockaddr *name, socklen_t namelen)
-{
- int flags, rv, timeout, error;
- socklen_t slen;
- struct timeval endtime, now, td;
- struct pollfd pfd[1];
-
- setupsockbufsize(sock);
-
- if ((flags = fcntl(sock, F_GETFL, 0)) == -1)
- return -1; /* get current socket flags */
- if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
- return -1; /* set non-blocking connect */
-
- /* NOTE: we now must restore socket flags on successful exit */
-
- pfd[0].fd = sock;
- pfd[0].events = POLLIN|POLLOUT;
-
- if (quit_time > 0) { /* want a non default timeout */
- (void)gettimeofday(&endtime, NULL);
- endtime.tv_sec += quit_time; /* determine end time */
- }
-
- rv = connect(sock, name, namelen); /* inititate the connection */
- if (rv == -1) { /* connection error */
- if (errno != EINPROGRESS) /* error isn't "please wait" */
- return -1;
-
- /* connect EINPROGRESS; wait */
- do {
- if (quit_time > 0) { /* determine timeout */
- (void)gettimeofday(&now, NULL);
- timersub(&endtime, &now, &td);
- timeout = td.tv_sec * 1000 + td.tv_usec/1000;
- if (timeout < 0)
- timeout = 0;
- } else {
- timeout = INFTIM;
- }
- pfd[0].revents = 0;
- rv = xpoll(pfd, 1, timeout);
- /* loop until poll ! EINTR */
- } while (rv == -1 && errno == EINTR);
-
- if (rv == 0) { /* poll (connect) timed out */
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (rv == -1) { /* poll error */
- return -1;
- } else if (pfd[0].revents & (POLLIN|POLLOUT)) {
- slen = sizeof(error); /* OK, or pending error */
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR,
- &error, &slen) == -1)
- return -1; /* Solaris pending error */
- if (error != 0) {
- errno = error; /* BSD pending error */
- return -1;
- }
- } else {
- errno = EBADF; /* this shouldn't happen ... */
- return -1;
- }
- }
-
- if (fcntl(sock, F_SETFL, flags) == -1) /* restore socket flags */
- return -1;
- return 0;
-}
-
-/*
- * Internal version of listen(2); sets socket buffer sizes first.
- */
-int
-xlisten(int sock, int backlog)
-{
-
- setupsockbufsize(sock);
- return (listen(sock, backlog));
-}
-
-/*
- * Internal version of poll(2), to allow reimplementation by select(2)
- * on platforms without the former.
- */
-int
-xpoll(struct pollfd *fds, int nfds, int timeout)
-{
- return poll(fds, nfds, timeout);
-}
-
-/*
- * malloc() with inbuilt error checking
- */
-void *
-xmalloc(size_t size)
-{
- void *p;
-
- p = malloc(size);
- if (p == NULL)
- err(1, "Unable to allocate %ld bytes of memory", (long)size);
- return (p);
-}
-
-/*
- * sl_init() with inbuilt error checking
- */
-StringList *
-xsl_init(void)
-{
- StringList *p;
-
- p = sl_init();
- if (p == NULL)
- err(1, "Unable to allocate memory for stringlist");
- return (p);
-}
-
-/*
- * sl_add() with inbuilt error checking
- */
-void
-xsl_add(StringList *sl, char *i)
-{
-
- if (sl_add(sl, i) == -1)
- err(1, "Unable to add `%s' to stringlist", i);
-}
-
-/*
- * strdup() with inbuilt error checking
- */
-char *
-xstrdup(const char *str)
-{
- char *s;
-
- if (str == NULL)
- errx(1, "xstrdup() called with NULL argument");
- s = strdup(str);
- if (s == NULL)
- err(1, "Unable to allocate memory for string copy");
- return (s);
-}
diff --git a/contrib/lukemftp/src/version.h b/contrib/lukemftp/src/version.h
deleted file mode 100644
index 7b69df1..0000000
--- a/contrib/lukemftp/src/version.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $NetBSD: version.h,v 1.50 2005/05/14 15:26:43 lukem Exp $ */
-/*-
- * Copyright (c) 1999-2005 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 FTP_PRODUCT
-#define FTP_PRODUCT "NetBSD-ftp"
-#endif
-
-#ifndef FTP_VERSION
-#define FTP_VERSION "20050514"
-#endif
OpenPOWER on IntegriCloud