386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Thu, 18 Apr 1991 23:17:26 +0000 (15:17 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Thu, 18 Apr 1991 23:17:26 +0000 (15:17 -0800)
Work on file usr/src/usr.bin/msgs/msgs.c
Work on file usr/src/usr.bin/msgs/pathnames.h

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/usr.bin/msgs/msgs.c [new file with mode: 0644]
usr/src/usr.bin/msgs/pathnames.h [new file with mode: 0644]

diff --git a/usr/src/usr.bin/msgs/msgs.c b/usr/src/usr.bin/msgs/msgs.c
new file mode 100644 (file)
index 0000000..28208e0
--- /dev/null
@@ -0,0 +1,860 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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
+char copyright[] =
+"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)msgs.c     5.8 (Berkeley) 2/4/91";
+#endif /* not lint */
+
+/*
+ * msgs - a user bulletin board program
+ *
+ * usage:
+ *     msgs [fhlopq] [[-]number]       to read messages
+ *     msgs -s                         to place messages
+ *     msgs -c [-days]                 to clean up the bulletin board
+ *
+ * prompt commands are:
+ *     y       print message
+ *     n       flush message, go to next message
+ *     q       flush message, quit
+ *     p       print message, turn on 'pipe thru more' mode
+ *     P       print message, turn off 'pipe thru more' mode
+ *     -       reprint last message
+ *     s[-][<num>] [<filename>]        save message
+ *     m[-][<num>]     mail with message in temp mbox
+ *     x       exit without flushing this message
+ *     <num>   print message number <num>
+ */
+
+#define V7             /* will look for TERM in the environment */
+#define OBJECT         /* will object to messages without Subjects */
+/* #define REJECT      /* will reject messages without Subjects
+                          (OBJECT must be defined also) */
+/* #define UNBUFFERED  /* use unbuffered output */
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <sgtty.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "pathnames.h"
+
+#define CMODE  0666            /* bounds file creation mode */
+#define NO     0
+#define YES    1
+#define SUPERUSER      0       /* superuser uid */
+#define DAEMON         1       /* daemon uid */
+#define NLINES 24              /* default number of lines/crt screen */
+#define NDAYS  21              /* default keep time for messages */
+#define DAYS   *24*60*60       /* seconds/day */
+#define MSGSRC ".msgsrc"       /* user's rc file */
+#define BOUNDS "bounds"        /* message bounds file */
+#define NEXT   "Next message? [yq]"
+#define MORE   "More? [ynq]"
+#define NOMORE "(No more) [q] ?"
+
+typedef        char    bool;
+
+FILE   *msgsrc;
+FILE   *newmsg;
+char   *sep = "-";
+char   inbuf[BUFSIZ];
+char   fname[128];
+char   cmdbuf[128];
+char   subj[128];
+char   from[128];
+char   date[128];
+char   *ptr;
+char   *in;
+bool   local;
+bool   ruptible;
+bool   totty;
+bool   seenfrom;
+bool   seensubj;
+bool   blankline;
+bool   printing = NO;
+bool   mailing = NO;
+bool   quitit = NO;
+bool   sending = NO;
+bool   intrpflg = NO;
+int    uid;
+int    msg;
+int    prevmsg;
+int    lct;
+int    nlines;
+int    Lpp = 0;
+time_t t;
+time_t keep;
+struct sgttyb  otty;
+
+char   *mktemp();
+char   *nxtfld();
+void   onintr();
+void   onsusp();
+
+/* option initialization */
+bool   hdrs = NO;
+bool   qopt = NO;
+bool   hush = NO;
+bool   send_msg = NO;
+bool   locomode = NO;
+bool   use_pager = NO;
+bool   clean = NO;
+bool   lastcmd = NO;
+jmp_buf        tstpbuf;
+
+main(argc, argv)
+int argc; char *argv[];
+{
+       bool newrc, already;
+       int rcfirst = 0;                /* first message to print (from .rc) */
+       int rcback = 0;                 /* amount to back off of rcfirst */
+       int firstmsg, nextmsg, lastmsg = 0;
+       int blast = 0;
+       FILE *bounds;
+
+#ifdef UNBUFFERED
+       setbuf(stdout, NULL);
+#endif
+
+       gtty(fileno(stdout), &otty);
+       time(&t);
+       setuid(uid = getuid());
+       ruptible = (signal(SIGINT, SIG_IGN) == SIG_DFL);
+       if (ruptible)
+               signal(SIGINT, SIG_DFL);
+
+       argc--, argv++;
+       while (argc > 0) {
+               if (isdigit(argv[0][0])) {      /* starting message # */
+                       rcfirst = atoi(argv[0]);
+               }
+               else if (isdigit(argv[0][1])) { /* backward offset */
+                       rcback = atoi( &( argv[0][1] ) );
+               }
+               else {
+                       ptr = *argv;
+                       while (*ptr) switch (*ptr++) {
+
+                       case '-':
+                               break;
+
+                       case 'c':
+                               if (uid != SUPERUSER && uid != DAEMON) {
+                                       fprintf(stderr, "Sorry\n");
+                                       exit(1);
+                               }
+                               clean = YES;
+                               break;
+
+                       case 'f':               /* silently */
+                               hush = YES;
+                               break;
+
+                       case 'h':               /* headers only */
+                               hdrs = YES;
+                               break;
+
+                       case 'l':               /* local msgs only */
+                               locomode = YES;
+                               break;
+
+                       case 'o':               /* option to save last message */
+                               lastcmd = YES;
+                               break;
+
+                       case 'p':               /* pipe thru 'more' during long msgs */
+                               use_pager = YES;
+                               break;
+
+                       case 'q':               /* query only */
+                               qopt = YES;
+                               break;
+
+                       case 's':               /* sending TO msgs */
+                               send_msg = YES;
+                               break;
+
+                       default:
+                               fprintf(stderr,
+                                       "usage: msgs [fhlopq] [[-]number]\n");
+                               exit(1);
+                       }
+               }
+               argc--, argv++;
+       }
+
+       /*
+        * determine current message bounds
+        */
+       sprintf(fname, "%s/%s", _PATH_MSGS, BOUNDS);
+       bounds = fopen(fname, "r");
+
+       if (bounds != NULL) {
+               fscanf(bounds, "%d %d\n", &firstmsg, &lastmsg);
+               fclose(bounds);
+               blast = lastmsg;        /* save upper bound */
+       }
+
+       if (clean)
+               keep = t - (rcback? rcback : NDAYS) DAYS;
+
+       if (clean || bounds == NULL) {  /* relocate message bounds */
+               struct direct *dp;
+               struct stat stbuf;
+               bool seenany = NO;
+               DIR     *dirp;
+
+               dirp = opendir(_PATH_MSGS);
+               if (dirp == NULL) {
+                       perror(_PATH_MSGS);
+                       exit(errno);
+               }
+
+               firstmsg = 32767;
+               lastmsg = 0;
+
+               for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)){
+                       register char *cp = dp->d_name;
+                       register int i = 0;
+
+                       if (dp->d_ino == 0)
+                               continue;
+                       if (dp->d_namlen == 0)
+                               continue;
+
+                       if (clean)
+                               sprintf(inbuf, "%s/%s", _PATH_MSGS, cp);
+
+                       while (isdigit(*cp))
+                               i = i * 10 + *cp++ - '0';
+                       if (*cp)
+                               continue;       /* not a message! */
+
+                       if (clean) {
+                               if (stat(inbuf, &stbuf) != 0)
+                                       continue;
+                               if (stbuf.st_mtime < keep
+                                   && stbuf.st_mode&S_IWRITE) {
+                                       unlink(inbuf);
+                                       continue;
+                               }
+                       }
+
+                       if (i > lastmsg)
+                               lastmsg = i;
+                       if (i < firstmsg)
+                               firstmsg = i;
+                       seenany = YES;
+               }
+               closedir(dirp);
+
+               if (!seenany) {
+                       if (blast != 0) /* never lower the upper bound! */
+                               lastmsg = blast;
+                       firstmsg = lastmsg + 1;
+               }
+               else if (blast > lastmsg)
+                       lastmsg = blast;
+
+               if (!send_msg) {
+                       bounds = fopen(fname, "w");
+                       if (bounds == NULL) {
+                               perror(fname);
+                               exit(errno);
+                       }
+                       chmod(fname, CMODE);
+                       fprintf(bounds, "%d %d\n", firstmsg, lastmsg);
+                       fclose(bounds);
+               }
+       }
+
+       if (send_msg) {
+               /*
+                * Send mode - place msgs in _PATH_MSGS
+                */
+               bounds = fopen(fname, "w");
+               if (bounds == NULL) {
+                       perror(fname);
+                       exit(errno);
+               }
+
+               nextmsg = lastmsg + 1;
+               sprintf(fname, "%s/%d", _PATH_MSGS, nextmsg);
+               newmsg = fopen(fname, "w");
+               if (newmsg == NULL) {
+                       perror(fname);
+                       exit(errno);
+               }
+               chmod(fname, 0644);
+
+               fprintf(bounds, "%d %d\n", firstmsg, nextmsg);
+               fclose(bounds);
+
+               sending = YES;
+               if (ruptible)
+                       signal(SIGINT, onintr);
+
+               if (isatty(fileno(stdin))) {
+                       ptr = getpwuid(uid)->pw_name;
+                       printf("Message %d:\nFrom %s %sSubject: ",
+                               nextmsg, ptr, ctime(&t));
+                       fflush(stdout);
+                       fgets(inbuf, sizeof inbuf, stdin);
+                       putchar('\n');
+                       fflush(stdout);
+                       fprintf(newmsg, "From %s %sSubject: %s\n",
+                               ptr, ctime(&t), inbuf);
+                       blankline = seensubj = YES;
+               }
+               else
+                       blankline = seensubj = NO;
+               for (;;) {
+                       fgets(inbuf, sizeof inbuf, stdin);
+                       if (feof(stdin) || ferror(stdin))
+                               break;
+                       blankline = (blankline || (inbuf[0] == '\n'));
+                       seensubj = (seensubj || (!blankline && (strncmp(inbuf, "Subj", 4) == 0)));
+                       fputs(inbuf, newmsg);
+               }
+#ifdef OBJECT
+               if (!seensubj) {
+                       printf("NOTICE: Messages should have a Subject field!\n");
+#ifdef REJECT
+                       unlink(fname);
+#endif
+                       exit(1);
+               }
+#endif
+               exit(ferror(stdin));
+       }
+       if (clean)
+               exit(0);
+
+       /*
+        * prepare to display messages
+        */
+       totty = (isatty(fileno(stdout)) != 0);
+       use_pager = use_pager && totty;
+
+       sprintf(fname, "%s/%s", getenv("HOME"), MSGSRC);
+       msgsrc = fopen(fname, "r");
+       if (msgsrc) {
+               newrc = NO;
+               fscanf(msgsrc, "%d\n", &nextmsg);
+               fclose(msgsrc);
+               if (nextmsg > lastmsg+1) {
+                       printf("Warning: bounds have been reset (%d, %d)\n",
+                               firstmsg, lastmsg);
+                       truncate(fname, (off_t)0);
+                       newrc = YES;
+               }
+               else if (!rcfirst)
+                       rcfirst = nextmsg - rcback;
+       }
+       else
+               newrc = YES;
+       msgsrc = fopen(fname, "a");
+       if (msgsrc == NULL) {
+               perror(fname);
+               exit(errno);
+       }
+       if (rcfirst) {
+               if (rcfirst > lastmsg+1) {
+                       printf("Warning: the last message is number %d.\n",
+                               lastmsg);
+                       rcfirst = nextmsg;
+               }
+               if (rcfirst > firstmsg)
+                       firstmsg = rcfirst;     /* don't set below first msg */
+       }
+       if (newrc) {
+               nextmsg = firstmsg;
+               fseek(msgsrc, 0L, 0);
+               fprintf(msgsrc, "%d\n", nextmsg);
+               fflush(msgsrc);
+       }
+
+#ifdef V7
+       if (totty) {
+               struct winsize win;
+               if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1)
+                       Lpp = win.ws_row;
+               if (Lpp <= 0) {
+                       if (tgetent(inbuf, getenv("TERM")) <= 0
+                           || (Lpp = tgetnum("li")) <= 0) {
+                               Lpp = NLINES;
+                       }
+               }
+       }
+#endif
+       Lpp -= 6;       /* for headers, etc. */
+
+       already = NO;
+       prevmsg = firstmsg;
+       printing = YES;
+       if (ruptible)
+               signal(SIGINT, onintr);
+
+       /*
+        * Main program loop
+        */
+       for (msg = firstmsg; msg <= lastmsg; msg++) {
+
+               sprintf(fname, "%s/%d", _PATH_MSGS, msg);
+               newmsg = fopen(fname, "r");
+               if (newmsg == NULL)
+                       continue;
+
+               gfrsub(newmsg);         /* get From and Subject fields */
+               if (locomode && !local) {
+                       fclose(newmsg);
+                       continue;
+               }
+
+               if (qopt) {     /* This has to be located here */
+                       printf("There are new messages.\n");
+                       exit(0);
+               }
+
+               if (already && !hdrs)
+                       putchar('\n');
+
+               /*
+                * Print header
+                */
+               if (totty)
+                       signal(SIGTSTP, onsusp);
+               (void) setjmp(tstpbuf);
+               already = YES;
+               nlines = 2;
+               if (seenfrom) {
+                       printf("Message %d:\nFrom %s %s", msg, from, date);
+                       nlines++;
+               }
+               if (seensubj) {
+                       printf("Subject: %s", subj);
+                       nlines++;
+               }
+               else {
+                       if (seenfrom) {
+                               putchar('\n');
+                               nlines++;
+                       }
+                       while (nlines < 6
+                           && fgets(inbuf, sizeof inbuf, newmsg)
+                           && inbuf[0] != '\n') {
+                               fputs(inbuf, stdout);
+                               nlines++;
+                       }
+               }
+
+               lct = linecnt(newmsg);
+               if (lct)
+                       printf("(%d%slines) ", lct, seensubj? " " : " more ");
+
+               if (hdrs) {
+                       printf("\n-----\n");
+                       fclose(newmsg);
+                       continue;
+               }
+
+               /*
+                * Ask user for command
+                */
+               if (totty)
+                       ask(lct? MORE : (msg==lastmsg? NOMORE : NEXT));
+               else
+                       inbuf[0] = 'y';
+               if (totty)
+                       signal(SIGTSTP, SIG_DFL);
+cmnd:
+               in = inbuf;
+               switch (*in) {
+                       case 'x':
+                       case 'X':
+                               exit(0);
+
+                       case 'q':
+                       case 'Q':
+                               quitit = YES;
+                               printf("--Postponed--\n");
+                               exit(0);
+                               /* intentional fall-thru */
+                       case 'n':
+                       case 'N':
+                               if (msg >= nextmsg) sep = "Flushed";
+                               prevmsg = msg;
+                               break;
+
+                       case 'p':
+                       case 'P':
+                               use_pager = (*in++ == 'p');
+                               /* intentional fallthru */
+                       case '\n':
+                       case 'y':
+                       default:
+                               if (*in == '-') {
+                                       msg = prevmsg-1;
+                                       sep = "replay";
+                                       break;
+                               }
+                               if (isdigit(*in)) {
+                                       msg = next(in);
+                                       sep = in;
+                                       break;
+                               }
+
+                               prmesg(nlines + lct + (seensubj? 1 : 0));
+                               prevmsg = msg;
+
+               }
+
+               printf("--%s--\n", sep);
+               sep = "-";
+               if (msg >= nextmsg) {
+                       nextmsg = msg + 1;
+                       fseek(msgsrc, 0L, 0);
+                       fprintf(msgsrc, "%d\n", nextmsg);
+                       fflush(msgsrc);
+               }
+               if (newmsg)
+                       fclose(newmsg);
+               if (quitit)
+                       break;
+       }
+
+       /*
+        * Make sure .rc file gets updated
+        */
+       if (--msg >= nextmsg) {
+               nextmsg = msg + 1;
+               fseek(msgsrc, 0L, 0);
+               fprintf(msgsrc, "%d\n", nextmsg);
+               fflush(msgsrc);
+       }
+       if (already && !quitit && lastcmd && totty) {
+               /*
+                * save or reply to last message?
+                */
+               msg = prevmsg;
+               ask(NOMORE);
+               if (inbuf[0] == '-' || isdigit(inbuf[0]))
+                       goto cmnd;
+       }
+       if (!(already || hush || qopt))
+               printf("No new messages.\n");
+       exit(0);
+}
+
+prmesg(length)
+int length;
+{
+       FILE *outf;
+
+       if (use_pager && length > Lpp) {
+               signal(SIGPIPE, SIG_IGN);
+               signal(SIGQUIT, SIG_IGN);
+               sprintf(cmdbuf, _PATH_PAGER, Lpp);
+               outf = popen(cmdbuf, "w");
+               if (!outf)
+                       outf = stdout;
+               else
+                       setbuf(outf, (char *)NULL);
+       }
+       else
+               outf = stdout;
+
+       if (seensubj)
+               putc('\n', outf);
+
+       while (fgets(inbuf, sizeof inbuf, newmsg)) {
+               fputs(inbuf, outf);
+               if (ferror(outf)) {
+                       clearerr(outf);
+                       break;
+               }
+       }
+
+       if (outf != stdout) {
+               pclose(outf);
+               signal(SIGPIPE, SIG_DFL);
+               signal(SIGQUIT, SIG_DFL);
+       }
+       else {
+               fflush(stdout);
+       }
+
+       /* trick to force wait on output */
+       stty(fileno(stdout), &otty);
+}
+
+void
+onintr()
+{
+       signal(SIGINT, onintr);
+       if (mailing)
+               unlink(fname);
+       if (sending) {
+               unlink(fname);
+               puts("--Killed--");
+               exit(1);
+       }
+       if (printing) {
+               putchar('\n');
+               if (hdrs)
+                       exit(0);
+               sep = "Interrupt";
+               if (newmsg)
+                       fseek(newmsg, 0L, 2);
+               intrpflg = YES;
+       }
+}
+
+/*
+ * We have just gotten a susp.  Suspend and prepare to resume.
+ */
+void
+onsusp()
+{
+
+       signal(SIGTSTP, SIG_DFL);
+       sigsetmask(0);
+       kill(0, SIGTSTP);
+       signal(SIGTSTP, onsusp);
+       if (!mailing)
+               longjmp(tstpbuf, 0);
+}
+
+linecnt(f)
+FILE *f;
+{
+       off_t oldpos = ftell(f);
+       int l = 0;
+       char lbuf[BUFSIZ];
+
+       while (fgets(lbuf, sizeof lbuf, f))
+               l++;
+       clearerr(f);
+       fseek(f, oldpos, 0);
+       return (l);
+}
+
+next(buf)
+char *buf;
+{
+       int i;
+       sscanf(buf, "%d", &i);
+       sprintf(buf, "Goto %d", i);
+       return(--i);
+}
+
+ask(prompt)
+char *prompt;
+{
+       char    inch;
+       int     n, cmsg;
+       off_t   oldpos;
+       FILE    *cpfrom, *cpto;
+
+       printf("%s ", prompt);
+       fflush(stdout);
+       intrpflg = NO;
+       (void) fgets(inbuf, sizeof inbuf, stdin);
+       if ((n = strlen(inbuf)) > 0 && inbuf[n - 1] == '\n')
+               inbuf[n - 1] = '\0';
+       if (intrpflg)
+               inbuf[0] = 'x';
+
+       /*
+        * Handle 'mail' and 'save' here.
+        */
+       if ((inch = inbuf[0]) == 's' || inch == 'm') {
+               if (inbuf[1] == '-')
+                       cmsg = prevmsg;
+               else if (isdigit(inbuf[1]))
+                       cmsg = atoi(&inbuf[1]);
+               else
+                       cmsg = msg;
+               sprintf(fname, "%s/%d", _PATH_MSGS, cmsg);
+
+               oldpos = ftell(newmsg);
+
+               cpfrom = fopen(fname, "r");
+               if (!cpfrom) {
+                       printf("Message %d not found\n", cmsg);
+                       ask (prompt);
+                       return;
+               }
+
+               if (inch == 's') {
+                       in = nxtfld(inbuf);
+                       if (*in) {
+                               for (n=0; in[n] > ' '; n++) { /* sizeof fname? */
+                                       fname[n] = in[n];
+                               }
+                               fname[n] = NULL;
+                       }
+                       else
+                               strcpy(fname, "Messages");
+               }
+               else {
+                       strcpy(fname, _PATH_TMP);
+                       mktemp(fname);
+                       sprintf(cmdbuf, _PATH_MAIL, fname);
+                       mailing = YES;
+               }
+               cpto = fopen(fname, "a");
+               if (!cpto) {
+                       perror(fname);
+                       mailing = NO;
+                       fseek(newmsg, oldpos, 0);
+                       ask(prompt);
+                       return;
+               }
+
+               while (n = fread(inbuf, 1, sizeof inbuf, cpfrom))
+                       fwrite(inbuf, 1, n, cpto);
+
+               fclose(cpfrom);
+               fclose(cpto);
+               fseek(newmsg, oldpos, 0);       /* reposition current message */
+               if (inch == 's')
+                       printf("Message %d saved in \"%s\"\n", cmsg, fname);
+               else {
+                       system(cmdbuf);
+                       unlink(fname);
+                       mailing = NO;
+               }
+               ask(prompt);
+       }
+}
+
+gfrsub(infile)
+FILE *infile;
+{
+       off_t frompos;
+
+       seensubj = seenfrom = NO;
+       local = YES;
+       subj[0] = from[0] = date[0] = NULL;
+
+       /*
+        * Is this a normal message?
+        */
+       if (fgets(inbuf, sizeof inbuf, infile)) {
+               if (strncmp(inbuf, "From", 4)==0) {
+                       /*
+                        * expected form starts with From
+                        */
+                       seenfrom = YES;
+                       frompos = ftell(infile);
+                       ptr = from;
+                       in = nxtfld(inbuf);
+                       if (*in) while (*in && *in > ' ') {
+                               if (*in == ':' || *in == '@' || *in == '!')
+                                       local = NO;
+                               *ptr++ = *in++;
+                               /* what about sizeof from ? */
+                       }
+                       *ptr = NULL;
+                       if (*(in = nxtfld(in)))
+                               strncpy(date, in, sizeof date);
+                       else {
+                               date[0] = '\n';
+                               date[1] = NULL;
+                       }
+               }
+               else {
+                       /*
+                        * not the expected form
+                        */
+                       fseek(infile, 0L, 0);
+                       return;
+               }
+       }
+       else
+               /*
+                * empty file ?
+                */
+               return;
+
+       /*
+        * look for Subject line until EOF or a blank line
+        */
+       while (fgets(inbuf, sizeof inbuf, infile)
+           && !(blankline = (inbuf[0] == '\n'))) {
+               /*
+                * extract Subject line
+                */
+               if (!seensubj && strncmp(inbuf, "Subj", 4)==0) {
+                       seensubj = YES;
+                       frompos = ftell(infile);
+                       strncpy(subj, nxtfld(inbuf), sizeof subj);
+               }
+       }
+       if (!blankline)
+               /*
+                * ran into EOF
+                */
+               fseek(infile, frompos, 0);
+
+       if (!seensubj)
+               /*
+                * for possible use with Mail
+                */
+               strncpy(subj, "(No Subject)\n", sizeof subj);
+}
+
+char *
+nxtfld(s)
+char *s;
+{
+       if (*s) while (*s && *s > ' ') s++;     /* skip over this field */
+       if (*s) while (*s && *s <= ' ') s++;    /* find start of next field */
+       return (s);
+}
diff --git a/usr/src/usr.bin/msgs/pathnames.h b/usr/src/usr.bin/msgs/pathnames.h
new file mode 100644 (file)
index 0000000..a569c7e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ *     @(#)pathnames.h 5.3 (Berkeley) 6/1/90
+ */
+
+#define        _PATH_MSGS      "/var/msgs"
+#define        _PATH_MAIL      "/usr/bin/Mail -f %s"
+#define        _PATH_PAGER     "/usr/bin/more -%d"
+#undef _PATH_TMP
+#define        _PATH_TMP       "/tmp/msgXXXXXX"