aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Heffner <mikeh@FreeBSD.org>2005-02-20 17:33:34 +0000
committerMike Heffner <mikeh@FreeBSD.org>2005-02-20 17:33:34 +0000
commit90580277219d71354d55ed572fca05ccbec50a31 (patch)
treeb3e525aeb6db7ad0b9e566173c63af30b14693ce
parent7e475d60f53f104292ac3b1c0015eeb52678c424 (diff)
downloadsrc-90580277219d71354d55ed572fca05ccbec50a31.tar.gz
src-90580277219d71354d55ed572fca05ccbec50a31.zip
Import the latest CVS version of lukemftp.
Short list of changes: * SIGINT termination from auto-fetch. * Less trusting of remote filenames during auto mgets. * Improved RFC2616 compliancy. * Fix globs when using ftp reget (from mat@). * Limit send buffer size.
Notes
Notes: svn path=/vendor/lukemftp/dist/; revision=142129
-rw-r--r--contrib/lukemftp/src/Makefile8
-rw-r--r--contrib/lukemftp/src/cmds.c324
-rw-r--r--contrib/lukemftp/src/cmdtab.c390
-rw-r--r--contrib/lukemftp/src/extern.h11
-rw-r--r--contrib/lukemftp/src/fetch.c242
-rw-r--r--contrib/lukemftp/src/ftp.143
-rw-r--r--contrib/lukemftp/src/ftp.c16
-rw-r--r--contrib/lukemftp/src/ftp_var.h22
-rw-r--r--contrib/lukemftp/src/main.c33
-rw-r--r--contrib/lukemftp/src/progressbar.c12
-rw-r--r--contrib/lukemftp/src/progressbar.h3
-rw-r--r--contrib/lukemftp/src/util.c77
-rw-r--r--contrib/lukemftp/src/version.h6
13 files changed, 669 insertions, 518 deletions
diff --git a/contrib/lukemftp/src/Makefile b/contrib/lukemftp/src/Makefile
index 4ba5e9202efa..79cc5a6060d4 100644
--- a/contrib/lukemftp/src/Makefile
+++ b/contrib/lukemftp/src/Makefile
@@ -1,6 +1,8 @@
-# $NetBSD: Makefile,v 1.26 2003/01/21 16:08:06 jhawk Exp $
+# $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
@@ -10,13 +12,13 @@ SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \
#CPPFLAGS+=-DGATE_SERVER=\"ftp-gw.host\" # -DGATE_PORT=21
.if defined(SMALLPROG)
-CPPFLAGS+=-DNO_EDITCOMPLETE -DNO_ABOUT
+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)
+.if (!defined(SMALLPROG) || defined(SMALLPROG_INET6)) && (${USE_INET6} != "no")
CPPFLAGS+= -DINET6
.endif
diff --git a/contrib/lukemftp/src/cmds.c b/contrib/lukemftp/src/cmds.c
index fe469cc93ed9..087bc5640cd6 100644
--- a/contrib/lukemftp/src/cmds.c
+++ b/contrib/lukemftp/src/cmds.c
@@ -1,7 +1,7 @@
-/* $NetBSD: cmds.c,v 1.102 2003/08/07 11:13:52 agc Exp $ */
+/* $NetBSD: cmds.c,v 1.111 2005/02/11 06:21:22 simonb Exp $ */
/*-
- * Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -103,7 +103,7 @@
#if 0
static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
#else
-__RCSID("$NetBSD: cmds.c,v 1.102 2003/08/07 11:13:52 agc Exp $");
+__RCSID("$NetBSD: cmds.c,v 1.111 2005/02/11 06:21:22 simonb Exp $");
#endif
#endif /* not lint */
@@ -147,10 +147,15 @@ struct types {
};
sigjmp_buf jabort;
-char *mname;
+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)
{
@@ -167,7 +172,7 @@ confirm(const char *cmd, const char *file)
clearerr(stdin);
return (0);
}
- switch (tolower(*line)) {
+ switch (tolower((unsigned char)*line)) {
case 'a':
confirmrest = 1;
fprintf(ttyout,
@@ -392,9 +397,11 @@ setstruct(int argc, char *argv[])
void
put(int argc, char *argv[])
{
+ char buf[MAXPATHLEN];
char *cmd;
int loc = 0;
- char *locfile, *remfile;
+ char *locfile;
+ const char *remfile;
if (argc == 2) {
argc++;
@@ -418,15 +425,26 @@ put(int argc, char *argv[])
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");
- if (loc && ntflag)
- remfile = dotrans(remfile);
- if (loc && mapflag)
- remfile = domap(remfile);
+ 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.
*/
@@ -436,7 +454,7 @@ mput(int argc, char *argv[])
int i;
sigfunc oldintr;
int ointer;
- char *tp;
+ const char *tp;
if (argc == 0 || (argc == 1 && !another(&argc, &argv, "local-files"))) {
fprintf(ttyout, "usage: %s local-files\n", argv[0]);
@@ -457,13 +475,9 @@ mput(int argc, char *argv[])
continue;
}
if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase)
- tp = docase(tp);
- if (ntflag)
- tp = dotrans(tp);
- if (mapflag)
- tp = domap(tp);
+ char buf[MAXPATHLEN];
+ tp = doprocess(buf, sizeof(buf), cp,
+ mcase, ntflag, mapflag);
sendrequest((sunique) ? "STOU" : "STOR",
cp, tp, cp != tp || !interactive);
if (!mflag && fromatty) {
@@ -485,8 +499,9 @@ mput(int argc, char *argv[])
if (!doglob) {
if (mflag && confirm(argv[0], argv[i])) {
- tp = (ntflag) ? dotrans(argv[i]) : argv[i];
- tp = (mapflag) ? domap(tp) : tp;
+ 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) {
@@ -511,8 +526,10 @@ mput(int argc, char *argv[])
for (cpp = gl.gl_pathv; cpp && *cpp != NULL && connected;
cpp++) {
if (mflag && confirm(argv[0], *cpp)) {
- tp = (ntflag) ? dotrans(*cpp) : *cpp;
- tp = (mapflag) ? domap(tp) : tp;
+ 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) {
@@ -555,7 +572,9 @@ int
getit(int argc, char *argv[], int restartit, const char *mode)
{
int loc, rval;
- char *remfile, *locfile, *olocfile;
+ char *remfile, *olocfile;
+ const char *locfile;
+ char buf[MAXPATHLEN];
loc = rval = 0;
if (argc == 2) {
@@ -577,13 +596,8 @@ getit(int argc, char *argv[], int restartit, const char *mode)
code = -1;
return (0);
}
- locfile = olocfile;
- if (loc && mcase)
- locfile = docase(locfile);
- if (loc && ntflag)
- locfile = dotrans(locfile);
- if (loc && mapflag)
- locfile = domap(locfile);
+ locfile = doprocess(buf, sizeof(buf), olocfile,
+ loc && mcase, loc && ntflag, loc && mapflag);
if (restartit) {
struct stat stbuf;
int ret;
@@ -663,7 +677,8 @@ mget(int argc, char *argv[])
{
sigfunc oldintr;
int ointer;
- char *cp, *tp;
+ char *cp;
+ const char *tp;
int restartit;
if (argc == 0 ||
@@ -688,19 +703,21 @@ mget(int argc, char *argv[])
if (sigsetjmp(jabort, 1))
mabort();
while ((cp = remglob(argv, proxy, NULL)) != NULL) {
+ char buf[MAXPATHLEN];
if (*cp == '\0' || !connected) {
mflag = 0;
continue;
}
- if (! mflag || !confirm(argv[0], cp))
+ if (! mflag)
continue;
- tp = cp;
- if (mcase)
- tp = docase(tp);
- if (ntflag)
- tp = dotrans(tp);
- if (mapflag)
- tp = domap(tp);
+ 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;
@@ -774,13 +791,13 @@ onoff(int bool)
void
status(int argc, char *argv[])
{
- int i;
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);
@@ -844,13 +861,16 @@ status(int argc, char *argv[])
onoff(editing)
#endif /* !def NO_EDITCOMPLETE */
);
- fprintf(ttyout, "Version: %s %s\n", FTP_PRODUCT, FTP_VERSION);
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;
}
@@ -1131,7 +1151,7 @@ cd(int argc, char *argv[])
}
if (r == COMPLETE) {
dirchange = 1;
- updateremotepwd();
+ updateremotecwd();
}
}
@@ -1141,7 +1161,6 @@ cd(int argc, char *argv[])
void
lcd(int argc, char *argv[])
{
- char buf[MAXPATHLEN];
char *locdir;
code = -1;
@@ -1155,14 +1174,16 @@ lcd(int argc, char *argv[])
}
if ((locdir = globulize(argv[1])) == NULL)
return;
- if (chdir(locdir) < 0)
- warn("local: %s", locdir);
+ if (chdir(locdir) == -1)
+ warn("lcd %s", locdir);
else {
- if (getcwd(buf, sizeof(buf)) != NULL) {
- fprintf(ttyout, "Local directory now %s\n", buf);
+ updatelocalcwd();
+ if (localcwd[0]) {
+ fprintf(ttyout, "Local directory now: %s\n", localcwd);
code = 0;
- } else
- warn("getcwd: %s", locdir);
+ } else {
+ fprintf(ttyout, "Unable to determine local directory\n");
+ }
}
(void)free(locdir);
}
@@ -1174,7 +1195,6 @@ 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]);
@@ -1323,6 +1343,7 @@ ls(int argc, char *argv[])
(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;
@@ -1359,6 +1380,7 @@ mls(int argc, char *argv[])
}
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)) {
@@ -1366,7 +1388,6 @@ mls(int argc, char *argv[])
return;
}
dolist = strcmp(argv[0], "mls");
- mname = argv[0];
mflag = 1;
oldintr = xsignal(SIGINT, mintr);
if (sigsetjmp(jabort, 1))
@@ -1379,7 +1400,7 @@ mls(int argc, char *argv[])
ointer = interactive;
interactive = 1;
if (confirm("Continue with", argv[0])) {
- mflag ++;
+ mflag++;
}
interactive = ointer;
}
@@ -1398,7 +1419,7 @@ void
shell(int argc, char *argv[])
{
pid_t pid;
- sigfunc old1;
+ sigfunc oldintr;
char shellnam[MAXPATHLEN], *shell, *namep;
int wait_status;
@@ -1407,7 +1428,7 @@ shell(int argc, char *argv[])
code = -1;
return;
}
- old1 = xsignal(SIGINT, SIG_IGN);
+ oldintr = xsignal(SIGINT, SIG_IGN);
if ((pid = fork()) == 0) {
for (pid = 3; pid < 20; pid++)
(void)close(pid);
@@ -1438,7 +1459,7 @@ shell(int argc, char *argv[])
if (pid > 0)
while (wait(&wait_status) != pid)
;
- (void)xsignal(SIGINT, old1);
+ (void)xsignal(SIGINT, oldintr);
if (pid == -1) {
warn("Try again later");
code = -1;
@@ -1509,19 +1530,20 @@ user(int argc, char *argv[])
void
pwd(int argc, char *argv[])
{
- int oldverbose = verbose;
- if (argc == 0) {
+ code = -1;
+ if (argc != 1) {
fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
return;
}
- verbose = 1; /* If we aren't verbose, this doesn't do anything! */
- if (command("PWD") == ERROR && code == 500) {
- fputs("PWD command not recognized, trying XPWD.\n", ttyout);
- (void)command("XPWD");
+ 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;
}
- verbose = oldverbose;
}
/*
@@ -1530,19 +1552,19 @@ pwd(int argc, char *argv[])
void
lpwd(int argc, char *argv[])
{
- char buf[MAXPATHLEN];
- if (argc == 0) {
+ code = -1;
+ if (argc != 1) {
fprintf(ttyout, "usage: %s\n", argv[0]);
- code = -1;
return;
}
- if (getcwd(buf, sizeof(buf)) != NULL) {
- fprintf(ttyout, "Local directory %s\n", buf);
+ 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;
- } else {
- warn("getcwd");
- code = -1;
}
}
@@ -1788,6 +1810,7 @@ void
proxabort(int notused)
{
+ sigint_raised = 1;
alarmtimer(0);
if (!proxy) {
pswitch(1);
@@ -1869,26 +1892,25 @@ setcase(int argc, char *argv[])
* convert the given name to lower case if it's all upper case, into
* a static buffer which is returned to the caller
*/
-char *
-docase(char *name)
+static const char *
+docase(char *dst, size_t dlen, const char *src)
{
- static char new[MAXPATHLEN];
- int i, dochange;
+ size_t i;
+ int dochange = 1;
- dochange = 1;
- for (i = 0; name[i] != '\0' && i < sizeof(new) - 1; i++) {
- new[i] = name[i];
- if (islower((unsigned char)new[i]))
+ for (i = 0; src[i] != '\0' && i < dlen - 1; i++) {
+ dst[i] = src[i];
+ if (islower((unsigned char)dst[i]))
dochange = 0;
}
- new[i] = '\0';
+ dst[i] = '\0';
if (dochange) {
- for (i = 0; new[i] != '\0'; i++)
- if (isupper((unsigned char)new[i]))
- new[i] = tolower(new[i]);
+ for (i = 0; dst[i] != '\0'; i++)
+ if (isupper((unsigned char)dst[i]))
+ dst[i] = tolower((unsigned char)dst[i]);
}
- return (new);
+ return dst;
}
void
@@ -1923,22 +1945,24 @@ setntrans(int argc, char *argv[])
(void)strlcpy(ntout, argv[2], sizeof(ntout));
}
-char *
-dotrans(char *name)
+static const char *
+dotrans(char *dst, size_t dlen, const char *src)
{
- static char new[MAXPATHLEN];
- char *cp1, *cp2 = new;
- int i, ostop, found;
+ const char *cp1;
+ char *cp2 = dst;
+ size_t i, ostop;
for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++)
continue;
- for (cp1 = name; *cp1; cp1++) {
- found = 0;
+ 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;
}
@@ -1947,8 +1971,9 @@ dotrans(char *name)
*cp2++ = *cp1;
}
}
+out:
*cp2 = '\0';
- return (new);
+ return dst;
}
void
@@ -1984,12 +2009,12 @@ setnmap(int argc, char *argv[])
(void)strlcpy(mapout, cp, MAXPATHLEN);
}
-char *
-domap(char *name)
+static const char *
+domap(char *dst, size_t dlen, const char *src)
{
- static char new[MAXPATHLEN];
- char *cp1 = name, *cp2 = mapin;
- char *tp[9], *te[9];
+ 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) {
@@ -2032,130 +2057,127 @@ domap(char *name)
{
toks[toknum] = 0;
}
- cp1 = new;
- *cp1 = '\0';
- cp2 = mapout;
- while (*cp2) {
+ cp2 = dst;
+ *cp2 = '\0';
+ cp1 = mapout;
+ while (*cp1) {
match = 0;
- switch (*cp2) {
+ switch (*cp1) {
case '\\':
- if (*(cp2 + 1)) {
- *cp1++ = *++cp2;
+ if (*(cp1 + 1)) {
+ *cp2++ = *++cp1;
}
break;
case '[':
LOOP:
- if (*++cp2 == '$' &&
- isdigit((unsigned char)*(cp2+1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
+ if (*++cp1 == '$' &&
+ isdigit((unsigned char)*(cp1+1))) {
+ if (*++cp1 == '0') {
+ const char *cp3 = src;
while (*cp3) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
match = 1;
}
- else if (toks[toknum = *cp2 - '1']) {
- char *cp3 = tp[toknum];
+ else if (toks[toknum = *cp1 - '1']) {
+ const char *cp3 = tp[toknum];
while (cp3 != te[toknum]) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
match = 1;
}
}
else {
- while (*cp2 && *cp2 != ',' &&
- *cp2 != ']') {
- if (*cp2 == '\\') {
- cp2++;
+ while (*cp1 && *cp1 != ',' &&
+ *cp1 != ']') {
+ if (*cp1 == '\\') {
+ cp1++;
}
- else if (*cp2 == '$' &&
- isdigit((unsigned char)*(cp2+1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
+ else if (*cp1 == '$' &&
+ isdigit((unsigned char)*(cp1+1))) {
+ if (*++cp1 == '0') {
+ const char *cp3 = src;
while (*cp3) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
}
else if (toks[toknum =
- *cp2 - '1']) {
- char *cp3=tp[toknum];
+ *cp1 - '1']) {
+ const char *cp3=tp[toknum];
while (cp3 !=
te[toknum]) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
}
}
- else if (*cp2) {
- *cp1++ = *cp2++;
+ else if (*cp1) {
+ *cp2++ = *cp1++;
}
}
- if (!*cp2) {
+ if (!*cp1) {
fputs(
"nmap: unbalanced brackets.\n",
ttyout);
- return (name);
+ return (src);
}
match = 1;
- cp2--;
+ cp1--;
}
if (match) {
- while (*++cp2 && *cp2 != ']') {
- if (*cp2 == '\\' && *(cp2 + 1)) {
- cp2++;
+ while (*++cp1 && *cp1 != ']') {
+ if (*cp1 == '\\' && *(cp1 + 1)) {
+ cp1++;
}
}
- if (!*cp2) {
+ if (!*cp1) {
fputs(
"nmap: unbalanced brackets.\n",
ttyout);
- return (name);
+ return (src);
}
break;
}
- switch (*++cp2) {
+ switch (*++cp1) {
case ',':
goto LOOP;
case ']':
break;
default:
- cp2--;
+ cp1--;
goto LOOP;
}
break;
case '$':
- if (isdigit((unsigned char)*(cp2 + 1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
+ if (isdigit((unsigned char)*(cp1 + 1))) {
+ if (*++cp1 == '0') {
+ const char *cp3 = src;
while (*cp3) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
}
- else if (toks[toknum = *cp2 - '1']) {
- char *cp3 = tp[toknum];
+ else if (toks[toknum = *cp1 - '1']) {
+ const char *cp3 = tp[toknum];
while (cp3 != te[toknum]) {
- *cp1++ = *cp3++;
+ *cp2++ = *cp3++;
}
}
break;
}
/* intentional drop through */
default:
- *cp1++ = *cp2;
+ *cp2++ = *cp1;
break;
}
- cp2++;
+ cp1++;
}
- *cp1 = '\0';
- if (!*new) {
- return (name);
- }
- return (new);
+ *cp2 = '\0';
+ return *dst ? dst : src;
}
void
@@ -2307,7 +2329,7 @@ cdup(int argc, char *argv[])
}
if (r == COMPLETE) {
dirchange = 1;
- updateremotepwd();
+ updateremotecwd();
}
}
diff --git a/contrib/lukemftp/src/cmdtab.c b/contrib/lukemftp/src/cmdtab.c
index f342a81a6c4d..08a3b235189c 100644
--- a/contrib/lukemftp/src/cmdtab.c
+++ b/contrib/lukemftp/src/cmdtab.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cmdtab.c,v 1.41 2003/08/07 11:13:53 agc Exp $ */
+/* $NetBSD: cmdtab.c,v 1.43 2004/07/15 08:50:10 lukem Exp $ */
/*-
* Copyright (c) 1996-2000 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
#if 0
static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94";
#else
-__RCSID("$NetBSD: cmdtab.c,v 1.41 2003/08/07 11:13:53 agc Exp $");
+__RCSID("$NetBSD: cmdtab.c,v 1.43 2004/07/15 08:50:10 lukem Exp $");
#endif
#endif /* not lint */
@@ -81,207 +81,219 @@ __RCSID("$NetBSD: cmdtab.c,v 1.41 2003/08/07 11:13:53 agc Exp $");
* User FTP -- Command Tables.
*/
-char accounthelp[] = "send account command to remote server";
-char appendhelp[] = "append to a file";
-char asciihelp[] = "set ascii transfer type";
-char beephelp[] = "beep when command completed";
-char binaryhelp[] = "set binary transfer type";
-char casehelp[] = "toggle mget upper/lower case id mapping";
-char cdhelp[] = "change remote working directory";
-char cduphelp[] = "change remote working directory to parent directory";
-char chmodhelp[] = "change file permissions of remote file";
-char connecthelp[] = "connect to remote ftp server";
-char crhelp[] = "toggle carriage return stripping on ascii gets";
-char debughelp[] = "toggle/set debugging mode";
-char deletehelp[] = "delete remote file";
-char disconhelp[] = "terminate ftp session";
-char domachelp[] = "execute macro";
-char edithelp[] = "toggle command line editing";
-char epsv4help[] = "toggle use of EPSV/EPRT on IPv4 ftp";
-char feathelp[] = "show FEATures supported by remote system";
-char formhelp[] = "set file transfer format";
-char gatehelp[] = "toggle gate-ftp; specify host[:port] to change proxy";
-char globhelp[] = "toggle metacharacter expansion of local file names";
-char hashhelp[] = "toggle printing `#' marks; specify number to set size";
-char helphelp[] = "print local help information";
-char idlehelp[] = "get (set) idle timer on remote side";
-char lcdhelp[] = "change local working directory";
-char lpagehelp[] = "view a local file through your pager";
-char lpwdhelp[] = "print local working directory";
-char lshelp[] = "list contents of remote path";
-char macdefhelp[] = "define a macro";
-char mdeletehelp[] = "delete multiple files";
-char mgethelp[] = "get multiple files";
-char mregethelp[] = "get multiple files restarting at end of local file";
-char fgethelp[] = "get files using a localfile as a source of names";
-char mkdirhelp[] = "make directory on the remote machine";
-char mlshelp[] = "list contents of multiple remote directories";
-char mlsdhelp[] = "list contents of remote directory in a machine "
+#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";
-char mlsthelp[] = "list remote path in a machine parsable form";
-char modehelp[] = "set file transfer mode";
-char modtimehelp[] = "show last modification time of remote file";
-char mputhelp[] = "send multiple files";
-char newerhelp[] = "get file if remote file is newer than local file ";
-char nmaphelp[] = "set templates for default file name mapping";
-char ntranshelp[] = "set translation table for default file name mapping";
-char optshelp[] = "show or set options for remote commands";
-char pagehelp[] = "view a remote file through your pager";
-char passivehelp[] = "toggle use of passive transfer mode";
-char plshelp[] = "list contents of remote path through your pager";
-char pmlsdhelp[] = "list contents of remote directory in a machine "
+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";
-char porthelp[] = "toggle use of PORT/LPRT cmd for each data connection";
-char preservehelp[] ="toggle preservation of modification time of "
+HSTR porthelp[] = "toggle use of PORT/LPRT cmd for each data connection";
+HSTR preservehelp[] ="toggle preservation of modification time of "
"retrieved files";
-char progresshelp[] ="toggle transfer progress meter";
-char prompthelp[] = "force interactive prompting on multiple commands";
-char proxyhelp[] = "issue command on alternate connection";
-char pwdhelp[] = "print working directory on remote machine";
-char quithelp[] = "terminate ftp session and exit";
-char quotehelp[] = "send arbitrary ftp command";
-char ratehelp[] = "set transfer rate limit (in bytes/second)";
-char receivehelp[] = "receive file";
-char regethelp[] = "get file restarting at end of local file";
-char remotehelp[] = "get help from remote server";
-char renamehelp[] = "rename file";
-char resethelp[] = "clear queued command replies";
-char restarthelp[]= "restart file transfer at bytecount";
-char rmdirhelp[] = "remove directory on the remote machine";
-char rmtstatushelp[]="show status of remote machine";
-char runiquehelp[] = "toggle store unique for local files";
-char sendhelp[] = "send one file";
-char sethelp[] = "set or display options";
-char shellhelp[] = "escape to the shell";
-char sitehelp[] = "send site specific command to remote server\n"
+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";
-char sizecmdhelp[] = "show size of remote file";
-char statushelp[] = "show current status";
-char structhelp[] = "set file transfer structure";
-char suniquehelp[] = "toggle store unique on remote machine";
-char systemhelp[] = "show remote system type";
-char tenexhelp[] = "set tenex file transfer type";
-char tracehelp[] = "toggle packet tracing";
-char typehelp[] = "set file transfer type";
-char umaskhelp[] = "get (set) umask on remote side";
-char unsethelp[] = "unset an option";
-char usagehelp[] = "show command usage";
-char userhelp[] = "send new user information";
-char verbosehelp[] = "toggle verbose mode";
-char xferbufhelp[] = "set socket send/receive buffer size";
+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 "",
+#define CMPL0 empty,
#endif /* !NO_EDITCOMPLETE */
struct cmd cmdtab[] = {
- { "!", shellhelp, 0, 0, 0, CMPL0 shell },
- { "$", domachelp, 1, 0, 0, CMPL0 domacro },
- { "account", accounthelp, 0, 1, 1, CMPL0 account},
- { "append", appendhelp, 1, 1, 1, CMPL(lr) put },
- { "ascii", asciihelp, 0, 1, 1, CMPL0 setascii },
- { "bell", beephelp, 0, 0, 0, CMPL0 setbell },
- { "binary", binaryhelp, 0, 1, 1, CMPL0 setbinary },
- { "bye", quithelp, 0, 0, 0, CMPL0 quit },
- { "case", casehelp, 0, 0, 1, CMPL0 setcase },
- { "cd", cdhelp, 0, 1, 1, CMPL(r) cd },
- { "cdup", cduphelp, 0, 1, 1, CMPL0 cdup },
- { "chmod", chmodhelp, 0, 1, 1, CMPL(nr) do_chmod },
- { "close", disconhelp, 0, 1, 1, CMPL0 disconnect },
- { "cr", crhelp, 0, 0, 0, CMPL0 setcr },
- { "debug", debughelp, 0, 0, 0, CMPL0 setdebug },
- { "delete", deletehelp, 0, 1, 1, CMPL(r) delete },
- { "dir", lshelp, 1, 1, 1, CMPL(rl) ls },
- { "disconnect", disconhelp, 0, 1, 1, CMPL0 disconnect },
- { "edit", edithelp, 0, 0, 0, CMPL0 setedit },
- { "epsv4", epsv4help, 0, 0, 0, CMPL0 setepsv4 },
- { "exit", quithelp, 0, 0, 0, CMPL0 quit },
- { "features", feathelp, 0, 1, 1, CMPL0 feat },
- { "fget", fgethelp, 1, 1, 1, CMPL(l) fget },
- { "form", formhelp, 0, 1, 1, CMPL0 setform },
- { "ftp", connecthelp, 0, 0, 1, CMPL0 setpeer },
- { "gate", gatehelp, 0, 0, 0, CMPL0 setgate },
- { "get", receivehelp, 1, 1, 1, CMPL(rl) get },
- { "glob", globhelp, 0, 0, 0, CMPL0 setglob },
- { "hash", hashhelp, 0, 0, 0, CMPL0 sethash },
- { "help", helphelp, 0, 0, 1, CMPL(C) help },
- { "idle", idlehelp, 0, 1, 1, CMPL0 idlecmd },
- { "image", binaryhelp, 0, 1, 1, CMPL0 setbinary },
- { "lcd", lcdhelp, 0, 0, 0, CMPL(l) lcd },
- { "less", pagehelp, 1, 1, 1, CMPL(r) page },
- { "lpage", lpagehelp, 0, 0, 0, CMPL(l) lpage },
- { "lpwd", lpwdhelp, 0, 0, 0, CMPL0 lpwd },
- { "ls", lshelp, 1, 1, 1, CMPL(rl) ls },
- { "macdef", macdefhelp, 0, 0, 0, CMPL0 macdef },
- { "mdelete", mdeletehelp, 1, 1, 1, CMPL(R) mdelete },
- { "mdir", mlshelp, 1, 1, 1, CMPL(R) mls },
- { "mget", mgethelp, 1, 1, 1, CMPL(R) mget },
- { "mkdir", mkdirhelp, 0, 1, 1, CMPL(r) makedir },
- { "mls", mlshelp, 1, 1, 1, CMPL(R) mls },
- { "mlsd", mlsdhelp, 1, 1, 1, CMPL(r) ls },
- { "mlst", mlsthelp, 1, 1, 1, CMPL(r) mlst },
- { "mode", modehelp, 0, 1, 1, CMPL0 setftmode },
- { "modtime", modtimehelp, 0, 1, 1, CMPL(r) modtime },
- { "more", pagehelp, 1, 1, 1, CMPL(r) page },
- { "mput", mputhelp, 1, 1, 1, CMPL(L) mput },
- { "mreget", mregethelp, 1, 1, 1, CMPL(R) mget },
- { "msend", mputhelp, 1, 1, 1, CMPL(L) mput },
- { "newer", newerhelp, 1, 1, 1, CMPL(r) newer },
- { "nlist", lshelp, 1, 1, 1, CMPL(rl) ls },
- { "nmap", nmaphelp, 0, 0, 1, CMPL0 setnmap },
- { "ntrans", ntranshelp, 0, 0, 1, CMPL0 setntrans },
- { "open", connecthelp, 0, 0, 1, CMPL0 setpeer },
- { "page", pagehelp, 1, 1, 1, CMPL(r) page },
- { "passive", passivehelp, 0, 0, 0, CMPL0 setpassive },
- { "pdir", plshelp, 1, 1, 1, CMPL(r) ls },
- { "pls", plshelp, 1, 1, 1, CMPL(r) ls },
- { "pmlsd", pmlsdhelp, 1, 1, 1, CMPL(r) ls },
- { "preserve", preservehelp, 0, 0, 0, CMPL0 setpreserve },
- { "progress", progresshelp, 0, 0, 0, CMPL0 setprogress },
- { "prompt", prompthelp, 0, 0, 0, CMPL0 setprompt },
- { "proxy", proxyhelp, 0, 0, 1, CMPL(c) doproxy },
- { "put", sendhelp, 1, 1, 1, CMPL(lr) put },
- { "pwd", pwdhelp, 0, 1, 1, CMPL0 pwd },
- { "quit", quithelp, 0, 0, 0, CMPL0 quit },
- { "quote", quotehelp, 1, 1, 1, CMPL0 quote },
- { "rate", ratehelp, 0, 0, 0, CMPL0 setrate },
- { "rcvbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
- { "recv", receivehelp, 1, 1, 1, CMPL(rl) get },
- { "reget", regethelp, 1, 1, 1, CMPL(rl) reget },
- { "remopts", optshelp, 0, 1, 1, CMPL0 opts },
- { "rename", renamehelp, 0, 1, 1, CMPL(rr) renamefile },
- { "reset", resethelp, 0, 1, 1, CMPL0 reset },
- { "restart", restarthelp, 1, 1, 1, CMPL0 restart },
- { "rhelp", remotehelp, 0, 1, 1, CMPL0 rmthelp },
- { "rmdir", rmdirhelp, 0, 1, 1, CMPL(r) removedir },
- { "rstatus", rmtstatushelp, 0, 1, 1, CMPL(r) rmtstatus },
- { "runique", runiquehelp, 0, 0, 1, CMPL0 setrunique },
- { "send", sendhelp, 1, 1, 1, CMPL(lr) put },
- { "sendport", porthelp, 0, 0, 0, CMPL0 setport },
- { "set", sethelp, 0, 0, 0, CMPL(o) setoption },
- { "site", sitehelp, 0, 1, 1, CMPL0 site },
- { "size", sizecmdhelp, 1, 1, 1, CMPL(r) sizecmd },
- { "sndbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
- { "status", statushelp, 0, 0, 1, CMPL0 status },
- { "struct", structhelp, 0, 1, 1, CMPL0 setstruct },
- { "sunique", suniquehelp, 0, 0, 1, CMPL0 setsunique },
- { "system", systemhelp, 0, 1, 1, CMPL0 syst },
- { "tenex", tenexhelp, 0, 1, 1, CMPL0 settenex },
- { "throttle", ratehelp, 0, 0, 0, CMPL0 setrate },
- { "trace", tracehelp, 0, 0, 0, CMPL0 settrace },
- { "type", typehelp, 0, 1, 1, CMPL0 settype },
- { "umask", umaskhelp, 0, 1, 1, CMPL0 do_umask },
- { "unset", unsethelp, 0, 0, 0, CMPL(o) unsetoption },
- { "usage", usagehelp, 0, 0, 1, CMPL(C) help },
- { "user", userhelp, 0, 1, 1, CMPL0 user },
- { "verbose", verbosehelp, 0, 0, 0, CMPL0 setverbose },
- { "xferbuf", xferbufhelp, 0, 0, 0, CMPL0 setxferbuf },
- { "?", helphelp, 0, 0, 1, CMPL(C) help },
+ { "!", 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 },
};
diff --git a/contrib/lukemftp/src/extern.h b/contrib/lukemftp/src/extern.h
index 9dba874a4a78..1111c858b983 100644
--- a/contrib/lukemftp/src/extern.h
+++ b/contrib/lukemftp/src/extern.h
@@ -1,7 +1,7 @@
-/* $NetBSD: extern.h,v 1.62 2003/08/07 11:13:54 agc Exp $ */
+/* $NetBSD: extern.h,v 1.64 2005/02/09 23:17:27 christos Exp $ */
/*-
- * Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -129,13 +129,11 @@ void delete(int, char **);
void disconnect(int, char **);
void do_chmod(int, char **);
void do_umask(int, char **);
-char *docase(char *);
void domacro(int, char **);
-char *domap(char *);
void doproxy(int, char **);
-char *dotrans(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);
@@ -246,7 +244,8 @@ int strsuftoi(const char *);
void syst(int, char **);
int togglevar(int, char **, int *, const char *);
void unsetoption(int, char **);
-void updateremotepwd(void);
+void updatelocalcwd(void);
+void updateremotecwd(void);
void usage(void);
void user(int, char **);
int xconnect(int, const struct sockaddr *, int);
diff --git a/contrib/lukemftp/src/fetch.c b/contrib/lukemftp/src/fetch.c
index abb89ce15946..f2e776363858 100644
--- a/contrib/lukemftp/src/fetch.c
+++ b/contrib/lukemftp/src/fetch.c
@@ -1,7 +1,7 @@
-/* $NetBSD: fetch.c,v 1.146 2003/12/10 12:34:28 lukem Exp $ */
+/* $NetBSD: fetch.c,v 1.155 2005/01/12 22:37:41 lukem Exp $ */
/*-
- * Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.146 2003/12/10 12:34:28 lukem Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.155 2005/01/12 22:37:41 lukem Exp $");
#endif /* not lint */
/*
@@ -83,11 +83,14 @@ typedef enum {
} url_t;
void aborthttp(int);
+#ifndef NO_AUTH
static int auth_url(const char *, char **, const char *, const char *);
-static void base64_encode(const u_char *, size_t, u_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 *);
@@ -95,6 +98,11 @@ 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 */
@@ -102,6 +110,35 @@ static int redirect_loop;
/*
+ * 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.
@@ -110,52 +147,52 @@ static int
auth_url(const char *challenge, char **response, const char *guser,
const char *gpass)
{
- char *cp, *ep, *clear, *line, *realm, *scheme;
+ const char *cp, *scheme;
+ char *ep, *clear, *realm;
char user[BUFSIZ], *pass;
int rval;
size_t len, clen, rlen;
*response = NULL;
- clear = realm = scheme = NULL;
+ clear = realm = NULL;
rval = -1;
- line = xstrdup(challenge);
- cp = line;
+ cp = challenge;
+ scheme = "Basic"; /* only support Basic authentication */
if (debug)
fprintf(ttyout, "auth_url: challenge `%s'\n", challenge);
- scheme = strsep(&cp, " ");
-#define SCHEME_BASIC "Basic"
- if (strncasecmp(scheme, SCHEME_BASIC, sizeof(SCHEME_BASIC) - 1) != 0) {
- warnx("Unsupported WWW Authentication challenge - `%s'",
+ if (! match_token(&cp, scheme)) {
+ warnx("Unsupported authentication challenge - `%s'",
challenge);
goto cleanup_auth_url;
}
- cp += strspn(cp, " ");
#define REALM "realm=\""
- if (strncasecmp(cp, REALM, sizeof(REALM) - 1) == 0)
+ if (STRNEQUAL(cp, REALM))
cp += sizeof(REALM) - 1;
else {
- warnx("Unsupported WWW Authentication challenge - `%s'",
+ 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 WWW Authentication challenge - `%s'",
+ warnx("Unsupported authentication challenge - `%s'",
challenge);
goto cleanup_auth_url;
}
- if (guser != NULL)
+ fprintf(ttyout, "Username for `%s': ", realm);
+ if (guser != NULL) {
(void)strlcpy(user, guser, sizeof(user));
- else {
- fprintf(ttyout, "Username for `%s': ", realm);
+ fprintf(ttyout, "%s\n", user);
+ } else {
(void)fflush(ttyout);
if (fgets(user, sizeof(user) - 1, stdin) == NULL) {
clearerr(stdin);
@@ -181,13 +218,13 @@ auth_url(const char *challenge, char **response, const char *guser,
*response = (char *)xmalloc(rlen);
(void)strlcpy(*response, scheme, rlen);
len = strlcat(*response, " ", rlen);
- base64_encode(clear, clen, (u_char *)*response + len);
+ /* use `clen - 1' to not encode the trailing NUL */
+ base64_encode(clear, clen - 1, (unsigned char *)*response + len);
memset(clear, 0, clen);
rval = 0;
cleanup_auth_url:
FREEPTR(clear);
- FREEPTR(line);
FREEPTR(realm);
return (rval);
}
@@ -197,11 +234,11 @@ auth_url(const char *challenge, char **response, const char *guser,
* which should be at least ((len + 2) * 4 / 3 + 1) in size.
*/
static void
-base64_encode(const u_char *clear, size_t len, u_char *encoded)
+base64_encode(const unsigned char *clear, size_t len, unsigned char *encoded)
{
- static const u_char enc[] =
+ static const unsigned char enc[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- u_char *cp;
+ unsigned char *cp;
int i;
cp = encoded;
@@ -217,6 +254,7 @@ base64_encode(const u_char *clear, size_t len, u_char *encoded)
while (i-- > len)
*(--cp) = '=';
}
+#endif
/*
* Decode %xx escapes in given string, `in-place'.
@@ -295,17 +333,17 @@ parse_url(const char *url, const char *desc, url_t *type,
*portnum = 0;
tport = NULL;
- if (strncasecmp(url, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) {
+ if (STRNEQUAL(url, HTTP_URL)) {
url += sizeof(HTTP_URL) - 1;
*type = HTTP_URL_T;
*portnum = HTTP_PORT;
tport = httpport;
- } else if (strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
+ } else if (STRNEQUAL(url, FTP_URL)) {
url += sizeof(FTP_URL) - 1;
*type = FTP_URL_T;
*portnum = FTP_PORT;
tport = ftpport;
- } else if (strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) {
+ } else if (STRNEQUAL(url, FILE_URL)) {
url += sizeof(FILE_URL) - 1;
*type = FILE_URL_T;
} else {
@@ -347,6 +385,9 @@ parse_url(const char *url, const char *desc, url_t *type,
*cp = '\0';
*pass = xstrdup(cp + 1);
}
+ url_decode(*user);
+ if (*pass)
+ url_decode(*pass);
}
#ifdef INET6
@@ -435,7 +476,8 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
size_t len;
static size_t bufsize;
static char *xferbuf;
- char *cp, *ep, *buf, *savefile;
+ const char *cp, *token;
+ char *ep, *buf, *savefile;
char *auth, *location, *message;
char *user, *pass, *host, *port, *path, *decodedpath;
char *puser, *ppass, *useragent;
@@ -515,7 +557,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
goto cleanup_fetch_url;
} else {
if (debug)
- fprintf(ttyout, "got savefile as `%s'\n", savefile);
+ fprintf(ttyout, "savefile `%s'\n", savefile);
}
restart_point = 0;
@@ -788,7 +830,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
warn("Receiving HTTP reply");
goto cleanup_fetch_url;
}
- while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
+ while (len > 0 && (ISLWS(buf[len-1])))
buf[--len] = '\0';
if (debug)
fprintf(ttyout, "received `%s'\n", buf);
@@ -805,28 +847,27 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
message = xstrdup(cp);
/* Read the rest of the header. */
- FREEPTR(buf);
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 &&
- (buf[len-1] == '\r' || buf[len-1] == '\n'))
+ 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 */
+ /*
+ * Look for some headers
+ */
+
cp = buf;
-#define CONTENTLEN "Content-Length: "
- if (strncasecmp(cp, CONTENTLEN,
- sizeof(CONTENTLEN) - 1) == 0) {
- cp += sizeof(CONTENTLEN) - 1;
+ if (match_token(&cp, "Content-Length:")) {
filesize = STRTOLL(cp, &ep, 10);
if (filesize < 0 || *ep != '\0')
goto improper;
@@ -835,13 +876,12 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
"parsed len as: " LLF "\n",
(LLT)filesize);
-#define CONTENTRANGE "Content-Range: bytes "
- } else if (strncasecmp(cp, CONTENTRANGE,
- sizeof(CONTENTRANGE) - 1) == 0) {
- cp += sizeof(CONTENTRANGE) - 1;
- if (*cp == '*') {
- ep = cp + 1;
- }
+ } 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 != '-')
@@ -850,19 +890,20 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
rangeend = STRTOLL(cp, &ep, 10);
if (rangeend < 0 || rangeend < rangestart)
goto improper;
+ cp = ep;
}
- if (*ep != '/')
+ if (*cp != '/')
goto improper;
- cp = ep + 1;
- if (*cp == '*') {
- ep = cp + 1;
- }
+ cp++;
+ if (*cp == '*')
+ cp++;
else {
entitylen = STRTOLL(cp, &ep, 10);
if (entitylen < 0)
goto improper;
+ cp = ep;
}
- if (*ep != '\0')
+ if (*cp != '\0')
goto improper;
if (debug) {
@@ -881,13 +922,10 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
goto cleanup_fetch_url;
}
-#define LASTMOD "Last-Modified: "
- } else if (strncasecmp(cp, LASTMOD,
- sizeof(LASTMOD) - 1) == 0) {
+ } else if (match_token(&cp, "Last-Modified:")) {
struct tm parsed;
char *t;
- cp += sizeof(LASTMOD) - 1;
/* RFC 1123 */
if ((t = strptime(cp,
"%a, %d %b %Y %H:%M:%S GMT",
@@ -910,29 +948,22 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
}
-#define LOCATION "Location: "
- } else if (strncasecmp(cp, LOCATION,
- sizeof(LOCATION) - 1) == 0) {
- cp += sizeof(LOCATION) - 1;
+ } else if (match_token(&cp, "Location:")) {
location = xstrdup(cp);
if (debug)
fprintf(ttyout,
- "parsed location as: %s\n", cp);
+ "parsed location as `%s'\n", cp);
-#define TRANSENC "Transfer-Encoding: "
- } else if (strncasecmp(cp, TRANSENC,
- sizeof(TRANSENC) - 1) == 0) {
- cp += sizeof(TRANSENC) - 1;
- if (strcasecmp(cp, "binary") == 0) {
+ } else if (match_token(&cp, "Transfer-Encoding:")) {
+ if (match_token(&cp, "binary")) {
warnx(
- "Bogus transfer encoding - `%s' (fetching anyway)",
- cp);
+ "Bogus transfer encoding - `binary' (fetching anyway)");
continue;
}
- if (strcasecmp(cp, "chunked") != 0) {
+ if (! (token = match_token(&cp, "chunked"))) {
warnx(
"Unsupported transfer encoding - `%s'",
- cp);
+ token);
goto cleanup_fetch_url;
}
ischunked++;
@@ -940,26 +971,20 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
fprintf(ttyout,
"using chunked encoding\n");
-#define PROXYAUTH "Proxy-Authenticate: "
- } else if (strncasecmp(cp, PROXYAUTH,
- sizeof(PROXYAUTH) - 1) == 0) {
- cp += sizeof(PROXYAUTH) - 1;
- FREEPTR(auth);
- auth = xstrdup(cp);
- if (debug)
- fprintf(ttyout,
- "parsed proxy-auth as: %s\n", cp);
-
-#define WWWAUTH "WWW-Authenticate: "
- } else if (strncasecmp(cp, WWWAUTH,
- sizeof(WWWAUTH) - 1) == 0) {
- cp += sizeof(WWWAUTH) - 1;
+ } 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(cp);
+ auth = xstrdup(token);
if (debug)
fprintf(ttyout,
- "parsed www-auth as: %s\n", cp);
-
+ "parsed auth as `%s'\n", cp);
}
}
@@ -1002,18 +1027,13 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
rval = go_fetch(location);
}
goto cleanup_fetch_url;
+#ifndef NO_AUTH
case 401:
case 407:
{
char **authp;
char *auser, *apass;
- fprintf(ttyout, "%s\n", message);
- if (EMPTYSTRING(auth)) {
- warnx(
- "No authentication challenge provided by server");
- goto cleanup_fetch_url;
- }
if (hcode == 401) {
authp = &wwwauth;
auser = user;
@@ -1023,6 +1043,14 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
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];
@@ -1032,10 +1060,9 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
== NULL) {
clearerr(stdin);
goto cleanup_fetch_url;
- } else {
- if (tolower(reply[0]) != 'y')
- goto cleanup_fetch_url;
}
+ if (tolower((unsigned char)reply[0]) != 'y')
+ goto cleanup_fetch_url;
auser = NULL;
apass = NULL;
}
@@ -1047,6 +1074,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
goto cleanup_fetch_url;
}
+#endif
default:
if (message)
warnx("Error retrieving file - `%s'", message);
@@ -1273,6 +1301,7 @@ 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);
@@ -1299,7 +1328,7 @@ fetch_ftp(const char *url)
rval = 1;
type = TYPE_I;
- if (strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
+ if (STRNEQUAL(url, FTP_URL)) {
if ((parse_url(url, "URL", &urltype, &user, &pass,
&host, &port, &portnum, &path) == -1) ||
(user != NULL && *user == '\0') ||
@@ -1307,8 +1336,6 @@ fetch_ftp(const char *url)
warnx("Invalid URL `%s'", url);
goto cleanup_fetch_ftp;
}
- url_decode(user);
- url_decode(pass);
/*
* Note: Don't url_decode(path) here. We need to keep the
* distinction between "/" and "%2F" until later.
@@ -1570,7 +1597,10 @@ fetch_ftp(const char *url)
ointeractive = interactive;
interactive = 0;
- xargv[0] = "mget";
+ if (restartautofetch)
+ xargv[0] = "mreget";
+ else
+ xargv[0] = "mget";
mget(xargc, xargv);
interactive = ointeractive;
} else {
@@ -1618,10 +1648,11 @@ go_fetch(const char *url)
{
char *proxy;
+#ifndef NO_ABOUT
/*
* Check for about:*
*/
- if (strncasecmp(url, ABOUT_URL, sizeof(ABOUT_URL) - 1) == 0) {
+ if (STRNEQUAL(url, ABOUT_URL)) {
url += sizeof(ABOUT_URL) -1;
if (strcasecmp(url, "ftp") == 0 ||
strcasecmp(url, "tnftp") == 0) {
@@ -1651,12 +1682,12 @@ go_fetch(const char *url)
fputs("\n", ttyout);
return (0);
}
+#endif
/*
* Check for file:// and http:// URLs.
*/
- if (strncasecmp(url, HTTP_URL, sizeof(HTTP_URL) - 1) == 0 ||
- strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0)
+ if (STRNEQUAL(url, HTTP_URL) || STRNEQUAL(url, FILE_URL))
return (fetch_url(url, NULL, NULL, NULL));
/*
@@ -1665,8 +1696,7 @@ go_fetch(const char *url)
* Othewise, use fetch_ftp().
*/
proxy = getoptionvalue("ftp_proxy");
- if (!EMPTYSTRING(proxy) &&
- strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0)
+ if (!EMPTYSTRING(proxy) && STRNEQUAL(url, FTP_URL))
return (fetch_url(url, NULL, NULL, NULL));
return (fetch_ftp(url));
@@ -1695,7 +1725,9 @@ auto_fetch(int argc, char *argv[])
if (sigsetjmp(toplevel, 1)) {
if (connected)
disconnect(0, NULL);
- return (argpos + 1);
+ if (rval > 0)
+ rval = argpos + 1;
+ return (rval);
}
(void)xsignal(SIGINT, intr);
(void)xsignal(SIGPIPE, lostpeer);
diff --git a/contrib/lukemftp/src/ftp.1 b/contrib/lukemftp/src/ftp.1
index f197d3d196c3..23e0b4a5f405 100644
--- a/contrib/lukemftp/src/ftp.1
+++ b/contrib/lukemftp/src/ftp.1
@@ -1,6 +1,6 @@
-.\" $NetBSD: ftp.1,v 1.101 2003/12/19 03:46:02 lukem Exp $
+.\" $NetBSD: ftp.1,v 1.108 2005/01/15 21:28:16 lukem Exp $
.\"
-.\" Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@@ -64,7 +64,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
-.Dd December 19, 2003
+.Dd January 15, 2005
.Dt FTP 1
.Os
.Sh NAME
@@ -951,7 +951,9 @@ traffic.
.Tn FTP
servers are required to support the
.Dv PASV
-command by RFC 1123, some do not.)
+command by
+.Cm RFC 1123 ,
+some do not.)
.It Ic pdir Op Ar remote-path
Perform
.Ic dir
@@ -1121,7 +1123,7 @@ Outgoing transfers.
.El
.Pp
.Ar maximum
-can by modified on the fly by
+can be modified on the fly by
.Ar increment
bytes (default: 1024) each time a given signal is received:
.B
@@ -1614,7 +1616,10 @@ This is unlikely to be useful.
.It
Any
.Sq Li \&% Ns Ar XX
-codes within the path components are decoded, with
+codes
+(per
+.Cm RFC 1738 )
+within the path components are decoded, with
.Ar XX
representing a character code in hexadecimal.
This decoding takes place after the
@@ -1746,6 +1751,14 @@ 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
@@ -2214,9 +2227,9 @@ URL requests
.Tn FTP
protocol).
.Pp
-.Em NOTE :
-this is not used for interactive sessions, only for command-line
-fetches.
+See
+.Ev http_proxy
+for further notes about proxy use.
.It Ev http_proxy
URL of
.Tn HTTP
@@ -2227,6 +2240,18 @@ 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
+.Cm RFC 1738
+.Sq Li \&% Ns Ar XX
+encoding.
+.Pp
Note that the use of a username and password in
.Ev ftp_proxy
and
diff --git a/contrib/lukemftp/src/ftp.c b/contrib/lukemftp/src/ftp.c
index 0c3b3d4c85f8..72a4262c1739 100644
--- a/contrib/lukemftp/src/ftp.c
+++ b/contrib/lukemftp/src/ftp.c
@@ -1,7 +1,7 @@
-/* $NetBSD: ftp.c,v 1.125 2004/04/10 12:21:39 lukem Exp $ */
+/* $NetBSD: ftp.c,v 1.126 2004/07/20 10:40:22 lukem Exp $ */
/*-
- * Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -99,7 +99,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
-__RCSID("$NetBSD: ftp.c,v 1.125 2004/04/10 12:21:39 lukem Exp $");
+__RCSID("$NetBSD: ftp.c,v 1.126 2004/07/20 10:40:22 lukem Exp $");
#endif
#endif /* not lint */
@@ -131,8 +131,9 @@ __RCSID("$NetBSD: ftp.c,v 1.125 2004/04/10 12:21:39 lukem Exp $");
#include "ftp_var.h"
-volatile int abrtflag = 0;
-volatile int timeoutflag = 0;
+volatile sig_atomic_t abrtflag;
+volatile sig_atomic_t timeoutflag;
+
sigjmp_buf ptabort;
int ptabflg;
int ptflag = 0;
@@ -318,6 +319,7 @@ cmdabort(int notused)
{
int oerrno = errno;
+ sigint_raised = 1;
alarmtimer(0);
if (fromatty)
write(fileno(ttyout), "\n", 1);
@@ -601,6 +603,7 @@ abortxfer(int notused)
char msgbuf[100];
int len;
+ sigint_raised = 1;
alarmtimer(0);
mflag = 0;
abrtflag = 0;
@@ -1742,6 +1745,7 @@ psabort(int notused)
{
int oerrno = errno;
+ sigint_raised = 1;
alarmtimer(0);
abrtflag++;
errno = oerrno;
@@ -1838,6 +1842,7 @@ void
abortpt(int notused)
{
+ sigint_raised = 1;
alarmtimer(0);
if (fromatty)
write(fileno(ttyout), "\n", 1);
@@ -2056,6 +2061,7 @@ abort_squared(int dummy)
char msgbuf[100];
int len;
+ sigint_raised = 1;
alarmtimer(0);
len = strlcpy(msgbuf, "\nremote abort aborted; closing connection.\n",
sizeof(msgbuf));
diff --git a/contrib/lukemftp/src/ftp_var.h b/contrib/lukemftp/src/ftp_var.h
index 46c4b61396fa..812f00061049 100644
--- a/contrib/lukemftp/src/ftp_var.h
+++ b/contrib/lukemftp/src/ftp_var.h
@@ -1,7 +1,7 @@
-/* $NetBSD: ftp_var.h,v 1.65 2003/08/07 11:13:56 agc Exp $ */
+/* $NetBSD: ftp_var.h,v 1.69 2005/01/03 09:50:09 lukem Exp $ */
/*-
- * Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -126,15 +126,15 @@
* Format of command table.
*/
struct cmd {
- char *c_name; /* name of command */
- char *c_help; /* help string */
- char c_bell; /* give bell when command completes */
- char c_conn; /* must be connected to use command */
- char c_proxy; /* proxy server may execute */
+ 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
- char *c_complete; /* context sensitive completion list */
+ const char *c_complete; /* context sensitive completion list */
#endif /* !NO_EDITCOMPLETE */
- void (*c_handler)(int, char **); /* function to call */
+ void (*c_handler)(int, char **); /* function to call */
};
/*
@@ -269,7 +269,8 @@ 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 remotepwd[MAXPATHLEN]; /* remote dir */
+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 */
@@ -310,6 +311,7 @@ GLOBAL void (*reply_callback)(const char *);
* first (`xxx-') and last (`xxx ')
*/
+GLOBAL volatile sig_atomic_t sigint_raised;
GLOBAL FILE *cin;
GLOBAL FILE *cout;
diff --git a/contrib/lukemftp/src/main.c b/contrib/lukemftp/src/main.c
index be2940a1d0bb..ffed2571b1a4 100644
--- a/contrib/lukemftp/src/main.c
+++ b/contrib/lukemftp/src/main.c
@@ -1,7 +1,7 @@
-/* $NetBSD: main.c,v 1.86 2003/08/07 11:13:56 agc Exp $ */
+/* $NetBSD: main.c,v 1.90 2004/07/21 00:09:14 lukem Exp $ */
/*-
- * Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -104,7 +104,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
#else
-__RCSID("$NetBSD: main.c,v 1.86 2003/08/07 11:13:56 agc Exp $");
+__RCSID("$NetBSD: main.c,v 1.90 2004/07/21 00:09:14 lukem Exp $");
#endif
#endif /* not lint */
@@ -119,6 +119,7 @@ __RCSID("$NetBSD: main.c,v 1.86 2003/08/07 11:13:56 agc Exp $");
#include <netdb.h>
#include <paths.h>
#include <pwd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -147,6 +148,8 @@ main(int argc, char *argv[])
setlocale(LC_ALL, "");
setprogname(argv[0]);
+ sigint_raised = 0;
+
ftpport = "ftp";
httpport = "http";
gateport = NULL;
@@ -214,9 +217,14 @@ main(int argc, char *argv[])
(void)close(s);
/* sanity check returned buffer sizes */
if (rcvbuf_size <= 0)
- rcvbuf_size = 8192;
+ rcvbuf_size = 8 * 1024;
if (sndbuf_size <= 0)
- sndbuf_size = 8192;
+ 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)
@@ -501,17 +509,22 @@ main(int argc, char *argv[])
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 */
- exit(rval);
+ goto sigint_or_rval_exit;
} else {
char *xargv[4], *user, *host;
- if (sigsetjmp(toplevel, 1))
- exit(0);
+ if ((rval = sigsetjmp(toplevel, 1)))
+ goto sigint_or_rval_exit;
(void)xsignal(SIGINT, intr);
(void)xsignal(SIGPIPE, lostpeer);
user = NULL;
@@ -1024,8 +1037,8 @@ usage(void)
const char *progname = getprogname();
(void)fprintf(stderr,
-"usage: %s [-46AadefginpRtvV] [-N netrc] [-o outfile] [-P port] [-r retry]\n"
-" [-T dir,max[,inc][[user@]host [port]]] [host:path[/]]\n"
+"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);
diff --git a/contrib/lukemftp/src/progressbar.c b/contrib/lukemftp/src/progressbar.c
index 48332a62c357..9c8ad108b730 100644
--- a/contrib/lukemftp/src/progressbar.c
+++ b/contrib/lukemftp/src/progressbar.c
@@ -1,4 +1,4 @@
-/* $NetBSD: progressbar.c,v 1.5 2004/03/09 17:04:24 hubertf Exp $ */
+/* $NetBSD: progressbar.c,v 1.6 2005/02/10 16:00:28 jmc Exp $ */
/*-
* Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: progressbar.c,v 1.5 2004/03/09 17:04:24 hubertf Exp $");
+__RCSID("$NetBSD: progressbar.c,v 1.6 2005/02/10 16:00:28 jmc Exp $");
#endif /* not lint */
/*
@@ -79,7 +79,6 @@ foregroundproc(void)
#endif /* !defined(NO_PROGRESS) */
-#ifndef NO_PROGRESS
static void updateprogressmeter(int);
/*
@@ -93,8 +92,6 @@ updateprogressmeter(int dummy)
progressmeter(0);
errno = oerrno;
}
-#endif /* NO_PROGRESS */
-
/*
* List of order of magnitude prefixes.
@@ -127,7 +124,7 @@ progressmeter(int flag)
struct timeval td;
off_t abbrevsize, bytespersec;
double elapsed;
- int ratio, barlength, i, len, remaining;
+ int ratio, barlength, i, remaining;
/*
* Work variables for progress bar.
@@ -137,7 +134,10 @@ progressmeter(int flag)
* `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
diff --git a/contrib/lukemftp/src/progressbar.h b/contrib/lukemftp/src/progressbar.h
index b8e416e80c36..9e004f415b62 100644
--- a/contrib/lukemftp/src/progressbar.h
+++ b/contrib/lukemftp/src/progressbar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: progressbar.h,v 1.4 2004/03/09 17:04:24 hubertf Exp $ */
+/* $NetBSD: progressbar.h,v 1.5 2005/02/10 16:00:38 jmc Exp $ */
/*-
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
@@ -82,7 +82,6 @@ void psummary(int);
void ptransfer(int);
#endif /* !STANDALONE_PROGRESS */
-
#ifdef NO_LONG_LONG
# define LLF "%ld"
# define LLFP(x) "%" x "ld"
diff --git a/contrib/lukemftp/src/util.c b/contrib/lukemftp/src/util.c
index 56fbd79b4e7f..49c9a2a2c3fd 100644
--- a/contrib/lukemftp/src/util.c
+++ b/contrib/lukemftp/src/util.c
@@ -1,7 +1,7 @@
-/* $NetBSD: util.c,v 1.115 2004/04/10 12:21:39 lukem Exp $ */
+/* $NetBSD: util.c,v 1.117 2005/01/03 09:50:09 lukem Exp $ */
/*-
- * Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -71,13 +71,13 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: util.c,v 1.115 2004/04/10 12:21:39 lukem Exp $");
+__RCSID("$NetBSD: util.c,v 1.117 2005/01/03 09:50:09 lukem Exp $");
#endif /* not lint */
/*
* FTP User Program -- Misc support routines
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
@@ -319,9 +319,10 @@ cleanuppeer(void)
* Top-level signal handler for interrupted commands.
*/
void
-intr(int dummy)
+intr(int signo)
{
+ sigint_raised = 1;
alarmtimer(0);
if (fromatty)
write(fileno(ttyout), "\n", 1);
@@ -478,7 +479,8 @@ ftp_login(const char *host, const char *user, const char *pass)
break;
}
}
- updateremotepwd();
+ updatelocalcwd();
+ updateremotecwd();
cleanup_ftp_login:
if (user != NULL && freeuser)
@@ -773,10 +775,23 @@ remotemodtime(const char *file, int noisy)
}
/*
- * update global `remotepwd', which contains the state of the remote cwd
+ * Update global `localcwd', which contains the state of the local cwd
*/
void
-updateremotepwd(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;
@@ -786,31 +801,55 @@ updateremotepwd(void)
if (debug == 0)
verbose = -1;
if (command("PWD") != COMPLETE)
- goto badremotepwd;
+ goto badremotecwd;
cp = strchr(reply_string, ' ');
if (cp == NULL || cp[0] == '\0' || cp[1] != '"')
- goto badremotepwd;
+ goto badremotecwd;
cp += 2;
- for (i = 0; *cp && i < sizeof(remotepwd) - 1; i++, cp++) {
+ for (i = 0; *cp && i < sizeof(remotecwd) - 1; i++, cp++) {
if (cp[0] == '"') {
if (cp[1] == '"')
cp++;
else
break;
}
- remotepwd[i] = *cp;
+ remotecwd[i] = *cp;
}
- remotepwd[i] = '\0';
+ remotecwd[i] = '\0';
if (debug)
- fprintf(ttyout, "got remotepwd as `%s'\n", remotepwd);
- goto cleanupremotepwd;
- badremotepwd:
- remotepwd[0]='\0';
- cleanupremotepwd:
+ 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
@@ -1057,7 +1096,7 @@ formatbuf(char *buf, size_t len, const char *src)
case '/':
case '.':
case 'c':
- p2 = connected ? remotepwd : "";
+ p2 = connected ? remotecwd : "";
updirs = pdirs = 0;
/* option to determine fixed # of dirs from path */
diff --git a/contrib/lukemftp/src/version.h b/contrib/lukemftp/src/version.h
index 25307fb5ddb4..b864b6815d89 100644
--- a/contrib/lukemftp/src/version.h
+++ b/contrib/lukemftp/src/version.h
@@ -1,6 +1,6 @@
-/* $NetBSD: version.h,v 1.35 2004/04/10 12:21:39 lukem Exp $ */
+/* $NetBSD: version.h,v 1.44 2005/01/12 22:37:41 lukem Exp $ */
/*-
- * Copyright (c) 1999-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -40,5 +40,5 @@
#endif
#ifndef FTP_VERSION
-#define FTP_VERSION "20040410"
+#define FTP_VERSION "20050112"
#endif