numerous bug fixes from sun!gorodish!guy
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Tue, 14 Jan 1986 11:32:55 +0000 (03:32 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Tue, 14 Jan 1986 11:32:55 +0000 (03:32 -0800)
SCCS-vsn: usr.bin/ftp/main.c 5.3
SCCS-vsn: usr.bin/ftp/ftp.c 5.5
SCCS-vsn: usr.bin/ftp/cmds.c 5.3

usr/src/usr.bin/ftp/cmds.c
usr/src/usr.bin/ftp/ftp.c
usr/src/usr.bin/ftp/main.c

index 860529d..658fada 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmds.c     5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmds.c     5.3 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -213,6 +213,7 @@ put(argc, argv)
        char *argv[];
 {
        char *cmd;
        char *argv[];
 {
        char *cmd;
+       char *oldargv1;
 
        if (argc == 2)
                argc++, argv[2] = argv[1];
 
        if (argc == 2)
                argc++, argv[2] = argv[1];
@@ -239,8 +240,15 @@ usage:
        }
        if (argc < 3) 
                goto usage;
        }
        if (argc < 3) 
                goto usage;
+       oldargv1 = argv[1];
        if (!globulize(&argv[1]))
                return;
        if (!globulize(&argv[1]))
                return;
+       /*
+        * If "globulize" modifies argv[1], and argv[2] is a copy of
+        * the old argv[1], make it a copy of the new argv[1].
+        */
+       if (argv[1] != oldargv1 && argv[2] == oldargv1)
+               argv[2] = argv[1];
        cmd = (argv[0][0] == 'a') ? "APPE" : "STOR";
        sendrequest(cmd, argv[1], argv[2]);
 }
        cmd = (argv[0][0] == 'a') ? "APPE" : "STOR";
        sendrequest(cmd, argv[1], argv[2]);
 }
@@ -736,45 +744,32 @@ shell(argc, argv)
                        close(pid);
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
                        close(pid);
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
+               shell = getenv("SHELL");
+               if (shell == NULL)
+                       shell = "/bin/sh";
+               namep = rindex(shell,'/');
+               if (namep == NULL)
+                       namep = shell;
                if (argc <= 1) {
                if (argc <= 1) {
-                       shell = getenv("SHELL");
-                       if (shell == NULL)
-                               shell = "/bin/sh";
-                       namep = rindex(shell,'/');
-                       if (namep == NULL)
-                               namep = shell;
-                       strcpy(shellnam,"-");
-                       strcat(shellnam, ++namep);
-                       if (strcmp(namep, "sh") != 0)
-                               shellnam[0] = '+';
                        if (debug) {
                                printf ("%s\n", shell);
                                fflush (stdout);
                        }
                        if (debug) {
                                printf ("%s\n", shell);
                                fflush (stdout);
                        }
-                       execl(shell, shellnam, 0);
-                       perror(shell);
-                       exit(1);
-               }
-               cpp = &argv[1];
-               if (argc > 2) {
-                       if ((gargs = glob(cpp)) != NULL)
-                               cpp = gargs;
-                       if (globerr != NULL) {
-                               printf("%s\n", globerr);
-                               exit(1);
+                       execl(shell, shell, (char *)0);
+               } else {
+                       char *args[4];  /* "sh" "-c" <command> NULL */
+
+                       args[0] = shell;
+                       args[1] = "-c";
+                       args[2] = argv[1];
+                       args[3] = NULL;
+                       if (debug) {
+                               printf("%s -c %s\n", shell, argv[1]);
+                               fflush(stdout);
                        }
                        }
+                       execv(shell, args);
                }
                }
-               if (debug) {
-                       register char **zip = cpp;
-
-                       printf("%s", *zip);
-                       while (*++zip != NULL)
-                               printf(" %s", *zip);
-                       printf("\n");
-                       fflush(stdout);
-               }
-               execvp(argv[1], cpp);
-               perror(argv[1]);
+               perror(shell);
                exit(1);
        }
        if (pid > 0)
                exit(1);
        }
        if (pid > 0)
