From: Kirk McKusick Date: Tue, 14 Jan 1986 11:32:55 +0000 (-0800) Subject: numerous bug fixes from sun!gorodish!guy X-Git-Tag: BSD-4_3-Snapshot-Development~3567 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/14433a7321f00cbfce9462abb7e2d11698f1b78a numerous bug fixes from sun!gorodish!guy 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 --- diff --git a/usr/src/usr.bin/ftp/cmds.c b/usr/src/usr.bin/ftp/cmds.c index 860529d690..658fada3ba 100644 --- a/usr/src/usr.bin/ftp/cmds.c +++ b/usr/src/usr.bin/ftp/cmds.c @@ -5,7 +5,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)cmds.c 5.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)cmds.c 5.3 (Berkeley) %G%"; #endif not lint /* @@ -213,6 +213,7 @@ put(argc, argv) char *argv[]; { char *cmd; + char *oldargv1; if (argc == 2) argc++, argv[2] = argv[1]; @@ -239,8 +240,15 @@ usage: } if (argc < 3) goto usage; + oldargv1 = argv[1]; 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]); } @@ -736,45 +744,32 @@ shell(argc, argv) 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) { - 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); } - 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" 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) diff --git a/usr/src/usr.bin/ftp/ftp.c b/usr/src/usr.bin/ftp/ftp.c index 7f83ba0aed..ab1ac06589 100644 --- a/usr/src/usr.bin/ftp/ftp.c +++ b/usr/src/usr.bin/ftp/ftp.c @@ -5,7 +5,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)ftp.c 5.4 (Berkeley) %G%"; +static char sccsid[] = "@(#)ftp.c 5.5 (Berkeley) %G%"; #endif not lint #include @@ -191,25 +191,10 @@ getreply(expecteof) 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() @@ -224,6 +209,7 @@ sendrequest(cmd, local, remote) 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; @@ -236,9 +222,15 @@ sendrequest(cmd, local, remote) 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) { - perror(local + 1); + perror(local); goto bad; } closefunc = pclose; @@ -263,6 +255,7 @@ sendrequest(cmd, local, remote) } else if (command("%s", cmd) != PRELIM) goto bad; + expectingreply++; /* got preliminary reply, expecting final reply */ dout = dataconn("w"); if (dout == NULL) goto bad; @@ -325,10 +318,13 @@ sendrequest(cmd, local, remote) } gettimeofday(&stop, (struct timezone *)0); if (closefunc != NULL) - (*closefunc)(fin); + (*closefunc)(fin), closefunc = NULL; (void) fclose(dout); - (void) getreply(0); done: + if (expectingreply) { + (void) getreply(0); + expectingreply = 0; + } 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) - (*closefunc)(fin); + (*closefunc)(fin), closefunc = NULL; + bytes = 0; /* so we don't print a message if the transfer was aborted */ goto done; } @@ -355,6 +352,7 @@ recvrequest(cmd, local, remote, mode) 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; @@ -365,14 +363,19 @@ recvrequest(cmd, local, remote, mode) 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; } @@ -385,17 +388,23 @@ recvrequest(cmd, local, remote, mode) } else if (command("%s", cmd) != PRELIM) goto bad; + expectingreply++; /* got preliminary reply, expecting final reply */ 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) { - perror(local + 1); + perror(local); 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) - (*closefunc)(fout); - (void) getreply(0); + (*closefunc)(fout), closefunc = NULL; done: + if (expectingreply) { + (void) getreply(0); + expectingreply = 0; + } 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); + bytes = 0; /* so we don't print a message if the transfer was aborted */ goto done; } @@ -504,7 +517,7 @@ noport: } 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) { diff --git a/usr/src/usr.bin/ftp/main.c b/usr/src/usr.bin/ftp/main.c index 1f1431aaf7..3bca1fc383 100644 --- a/usr/src/usr.bin/ftp/main.c +++ b/usr/src/usr.bin/ftp/main.c @@ -11,7 +11,7 @@ char copyright[] = #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 /* @@ -35,13 +35,14 @@ static char sccsid[] = "@(#)main.c 5.2 (Berkeley) %G%"; int intr(); int lostpeer(); extern char *home; +char *getlogin(); main(argc, argv) char *argv[]; { register char *cp; int top; - struct passwd *pw; + struct passwd *pw = NULL; char homedir[MAXPATHLEN]; sp = getservbyname("ftp", "tcp"); @@ -103,7 +104,9 @@ main(argc, argv) /* * 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) { @@ -198,6 +201,8 @@ cmdscanner(top) if (line[0] == 0) break; makeargv(); + if (margc == 0) + continue; 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; } - longjmp(toplevel, 0); } struct cmd * @@ -261,8 +265,23 @@ makeargv() 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++; + 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 */ - if (*sb == '!') { /* recognize ! as a token for shell */ - stringbase++; - return ("!"); - } 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; - printf("%s", c->c_name); + if (c->c_name) + printf("%s", c->c_name); if (c + lines >= &cmdtab[NCMDS]) { printf("\n"); break;