From: Dave A. Borman Date: Fri, 21 Apr 1995 00:59:22 +0000 (-0800) Subject: Add support for "inc" command and "autoinc" variable. X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/71012a2d4a58175269bdcfc0ff716985209ce61d Add support for "inc" command and "autoinc" variable. Recognize timestamps in From lines created by SysV/Solaris Recognize MAILRC env variable for .mailrc location Change tty handling from sgtty to termios Turn off EXTPROC when editing headers so that it works correctly with Linemode telnet. SCCS-vsn: usr.bin/mail/Makefile 8.3 SCCS-vsn: usr.bin/mail/cmd1.c 8.2 SCCS-vsn: usr.bin/mail/cmd3.c 8.2 SCCS-vsn: usr.bin/mail/cmdtab.c 8.2 SCCS-vsn: usr.bin/mail/def.h 8.4 SCCS-vsn: usr.bin/mail/extern.h 8.2 SCCS-vsn: usr.bin/mail/fio.c 8.2 SCCS-vsn: usr.bin/mail/head.c 8.2 SCCS-vsn: usr.bin/mail/lex.c 8.2 SCCS-vsn: usr.bin/mail/mail.1 8.5 SCCS-vsn: usr.bin/mail/main.c 8.2 SCCS-vsn: usr.bin/mail/tty.c 8.2 --- diff --git a/usr/src/usr.bin/mail/Makefile b/usr/src/usr.bin/mail/Makefile index fe7616ff51..9bb23c8ab2 100644 --- a/usr/src/usr.bin/mail/Makefile +++ b/usr/src/usr.bin/mail/Makefile @@ -1,7 +1,7 @@ -# @(#)Makefile 8.2 (Berkeley) %G% +# @(#)Makefile 8.3 (Berkeley) %G% PROG= mail -CFLAGS+=-R -DUSE_OLD_TTY +CFLAGS+=-R SRCS= version.c aux.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c edit.c fio.c \ getname.c head.c v7.local.c lex.c list.c main.c names.c popen.c \ quit.c send.c strings.c temp.c tty.c vars.c diff --git a/usr/src/usr.bin/mail/cmd1.c b/usr/src/usr.bin/mail/cmd1.c index e1f55aa631..0c3b416107 100644 --- a/usr/src/usr.bin/mail/cmd1.c +++ b/usr/src/usr.bin/mail/cmd1.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)cmd1.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)cmd1.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -423,3 +423,25 @@ folders() (void) run_command(cmd, 0, -1, -1, dirname, NOSTR, NOSTR); return 0; } + +/* + * Update the mail file with any new messages that have + * come in since we started reading mail. + */ +inc() +{ + int nmsg, mdot; + + nmsg = incfile(); + + if (nmsg == 0) { + printf("No new mail.\n"); + } else if (nmsg > 0) { + mdot = newfileinfo(msgCount - nmsg); + dot = &message[mdot - 1]; + } else { + printf("\"inc\" command failed...\n"); + } + + return 0; +} diff --git a/usr/src/usr.bin/mail/cmd3.c b/usr/src/usr.bin/mail/cmd3.c index 987e2d98aa..22e72d42f1 100644 --- a/usr/src/usr.bin/mail/cmd3.c +++ b/usr/src/usr.bin/mail/cmd3.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)cmd3.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -519,7 +519,7 @@ file(argv) { if (argv[0] == NOSTR) { - newfileinfo(); + newfileinfo(0); return 0; } if (setfile(*argv) < 0) diff --git a/usr/src/usr.bin/mail/cmdtab.c b/usr/src/usr.bin/mail/cmdtab.c index 92d7a5e360..146ed2ffa8 100644 --- a/usr/src/usr.bin/mail/cmdtab.c +++ b/usr/src/usr.bin/mail/cmdtab.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)cmdtab.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "def.h" @@ -87,5 +87,6 @@ struct cmd cmdtab[] = { "core", core, M|NOLIST, 0, 0, "#", null, M|NOLIST, 0, 0, "clobber", clobber, M|RAWLIST, 0, 1, + "inc", inc, T|NOLIST, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/usr/src/usr.bin/mail/def.h b/usr/src/usr.bin/mail/def.h index 1f845e212d..88058c8a17 100644 --- a/usr/src/usr.bin/mail/def.h +++ b/usr/src/usr.bin/mail/def.h @@ -4,7 +4,7 @@ * * %sccs.include.redist.c% * - * @(#)def.h 8.3 (Berkeley) %G% + * @(#)def.h 8.4 (Berkeley) %G% */ /* @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include diff --git a/usr/src/usr.bin/mail/extern.h b/usr/src/usr.bin/mail/extern.h index bb7e2adb0f..00bf45e400 100644 --- a/usr/src/usr.bin/mail/extern.h +++ b/usr/src/usr.bin/mail/extern.h @@ -4,7 +4,7 @@ * * %sccs.include.redist.c% * - * @(#)extern.h 8.1 (Berkeley) %G% + * @(#)extern.h 8.2 (Berkeley) %G% */ struct name *cat __P((struct name *, struct name *)); @@ -123,6 +123,7 @@ int igfield __P((char *[])); int ignore1 __P((char *[], struct ignoretab *, char *)); int igshow __P((struct ignoretab *, char *)); void intr __P((int)); +int inc __P((void)); int isdate __P((char [])); int isdir __P((char [])); int isfileaddr __P((char *)); @@ -138,7 +139,7 @@ struct var * int mail __P((struct name *, struct name *, struct name *, struct name *, char *)); void mail1 __P((struct header *, int)); -void makemessage __P((FILE *)); +void makemessage __P((FILE *, int)); void mark __P((int)); int markall __P((char [], int)); int matchsender __P((char *, int)); @@ -150,7 +151,7 @@ void mespipe __P((FILE *, char [])); int messize __P((int *)); int metamess __P((int, int)); int more __P((int *)); -int newfileinfo __P((void)); +int newfileinfo __P((int)); int next __P((int *)); int null __P((int)); void panic __P((const char *, ...)); @@ -193,7 +194,7 @@ int sendmail __P((char *)); int set __P((char **)); int setfile __P((char *)); void setmsize __P((int)); -void setptr __P((FILE *)); +void setptr __P((FILE *, off_t)); void setscreensize __P((void)); int shell __P((char *)); void sigchild __P((int)); diff --git a/usr/src/usr.bin/mail/fio.c b/usr/src/usr.bin/mail/fio.c index b8943b41d0..b7156caabd 100644 --- a/usr/src/usr.bin/mail/fio.c +++ b/usr/src/usr.bin/mail/fio.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -28,17 +28,18 @@ static char sccsid[] = "@(#)fio.c 8.1 (Berkeley) %G%"; * Set up the input pointers while copying the mail file into /tmp. */ void -setptr(ibuf) +setptr(ibuf, offset) register FILE *ibuf; + off_t offset; { extern char *tmpdir; register int c, count; register char *cp, *cp2; struct message this; FILE *mestmp; - off_t offset; int maybe, inhead; char linebuf[LINESIZE]; + int omsgCount; /* Get temporary file. */ (void)sprintf(linebuf, "%s/mail.XXXXXX", tmpdir); @@ -49,10 +50,23 @@ setptr(ibuf) } (void)unlink(linebuf); - msgCount = 0; + if (offset == 0) { + msgCount = 0; + } else { + /* Seek into the file to get to the new messages */ + (void) fseek(ibuf, offset, 0); + /* + * We need to make "offset" a pointer to the end of + * the temp file that has the copy of the mail file. + * If any messages have been edited, this will be + * different from the offset into the mail file. + */ + (void) fseek(otf, 0L, 2); + offset = ftell(otf); + } + omsgCount = msgCount; maybe = 1; inhead = 0; - offset = 0; this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; @@ -64,7 +78,7 @@ setptr(ibuf) perror("temporary file"); exit(1); } - makemessage(mestmp); + makemessage(mestmp, omsgCount); return; } count = strlen(linebuf); @@ -178,20 +192,27 @@ setinput(mp) * a dynamically allocated message structure. */ void -makemessage(f) +makemessage(f, omsgCount) FILE *f; + int omsgCount; { register size = (msgCount + 1) * sizeof (struct message); - if (message != 0) - free((char *) message); - if ((message = (struct message *) malloc((unsigned) size)) == 0) - panic("Insufficient memory for %d messages", msgCount); - dot = message; - size -= sizeof (struct message); + if (omsgCount) { + message = (struct message *)realloc(message, (unsigned) size); + if (message == 0) + panic("Insufficient memory for %d messages\n", msgCount); + } else { + if (message != 0) + free((char *) message); + if ((message = (struct message *) malloc((unsigned) size)) == 0) + panic("Insufficient memory for %d messages", msgCount); + dot = message; + } + size -= (omsgCount + 1) * sizeof (struct message); fflush(f); (void) lseek(fileno(f), (off_t)sizeof *message, 0); - if (read(fileno(f), (char *) message, size) != size) + if (read(fileno(f), (char *) &message[omsgCount], size) != size) panic("Message temporary file corrupted"); message[msgCount].m_size = 0; message[msgCount].m_lines = 0; diff --git a/usr/src/usr.bin/mail/head.c b/usr/src/usr.bin/mail/head.c index 73c73d817a..7c69c103d3 100644 --- a/usr/src/usr.bin/mail/head.c +++ b/usr/src/usr.bin/mail/head.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)head.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)head.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -138,13 +138,20 @@ copyin(src, space) */ char ctype[] = "Aaa Aaa O0 00:00:00 0000"; char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000"; +/* + * Yuck. If the mail file is created by Sys V (Solaris), + * there are no seconds in the time... + */ +char SysV_ctype[] = "Aaa Aaa O0 00:00 0000"; +char SysV_tmztype[] = "Aaa Aaa O0 00:00 AAA 0000"; int isdate(date) char date[]; { - return cmatch(date, ctype) || cmatch(date, tmztype); + return cmatch(date, ctype) || cmatch(date, tmztype) + || cmatch(date, SysV_tmztype) || cmatch(date, SysV_ctype); } /* diff --git a/usr/src/usr.bin/mail/lex.c b/usr/src/usr.bin/mail/lex.c index 58325eb0b4..6054f8c430 100644 --- a/usr/src/usr.bin/mail/lex.c +++ b/usr/src/usr.bin/mail/lex.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)lex.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)lex.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -116,8 +116,14 @@ setfile(name) } (void) fcntl(fileno(itf), F_SETFD, 1); rm(tempMesg); - setptr(ibuf); + setptr(ibuf, 0); setmsize(msgCount); + /* + * New mail mail have arrived while we were reading + * up the mail file, so reset mailsize to be where + * we really are in the file... + */ + mailsize = ftell(ibuf); Fclose(ibuf); relsesigs(); sawcom = 0; @@ -129,6 +135,36 @@ nomail: return(0); } +/* + * Incorporate any new mail that has arrived since we first + * started reading mail. + */ +int +incfile() +{ + int newsize; + int omsgCount = msgCount; + FILE *ibuf; + + ibuf = Fopen(mailname, "r"); + if (ibuf == NULL) + return -1; + holdsigs(); + newsize = fsize(ibuf); + if (newsize == 0) + return -1; /* mail box is now empty??? */ + if (newsize < mailsize) + return -1; /* mail box has shrunk??? */ + if (newsize == mailsize) + return 0; /* no new mail */ + setptr(ibuf, mailsize); + setmsize(msgCount); + mailsize = ftell(ibuf); + Fclose(ibuf); + relsesigs(); + return(msgCount - omsgCount); +} + int *msgvec; int reset_on_stop; /* do a reset() if stopped */ @@ -160,6 +196,8 @@ commands() * string space, and flush the output. */ if (!sourcing && value("interactive") != NOSTR) { + if ((value("autoinc") != NOSTR) && (incfile() > 0)) + printf("New mail has arrived.\n"); reset_on_stop = 1; printf(prompt); } @@ -530,7 +568,7 @@ announce() { int vec[2], mdot; - mdot = newfileinfo(); + mdot = newfileinfo(0); vec[0] = mdot; vec[1] = 0; dot = &message[mdot - 1]; @@ -546,23 +584,24 @@ announce() * Return a likely place to set dot. */ int -newfileinfo() +newfileinfo(omsgCount) + int omsgCount; { register struct message *mp; register int u, n, mdot, d, s; char fname[BUFSIZ], zname[BUFSIZ], *ename; - for (mp = &message[0]; mp < &message[msgCount]; mp++) + for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++) if (mp->m_flag & MNEW) break; if (mp >= &message[msgCount]) - for (mp = &message[0]; mp < &message[msgCount]; mp++) + for (mp = &message[omsgCount]; mp < &message[msgCount]; mp++) if ((mp->m_flag & MREAD) == 0) break; if (mp < &message[msgCount]) mdot = mp - &message[0] + 1; else - mdot = 1; + mdot = omsgCount + 1; s = d = 0; for (mp = &message[0], n = 0, u = 0; mp < &message[msgCount]; mp++) { if (mp->m_flag & MNEW) diff --git a/usr/src/usr.bin/mail/mail.1 b/usr/src/usr.bin/mail/mail.1 index e5e10bf6dd..fe1c4f6c37 100644 --- a/usr/src/usr.bin/mail/mail.1 +++ b/usr/src/usr.bin/mail/mail.1 @@ -3,7 +3,7 @@ .\" .\" %sccs.include.redist.roff% .\" -.\" @(#)mail.1 8.4 (Berkeley) %G% +.\" @(#)mail.1 8.5 (Berkeley) %G% .\" .Dd .Dt MAIL 1 @@ -450,6 +450,13 @@ If .Ic ignore is executed with no arguments, it lists the current set of ignored fields. +.It Ic inc +Incorporate any new messages that have arrived while mail +is being read. +The new messages are added to the end of the message list, +and the current message is reset to be the first new mail message. +This does not renumber the existing message list, nor does +does it cause any changes made so far to be saved. .It Ic mail .Pq Ic m Takes as argument login names and distribution group names and sends @@ -785,6 +792,12 @@ Causes you to be prompted for additional carbon copy recipients at the end of each message. Responding with a newline indicates your satisfaction with the current list. +.It Ar autoinc +Causes new mail to be automatically incorporated when it arrives. +Setting this is similar to issuing the +.Ic inc +command at each prompt, except that the current message is not +reset when new mail arrives. .It Ar autoprint Causes the .Ic delete @@ -970,6 +983,9 @@ Post office. User's old mail. .It ~/.mailrc File giving initial mail commands. +This can be overridden by setting the +.Ev MAILRC +environment variable. .It Pa /tmp/R* Temporary files. .It Pa /usr/share/misc/Mail.help* diff --git a/usr/src/usr.bin/mail/main.c b/usr/src/usr.bin/mail/main.c index 2cd65ffabf..d57f41465f 100644 --- a/usr/src/usr.bin/mail/main.c +++ b/usr/src/usr.bin/mail/main.c @@ -12,7 +12,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)main.c 8.2 (Berkeley) %G%"; #endif /* not lint */ #include "rcv.h" @@ -40,6 +40,7 @@ main(argc, argv) void hdrstop(); sig_t prevint; void sigchild(); + char *rc; /* * Set up a reasonable environment. @@ -187,7 +188,9 @@ Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\ * Expand returns a savestr, but load only uses the file name * for fopen, so it's safe to do this. */ - load(expand("~/.mailrc")); + if ((rc = getenv("MAILRC")) == 0) + rc = "~/.mailrc"; + load(expand(rc)); if (!rcvmode) { mail(to, cc, bcc, smopts, subject); /* @@ -248,16 +251,19 @@ hdrstop(signo) void setscreensize() { - struct sgttyb tbuf; + struct termios tbuf; struct winsize ws; + int ospeed; if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) ws.ws_col = ws.ws_row = 0; - if (ioctl(1, TIOCGETP, &tbuf) < 0) - tbuf.sg_ospeed = B9600; - if (tbuf.sg_ospeed < B1200) + if (ioctl(1, TIOCGETA, &tbuf) < 0) + ospeed = B9600; + else + ospeed = cfgetospeed(&tbuf); + if (ospeed < B1200) screenheight = 9; - else if (tbuf.sg_ospeed == B1200) + else if (ospeed == B1200) screenheight = 14; else if (ws.ws_row != 0) screenheight = ws.ws_row; diff --git a/usr/src/usr.bin/mail/tty.c b/usr/src/usr.bin/mail/tty.c index 6a77724757..0727b4c50c 100644 --- a/usr/src/usr.bin/mail/tty.c +++ b/usr/src/usr.bin/mail/tty.c @@ -6,7 +6,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)tty.c 8.2 (Berkeley) %G%"; #endif /* not lint */ /* @@ -35,10 +35,12 @@ grabh(hp, gflags) struct header *hp; int gflags; { - struct sgttyb ttybuf; + struct termios ttybuf; sig_t saveint; #ifndef TIOCSTI sig_t savequit; +#else + int extproc, flag; #endif sig_t savetstp; sig_t savettou; @@ -53,20 +55,28 @@ grabh(hp, gflags) #ifndef TIOCSTI ttyset = 0; #endif - if (ioctl(fileno(stdin), TIOCGETP, &ttybuf) < 0) { - perror("gtty"); + if (ioctl(fileno(stdin), TIOCGETA, &ttybuf) < 0) { + perror("TIOCGETA"); return(-1); } - c_erase = ttybuf.sg_erase; - c_kill = ttybuf.sg_kill; + c_erase = ttybuf.c_cc[VERASE]; + c_kill = ttybuf.c_cc[VKILL]; #ifndef TIOCSTI - ttybuf.sg_erase = 0; - ttybuf.sg_kill = 0; + ttybuf.c_cc[VERASE] = 0; + ttybuf.c_cc[VKILL] = 0; if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) signal(SIGINT, SIG_DFL); if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) signal(SIGQUIT, SIG_DFL); #else +# ifdef TIOCEXT + extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0); + if (extproc) { + flag = 0; + if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0) + perror("TIOCEXT: off"); + } +# endif /* TIOCEXT */ if (setjmp(intjmp)) goto out; saveint = signal(SIGINT, ttyint); @@ -74,7 +84,7 @@ grabh(hp, gflags) if (gflags & GTO) { #ifndef TIOCSTI if (!ttyset && hp->h_to != NIL) - ttyset++, stty(fileno(stdin), &ttybuf); + ttyset++, tcsetattr(fileno(stdin), &ttybuf); #endif hp->h_to = extract(readtty("To: ", detract(hp->h_to, 0)), GTO); @@ -82,14 +92,14 @@ grabh(hp, gflags) if (gflags & GSUBJECT) { #ifndef TIOCSTI if (!ttyset && hp->h_subject != NOSTR) - ttyset++, stty(fileno(stdin), &ttybuf); + ttyset++, tcsetattr(fileno(stdin), &ttybuf); #endif hp->h_subject = readtty("Subject: ", hp->h_subject); } if (gflags & GCC) { #ifndef TIOCSTI if (!ttyset && hp->h_cc != NIL) - ttyset++, stty(fileno(stdin), &ttybuf); + ttyset++, tcsetattr(fileno(stdin), &ttybuf); #endif hp->h_cc = extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC); @@ -97,7 +107,7 @@ grabh(hp, gflags) if (gflags & GBCC) { #ifndef TIOCSTI if (!ttyset && hp->h_bcc != NIL) - ttyset++, stty(fileno(stdin), &ttybuf); + ttyset++, tcsetattr(fileno(stdin), &ttybuf); #endif hp->h_bcc = extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC); @@ -107,11 +117,19 @@ out: signal(SIGTTOU, savettou); signal(SIGTTIN, savettin); #ifndef TIOCSTI - ttybuf.sg_erase = c_erase; - ttybuf.sg_kill = c_kill; + ttybuf.c_cc[VERASE] = c_erase; + ttybuf.c_cc[VKILL] = c_kill; if (ttyset) - stty(fileno(stdin), &ttybuf); + tcsetattr(fileno(stdin), &ttybuf); signal(SIGQUIT, savequit); +#else +# ifdef TIOCEXT + if (extproc) { + flag = 1; + if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0) + perror("TIOCEXT: on"); + } +# endif /* TIOCEXT */ #endif signal(SIGINT, saveint); return(errs);