index 7f83ba0..ab1ac06 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftp.c      5.4 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftp.c      5.5 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/param.h>
 #endif not lint
 
 #include <sys/param.h>
@@ -191,25 +191,10 @@ getreply(expecteof)
                                originalcode = code;
                        continue;
                }
                                originalcode = code;
                        continue;
                }
-               if (expecteof || empty(cin))
-                       return (n - '0');
+               return (n - '0');
        }
 }
 
        }
 }
 
-empty(f)
-       FILE *f;
-{
-       long mask;
-       struct timeval t;
-
-       if (f->_cnt > 0)
-               return (0);
-       mask = (1 << fileno(f));
-       t.tv_sec = t.tv_usec = 0;
-       (void) select(20, &mask, 0, 0, &t);
-       return (mask == 0);
-}
-
 jmp_buf        sendabort;
 
 abortsend()
 jmp_buf        sendabort;
 
 abortsend()
@@ -224,6 +209,7 @@ sendrequest(cmd, local, remote)
        FILE *fin, *dout, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
        FILE *fin, *dout, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
+       int expectingreply = 0;
        long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct stat st;
        long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct stat st;
@@ -236,9 +222,15 @@ sendrequest(cmd, local, remote)
        if (strcmp(local, "-") == 0)
                fin = stdin;
        else if (*local == '|') {
        if (strcmp(local, "-") == 0)
                fin = stdin;
        else if (*local == '|') {
-               fin = popen(local + 1, "r");
+               /*
+                * Advance local so further uses just yield file name
+                * thus later references for error messages need not check
+                * for '|' special case.
+                */
+               local += 1;
+               fin = popen(local, "r");
                if (fin == NULL) {
                if (fin == NULL) {
-                       perror(local + 1);
+                       perror(local);
                        goto bad;
                }
                closefunc = pclose;
                        goto bad;
                }
                closefunc = pclose;
@@ -263,6 +255,7 @@ sendrequest(cmd, local, remote)
        } else
                if (command("%s", cmd) != PRELIM)
                        goto bad;
        } else
                if (command("%s", cmd) != PRELIM)
                        goto bad;
+       expectingreply++;       /* got preliminary reply, expecting final reply */
        dout = dataconn("w");
        if (dout == NULL)
                goto bad;
        dout = dataconn("w");
        if (dout == NULL)
                goto bad;
@@ -325,10 +318,13 @@ sendrequest(cmd, local, remote)
        }
        gettimeofday(&stop, (struct timezone *)0);
        if (closefunc != NULL)
        }
        gettimeofday(&stop, (struct timezone *)0);
        if (closefunc != NULL)
-               (*closefunc)(fin);
+               (*closefunc)(fin), closefunc = NULL;
        (void) fclose(dout);
        (void) fclose(dout);
-       (void) getreply(0);
 done:
 done:
+       if (expectingreply) {
+               (void) getreply(0);
+               expectingreply = 0;
+       }
        signal(SIGINT, oldintr);
        if (bytes > 0 && verbose)
                ptransfer("sent", bytes, &start, &stop);
        signal(SIGINT, oldintr);
        if (bytes > 0 && verbose)
                ptransfer("sent", bytes, &start, &stop);
@@ -337,7 +333,8 @@ bad:
        if (data >= 0)
                (void) close(data), data = -1;
        if (closefunc != NULL && fin != NULL)
        if (data >= 0)
                (void) close(data), data = -1;
        if (closefunc != NULL && fin != NULL)
-               (*closefunc)(fin);
+               (*closefunc)(fin), closefunc = NULL;
+       bytes = 0;      /* so we don't print a message if the transfer was aborted */
        goto done;
 }
 
        goto done;
 }
 
@@ -355,6 +352,7 @@ recvrequest(cmd, local, remote, mode)
        FILE *fout, *din, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
        FILE *fout, *din, *popen();
        int (*closefunc)(), pclose(), fclose(), (*oldintr)();
        char buf[BUFSIZ];
+       int expectingreply = 0;
        long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct timeval start, stop;
        long bytes = 0, hashbytes = sizeof (buf);
        register int c, d;
        struct timeval start, stop;
