X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2ae9f53f75d78089d784d0be9fccf0396252244a..064d7d97a44160e1084688e54ccdbf4f09ffe7be:/usr/src/usr.bin/mail/lex.c diff --git a/usr/src/usr.bin/mail/lex.c b/usr/src/usr.bin/mail/lex.c index e820ce9a94..55c6754fc8 100644 --- a/usr/src/usr.bin/mail/lex.c +++ b/usr/src/usr.bin/mail/lex.c @@ -1,8 +1,22 @@ -#ifndef lint -static char sccsid[] = "@(#)lex.c 2.14 (Berkeley) %G%"; -#endif +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#ifdef notdef +static char sccsid[] = "@(#)lex.c 5.13 (Berkeley) %G%"; +#endif /* notdef */ #include "rcv.h" +#include +#include /* * Mail -- a mail program @@ -24,13 +38,39 @@ setfile(name, isedit) { FILE *ibuf; int i; + struct stat stb; static int shudclob; - static char efile[128]; extern char tempMesg[]; + extern int errno; if ((ibuf = fopen(name, "r")) == NULL) return(-1); + if (fstat(fileno(ibuf), &stb) < 0) { + fclose(ibuf); + return (-1); + } + + switch (stb.st_mode & S_IFMT) { + case S_IFDIR: + fclose(ibuf); + errno = EISDIR; + return (-1); + + case S_IFREG: + break; + + default: + fclose(ibuf); + errno = EINVAL; + return (-1); + } + + if (!edit && stb.st_size == 0) { + fclose(ibuf); + return(-1); + } + /* * Looks like all will be well. We must now relinquish our * hold on the current set of stuff. Must hold signals @@ -62,8 +102,6 @@ setfile(name, isedit) } shudclob = 1; edit = isedit; - strncpy(efile, name, 128); - editfile = efile; if (name != mailname) strcpy(mailname, name); mailsize = fsize(ibuf); @@ -90,24 +128,22 @@ setfile(name, isedit) */ int *msgvec; +jmp_buf commjmp; commands() { - int eofloop, shudprompt, stop(); + int eofloop, stop(); register int n; char linebuf[LINESIZE]; int hangup(), contin(); -# ifdef VMUNIX - sigset(SIGCONT, SIG_DFL); -# endif VMUNIX + signal(SIGCONT, SIG_DFL); if (rcvmode && !sourcing) { - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - sigset(SIGINT, stop); - if (sigset(SIGHUP, SIG_IGN) != SIG_IGN) - sigset(SIGHUP, hangup); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, stop); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, hangup); } - shudprompt = intty && !sourcing; for (;;) { setexit(); @@ -120,15 +156,14 @@ commands() return; eofloop = 0; top: - if (shudprompt) { + if (!sourcing && value("interactive") != NOSTR) { + setjmp(commjmp); + signal(SIGCONT, contin); printf(prompt); - flush(); -# ifdef VMUNIX - sigset(SIGCONT, contin); -# endif VMUNIX - } else - flush(); - sreset(); + } + fflush(stdout); + if (!sourcing) + sreset(); /* * Read a line of commands from the current input @@ -137,7 +172,7 @@ top: n = 0; for (;;) { - if (readline(input, &linebuf[n]) <= 0) { + if (readline(input, &linebuf[n]) < 0) { if (n != 0) break; if (loading) @@ -146,7 +181,8 @@ top: unstack(); goto more; } - if (value("ignoreeof") != NOSTR && shudprompt) { + if (value("interactive") != NOSTR && + value("ignoreeof") != NOSTR) { if (++eofloop < 25) { printf("Use \"quit\" to quit.\n"); goto top; @@ -163,9 +199,7 @@ top: break; linebuf[n++] = ' '; } -# ifdef VMUNIX - sigset(SIGCONT, SIG_DFL); -# endif VMUNIX + signal(SIGCONT, SIG_DFL); if (execute(linebuf, 0)) return; more: ; @@ -199,9 +233,8 @@ execute(linebuf, contxt) * lexical conventions. */ - cp = linebuf; - while (any(*cp, " \t")) - cp++; + for (cp = linebuf; isspace(*cp); cp++) + ; if (*cp == '!') { if (sourcing) { printf("Can't \"!\" while sourcing\n"); @@ -224,7 +257,7 @@ execute(linebuf, contxt) * confusion. */ - if (sourcing && equal(word, "")) + if (sourcing && *word == '\0') return(0); com = lex(word); if (com == NONE) { @@ -258,7 +291,7 @@ execute(linebuf, contxt) return(0); } if (!edit && com->c_func == edstop) { - sigset(SIGINT, SIG_IGN); + signal(SIGINT, SIG_IGN); return(1); } @@ -343,7 +376,7 @@ execute(linebuf, contxt) * Just the straight string, with * leading blanks removed. */ - while (any(*cp, " \t")) + while (isspace(*cp)) cp++; e = (*com->c_func)(cp); break; @@ -352,7 +385,8 @@ execute(linebuf, contxt) /* * A vector of strings, in shell style. */ - if ((c = getrawlist(cp, arglist)) < 0) + if ((c = getrawlist(cp, arglist, + sizeof arglist / sizeof *arglist)) < 0) break; if (c < com->c_minargs) { printf("%s requires at least %d arg(s)\n", @@ -404,27 +438,21 @@ execute(linebuf, contxt) /* * When we wake up after ^Z, reprint the prompt. */ +/*ARGSUSED*/ contin(s) { - printf(prompt); - fflush(stdout); + longjmp(commjmp, 1); } /* - * Branch here on hangup signal and simulate quit. + * Branch here on hangup signal and simulate "exit". */ -hangup() +/*ARGSUSED*/ +hangup(s) { - holdsigs(); - if (edit) { - if (setexit()) - exit(0); - edstop(); - } - else - quit(); + /* nothing to do? */ exit(0); } @@ -436,8 +464,8 @@ hangup() setmsize(sz) { - if (msgvec != (int *) 0) - cfree(msgvec); + if (msgvec != 0) + cfree((char *) msgvec); msgvec = (int *) calloc((unsigned) (sz + 1), sizeof *msgvec); } @@ -478,54 +506,64 @@ isprefix(as1, as2) } /* - * The following gets called on receipt of a rubout. This is + * The following gets called on receipt of an interrupt. This is * to abort printout of a command, mainly. * Dispatching here when command() is inactive crashes rcv. * Close all open files except 0, 1, 2, and the temporary. - * The special call to getuserid() is needed so it won't get - * annoyed about losing its open file. * Also, unstack all source files. */ int inithdr; /* am printing startup headers */ +#ifdef _NFILE +static +_fwalk(function) + register int (*function)(); +{ + register FILE *iop; + + for (iop = _iob; iop < _iob + _NFILE; iop++) + (*function)(iop); +} +#endif + +static +xclose(iop) + register FILE *iop; +{ + if (iop == stdin || iop == stdout || + iop == stderr || iop == itf || iop == otf) + return; + + if (iop != pipef) + fclose(iop); + else { + pclose(pipef); + pipef = NULL; + } +} + +/*ARGSUSED*/ stop(s) { - register FILE *fp; -# ifndef VMUNIX - s = SIGINT; -# endif VMUNIX noreset = 0; if (!inithdr) sawcom++; inithdr = 0; while (sourcing) unstack(); - getuserid((char *) -1); - for (fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) { - if (fp == stdin || fp == stdout) - continue; - if (fp == itf || fp == otf) - continue; - if (fp == stderr) - continue; - if (fp == pipef) { - pclose(pipef); - pipef = NULL; - continue; - } - fclose(fp); - } + + /* + * Walk through all the open FILEs, applying xclose() to them + */ + _fwalk(xclose); + if (image >= 0) { close(image); image = -1; } - clrbuf(stdout); - printf("Interrupt\n"); -# ifndef VMUNIX - signal(s, stop); -# endif + fprintf(stderr, "Interrupt\n"); reset(0); } @@ -534,20 +572,15 @@ stop(s) * give the message count, and print a header listing. */ -char *greeting = "Mail version %s. Type ? for help.\n"; - -announce(pr) +announce() { int vec[2], mdot; - extern char *version; - if (pr && value("quiet") == NOSTR) - printf(greeting, version); mdot = newfileinfo(); vec[0] = mdot; vec[1] = 0; dot = &message[mdot - 1]; - if (msgCount > 0 && !noheader) { + if (msgCount > 0 && value("noheader") == NOSTR) { inithdr++; headers(vec); inithdr = 0; @@ -613,14 +646,15 @@ newfileinfo() return(mdot); } -strace() {} - /* * Print the current version number. */ +/*ARGSUSED*/ pversion(e) { + extern char *version; + printf("Version %s\n", version); return(0); }