summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2008-07-08 21:07:58 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2008-07-08 21:07:58 +0000
commit66a9ee29034eff1ef97bd24b19f4535c46d34b39 (patch)
tree77b34a49e6173e9b4c9f16116a58c71b195c422f
parent7a3d395c69db3c8452efe68ea465fcf6112fd974 (diff)
- add support for recursive transfers (but not for floppies), e.g.
'mget -cr 4.*' would recursively fetch (-r), and resume the previous transfers (-c) of 4.X release directories uses local matching (fnmatch), but only for recursive transfers. current behavior is not changed in any way. - while here, ifndef SMALL debugging stuff, this saves some space, for floppies - some debugging code was enabled for non-debugging mode, checks assume debug is set to zero, but it's not initially set - all "Confirm with" prompts are forced, remove redundant argument - fix usage: -C and -c are not available for SMALL discussed a year ago w/ pyr@ looks good to millert@ previous version looked good to pyr@ man page tweaks & ok jmc@
-rw-r--r--usr.bin/ftp/Makefile6
-rw-r--r--usr.bin/ftp/cmds.c149
-rw-r--r--usr.bin/ftp/cmdtab.c6
-rw-r--r--usr.bin/ftp/complete.c6
-rw-r--r--usr.bin/ftp/extern.h10
-rw-r--r--usr.bin/ftp/fetch.c14
-rw-r--r--usr.bin/ftp/ftp.141
-rw-r--r--usr.bin/ftp/ftp.c29
-rw-r--r--usr.bin/ftp/ftp_var.h4
-rw-r--r--usr.bin/ftp/list.c76
-rw-r--r--usr.bin/ftp/main.c30
-rw-r--r--usr.bin/ftp/util.c95
12 files changed, 370 insertions, 96 deletions
diff --git a/usr.bin/ftp/Makefile b/usr.bin/ftp/Makefile
index b2e4e802d96..bcdc8eedd99 100644
--- a/usr.bin/ftp/Makefile
+++ b/usr.bin/ftp/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.22 2007/06/13 13:52:26 pyr Exp $
+# $OpenBSD: Makefile,v 1.23 2008/07/08 21:07:57 martynas Exp $
# Define SMALL to disable command line editing and https support
#CFLAGS+=-DSMALL
@@ -12,8 +12,8 @@ LDADD += -lsocks5
.endif
PROG= ftp
-SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c ruserpass.c \
- cookie.c stringlist.c util.c
+SRCS= cmds.c cmdtab.c complete.c cookie.c domacro.c fetch.c ftp.c list.c \
+ main.c ruserpass.c stringlist.c util.c
CPPFLAGS+= -DINET6
diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c
index d04ab8ca3ca..b97454cdd19 100644
--- a/usr.bin/ftp/cmds.c
+++ b/usr.bin/ftp/cmds.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmds.c,v 1.62 2008/06/25 18:07:00 martynas Exp $ */
+/* $OpenBSD: cmds.c,v 1.63 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: cmds.c,v 1.27 1997/08/18 10:20:15 lukem Exp $ */
/*
@@ -60,7 +60,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: cmds.c,v 1.62 2008/06/25 18:07:00 martynas Exp $";
+static const char rcsid[] = "$OpenBSD: cmds.c,v 1.63 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -74,6 +74,9 @@ static const char rcsid[] = "$OpenBSD: cmds.c,v 1.62 2008/06/25 18:07:00 martyna
#include <ctype.h>
#include <err.h>
+#ifndef SMALL
+#include <fnmatch.h>
+#endif /* !SMALL */
#include <glob.h>
#include <netdb.h>
#include <stdio.h>
@@ -162,7 +165,11 @@ changetype(int newtype, int show)
newtype = TYPE_I;
if (newtype == curtype)
return;
- if (debug == 0 && show == 0)
+ if (
+#ifndef SMALL
+ !debug &&
+#endif /* !SMALL */
+ show == 0)
verbose = 0;
for (p = types; p->t_name; p++)
if (newtype == p->t_type)
@@ -372,10 +379,9 @@ usage:
}
#ifndef SMALL
- optind--;
- argv[optind] = argv[0];
- argc -= optind;
- argv += optind;
+ argv[optind - 1] = argv[0];
+ argc -= optind - 1;
+ argv += optind - 1;
#endif /* !SMALL */
mname = argv[0];
@@ -391,7 +397,7 @@ usage:
mflag = 0;
continue;
}
- if (mflag && confirm(argv[0], cp, 0)) {
+ if (mflag && confirm(argv[0], cp)) {
tp = cp;
if (mcase) {
while (*tp && !islower(*tp)) {
@@ -433,8 +439,7 @@ usage:
cp != tp || !interactive);
restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with",
- argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag = 1;
}
}
@@ -449,7 +454,7 @@ usage:
int flags;
if (!doglob) {
- if (mflag && confirm(argv[0], argv[i], 0)) {
+ if (mflag && confirm(argv[0], argv[i])) {
tp = (ntflag) ? dotrans(argv[i]) : argv[i];
tp = (mapflag) ? domap(tp) : tp;
#ifndef SMALL
@@ -468,8 +473,7 @@ usage:
tp != argv[i] || !interactive);
restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with",
- argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag = 1;
}
}
@@ -484,7 +488,7 @@ usage:
continue;
}
for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) {
- if (mflag && confirm(argv[0], *cpp, 0)) {
+ if (mflag && confirm(argv[0], *cpp)) {
tp = (ntflag) ? dotrans(*cpp) : *cpp;
tp = (mapflag) ? domap(tp) : tp;
#ifndef SMALL
@@ -503,8 +507,7 @@ usage:
*cpp != tp || !interactive);
restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with",
- argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag = 1;
}
}
@@ -630,7 +633,7 @@ mabort(int signo)
putc('\n', ttyout);
(void)fflush(ttyout);
if (mflag && fromatty)
- if (confirm("Continue with", mname, 1))
+ if (confirm(mname, NULL))
longjmp(jabort, 1);
mflag = 0;
longjmp(jabort, 1);
@@ -644,17 +647,26 @@ mget(int argc, char *argv[])
{
extern int optind, optreset;
sig_t oldintr;
- int ch, restartit = 0;
+ int ch;
char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN], localcwd[MAXPATHLEN];
+#ifndef SMALL
+ int i = 1, restartit = 0, xargc = 2;
+ char type = NULL, *xargv[] = {argv[0], ".", NULL, NULL};
+ FILE *ftemp = NULL;
+ static int depth = 0;
+#endif /* !SMALL */
optind = optreset = 1;
#ifndef SMALL
- while ((ch = getopt(argc, argv, "c")) != -1) {
+ while ((ch = getopt(argc, argv, "cr")) != -1) {
switch(ch) {
case 'c':
restartit = 1;
break;
+ case 'r':
+ depth++;
+ break;
default:
goto usage;
}
@@ -663,16 +675,15 @@ mget(int argc, char *argv[])
if (argc - optind < 1 && !another(&argc, &argv, "remote-files")) {
usage:
- fprintf(ttyout, "usage: %s [-c] remote-files\n", argv[0]);
+ fprintf(ttyout, "usage: %s [-cr] remote-files\n", argv[0]);
code = -1;
return;
}
#ifndef SMALL
- optind--;
- argv[optind] = argv[0];
- argc -= optind;
- argv += optind;
+ argv[optind - 1] = argv[0];
+ argc -= optind - 1;
+ argv += optind - 1;
#endif /* !SMALL */
mname = argv[0];
@@ -682,19 +693,80 @@ usage:
oldintr = signal(SIGINT, mabort);
(void)setjmp(jabort);
- while ((cp = remglob(argv, proxy, NULL)) != NULL) {
+ while ((cp =
+#ifndef SMALL
+ depth ? remglob2(xargv, proxy, NULL, &ftemp, &type) :
+#endif /* !SMALL */
+ remglob(argv, proxy, NULL)) != NULL
+#ifndef SMALL
+ || (mflag && depth && ++i < argc)
+#endif /* !SMALL */
+ ) {
+#ifndef SMALL
+ if (cp == NULL)
+ continue;
+#endif /* !SMALL */
if (*cp == '\0') {
mflag = 0;
continue;
}
if (!mflag)
continue;
+#ifndef SMALL
+ if (depth && fnmatch(argv[i], cp, FNM_PATHNAME) != 0)
+ continue;
+#endif /* !SMALL */
if (!fileindir(cp, localcwd)) {
fprintf(ttyout, "Skipping non-relative filename `%s'\n",
cp);
continue;
}
- if (confirm(argv[0], cp, 0)) {
+ if (confirm(argv[0], cp)) {
+#ifndef SMALL
+ if (type == 'd') {
+ mkdir(cp, 0755);
+ if (chdir(cp) != 0) {
+ warn("local: %s", cp);
+ continue;
+ }
+
+ xargv[1] = cp;
+ xargv[2] = NULL;
+ xargc = 2;
+ cd(xargc, xargv);
+ if (dirchange != 1)
+ goto out;
+
+ xargv[1] = (restartit == 1) ? "-cr" : "-r";
+ xargv[2] = "*";
+ xargv[3] = NULL;
+ xargc = 3;
+ mget(xargc, xargv);
+
+ xargv[1] = "..";
+ xargv[2] = NULL;
+ xargc = 2;
+ cd(xargc, xargv);
+ if (dirchange != 1) {
+ mflag = 0;
+ goto out;
+ }
+
+out:
+ if (chdir("..") != 0) {
+ warn("local: %s", cp);
+ mflag = 0;
+ }
+
+ xargv[1] = ".";
+ xargv[2] = NULL;
+ xargc = 2;
+ continue;
+ }
+ if (type == 's')
+ /* Currently ignored. */
+ continue;
+#endif /* !SMALL */
tp = cp;
if (mcase) {
for (tp2 = tmpbuf; (ch = *tp++) != 0; )
@@ -719,13 +791,20 @@ usage:
tp != cp || !interactive, 1);
restart_point = 0;
if (!mflag && fromatty) {
- if (confirm("Continue with", argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag = 1;
}
}
}
(void)signal(SIGINT, oldintr);
+#ifndef SMALL
+ if (depth)
+ depth--;
+ if (depth == 0 || mflag == 0)
+ depth = mflag = 0;
+#else /* !SMALL */
mflag = 0;
+#endif /* !SMALL */
}
char *
@@ -833,10 +912,10 @@ setbell(int argc, char *argv[])
code = togglevar(argc, argv, &bell, "Bell mode");
}
-#ifndef SMALL
/*
* Set command line editing
*/
+#ifndef SMALL
/*ARGSUSED*/
void
setedit(int argc, char *argv[])
@@ -1021,6 +1100,7 @@ setpreserve(int argc, char *argv[])
/*
* Set debugging mode on/off and/or set level of debugging.
*/
+#ifndef SMALL
/*ARGSUSED*/
void
setdebug(int argc, char *argv[])
@@ -1056,6 +1136,7 @@ setdebug(int argc, char *argv[])
fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(debug), debug);
code = debug > 0;
}
+#endif /* !SMALL */
/*
* Set current working directory on remote machine.
@@ -1158,10 +1239,10 @@ mdelete(int argc, char *argv[])
mflag = 0;
continue;
}
- if (mflag && confirm(argv[0], cp, 0)) {
+ if (mflag && confirm(argv[0], cp)) {
(void)command("DELE %s", cp);
if (!mflag && fromatty) {
- if (confirm("Continue with", argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag = 1;
}
}
@@ -1215,7 +1296,7 @@ ls(int argc, char *argv[])
}
globargv2 = argv[2];
if (strcmp(argv[2], "-") && *argv[2] != '|' && (!globulize(&argv[2]) ||
- !confirm("output to local-file:", argv[2], 0))) {
+ !confirm("output to local-file:", argv[2]))) {
code = -1;
goto freels;
}
@@ -1252,7 +1333,7 @@ usage:
argv[argc - 1] = NULL;
if (strcmp(dest, "-") && *dest != '|')
if (!globulize(&dest) ||
- !confirm("output to local-file:", dest, 0)) {
+ !confirm("output to local-file:", dest)) {
code = -1;
return;
}
@@ -1264,7 +1345,7 @@ usage:
*lmode = (i == 1) ? 'w' : 'a';
recvrequest("LIST", dest, argv[i], lmode, 0, 0);
if (!mflag && fromatty) {
- if (confirm("Continue with", argv[0], 1))
+ if (confirm(argv[0], NULL))
mflag ++;
}
}
@@ -1303,11 +1384,13 @@ shell(int argc, char *argv[])
(void)strlcpy(shellnam + 1, ++namep, sizeof(shellnam) - 1);
if (strcmp(namep, "sh") != 0)
shellnam[0] = '+';
+#ifndef SMALL
if (debug) {
fputs(shellp, ttyout);
fputc('\n', ttyout);
(void)fflush(ttyout);
}
+#endif /* !SMALL */
if (argc > 1) {
execl(shellp, shellnam, "-c", altarg, (char *)0);
}
diff --git a/usr.bin/ftp/cmdtab.c b/usr.bin/ftp/cmdtab.c
index 07744ae4818..bc84d937129 100644
--- a/usr.bin/ftp/cmdtab.c
+++ b/usr.bin/ftp/cmdtab.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmdtab.c,v 1.22 2008/06/25 21:15:19 martynas Exp $ */
+/* $OpenBSD: cmdtab.c,v 1.23 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: cmdtab.c,v 1.17 1997/08/18 10:20:17 lukem Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.22 2008/06/25 21:15:19 martynas Exp $";
+static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.23 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
#include <stdio.h>
@@ -148,7 +148,9 @@ struct cmd cmdtab[] = {
{ "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 },
+#ifndef SMALL
{ "debug", H(debughelp), 0, 0, 0, CMPL0 setdebug },
+#endif /* !SMALL */
{ "delete", H(deletehelp), 0, 1, 1, CMPL(r) deletecmd },
{ "dir", H(dirhelp), 1, 1, 1, CMPL(rl) ls },
{ "disconnect", H(disconhelp), 0, 1, 1, CMPL0 disconnect },
diff --git a/usr.bin/ftp/complete.c b/usr.bin/ftp/complete.c
index 147f4bf1441..c2224af07e0 100644
--- a/usr.bin/ftp/complete.c
+++ b/usr.bin/ftp/complete.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: complete.c,v 1.20 2008/06/26 05:42:20 ray Exp $ */
+/* $OpenBSD: complete.c,v 1.21 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: complete.c,v 1.10 1997/08/18 10:20:18 lukem Exp $ */
/*-
@@ -32,7 +32,7 @@
#ifndef SMALL
#ifndef lint
-static const char rcsid[] = "$OpenBSD: complete.c,v 1.20 2008/06/26 05:42:20 ray Exp $";
+static const char rcsid[] = "$OpenBSD: complete.c,v 1.21 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint */
/*
@@ -234,8 +234,10 @@ complete_remote(char *word, int list)
mflag = 1;
emesg = NULL;
+#ifndef SMALL
if (debug)
(void)putc('\n', ttyout);
+#endif /* !SMALL */
while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) {
char *tcp;
diff --git a/usr.bin/ftp/extern.h b/usr.bin/ftp/extern.h
index 7d3c32368e9..5afc88706ce 100644
--- a/usr.bin/ftp/extern.h
+++ b/usr.bin/ftp/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.34 2008/06/25 21:15:19 martynas Exp $ */
+/* $OpenBSD: extern.h,v 1.35 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: extern.h,v 1.17 1997/08/18 10:20:19 lukem Exp $ */
/*
@@ -82,7 +82,7 @@ int command(const char *, ...);
unsigned char complete(EditLine *, int);
void controlediting(void);
#endif /* !SMALL */
-int confirm(const char *, const char *, int);
+int confirm(const char *, const char *);
FILE *dataconn(const char *);
void deletecmd(int, char **);
void disconnect(int, char **);
@@ -142,6 +142,9 @@ void recvrequest(const char *, const char *, const char *,
const char *, int, int);
void reget(int, char **);
char *remglob(char **, int, char **);
+#ifndef SMALL
+char *remglob2(char **, int, char **, FILE **ftemp, char *type);
+#endif /* !SMALL */
off_t remotesize(const char *, int);
time_t remotemodtime(const char *, int);
void removedir(int, char **);
@@ -157,7 +160,9 @@ void setbell(int, char **);
void setbinary(int, char **);
void setcase(int, char **);
void setcr(int, char **);
+#ifndef SMALL
void setdebug(int, char **);
+#endif /* !SMALL */
void setedit(int, char **);
void setepsv4(int, char **);
void setform(int, char **);
@@ -195,6 +200,7 @@ void user(int, char **);
int ruserpass(const char *, char **, char **, char **);
void cookie_load(void);
void cookie_get(const char *, const char *, int, char **);
+void parse_list(char **, char *);
#endif /* !SMALL */
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index dffed5d9da5..e0afe8da70e 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fetch.c,v 1.79 2008/06/26 05:42:20 ray Exp $ */
+/* $OpenBSD: fetch.c,v 1.80 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
/*-
@@ -31,7 +31,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: fetch.c,v 1.79 2008/06/26 05:42:20 ray Exp $";
+static const char rcsid[] = "$OpenBSD: fetch.c,v 1.80 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -353,9 +353,11 @@ url_get(const char *origline, const char *proxyenv, const char *outfile)
if (portnum != NULL)
*portnum++ = '\0';
+#ifndef SMALL
if (debug)
fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n",
host, portnum, path, savefile);
+#endif /* !SMALL */
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
@@ -558,8 +560,10 @@ again:
while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
buf[--len] = '\0';
+#ifndef SMALL
if (debug)
fprintf(ttyout, "received '%s'\n", buf);
+#endif /* !SMALL */
cp = strchr(buf, ' ');
if (cp == NULL)
@@ -616,8 +620,10 @@ again:
buf[--len] = '\0';
if (len == 0)
break;
+#ifndef SMALL
if (debug)
fprintf(ttyout, "received '%s'\n", buf);
+#endif /* !SMALL */
/* Look for some headers */
cp = buf;
@@ -974,11 +980,13 @@ bad_ftp_url:
dir = NULL;
}
}
+#ifndef SMALL
if (debug)
fprintf(ttyout,
"user %s:%s host %s port %s dir %s file %s\n",
username, pass ? "XXXX" : NULL, host, portnum,
dir, file);
+#endif /* !SMALL */
/*
* Set up the connection.
@@ -1276,8 +1284,10 @@ proxy_connect(int socket, char *host)
l = asprintf(&connstr, "CONNECT %s:%s HTTP/1.1\n\n", host, port);
if (l == -1)
errx(1, "Could not allocate memory to assemble connect string!");
+#ifndef SMALL
if (debug)
printf("%s", connstr);
+#endif /* !SMALL */
if (write(socket, connstr, l) != l)
err(1, "Could not send connect string");
read(socket, &buf, sizeof(buf)); /* only proxy header XXX: error handling? */
diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1
index 7471497603e..f817cf1d2fc 100644
--- a/usr.bin/ftp/ftp.1
+++ b/usr.bin/ftp/ftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ftp.1,v 1.70 2008/06/25 18:07:00 martynas Exp $
+.\" $OpenBSD: ftp.1,v 1.71 2008/07/08 21:07:57 martynas Exp $
.\" $NetBSD: ftp.1,v 1.22 1997/08/18 10:20:22 lukem Exp $
.\"
.\" Copyright (c) 1985, 1989, 1990, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
-.Dd $Mdocdate: June 25 2008 $
+.Dd $Mdocdate: July 8 2008 $
.Dt FTP 1
.Os
.Sh NAME
@@ -557,7 +557,7 @@ on the remote machine.
A synonym for
.Ic mls .
.It Xo Ic mget
-.Op Fl c
+.Op Fl cr
.Ar remote-files
.Xc
Expand the
@@ -566,11 +566,6 @@ on the remote machine
and do a
.Ic get
for each file name thus produced.
-If the
-.Fl c
-flag is specified, then
-.Ic reget
-is used instead for the partially transferred files.
See
.Ic glob
for details on the filename expansion.
@@ -585,6 +580,19 @@ which can be changed with
.Ql lcd directory ;
new local directories can be created with
.Ql "\&! mkdir directory" .
+.Pp
+If the
+.Fl c
+flag is specified then
+.Ic reget
+is used instead of
+.Ic get .
+If the
+.Fl r
+flag is specified,
+.Nm
+recursively descends the directory tree,
+transferring all files and directories.
.It Ic mkdir Ar directory-name
Make a directory on the remote machine.
.It Ic mls Ar remote-files local-file
@@ -621,11 +629,6 @@ Expand wild cards in the list of local files given as arguments
and do a
.Ic put
for each file in the resulting list.
-If the
-.Fl c
-flag is specified, then
-.Ic reput
-is used instead for the partially transferred files.
See
.Ic glob
for details of filename expansion.
@@ -634,6 +637,13 @@ Resulting file names will then be processed according to
and
.Ic nmap
settings.
+.Pp
+If the
+.Fl c
+flag is specified then
+.Ic reput
+is used instead of
+.Ic put .
.It Ic msend Ar local-files
A synonym for
.Ic mput .
@@ -1638,3 +1648,8 @@ to and from
.Bx 4.2
servers using the ASCII type.
Avoid this problem by using the binary image type.
+.Pp
+In the recursive mode of
+.Ic mget ,
+files and directories starting with whitespace are ignored
+because the list cannot be parsed any other way.
diff --git a/usr.bin/ftp/ftp.c b/usr.bin/ftp/ftp.c
index 4055b6a7946..44f4297852e 100644
--- a/usr.bin/ftp/ftp.c
+++ b/usr.bin/ftp/ftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp.c,v 1.72 2008/06/25 21:15:19 martynas Exp $ */
+/* $OpenBSD: ftp.c,v 1.73 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: ftp.c,v 1.27 1997/08/18 10:20:23 lukem Exp $ */
/*
@@ -60,7 +60,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: ftp.c,v 1.72 2008/06/25 21:15:19 martynas Exp $";
+static const char rcsid[] = "$OpenBSD: ftp.c,v 1.73 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
#include <sys/types.h>
@@ -257,12 +257,13 @@ hookup(char *host, char *port)
}
#ifdef SO_OOBINLINE
{
- int on = 1;
+ int ret, on = 1;
- if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
- < 0 && debug) {
- warn("setsockopt");
- }
+ ret = setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on));
+#ifndef SMALL
+ if (ret < 0 && debug)
+ warn("setsockopt");
+#endif /* !SMALL */
}
#endif /* SO_OOBINLINE */
@@ -294,6 +295,7 @@ command(const char *fmt, ...)
sig_t oldintr;
abrtflag = 0;
+#ifndef SMALL
if (debug) {
fputs("---> ", ttyout);
va_start(ap, fmt);
@@ -307,6 +309,7 @@ command(const char *fmt, ...)
putc('\n', ttyout);
(void)fflush(ttyout);
}
+#endif /* !SMALL */
if (cout == NULL) {
warnx("No control connection for command.");
code = -1;
@@ -338,8 +341,10 @@ static int current_nop_pos = 0; /* 0 -> no noop started */
void
send_noop_char()
{
+#ifndef SMALL
if (debug)
fprintf(ttyout, "---> %c\n", noop[current_nop_pos]);
+#endif /* !SMALL */
fputc(noop[current_nop_pos++], cout);
(void)fflush(cout);
if (current_nop_pos >= NOOP_LENGTH) {
@@ -363,8 +368,10 @@ may_receive_noop_ack()
/* finish sending last incomplete noop */
if (current_nop_pos != 0) {
fputs(&(noop[current_nop_pos]), cout);
+#ifndef SMALL
if (debug)
fprintf(ttyout, "---> %s\n", &(noop[current_nop_pos]));
+#endif /* !SMALL */
(void)fflush(cout);
current_nop_pos = 0;
full_noops_sent++;
@@ -1245,10 +1252,12 @@ reinit:
warn("socket");
return (1);
}
+#ifndef SMALL
if ((options & SO_DEBUG) &&
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on)) < 0)
warn("setsockopt (ignored)");
+#endif /* !SMALL */
switch (data_addr.su_family) {
case AF_INET:
if (epsv4 && !epsv4bad) {
@@ -1270,11 +1279,13 @@ reinit:
}
if (result != COMPLETE) {
epsv4bad = 1;
+#ifndef SMALL
if (debug) {
fputs(
"disabling epsv4 for this connection\n",
ttyout);
}
+#endif /* !SMALL */
}
}
if (result != COMPLETE)
@@ -1513,10 +1524,12 @@ noport:
warn("bind");
goto bad;
}
+#ifndef SMALL
if (options & SO_DEBUG &&
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on)) < 0)
warn("setsockopt (ignored)");
+#endif /* !SMALL */
namelen = sizeof(data_addr);
if (getsockname(data, (struct sockaddr *)&data_addr, &namelen) < 0) {
warn("getsockname");
@@ -1553,11 +1566,13 @@ noport:
af_tmp, hname, pbuf);
if (result != COMPLETE) {
epsv4bad = 1;
+#ifndef SMALL
if (debug) {
fputs(
"disabling epsv4 for this connection\n",
ttyout);
}
+#endif /* !SMALL */
}
}
break;
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index 8a2e9763145..05990783b3e 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp_var.h,v 1.26 2008/06/25 21:15:19 martynas Exp $ */
+/* $OpenBSD: ftp_var.h,v 1.27 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: ftp_var.h,v 1.18 1997/08/18 10:20:25 lukem Exp $ */
/*
@@ -110,7 +110,9 @@ int connected; /* 1 = connected to server, -1 = logged in */
int fromatty; /* input is from a terminal */
int interactive; /* interactively prompt on m* cmds */
int confirmrest; /* confirm rest of current m* cmd */
+#ifndef SMALL
int debug; /* debugging level */
+#endif /* !SMALL */
int bell; /* ring bell on cmd completion */
int doglob; /* glob local file names */
int autologin; /* establish user account on connection */
diff --git a/usr.bin/ftp/list.c b/usr.bin/ftp/list.c
new file mode 100644
index 00000000000..909b7592975
--- /dev/null
+++ b/usr.bin/ftp/list.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SMALL
+#include <string.h>
+
+void
+parse_unix(char **line, char *type)
+{
+ char *tok;
+ int field = 0;
+
+ while ((tok = strsep(line, " \t")) != NULL) {
+ if (*tok == '\0')
+ continue;
+
+ if (field == 0)
+ *type = *tok;
+
+ if (field == 7) {
+ while (**line == ' ' || **line == '\t')
+ (*line)++;
+ break;
+ }
+
+ field++;
+ }
+}
+
+void
+parse_windows(char **line, char *type)
+{
+ char *tok;
+ int field = 0;
+
+ *type = '-';
+ while ((tok = strsep(line, " \t")) != NULL) {
+ if (*tok == '\0')
+ continue;
+
+ if (field == 2 && strcmp(tok, "<DIR>") == 0)
+ *type = 'd';
+
+ if (field == 2) {
+ while (**line == ' ' || **line == '\t')
+ (*line)++;
+ break;
+ }
+
+ field++;
+ }
+}
+
+void
+parse_list(char **line, char *type)
+{
+ if (**line >= '0' && **line <= '9')
+ return parse_windows(line, type);
+
+ return parse_unix(line, type);
+}
+
+#endif /* !SMALL */
diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index 02b96f151fe..90e247f7e7a 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.69 2008/06/25 21:15:19 martynas Exp $ */
+/* $OpenBSD: main.c,v 1.70 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: main.c,v 1.24 1997/08/18 10:20:26 lukem Exp $ */
/*
@@ -66,7 +66,7 @@ static const char copyright[] =
#endif /* not lint */
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: main.c,v 1.69 2008/06/25 21:15:19 martynas Exp $";
+static const char rcsid[] = "$OpenBSD: main.c,v 1.70 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -212,8 +212,10 @@ main(volatile int argc, char *argv[])
break;
case 'd':
+#ifndef SMALL
options |= SO_DEBUG;
debug++;
+#endif /* !SMALL */
break;
case 'E':
@@ -764,17 +766,33 @@ void
usage(void)
{
(void)fprintf(stderr,
- "usage: %s [-46AadEegimnptVv] [-k seconds] "
+ "usage: %s [-46Aa"
+#ifndef SMALL
+ "d"
+#endif /* !SMALL */
+ "EegimnptVv] [-k seconds] "
"[-P port] [-r seconds] [host [port]]\n"
- " %s [-C] [-o output] "
+ " %s "
+#ifndef SMALL
+ "[-C] "
+#endif /* !SMALL */
+ "[-o output] "
"ftp://[user:password@]host[:port]/file[/]\n"
- " %s [-C] [-c cookie] [-o output] "
+ " %s "
+#ifndef SMALL
+ "[-C] [-c cookie] "
+#endif /* !SMALL */
+ "[-o output] "
"http://host[:port]/file\n"
#ifndef SMALL
" %s [-C] [-c cookie] [-o output] "
"https://host[:port]/file\n"
#endif /* !SMALL */
- " %s [-C] [-o output] host:[/path/]file[/]\n",
+ " %s "
+#ifndef SMALL
+ "[-C] "
+#endif /* !SMALL */
+ "[-o output] host:[/path/]file[/]\n",
#ifndef SMALL
__progname, __progname, __progname, __progname, __progname);
#else /* !SMALL */
diff --git a/usr.bin/ftp/util.c b/usr.bin/ftp/util.c
index 95a98214e89..9bed9278af3 100644
--- a/usr.bin/ftp/util.c
+++ b/usr.bin/ftp/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.53 2008/06/26 05:42:20 ray Exp $ */
+/* $OpenBSD: util.c,v 1.54 2008/07/08 21:07:57 martynas Exp $ */
/* $NetBSD: util.c,v 1.12 1997/08/18 10:20:27 lukem Exp $ */
/*-
@@ -64,7 +64,7 @@
*/
#if !defined(lint) && !defined(SMALL)
-static const char rcsid[] = "$OpenBSD: util.c,v 1.53 2008/06/26 05:42:20 ray Exp $";
+static const char rcsid[] = "$OpenBSD: util.c,v 1.54 2008/07/08 21:07:57 martynas Exp $";
#endif /* not lint and not SMALL */
/*
@@ -174,7 +174,9 @@ setpeer(int argc, char *argv[])
* system and not checking this out. This way they have to think about it.
*/
overbose = verbose;
- if (debug == 0)
+#ifndef SMALL
+ if (!debug)
+#endif /* !SMALL */
verbose = -1;
if (command("SYST") == COMPLETE && overbose) {
char *cp, c;
@@ -364,22 +366,24 @@ another(int *pargc, char ***pargv, const char *prompt)
* glob files given in argv[] from the remote server.
* if errbuf isn't NULL, store error messages there instead
* of writing to the screen.
+ * if type isn't NULL, use LIST instead of NLST, and store filetype.
+ * 'd' means directory, 's' means symbolic link, '-' means plain
+ * file.
*/
char *
-remglob(char *argv[], int doswitch, char **errbuf)
+remglob2(char *argv[], int doswitch, char **errbuf, FILE **ftemp, char *type)
{
- char temp[MAXPATHLEN], *cp, *lmode;
+ char temp[MAXPATHLEN], *bufp, *cp, *lmode;
static char buf[MAXPATHLEN], **args;
- static FILE *ftemp = NULL;
int oldverbose, oldhash, fd;
if (!mflag) {
if (!doglob)
args = NULL;
else {
- if (ftemp) {
- (void)fclose(ftemp);
- ftemp = NULL;
+ if (*ftemp) {
+ (void)fclose(*ftemp);
+ *ftemp = NULL;
}
}
return (NULL);
@@ -391,7 +395,7 @@ remglob(char *argv[], int doswitch, char **errbuf)
args = NULL;
return (cp);
}
- if (ftemp == NULL) {
+ if (*ftemp == NULL) {
int len;
if ((cp = getenv("TMPDIR")) == NULL || *cp == '\0')
@@ -419,7 +423,8 @@ remglob(char *argv[], int doswitch, char **errbuf)
if (doswitch)
pswitch(!proxy);
for (lmode = "w"; *++argv != NULL; lmode = "a")
- recvrequest("NLST", temp, *argv, lmode, 0, 0);
+ recvrequest(type ? "LIST" : "NLST", temp, *argv, lmode,
+ 0, 0);
if ((code / 100) != COMPLETE) {
if (errbuf != NULL)
*errbuf = reply_string;
@@ -428,9 +433,9 @@ remglob(char *argv[], int doswitch, char **errbuf)
pswitch(!proxy);
verbose = oldverbose;
hash = oldhash;
- ftemp = fopen(temp, "r");
+ *ftemp = fopen(temp, "r");
(void)unlink(temp);
- if (ftemp == NULL) {
+ if (*ftemp == NULL) {
if (errbuf == NULL)
fputs("can't find list of remote files, oops.\n",
ttyout);
@@ -440,26 +445,50 @@ remglob(char *argv[], int doswitch, char **errbuf)
return (NULL);
}
}
- if (fgets(buf, sizeof(buf), ftemp) == NULL) {
- (void)fclose(ftemp);
- ftemp = NULL;
+again:
+ if (fgets(buf, sizeof(buf), *ftemp) == NULL) {
+ (void)fclose(*ftemp);
+ *ftemp = NULL;
return (NULL);
}
buf[strcspn(buf, "\n")] = '\0';
+ bufp = buf;
+
+#ifndef SMALL
+ if (type) {
+ parse_list(&bufp, type);
+ if (!bufp)
+ goto again;
+ }
+#endif /* !SMALL */
+
+ return (bufp);
+}
+
+/*
+ * wrapper for remglob2
+ */
+char *
+remglob(char *argv[], int doswitch, char **errbuf)
+{
+ static FILE *ftemp = NULL;
- return (buf);
+ return remglob2(argv, doswitch, errbuf, &ftemp, NULL);
}
int
-confirm(const char *cmd, const char *file, int force)
+confirm(const char *cmd, const char *file)
{
char str[BUFSIZ];
- if (!force && (confirmrest || !interactive))
+ if (file && (confirmrest || !interactive))
return (1);
top:
- fprintf(ttyout, "%s %s? ", cmd, file);
+ if (file)
+ fprintf(ttyout, "%s %s? ", cmd, file);
+ else
+ fprintf(ttyout, "Continue with %s? ", cmd);
(void)fflush(ttyout);
if (fgets(str, sizeof(str), stdin) == NULL)
goto quit;
@@ -545,7 +574,9 @@ remotesize(const char *file, int noisy)
overbose = verbose;
size = -1;
- if (debug == 0)
+#ifndef SMALL
+ if (!debug)
+#endif /* !SMALL */
verbose = -1;
if (command("SIZE %s", file) == COMPLETE) {
char *cp, *ep;
@@ -557,7 +588,11 @@ remotesize(const char *file, int noisy)
if (*ep != '\0' && !isspace(*ep))
size = -1;
}
- } else if (noisy && debug == 0) {
+ } else if (noisy
+#ifndef SMALL
+ && !debug
+#endif /* !SMALL */
+ ) {
fputs(reply_string, ttyout);
fputc('\n', ttyout);
}
@@ -578,7 +613,9 @@ remotemodtime(const char *file, int noisy)
overbose = verbose;
ocode = code;
rtime = -1;
- if (debug == 0)
+#ifndef SMALL
+ if (!debug)
+#endif /* !SMALL */
verbose = -1;
if (command("MDTM %s", file) == COMPLETE) {
struct tm timebuf;
@@ -614,11 +651,19 @@ remotemodtime(const char *file, int noisy)
timebuf.tm_year = yy - TM_YEAR_BASE;
timebuf.tm_isdst = -1;
rtime = mktime(&timebuf);
- if (rtime == -1 && (noisy || debug != 0))
+ if (rtime == -1 && (noisy
+#ifndef SMALL
+ || debug
+#endif /* !SMALL */
+ ))
fprintf(ttyout, "Can't convert %s to a time.\n", reply_string);
else
rtime += timebuf.tm_gmtoff; /* conv. local -> GMT */
- } else if (noisy && debug == 0) {
+ } else if (noisy
+#ifndef SMALL
+ && !debug
+#endif /* !SMALL */
+ ) {
fputs(reply_string, ttyout);
fputc('\n', ttyout);
}