@@ -365,14 +363,19 @@ recvrequest(cmd, local, remote, mode)
        oldintr = signal(SIGINT, abortrecv);
        if (strcmp(local, "-") && *local != '|')
                if (access(local, 2) < 0) {
        oldintr = signal(SIGINT, abortrecv);
        if (strcmp(local, "-") && *local != '|')
                if (access(local, 2) < 0) {
-                       char *dir = rindex(local, '/');
-
-                       if (dir != NULL)
-                               *dir = 0;
-                       d = access(dir ? local : ".", 2);
-                       if (dir != NULL)
-                               *dir = '/';
-                       if (d < 0) {
+                       if (errno == ENOENT) {
+                               char *dir = rindex(local, '/');
+
+                               if (dir != NULL)
+                                       *dir = 0;
+                               d = access(dir ? local : ".", 2);
+                               if (dir != NULL)
+                                       *dir = '/';
+                               if (d < 0) {
+                                       perror(local);
+                                       goto bad;
+                               }
+                       } else {
                                perror(local);
                                goto bad;
                        }
                                perror(local);
                                goto bad;
                        }
@@ -385,17 +388,23 @@ recvrequest(cmd, local, remote, mode)
        } else
                if (command("%s", cmd) != PRELIM)
                        goto bad;
        } else
                if (command("%s", cmd) != PRELIM)
                        goto bad;
+       expectingreply++;       /* got preliminary reply, expecting final reply */
        if (strcmp(local, "-") == 0)
                fout = stdout;
        else if (*local == '|') {
        if (strcmp(local, "-") == 0)
                fout = stdout;
        else if (*local == '|') {
-               fout = popen(local + 1, "w");
+               /*
+                * Advance local over '|' so don't need to check for
+                * '|' special case any further.
+                */
+               local += 1;
+               fout = popen(local, "w");
                closefunc = pclose;
        } else {
                fout = fopen(local, mode);
                closefunc = fclose;
        }
        if (fout == NULL) {
                closefunc = pclose;
        } else {
                fout = fopen(local, mode);
                closefunc = fclose;
        }
        if (fout == NULL) {
-               perror(local + 1);
+               perror(local);
                goto bad;
        }
        din = dataconn("r");
                goto bad;
        }
        din = dataconn("r");
@@ -463,9 +472,12 @@ recvrequest(cmd, local, remote, mode)
        gettimeofday(&stop, (struct timezone *)0);
        (void) fclose(din);
        if (closefunc != NULL)
        gettimeofday(&stop, (struct timezone *)0);
        (void) fclose(din);
        if (closefunc != NULL)
-               (*closefunc)(fout);
-       (void) getreply(0);
+               (*closefunc)(fout), closefunc = NULL;
 done:
 done:
+       if (expectingreply) {
+               (void) getreply(0);
+               expectingreply = 0;
+       }
        signal(SIGINT, oldintr);
        if (bytes > 0 && verbose)
                ptransfer("received", bytes, &start, &stop);
        signal(SIGINT, oldintr);
        if (bytes > 0 && verbose)
                ptransfer("received", bytes, &start, &stop);
@@ -475,6 +487,7 @@ bad:
                (void) close(data), data = -1;
        if (closefunc != NULL && fout != NULL)
                (*closefunc)(fout);
                (void) close(data), data = -1;
        if (closefunc != NULL && fout != NULL)
                (*closefunc)(fout);
+       bytes = 0;      /* so we don't print a message if the transfer was aborted */
        goto done;
 }
 
        goto done;
 }
 
