diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-02-03 01:02:44 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-02-03 01:02:44 +0000 |
commit | 608493bb3d8aaa88f2804c620ef8d208ba98b08a (patch) | |
tree | 23945a49ad1cb6c935d583e9738f80716c268e49 /usr.bin/ftp/cmds.c | |
parent | b6a2ec9ce1490038560dc7ff89049580f7123f3c (diff) |
Sync with NetBSD
Diffstat (limited to 'usr.bin/ftp/cmds.c')
-rw-r--r-- | usr.bin/ftp/cmds.c | 764 |
1 files changed, 273 insertions, 491 deletions
diff --git a/usr.bin/ftp/cmds.c b/usr.bin/ftp/cmds.c index 9b7d4aa812f..76529c943f6 100644 --- a/usr.bin/ftp/cmds.c +++ b/usr.bin/ftp/cmds.c @@ -1,5 +1,4 @@ -/* $OpenBSD: cmds.c,v 1.12 1997/01/29 22:11:36 millert Exp $ */ -/* $NetBSD: cmds.c,v 1.8 1995/09/08 01:06:05 tls Exp $ */ +/* $NetBSD: cmds.c,v 1.18 1997/02/01 10:44:54 lukem Exp $ */ /* * Copyright (c) 1985, 1989, 1993, 1994 @@ -38,31 +37,27 @@ #if 0 static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94"; #else -static char rcsid[] = "$OpenBSD: cmds.c,v 1.12 1997/01/29 22:11:36 millert Exp $"; +static char rcsid[] = "$NetBSD: cmds.c,v 1.18 1997/02/01 10:44:54 lukem Exp $"; #endif #endif /* not lint */ /* * FTP User Program -- Command Routines. */ -#include <sys/param.h> -#include <sys/wait.h> -#include <sys/stat.h> +#include <sys/types.h> #include <sys/socket.h> -#include <netinet/in.h> +#include <sys/stat.h> +#include <sys/wait.h> #include <arpa/ftp.h> #include <ctype.h> #include <err.h> #include <glob.h> #include <netdb.h> -#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <time.h> #include <unistd.h> -#include <fcntl.h> #include "ftp_var.h" #include "pathnames.h" @@ -71,147 +66,6 @@ jmp_buf jabort; char *mname; char *home = "/"; -/* - * `Another' gets another argument, and stores the new argc and argv. - * It reverts to the top level (via main.c's intr()) on EOF/error. - * - * Returns false if no new arguments have been added. - */ -int -another(pargc, pargv, prompt) - int *pargc; - char ***pargv; - char *prompt; -{ - int len = strlen(line), ret; - - if (len >= sizeof(line) - 3) { - printf("sorry, arguments too long\n"); - intr(); - } - printf("(%s) ", prompt); - line[len++] = ' '; - if (fgets(&line[len], sizeof(line) - len, stdin) == NULL) - intr(); - len += strlen(&line[len]); - if (len > 0 && line[len - 1] == '\n') - line[len - 1] = '\0'; - makeargv(); - ret = margc > *pargc; - *pargc = margc; - *pargv = margv; - return (ret); -} - -/* - * Connect to peer server and - * auto-login, if possible. - */ -void -setpeer(argc, argv) - int argc; - char *argv[]; -{ - char *host; - short port; - - if (connected) { - printf("Already connected to %s, use close first.\n", - hostname); - code = -1; - return; - } - if (argc < 2) - (void) another(&argc, &argv, "to"); - if (argc < 2 || argc > 3) { - printf("usage: %s host-name [port]\n", argv[0]); - code = -1; - return; - } - port = sp->s_port; - if (argc > 2) { - port = atoi(argv[2]); - if (port <= 0) { - printf("%s: bad port number-- %s\n", argv[1], argv[2]); - printf ("usage: %s host-name [port]\n", argv[0]); - code = -1; - return; - } - port = htons(port); - } - host = hookup(argv[1], port); - if (host) { - int overbose; - - connected = 1; - /* - * Set up defaults for FTP. - */ - (void) strcpy(typename, "ascii"), type = TYPE_A; - curtype = TYPE_A; - (void) strcpy(formname, "non-print"), form = FORM_N; - (void) strcpy(modename, "stream"), mode = MODE_S; - (void) strcpy(structname, "file"), stru = STRU_F; - (void) strcpy(bytename, "8"), bytesize = 8; - if (autologin) - (void) login(argv[1]); - -#if defined(unix) && NBBY == 8 -/* - * this ifdef is to keep someone form "porting" this to an incompatible - * system and not checking this out. This way they have to think about it. - */ - overbose = verbose; - if (debug == 0) - verbose = -1; - if (command("SYST") == COMPLETE && overbose) { - char *cp, c; - cp = strchr(reply_string+4, ' '); - if (cp == NULL) - cp = strchr(reply_string+4, '\r'); - if (cp) { - if (cp[-1] == '.') - cp--; - c = *cp; - *cp = '\0'; - } - - printf("Remote system type is %s.\n", - reply_string+4); - if (cp) - *cp = c; - } - if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { - if (proxy) - unix_proxy = 1; - else - unix_server = 1; - /* - * Set type to 0 (not specified by user), - * meaning binary by default, but don't bother - * telling server. We can use binary - * for text files unless changed by the user. - */ - type = 0; - (void) strcpy(typename, "binary"); - if (overbose) - printf("Using %s mode to transfer files.\n", - typename); - } else { - if (proxy) - unix_proxy = 0; - else - unix_server = 0; - if (overbose && - !strncmp(reply_string, "215 TOPS20", 10)) - printf( -"Remember to set tenex mode when transfering binary files from this machine.\n"); - } - verbose = overbose; -#endif /* unix */ - } -} - struct types { char *t_name; char *t_mode; @@ -320,7 +174,7 @@ char *stype[] = { void setbinary(argc, argv) int argc; - char **argv; + char *argv[]; { stype[1] = "binary"; @@ -416,9 +270,9 @@ put(argc, argv) } if (argc < 2 && !another(&argc, &argv, "local-file")) goto usage; - if (argc < 3 && !another(&argc, &argv, "remote-file")) { + if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) { usage: - printf("usage: %s local-file remote-file\n", argv[0]); + printf("usage: %s local-file [ remote-file ]\n", argv[0]); code = -1; return; } @@ -452,7 +306,7 @@ usage: void mput(argc, argv) int argc; - char **argv; + char *argv[]; { int i; sig_t oldintr; @@ -471,8 +325,8 @@ mput(argc, argv) if (proxy) { char *cp, *tp2, tmpbuf[MAXPATHLEN]; - while ((cp = remglob(argv,0)) != NULL) { - if (*cp == 0) { + while ((cp = remglob(argv, 0)) != NULL) { + if (*cp == '\0') { mflag = 0; continue; } @@ -506,7 +360,7 @@ mput(argc, argv) if (!mflag && fromatty) { ointer = interactive; interactive = 1; - if (confirm("Continue with","mput")) { + if (confirm("Continue with", "mput")) { mflag++; } interactive = ointer; @@ -518,7 +372,7 @@ mput(argc, argv) return; } for (i = 1; i < argc; i++) { - char **cpp, **gargs; + char **cpp; glob_t gl; int flags; @@ -531,7 +385,7 @@ mput(argc, argv) if (!mflag && fromatty) { ointer = interactive; interactive = 1; - if (confirm("Continue with","mput")) { + if (confirm("Continue with", "mput")) { mflag++; } interactive = ointer; @@ -556,7 +410,7 @@ mput(argc, argv) if (!mflag && fromatty) { ointer = interactive; interactive = 1; - if (confirm("Continue with","mput")) { + if (confirm("Continue with", "mput")) { mflag++; } interactive = ointer; @@ -594,8 +448,8 @@ int getit(argc, argv, restartit, mode) int argc; char *argv[]; - char *mode; int restartit; + const char *mode; { int loc = 0; char *oldargv1, *oldargv2; @@ -607,7 +461,7 @@ getit(argc, argv, restartit, mode) } if (argc < 2 && !another(&argc, &argv, "remote-file")) goto usage; - if (argc < 3 && !another(&argc, &argv, "local-file")) { + if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) { usage: printf("usage: %s remote-file [ local-file ]\n", argv[0]); code = -1; @@ -655,38 +509,13 @@ usage: restart_point = stbuf.st_size; } else { if (ret == 0) { - int overbose; - - overbose = verbose; - if (debug == 0) - verbose = -1; - if (command("MDTM %s", argv[1]) == COMPLETE) { - int yy, mo, day, hour, min, sec; - struct tm *tm; - verbose = overbose; - sscanf(reply_string, - "%*s %04d%02d%02d%02d%02d%02d", - &yy, &mo, &day, &hour, &min, &sec); - tm = gmtime(&stbuf.st_mtime); - tm->tm_mon++; - if (tm->tm_year > yy%100) - return (1); - if ((tm->tm_year == yy%100 && - tm->tm_mon > mo) || - (tm->tm_mon == mo && - tm->tm_mday > day) || - (tm->tm_mday == day && - tm->tm_hour > hour) || - (tm->tm_hour == hour && - tm->tm_min > min) || - (tm->tm_min == min && - tm->tm_sec > sec)) - return (1); - } else { - printf("%s\n", reply_string); - verbose = overbose; + time_t mtime; + + mtime = remotemodtime(argv[1], 0); + if (mtime == -1) return (0); - } + if (stbuf.st_mtime >= mtime) + return (1); } } } @@ -702,21 +531,26 @@ void mabort(signo) int signo; { - int ointer; + int ointer, oconf; + alarmtimer(0); printf("\n"); (void) fflush(stdout); if (mflag && fromatty) { ointer = interactive; + oconf = confirmrest; interactive = 1; + confirmrest = 0; if (confirm("Continue with", mname)) { interactive = ointer; - longjmp(jabort,0); + confirmrest = oconf; + longjmp(jabort, 0); } interactive = ointer; + confirmrest = oconf; } mflag = 0; - longjmp(jabort,0); + longjmp(jabort, 0); } /* @@ -725,7 +559,7 @@ mabort(signo) void mget(argc, argv) int argc; - char **argv; + char *argv[]; { sig_t oldintr; int ch, ointer; @@ -740,7 +574,7 @@ mget(argc, argv) mflag = 1; oldintr = signal(SIGINT, mabort); (void) setjmp(jabort); - while ((cp = remglob(argv,proxy)) != NULL) { + while ((cp = remglob(argv, proxy)) != NULL) { if (*cp == '\0') { mflag = 0; continue; @@ -748,7 +582,7 @@ mget(argc, argv) if (mflag && confirm(argv[0], cp)) { tp = cp; if (mcase) { - for (tp2 = tmpbuf; ch = *tp++;) + for (tp2 = tmpbuf; (ch = *tp++) != NULL; ) *tp2++ = isupper(ch) ? tolower(ch) : ch; *tp2 = '\0'; tp = tmpbuf; @@ -764,85 +598,18 @@ mget(argc, argv) if (!mflag && fromatty) { ointer = interactive; interactive = 1; - if (confirm("Continue with","mget")) { + if (confirm("Continue with", "mget")) { mflag++; } interactive = ointer; } } } - (void) signal(SIGINT,oldintr); + (void) signal(SIGINT, oldintr); mflag = 0; } char * -remglob(argv,doswitch) - char *argv[]; - int doswitch; -{ - char temp[16]; - static char buf[MAXPATHLEN]; - static FILE *ftemp = NULL; - int fd; - static char **args; - int oldverbose, oldhash; - char *cp, *mode; - - if (!mflag) { - if (!doglob) { - args = NULL; - } - else { - if (ftemp) { - (void) fclose(ftemp); - ftemp = NULL; - } - } - return (NULL); - } - if (!doglob) { - if (args == NULL) - args = argv; - if ((cp = *++args) == NULL) - args = NULL; - return (cp); - } - if (ftemp == NULL) { - (void) strcpy(temp, _PATH_TMPFILE); - fd = mkstemp(temp); - if (fd < 0) { - printf ("temporary file %s already exists\n", temp); - return NULL; - } - close (fd); - oldverbose = verbose, verbose = 0; - oldhash = hash, hash = 0; - if (doswitch) { - pswitch(!proxy); - } - for (mode = "w"; *++argv != NULL; mode = "a") - recvrequest ("NLST", temp, *argv, mode, 0); - if (doswitch) { - pswitch(!proxy); - } - verbose = oldverbose; hash = oldhash; - ftemp = fopen(temp, "r"); - (void) unlink(temp); - if (ftemp == NULL) { - printf("can't find list of remote files, oops\n"); - return (NULL); - } - } - if (fgets(buf, sizeof (buf), ftemp) == NULL) { - (void) fclose(ftemp), ftemp = NULL; - return (NULL); - } - if ((cp = strchr(buf, '\n')) != NULL) - *cp = '\0'; - return (buf); -} - -char * onoff(bool) int bool; { @@ -868,23 +635,26 @@ status(argc, argv) if (!proxy) { pswitch(1); if (connected) { - printf("Connected for proxy commands to %s.\n", hostname); + printf("Connected for proxy commands to %s.\n", + hostname); } else { printf("No proxy connection.\n"); } pswitch(0); } + printf("Passive mode: %s.\n", onoff(passivemode)); printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", modename, typename, formname, structname); - printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", + printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", onoff(verbose), onoff(bell), onoff(interactive), onoff(doglob)); printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), onoff(runique)); - printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); + printf("Preserve modification times: %s\n", onoff(preserve)); + printf("Case: %s; CR stripping: %s\n", onoff(mcase), onoff(crflag)); if (ntflag) { - printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); + printf("Ntrans: (in) %s (out) %s\n", ntin, ntout); } else { printf("Ntrans: off\n"); @@ -895,18 +665,46 @@ status(argc, argv) else { printf("Nmap: off\n"); } - printf("Hash mark printing: %s; Mark count: %d\n", onoff(hash), mark); + printf("Hash mark printing: %s; Mark count: %d; Progress bar: %s\n", + onoff(hash), mark, onoff(progress)); printf("Use of PORT cmds: %s\n", onoff(sendport)); +#ifndef SMALLFTP + printf("Command line editing: %s\n", onoff(editing)); +#endif /* !SMALLFTP */ if (macnum > 0) { printf("Macros:\n"); for (i=0; i<macnum; i++) { - printf("\t%s\n",macros[i].mac_name); + printf("\t%s\n", macros[i].mac_name); } } code = 0; } /* + * Toggle a variable + */ +int +togglevar(argc, argv, var, mesg) + int argc; + char *argv[]; + int *var; + const char *mesg; +{ + if (argc < 2) { + *var = !*var; + } else if (argc == 2 && strcasecmp(argv[1], "on") == 0) { + *var = 1; + } else if (argc == 2 && strcasecmp(argv[1], "off") == 0) { + *var = 0; + } else { + printf("usage: %s [ on | off ]\n", argv[0]); + return -1; + } + printf("%s %s.\n", mesg, onoff(*var)); + return *var; +} + +/* * Set beep on cmd completed mode. */ /*VARARGS*/ @@ -916,44 +714,39 @@ setbell(argc, argv) char *argv[]; { - bell = !bell; - printf("Bell mode %s.\n", onoff(bell)); - code = bell; + code = togglevar(argc, argv, &bell, "Bell mode"); } +#ifndef SMALLFTP /* - * Turn on packet tracing. + * Set command line editing */ /*VARARGS*/ void -settrace(argc, argv) +setedit(argc, argv) int argc; char *argv[]; { - trace = !trace; - printf("Packet tracing %s.\n", onoff(trace)); - code = trace; + code = togglevar(argc, argv, &editing, "Editing mode"); } +#endif /* !SMALLFTP */ /* - * Toggle hash mark printing during transfers. + * Turn on packet tracing. */ /*VARARGS*/ void -togglehash() +settrace(argc, argv) + int argc; + char *argv[]; { - hash = !hash; - printf("Hash mark printing %s", onoff(hash)); - code = hash; - if (hash) - printf(" (%d bytes/hash mark)", mark); - printf(".\n"); + code = togglevar(argc, argv, &trace, "Packet tracing"); } /* - * Set hash mark bytecount. + * Toggle hash mark printing during transfers, or set hash mark bytecount. */ /*VARARGS*/ void @@ -962,22 +755,32 @@ sethash(argc, argv) char *argv[]; { if (argc == 1) - togglehash(); + hash = !hash; else if (argc != 2) { - printf("usage: %s [number of bytes].\n", argv[0]); - } else { + printf("usage: %s [ on | off | bytecount ]\n", argv[0]); + code = -1; + return; + } else if (strcasecmp(argv[1], "on") == 0) + hash = 1; + else if (strcasecmp(argv[1], "off") == 0) + hash = 0; + else { int nmark = atol(argv[1]); if (nmark < 1) { - printf("A hash mark bytecount of %d %s", - nmark, "is rather pointless...\n"); - } else { - mark = nmark; - printf("Hash mark set to %d bytes/hash mark\n", mark); + printf("%s: bad bytecount value\n", argv[1]); + code = -1; + return; } + mark = nmark; + hash = 1; } + printf("Hash mark printing %s", onoff(hash)); + if (hash) + printf(" (%d bytes/hash mark)", mark); + printf(".\n"); + code = hash; } - /* * Turn on printing of server echo's. */ @@ -988,9 +791,7 @@ setverbose(argc, argv) char *argv[]; { - verbose = !verbose; - printf("Verbose mode %s.\n", onoff(verbose)); - code = verbose; + code = togglevar(argc, argv, &verbose, "Verbose mode"); } /* @@ -1003,9 +804,20 @@ setport(argc, argv) char *argv[]; { - sendport = !sendport; - printf("Use of PORT cmds %s.\n", onoff(sendport)); - code = sendport; + code = togglevar(argc, argv, &sendport, "Use of PORT cmds"); +} + +/* + * Toggle transfer progress bar. + */ +/*VARARGS*/ +void +setprogress(argc, argv) + int argc; + char *argv[]; +{ + + code = togglevar(argc, argv, &progress, "Progress bar"); } /* @@ -1019,9 +831,7 @@ setprompt(argc, argv) char *argv[]; { - interactive = !interactive; - printf("Interactive mode %s.\n", onoff(interactive)); - code = interactive; + code = togglevar(argc, argv, &interactive, "Interactive mode"); } /* @@ -1034,10 +844,21 @@ setglob(argc, argv) int argc; char *argv[]; { - - doglob = !doglob; - printf("Globbing %s.\n", onoff(doglob)); - code = doglob; + + code = togglevar(argc, argv, &doglob, "Globbing"); +} + +/* + * Toggle preserving modification times on retreived files. + */ +/*VARARGS*/ +void +setpreserve(argc, argv) + int argc; + char *argv[]; +{ + + code = togglevar(argc, argv, &preserve, "Preserve modification times"); } /* @@ -1052,16 +873,26 @@ setdebug(argc, argv) { int val; - if (argc > 1) { - val = atoi(argv[1]); - if (val < 0) { - printf("%s: bad debugging value.\n", argv[1]); - code = -1; - return; + if (argc > 2) { + printf("usage: %s [ on | off | debuglevel ]\n", argv[0]); + code = -1; + return; + } else if (argc == 2) { + if (strcasecmp(argv[1], "on") == 0) + debug = 1; + else if (strcasecmp(argv[1], "off") == 0) + debug = 0; + else { + val = atoi(argv[1]); + if (val < 0) { + printf("%s: bad debugging value.\n", argv[1]); + code = -1; + return; + } + debug = val; } } else - val = !debug; - debug = val; + debug = !debug; if (debug) options |= SO_DEBUG; else @@ -1074,36 +905,27 @@ setdebug(argc, argv) * Set current working directory * on remote machine. */ -int -mcd(argc, argv) +void +cd(argc, argv) int argc; char *argv[]; { + int r; - if (argc < 2 && !another(&argc, &argv, "remote-directory")) { + if ((argc < 2 && !another(&argc, &argv, "remote-directory")) || + argc > 2) { printf("usage: %s remote-directory\n", argv[0]); code = -1; - return (-1); - } - if (command("CWD %s", argv[1]) == ERROR) { - if (code == 500) { - if (verbose) - printf("CWD command not recognized, " - "trying XCWD\n"); - return(command("XCWD %s", argv[1])); - } - else - return(-1); + return; } - return(0); -} - -void -cd(argc, argv) - int argc; - char *argv[]; -{ - mcd(argc, argv); + r = command("CWD %s", argv[1]); + if (r == ERROR && code == 500) { + if (verbose) + printf("CWD command not recognized, trying XCWD\n"); + r = command("XCWD %s", argv[1]); + } + if (r == COMPLETE) + dirchange = 1; } /* @@ -1136,7 +958,7 @@ lcd(argc, argv) if (getcwd(buf, sizeof(buf)) != NULL) printf("Local directory now %s\n", buf); else - warnx("getcwd: %s", buf); + warn("getcwd: %s", argv[1]); code = 0; } @@ -1149,7 +971,7 @@ delete(argc, argv) char *argv[]; { - if (argc < 2 && !another(&argc, &argv, "remote-file")) { + if ((argc < 2 && !another(&argc, &argv, "remote-file")) || argc > 2) { printf("usage: %s remote-file\n", argv[0]); code = -1; return; @@ -1163,7 +985,7 @@ delete(argc, argv) void mdelete(argc, argv) int argc; - char **argv; + char *argv[]; { sig_t oldintr; int ointer; @@ -1178,7 +1000,7 @@ mdelete(argc, argv) mflag = 1; oldintr = signal(SIGINT, mabort); (void) setjmp(jabort); - while ((cp = remglob(argv,0)) != NULL) { + while ((cp = remglob(argv, 0)) != NULL) { if (*cp == '\0') { mflag = 0; continue; @@ -1210,7 +1032,7 @@ renamefile(argc, argv) if (argc < 2 && !another(&argc, &argv, "from-name")) goto usage; - if (argc < 3 && !another(&argc, &argv, "to-name")) { + if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) { usage: printf("%s from-name to-name\n", argv[0]); code = -1; @@ -1229,7 +1051,7 @@ ls(argc, argv) int argc; char *argv[]; { - char *cmd; + const char *cmd; if (argc < 2) argc++, argv[1] = NULL; @@ -1240,13 +1062,14 @@ ls(argc, argv) code = -1; return; } - cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; + cmd = strcmp(argv[0], "dir") == 0 ? "LIST" : "NLST"; if (strcmp(argv[2], "-") && !globulize(&argv[2])) { code = -1; return; } if (strcmp(argv[2], "-") && *argv[2] != '|') - if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { + if (!globulize(&argv[2]) || !confirm("output to local-file:", + argv[2])) { code = -1; return; } @@ -1263,11 +1086,12 @@ ls(argc, argv) void mls(argc, argv) int argc; - char **argv; + char *argv[]; { sig_t oldintr; int ointer, i; - char *cmd, mode[1], *dest; + const char *cmd; + char mode[1], *dest; if (argc < 2 && !another(&argc, &argv, "remote-files")) goto usage; @@ -1285,7 +1109,7 @@ usage: code = -1; return; } - cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; + cmd = strcmp(argv[0], "mls") == 0 ? "NLST" : "LIST"; mname = argv[0]; mflag = 1; oldintr = signal(SIGINT, mabort); @@ -1313,11 +1137,11 @@ usage: void shell(argc, argv) int argc; - char **argv; + char *argv[]; { pid_t pid; sig_t old1, old2; - char shellnam[40], *shell, *namep; + char shellnam[MAXPATHLEN], *shell, *namep; union wait status; old1 = signal (SIGINT, SIG_IGN); @@ -1330,11 +1154,11 @@ shell(argc, argv) shell = getenv("SHELL"); if (shell == NULL) shell = _PATH_BSHELL; - namep = strrchr(shell,'/'); + namep = strrchr(shell, '/'); if (namep == NULL) namep = shell; - (void) strcpy(shellnam,"-"); - (void) strcat(shellnam, ++namep); + shellnam[0] = '-'; + (void) strncpy(shellnam + 1, ++namep, sizeof(shellnam) - 1); if (strcmp(namep, "sh") != 0) shellnam[0] = '+'; if (debug) { @@ -1342,10 +1166,10 @@ shell(argc, argv) (void) fflush (stdout); } if (argc > 1) { - execl(shell,shellnam,"-c",altarg,(char *)0); + execl(shell, shellnam, "-c", altarg, (char *)0); } else { - execl(shell,shellnam,(char *)0); + execl(shell, shellnam, (char *)0); } warn("%s", shell); code = -1; @@ -1371,7 +1195,7 @@ shell(argc, argv) void user(argc, argv) int argc; - char **argv; + char *argv[]; { char acct[80]; int n, aflag = 0; @@ -1409,7 +1233,7 @@ user(argc, argv) } /* - * Print working directory. + * Print working directory on remote machine. */ /*VARARGS*/ void @@ -1431,6 +1255,23 @@ pwd(argc, argv) } /* + * Print working directory on local machine. + */ +void +lpwd(argc, argv) + int argc; + char *argv[]; +{ + char buf[MAXPATHLEN]; + + if (getcwd(buf, sizeof(buf)) != NULL) + printf("Local directory %s\n", buf); + else + warn("getcwd"); + code = 0; +} + +/* * Make a directory. */ void @@ -1439,7 +1280,8 @@ makedir(argc, argv) char *argv[]; { - if (argc < 2 && !another(&argc, &argv, "directory-name")) { + if ((argc < 2 && !another(&argc, &argv, "directory-name")) || + argc > 2) { printf("usage: %s directory-name\n", argv[0]); code = -1; return; @@ -1460,7 +1302,8 @@ removedir(argc, argv) char *argv[]; { - if (argc < 2 && !another(&argc, &argv, "directory-name")) { + if ((argc < 2 && !another(&argc, &argv, "directory-name")) || + argc > 2) { printf("usage: %s directory-name\n", argv[0]); code = -1; return; @@ -1514,20 +1357,21 @@ site(argc, argv) */ void quote1(initial, argc, argv) - char *initial; + const char *initial; int argc; - char **argv; + char *argv[]; { int i, len; char buf[BUFSIZ]; /* must be >= sizeof(line) */ - (void) strcpy(buf, initial); + (void) strncpy(buf, initial, sizeof(buf)); if (argc > 1) { len = strlen(buf); - len += strlen(strcpy(&buf[len], argv[1])); + len += strlen(strncpy(&buf[len], argv[1], sizeof(buf) - len)); for (i = 2; i < argc; i++) { buf[len++] = ' '; - len += strlen(strcpy(&buf[len], argv[i])); + len += strlen(strncpy(&buf[len], argv[i], + sizeof(buf) - len)); } } if (command(buf) == PRELIM) { @@ -1544,7 +1388,7 @@ do_chmod(argc, argv) if (argc < 2 && !another(&argc, &argv, "mode")) goto usage; - if (argc < 3 && !another(&argc, &argv, "file-name")) { + if ((argc < 3 && !another(&argc, &argv, "file-name")) || argc > 3) { usage: printf("usage: %s mode file-name\n", argv[0]); code = -1; @@ -1634,80 +1478,22 @@ disconnect(argc, argv) } } -int -confirm(cmd, file) - char *cmd, *file; -{ - char line[BUFSIZ]; - - if (!interactive) - return (1); - printf("%s %s? ", cmd, file); - (void) fflush(stdout); - if (fgets(line, sizeof line, stdin) == NULL) - return (0); - return (*line != 'n' && *line != 'N'); -} - -void -fatal(msg) - char *msg; -{ - - errx(1, "%s", msg); -} - -/* - * Glob a local file name specification with - * the expectation of a single return value. - * Can't control multiple values being expanded - * from the expression, we return only the first. - */ -int -globulize(cpp) - char **cpp; -{ - glob_t gl; - int flags; - - if (!doglob) - return (1); - - flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; - memset(&gl, 0, sizeof(gl)); - if (glob(*cpp, flags, NULL, &gl) || - gl.gl_pathc == 0) { - warnx("%s: not found", *cpp); - globfree(&gl); - return (0); - } - *cpp = strdup(gl.gl_pathv[0]); /* XXX - wasted memory */ - globfree(&gl); - return (1); -} - void -account(argc,argv) +account(argc, argv) int argc; - char **argv; + char *argv[]; { - char acct[50], *ap; + char *ap; - if (argc > 1) { - ++argv; - --argc; - (void) strncpy(acct,*argv,49); - acct[49] = '\0'; - while (argc > 1) { - --argc; - ++argv; - (void) strncat(acct,*argv, 49-strlen(acct)); - } - ap = acct; + if (argc > 2) { + printf("usage: %s [password]\n", argv[0]); + code = -1; + return; } - else { + else if (argc == 2) + ap = argv[1]; + else ap = getpass("Account:"); - } (void) command("ACCT %s", ap); } @@ -1717,6 +1503,7 @@ void proxabort() { + alarmtimer(0); if (!proxy) { pswitch(1); } @@ -1727,7 +1514,7 @@ proxabort() proxflag = 0; } pswitch(0); - longjmp(abortprox,1); + longjmp(abortprox, 1); } void @@ -1736,6 +1523,7 @@ doproxy(argc, argv) char *argv[]; { struct cmd *c; + int cmdpos; sig_t oldintr; if (argc < 2 && !another(&argc, &argv, "command")) { @@ -1776,6 +1564,9 @@ doproxy(argc, argv) code = -1; return; } + cmdpos = strcspn(line, " \t"); + if (cmdpos > 0) /* remove leading "proxy " from input buffer */ + memmove(line, line + cmdpos + 1, strlen(line) - cmdpos + 1); (*c->c_handler)(argc-1, argv+1); if (connected) { proxflag = 1; @@ -1793,9 +1584,7 @@ setcase(argc, argv) char *argv[]; { - mcase = !mcase; - printf("Case mapping %s.\n", onoff(mcase)); - code = mcase; + code = togglevar(argc, argv, &mcase, "Case mapping"); } void @@ -1804,13 +1593,11 @@ setcr(argc, argv) char *argv[]; { - crflag = !crflag; - printf("Carriage Return stripping %s.\n", onoff(crflag)); - code = crflag; + code = togglevar(argc, argv, &crflag, "Carriage Return stripping"); } void -setntrans(argc,argv) +setntrans(argc, argv) int argc; char *argv[]; { @@ -1874,8 +1661,8 @@ setnmap(argc, argv) code = mapflag; return; } - if (argc < 3 && !another(&argc, &argv, "mapout")) { - printf("Usage: %s [mapin mapout]\n",argv[0]); + if ((argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) { + printf("Usage: %s [mapin mapout]\n", argv[0]); code = -1; return; } @@ -1957,7 +1744,7 @@ domap(name) break; case '[': LOOP: - if (*++cp2 == '$' && isdigit(*(cp2+1))) { + if (*++cp2 == '$' && isdigit(*(cp2+1))) { if (*++cp2 == '0') { char *cp3 = name; @@ -1976,7 +1763,7 @@ LOOP: } } else { - while (*cp2 && *cp2 != ',' && + while (*cp2 && *cp2 != ',' && *cp2 != ']') { if (*cp2 == '\\') { cp2++; @@ -2005,7 +1792,8 @@ LOOP: } } if (!*cp2) { - printf("nmap: unbalanced brackets\n"); + printf("nmap: unbalanced " + "brackets\n"); return (name); } match = 1; @@ -2018,7 +1806,8 @@ LOOP: } } if (!*cp2) { - printf("nmap: unbalanced brackets\n"); + printf("nmap: unbalanced " + "brackets\n"); return (name); } break; @@ -2071,10 +1860,7 @@ setpassive(argc, argv) char *argv[]; { - passivemode = !passivemode; - if (verbose) - printf("Passive mode %s.\n", onoff(passivemode)); - code = passivemode; + code = togglevar(argc, argv, &passivemode, "Passive mode"); } void @@ -2083,9 +1869,7 @@ setsunique(argc, argv) char *argv[]; { - sunique = !sunique; - printf("Store unique %s.\n", onoff(sunique)); - code = sunique; + code = togglevar(argc, argv, &sunique, "Store unique"); } void @@ -2094,23 +1878,25 @@ setrunique(argc, argv) char *argv[]; { - runique = !runique; - printf("Receive unique %s.\n", onoff(runique)); - code = runique; + code = togglevar(argc, argv, &runique, "Receive unique"); } -/* change directory to perent directory */ +/* change directory to parent directory */ void cdup(argc, argv) int argc; char *argv[]; { + int r; - if (command("CDUP") == ERROR && code == 500) { + r = command("CDUP"); + if (r == ERROR && code == 500) { if (verbose) printf("CDUP command not recognized, trying XCUP\n"); - (void) command("XCUP"); + r = command("XCUP"); } + if (r == COMPLETE) + dirchange = 1; } /* restart transfer at specific point */ @@ -2124,8 +1910,8 @@ restart(argc, argv) printf("restart: offset not specified\n"); else { restart_point = atol(argv[1]); - printf("restarting at %qd. %s\n", restart_point, - "execute get, put or append to initiate transfer"); + printf("Restarting at %qd. Execute get, put or append to" + "initiate transfer\n", restart_point); } } @@ -2152,13 +1938,14 @@ macdef(argc, argv) code = -1; return; } - if (argc < 2 && !another(&argc, &argv, "macro name")) { - printf("Usage: %s macro_name\n",argv[0]); + if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) { + printf("Usage: %s macro_name\n", argv[0]); code = -1; return; } if (interactive) { - printf("Enter macro line by line, terminating it with a null line\n"); + printf("Enter macro line by line, terminating it with a " + "null line\n"); } (void) strncpy(macros[macnum].mac_name, argv[1], 8); if (macnum == 0) { @@ -2208,13 +1995,17 @@ sizecmd(argc, argv) int argc; char *argv[]; { + off_t size; - if (argc < 2 && !another(&argc, &argv, "filename")) { + if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { printf("usage: %s filename\n", argv[0]); code = -1; return; } - (void) command("SIZE %s", argv[1]); + size = remotesize(argv[1], 1); + if (size != -1) + printf("%s\t%qd\n", argv[1], size); + code = size; } /* @@ -2225,30 +2016,21 @@ modtime(argc, argv) int argc; char *argv[]; { - int overbose; + time_t mtime; - if (argc < 2 && !another(&argc, &argv, "filename")) { + if ((argc < 2 && !another(&argc, &argv, "filename")) || argc > 2) { printf("usage: %s filename\n", argv[0]); code = -1; return; } - overbose = verbose; - if (debug == 0) - verbose = -1; - if (command("MDTM %s", argv[1]) == COMPLETE) { - int yy, mo, day, hour, min, sec; - sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, - &day, &hour, &min, &sec); - /* might want to print this in local time */ - printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], - mo, day, yy, hour, min, sec); - } else - printf("%s\n", reply_string); - verbose = overbose; + mtime = remotemodtime(argv[1], 1); + if (mtime != -1) + printf("%s\t%s", argv[1], asctime(localtime(&mtime))); + code = mtime; } /* - * show status on reomte machine + * show status on remote machine */ void rmtstatus(argc, argv) |