BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / ftp / cmds.c
index 3fb9b3e..56cc428 100644 (file)
@@ -2,23 +2,37 @@
  * Copyright (c) 1985, 1989 Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1985, 1989 Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement:  ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmds.c     5.23 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)cmds.c     5.26 (Berkeley) 3/5/91";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -43,7 +57,7 @@ static char sccsid[] = "@(#)cmds.c    5.23 (Berkeley) 6/1/90";
 #include "pathnames.h"
 
 extern char *globerr;
 #include "pathnames.h"
 
 extern char *globerr;
-extern char **glob();
+extern char **ftpglob();
 extern char *home;
 extern char *remglob();
 extern char *getenv();
 extern char *home;
 extern char *remglob();
 extern char *getenv();
@@ -58,6 +72,38 @@ char *mname;
 jmp_buf jabort;
 char *dotrans(), *domap();
 
 jmp_buf jabort;
 char *dotrans(), *domap();
 
+/*
+ * `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.
+ */
+another(pargc, pargv, prompt)
+       int *pargc;
+       char ***pargv;
+       char *prompt;
+{
+       int len = strlen(line), ret;
+       extern sig_t intr();
+
+       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.
 /*
  * Connect to peer server and
  * auto-login, if possible.
@@ -75,15 +121,9 @@ setpeer(argc, argv)
                code = -1;
                return;
        }
                code = -1;
                return;
        }
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(to) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc > 3) {
+       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;
                printf("usage: %s host-name [port]\n", argv[0]);
                code = -1;
                return;
@@ -190,6 +230,7 @@ struct      types {
  * Set transfer type.
  */
 settype(argc, argv)
  * Set transfer type.
  */
 settype(argc, argv)
+       int argc;
        char *argv[];
 {
        register struct types *p;
        char *argv[];
 {
        register struct types *p;
@@ -305,6 +346,7 @@ settenex()
  */
 /*ARGSUSED*/
 setmode(argc, argv)
  */
 /*ARGSUSED*/
 setmode(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
@@ -317,6 +359,7 @@ setmode(argc, argv)
  */
 /*ARGSUSED*/
 setform(argc, argv)
  */
 /*ARGSUSED*/
 setform(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
@@ -329,6 +372,7 @@ setform(argc, argv)
  */
 /*ARGSUSED*/
 setstruct(argc, argv)
  */
 /*ARGSUSED*/
 setstruct(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
@@ -352,30 +396,14 @@ put(argc, argv)
                argv[2] = argv[1];
                loc++;
        }
                argv[2] = argv[1];
                loc++;
        }
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(local-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "local-file"))
+               goto usage;
+       if (argc < 3 && !another(&argc, &argv, "remote-file")) {
 usage:
 usage:
-               printf("usage:%s local-file remote-file\n", argv[0]);
+               printf("usage: %s local-file remote-file\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(remote-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) 
-               goto usage;
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        if (!globulize(&argv[1])) {
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        if (!globulize(&argv[1])) {
@@ -414,16 +442,8 @@ mput(argc, argv)
        char *tp;
        void mabort();
 
        char *tp;
        void mabort();
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(local-files) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s local-files\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "local-files")) {
+               printf("usage: %s local-files\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -500,7 +520,7 @@ mput(argc, argv)
                        }
                        continue;
                }
                        }
                        continue;
                }
-               gargs = glob(argv[i]);
+               gargs = ftpglob(argv[i]);
                if (globerr != NULL) {
                        printf("%s\n", globerr);
                        if (gargs) {
                if (globerr != NULL) {
                        printf("%s\n", globerr);
                        if (gargs) {
@@ -535,12 +555,14 @@ mput(argc, argv)
 }
 
 reget(argc, argv)
 }
 
 reget(argc, argv)
+       int argc;
        char *argv[];
 {
        (void) getit(argc, argv, 1, "r+w");
 }
 
 get(argc, argv)
        char *argv[];
 {
        (void) getit(argc, argv, 1, "r+w");
 }
 
 get(argc, argv)
+       int argc;
        char *argv[];
 {
        (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
        char *argv[];
 {
        (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
@@ -550,6 +572,7 @@ get(argc, argv)
  * Receive one file.
  */
 getit(argc, argv, restartit, mode)
  * Receive one file.
  */
 getit(argc, argv, restartit, mode)
+       int argc;
        char *argv[];
        char *mode;
 {
        char *argv[];
        char *mode;
 {
@@ -561,30 +584,14 @@ getit(argc, argv, restartit, mode)
                argv[2] = argv[1];
                loc++;
        }
                argv[2] = argv[1];
                loc++;
        }
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "remote-file"))
+               goto usage;
+       if (argc < 3 && !another(&argc, &argv, "local-file")) {
 usage:
                printf("usage: %s remote-file [ local-file ]\n", argv[0]);
                code = -1;
                return (0);
        }
 usage:
                printf("usage: %s remote-file [ local-file ]\n", argv[0]);
                code = -1;
                return (0);
        }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(local-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) 
-               goto usage;
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        if (!globulize(&argv[2])) {
        oldargv1 = argv[1];
        oldargv2 = argv[2];
        if (!globulize(&argv[2])) {
@@ -709,16 +716,8 @@ mget(argc, argv)
        char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
        void mabort();
 
        char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
        void mabort();
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-files) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s remote-files\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+               printf("usage: %s remote-files\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -846,6 +845,7 @@ onoff(bool)
  */
 /*ARGSUSED*/
 status(argc, argv)
  */
 /*ARGSUSED*/
 status(argc, argv)
+       int argc;
        char *argv[];
 {
        int i;
        char *argv[];
 {
        int i;
@@ -990,6 +990,7 @@ setglob()
  */
 /*VARARGS*/
 setdebug(argc, argv)
  */
 /*VARARGS*/
 setdebug(argc, argv)
+       int argc;
        char *argv[];
 {
        int val;
        char *argv[];
 {
        int val;
@@ -1017,19 +1018,12 @@ setdebug(argc, argv)
  * on remote machine.
  */
 cd(argc, argv)
  * on remote machine.
  */
 cd(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-directory) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s remote-directory\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "remote-directory")) {
+               printf("usage: %s remote-directory\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -1045,6 +1039,7 @@ cd(argc, argv)
  * on local machine.
  */
 lcd(argc, argv)
  * on local machine.
  */
 lcd(argc, argv)
+       int argc;
        char *argv[];
 {
        char buf[MAXPATHLEN];
        char *argv[];
 {
        char buf[MAXPATHLEN];
@@ -1053,7 +1048,7 @@ lcd(argc, argv)
        if (argc < 2)
                argc++, argv[1] = home;
        if (argc != 2) {
        if (argc < 2)
                argc++, argv[1] = home;
        if (argc != 2) {
-               printf("usage:%s local-directory\n", argv[0]);
+               printf("usage: %s local-directory\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -1074,19 +1069,12 @@ lcd(argc, argv)
  * Delete a single file.
  */
 delete(argc, argv)
  * Delete a single file.
  */
 delete(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s remote-file\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "remote-file")) {
+               printf("usage: %s remote-file\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -1106,16 +1094,8 @@ mdelete(argc, argv)
        char *cp;
        void mabort();
 
        char *cp;
        void mabort();
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-files) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s remote-files\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "remote-files")) {
+               printf("usage: %s remote-files\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -1148,33 +1128,18 @@ mdelete(argc, argv)
  * Rename a remote file.
  */
 renamefile(argc, argv)
  * Rename a remote file.
  */
 renamefile(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(from-name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "from-name"))
+               goto usage;
+       if (argc < 3 && !another(&argc, &argv, "to-name")) {
 usage:
                printf("%s from-name to-name\n", argv[0]);
                code = -1;
                return;
        }
 usage:
                printf("%s from-name to-name\n", argv[0]);
                code = -1;
                return;
        }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(to-name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) 
-               goto usage;
        if (command("RNFR %s", argv[1]) == CONTINUE)
                (void) command("RNTO %s", argv[2]);
 }
        if (command("RNFR %s", argv[1]) == CONTINUE)
                (void) command("RNTO %s", argv[2]);
 }
@@ -1184,6 +1149,7 @@ usage:
  * of remote files.
  */
 ls(argc, argv)
  * of remote files.
  */
 ls(argc, argv)
+       int argc;
        char *argv[];
 {
        char *cmd;
        char *argv[];
 {
        char *cmd;
@@ -1224,31 +1190,19 @@ mls(argc, argv)
        char *cmd, mode[1], *dest;
        void mabort();
 
        char *cmd, mode[1], *dest;
        void mabort();
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(remote-files) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(local-file) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) {
-               printf("usage:%s remote-files local-file\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "remote-files"))
+               goto usage;
+       if (argc < 3 && !another(&argc, &argv, "local-file")) {
+usage:
+               printf("usage: %s remote-files local-file\n", argv[0]);
                code = -1;
                return;
        }
        dest = argv[argc - 1];
        argv[argc - 1] = NULL;
        if (strcmp(dest, "-") && *dest != '|')
                code = -1;
                return;
        }
        dest = argv[argc - 1];
        argv[argc - 1] = NULL;
        if (strcmp(dest, "-") && *dest != '|')
-               if (!globulize(&dest) || !confirm("output to local-file:", dest)) {
+               if (!globulize(&dest) ||
+                   !confirm("output to local-file:", dest)) {
                        code = -1;
                        return;
        }
                        code = -1;
                        return;
        }
@@ -1318,7 +1272,7 @@ shell(argc, argv)
                exit(1);
                }
        if (pid > 0)
                exit(1);
                }
        if (pid > 0)
-               while (wait(&status) != pid)
+               while (wait((int *)&status) != pid)
                        ;
        (void) signal(SIGINT, old1);
        (void) signal(SIGQUIT, old2);
                        ;
        (void) signal(SIGINT, old1);
        (void) signal(SIGQUIT, old2);
@@ -1342,15 +1296,9 @@ user(argc, argv)
        char acct[80], *getpass();
        int n, aflag = 0;
 
        char acct[80], *getpass();
        int n, aflag = 0;
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(username) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc > 4) {
+       if (argc < 2)
+               (void) another(&argc, &argv, "username");
+       if (argc < 2 || argc > 4) {
                printf("usage: %s username [password] [account]\n", argv[0]);
                code = -1;
                return (0);
                printf("usage: %s username [password] [account]\n", argv[0]);
                code = -1;
                return (0);
@@ -1404,18 +1352,11 @@ pwd()
  * Make a directory.
  */
 makedir(argc, argv)
  * Make a directory.
  */
 makedir(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(directory-name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "directory-name")) {
                printf("usage: %s directory-name\n", argv[0]);
                code = -1;
                return;
                printf("usage: %s directory-name\n", argv[0]);
                code = -1;
                return;
@@ -1431,18 +1372,11 @@ makedir(argc, argv)
  * Remove a directory.
  */
 removedir(argc, argv)
  * Remove a directory.
  */
 removedir(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(directory-name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "directory-name")) {
                printf("usage: %s directory-name\n", argv[0]);
                code = -1;
                return;
                printf("usage: %s directory-name\n", argv[0]);
                code = -1;
                return;
@@ -1458,64 +1392,56 @@ removedir(argc, argv)
  * Send a line, verbatim, to the remote machine.
  */
 quote(argc, argv)
  * Send a line, verbatim, to the remote machine.
  */
 quote(argc, argv)
+       int argc;
        char *argv[];
 {
        char *argv[];
 {
-       int i;
-       char buf[BUFSIZ];
 
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(command line to send) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "command line to send")) {
                printf("usage: %s line-to-send\n", argv[0]);
                code = -1;
                return;
        }
                printf("usage: %s line-to-send\n", argv[0]);
                code = -1;
                return;
        }
-       (void) strcpy(buf, argv[1]);
-       for (i = 2; i < argc; i++) {
-               (void) strcat(buf, " ");
-               (void) strcat(buf, argv[i]);
-       }
-       if (command(buf) == PRELIM) {
-               while (getreply(0) == PRELIM);
-       }
+       quote1("", argc, argv);
 }
 
 /*
  * Send a SITE command to the remote machine.  The line
 }
 
 /*
  * Send a SITE command to the remote machine.  The line
- * is sent almost verbatim to the remote machine, the
- * first argument is changed to SITE.
+ * is sent verbatim to the remote machine, except that the
+ * word "SITE" is added at the front.
  */
  */
-
 site(argc, argv)
 site(argc, argv)
+       int argc;
        char *argv[];
 {
        char *argv[];
 {
-       int i;
-       char buf[BUFSIZ];
 
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(arguments to SITE command) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
+       if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) {
                printf("usage: %s line-to-send\n", argv[0]);
                code = -1;
                return;
        }
                printf("usage: %s line-to-send\n", argv[0]);
                code = -1;
                return;
        }
-       (void) strcpy(buf, "SITE ");
-       (void) strcat(buf, argv[1]);
-       for (i = 2; i < argc; i++) {
-               (void) strcat(buf, " ");
-               (void) strcat(buf, argv[i]);
+       quote1("SITE ", argc, argv);
+}
+
+/*
+ * Turn argv[1..argc) into a space-separated string, then prepend initial text.
+ * Send the result as a one-line command and get response.
+ */
+quote1(initial, argc, argv)
+       char *initial;
+       int argc;
+       char **argv;
+{
+       register int i, len;
+       char buf[BUFSIZ];               /* must be >= sizeof(line) */
+
+       (void) strcpy(buf, initial);
+       if (argc > 1) {
+               len = strlen(buf);
+               len += strlen(strcpy(&buf[len], argv[1]));
+               for (i = 2; i < argc; i++) {
+                       buf[len++] = ' ';
+                       len += strlen(strcpy(&buf[len], argv[i]));
+               }
        }
        if (command(buf) == PRELIM) {
                while (getreply(0) == PRELIM);
        }
        if (command(buf) == PRELIM) {
                while (getreply(0) == PRELIM);
@@ -1523,30 +1449,23 @@ site(argc, argv)
 }
 
 do_chmod(argc, argv)
 }
 
 do_chmod(argc, argv)
+       int argc;
        char *argv[];
 {
        char *argv[];
 {
-       if (argc == 2) {
-               printf("usage: %s mode file-name\n", argv[0]);
-               code = -1;
-               return;
-       }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(mode and file-name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc != 3) {
+
+       if (argc < 2 && !another(&argc, &argv, "mode"))
+               goto usage;
+       if (argc < 3 && !another(&argc, &argv, "file-name")) {
+usage:
                printf("usage: %s mode file-name\n", argv[0]);
                code = -1;
                return;
        }
                printf("usage: %s mode file-name\n", argv[0]);
                code = -1;
                return;
        }
-       (void)command("SITE CHMOD %s %s", argv[1], argv[2]);
+       (void) command("SITE CHMOD %s %s", argv[1], argv[2]);
 }
 
 do_umask(argc, argv)
 }
 
 do_umask(argc, argv)
+       int argc;
        char *argv[];
 {
        int oldverbose = verbose;
        char *argv[];
 {
        int oldverbose = verbose;
@@ -1557,6 +1476,7 @@ do_umask(argc, argv)
 }
 
 idle(argc, argv)
 }
 
 idle(argc, argv)
+       int argc;
        char *argv[];
 {
        int oldverbose = verbose;
        char *argv[];
 {
        int oldverbose = verbose;
@@ -1570,6 +1490,7 @@ idle(argc, argv)
  * Ask the other side for help.
  */
 rmthelp(argc, argv)
  * Ask the other side for help.
  */
 rmthelp(argc, argv)
+       int argc;
        char *argv[];
 {
        int oldverbose = verbose;
        char *argv[];
 {
        int oldverbose = verbose;
@@ -1626,7 +1547,8 @@ confirm(cmd, file)
                return (1);
        printf("%s %s? ", cmd, file);
        (void) fflush(stdout);
                return (1);
        printf("%s %s? ", cmd, file);
        (void) fflush(stdout);
-       (void) gets(line);
+       if (fgets(line, sizeof line, stdin) == NULL)
+               return (0);
        return (*line != 'n' && *line != 'N');
 }
 
        return (*line != 'n' && *line != 'N');
 }
 
@@ -1651,7 +1573,7 @@ globulize(cpp)
 
        if (!doglob)
                return (1);
 
        if (!doglob)
                return (1);
-       globbed = glob(*cpp);
+       globbed = ftpglob(*cpp);
        if (globerr != NULL) {
                printf("%s: %s\n", *cpp, globerr);
                if (globbed) {
        if (globerr != NULL) {
                printf("%s: %s\n", *cpp, globerr);
                if (globbed) {
@@ -1726,16 +1648,8 @@ doproxy(argc,argv)
        sig_t oldintr;
        void proxabort();
 
        sig_t oldintr;
        void proxabort();
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(command) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s command\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "command")) {
+               printf("usage: %s command\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -1859,15 +1773,7 @@ setnmap(argc, argv)
                code = mapflag;
                return;
        }
                code = mapflag;
                return;
        }
-       if (argc < 3) {
-               (void) strcat(line, " ");
-               printf("(mapout) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 3) {
+       if (argc < 3 && !another(&argc, &argv, "mapout")) {
                printf("Usage: %s [mapin mapout]\n",argv[0]);
                code = -1;
                return;
                printf("Usage: %s [mapin mapout]\n",argv[0]);
                code = -1;
                return;
@@ -2113,15 +2019,7 @@ macdef(argc, argv)
                code = -1;
                return;
        }
                code = -1;
                return;
        }
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(macro name) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc != 2) {
+       if (argc < 2 && !another(&argc, &argv, "macro name")) {
                printf("Usage: %s macro_name\n",argv[0]);
                code = -1;
                return;
                printf("Usage: %s macro_name\n",argv[0]);
                code = -1;
                return;
@@ -2173,19 +2071,12 @@ macdef(argc, argv)
  * get size of file on remote machine
  */
 sizecmd(argc, argv)
  * get size of file on remote machine
  */
 sizecmd(argc, argv)
+       int argc;
        char *argv[];
 {
 
        char *argv[];
 {
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(filename) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s filename\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "filename")) {
+               printf("usage: %s filename\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -2196,20 +2087,13 @@ sizecmd(argc, argv)
  * get last modification time of file on remote machine
  */
 modtime(argc, argv)
  * get last modification time of file on remote machine
  */
 modtime(argc, argv)
+       int argc;
        char *argv[];
 {
        int overbose;
 
        char *argv[];
 {
        int overbose;
 
-       if (argc < 2) {
-               (void) strcat(line, " ");
-               printf("(filename) ");
-               (void) gets(&line[strlen(line)]);
-               makeargv();
-               argc = margc;
-               argv = margv;
-       }
-       if (argc < 2) {
-               printf("usage:%s filename\n", argv[0]);
+       if (argc < 2 && !another(&argc, &argv, "filename")) {
+               printf("usage: %s filename\n", argv[0]);
                code = -1;
                return;
        }
                code = -1;
                return;
        }
@@ -2232,6 +2116,7 @@ modtime(argc, argv)
  * show status on reomte machine
  */
 rmtstatus(argc, argv)
  * show status on reomte machine
  */
 rmtstatus(argc, argv)
+       int argc;
        char *argv[];
 {
        (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
        char *argv[];
 {
        (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
@@ -2241,6 +2126,7 @@ rmtstatus(argc, argv)
  * get file if modtime is more recent than current file
  */
 newer(argc, argv)
  * get file if modtime is more recent than current file
  */
 newer(argc, argv)
+       int argc;
        char *argv[];
 {
        if (getit(argc, argv, -1, "w"))
        char *argv[];
 {
        if (getit(argc, argv, -1, "w"))