@@ -504,7 +517,7 @@ noport:
        }
        if (!sendport)
                if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) {
        }
        if (!sendport)
                if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) {
-                       perror("ftp: setsockopt (resuse address)");
+                       perror("ftp: setsockopt (reuse address)");
                        goto bad;
                }
        if (bind(data, (char *)&data_addr, sizeof (data_addr), 0) < 0) {
                        goto bad;
                }
        if (bind(data, (char *)&data_addr, sizeof (data_addr), 0) < 0) {
index 1f1431a..3bca1fc 100644 (file)
@@ -11,7 +11,7 @@ char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.3 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -35,13 +35,14 @@ static char sccsid[] = "@(#)main.c  5.2 (Berkeley) %G%";
 int    intr();
 int    lostpeer();
 extern char *home;
 int    intr();
 int    lostpeer();
 extern char *home;
+char   *getlogin();
 
 main(argc, argv)
        char *argv[];
 {
        register char *cp;
        int top;
 
 main(argc, argv)
        char *argv[];
 {
        register char *cp;
        int top;
-       struct passwd *pw;
+       struct passwd *pw = NULL;
        char homedir[MAXPATHLEN];
 
        sp = getservbyname("ftp", "tcp");
        char homedir[MAXPATHLEN];
 
        sp = getservbyname("ftp", "tcp");
@@ -103,7 +104,9 @@ main(argc, argv)
        /*
         * Set up the home directory in case we're globbing.
         */
        /*
         * Set up the home directory in case we're globbing.
         */
-       pw = getpwnam(getlogin());
+       cp = getlogin();
+       if (cp != NULL)
+               pw = getpwnam(cp);
        if (pw == NULL)
                pw = getpwuid(getuid());
        if (pw != NULL) {
        if (pw == NULL)
                pw = getpwuid(getuid());
        if (pw != NULL) {
@@ -198,6 +201,8 @@ cmdscanner(top)
                if (line[0] == 0)
                        break;
                makeargv();
                if (line[0] == 0)
                        break;
                makeargv();
+               if (margc == 0)
+                       continue;
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
                        printf("?Ambiguous command\n");
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
                        printf("?Ambiguous command\n");
@@ -217,7 +222,6 @@ cmdscanner(top)
                if (c->c_handler != help)
                        break;
        }
                if (c->c_handler != help)
                        break;
        }
-       longjmp(toplevel, 0);
 }
 
 struct cmd *
 }
 
 struct cmd *
@@ -261,8 +265,23 @@ makeargv()
        argp = margv;
        stringbase = line;              /* scan from first of buffer */
        argbase = argbuf;               /* store from first of buffer */
        argp = margv;
        stringbase = line;              /* scan from first of buffer */
        argbase = argbuf;               /* store from first of buffer */
-       while (*argp++ = slurpstring())
+       while (*stringbase == ' ' || *stringbase == '\t')
+               stringbase++;           /* skip initial white space */
+       if (*stringbase == '!') {       /* handle shell escapes specially */
+               stringbase++;
+               *argp++ = "!";          /* command name is "!" */
                margc++;
                margc++;
+               while (*stringbase == ' ' || *stringbase == '\t')
+                       stringbase++;           /* skip white space */
+               if (*stringbase != '\0') {
+                       *argp++ = stringbase;   /* argument is entire command string */
+                       margc++;
+               }
+               *argp++ = NULL;
+       } else {
+               while (*argp++ = slurpstring())
+                       margc++;
+       }
 }
 
 /*
 }
 
 /*
@@ -278,10 +297,6 @@ slurpstring()
        register char *ap = argbase;
        char *tmp = argbase;            /* will return this if token found */
 
        register char *ap = argbase;
        char *tmp = argbase;            /* will return this if token found */
 
-       if (*sb == '!') {               /* recognize ! as a token for shell */
-               stringbase++;
-               return ("!");
-       }
 S0:
        switch (*sb) {
 
 S0:
        switch (*sb) {
 
@@ -385,7 +400,8 @@ help(argc, argv)
                for (i = 0; i < lines; i++) {
                        for (j = 0; j < columns; j++) {
                                c = cmdtab + j * lines + i;
                for (i = 0; i < lines; i++) {
                        for (j = 0; j < columns; j++) {
                                c = cmdtab + j * lines + i;
-                               printf("%s", c->c_name);
+                               if (c->c_name)
+                                       printf("%s", c->c_name);
                                if (c + lines >= &cmdtab[NCMDS]) {
                                        printf("\n");
                                        break;
                                if (c + lines >= &cmdtab[NCMDS]) {
                                        printf("\n");
                                        break;