diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2008-07-08 21:07:58 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2008-07-08 21:07:58 +0000 |
commit | 66a9ee29034eff1ef97bd24b19f4535c46d34b39 (patch) | |
tree | 77b34a49e6173e9b4c9f16116a58c71b195c422f /usr.bin/ftp | |
parent | 7a3d395c69db3c8452efe68ea465fcf6112fd974 (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@
Diffstat (limited to 'usr.bin/ftp')
-rw-r--r-- | usr.bin/ftp/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/ftp/cmds.c | 149 | ||||
-rw-r--r-- | usr.bin/ftp/cmdtab.c | 6 | ||||
-rw-r--r-- | usr.bin/ftp/complete.c | 6 | ||||
-rw-r--r-- | usr.bin/ftp/extern.h | 10 | ||||
-rw-r--r-- | usr.bin/ftp/fetch.c | 14 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.1 | 41 | ||||
-rw-r--r-- | usr.bin/ftp/ftp.c | 29 | ||||
-rw-r--r-- | usr.bin/ftp/ftp_var.h | 4 | ||||
-rw-r--r-- | usr.bin/ftp/list.c | 76 | ||||
-rw-r--r-- | usr.bin/ftp/main.c | 30 | ||||
-rw-r--r-- | usr.bin/ftp/util.c | 95 |
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); } |