4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.bin / mail / main.c
index add7dfe..2cd65ff 100644 (file)
@@ -1,27 +1,23 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1993
+ *     The 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.
+ * %sccs.include.redist.c%
  */
 
  */
 
-#ifdef notdef
-char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* notdef */
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
 
 
-#ifdef notdef
-static char sccsid[] = "@(#)main.c     5.12 (Berkeley) %G%";
-#endif /* notdef */
+#ifndef lint
+static char sccsid[] = "@(#)main.c     8.1 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "rcv.h"
 
 #include "rcv.h"
-#include <sys/stat.h>
+#include <fcntl.h>
+#include "extern.h"
 
 /*
  * Mail -- a mail program
 
 /*
  * Mail -- a mail program
@@ -31,82 +27,61 @@ static char sccsid[] = "@(#)main.c  5.12 (Berkeley) %G%";
 
 jmp_buf        hdrjmp;
 
 
 jmp_buf        hdrjmp;
 
-/*
- * Find out who the user is, copy his mail file (if exists) into
- * /tmp/Rxxxxx and set up the message pointers.  Then, print out the
- * message headers and read user commands.
- *
- * Command line syntax:
- *     Mail [ -i ] [ -r address ] [ -h number ] [ -f [ name ] ]
- * or:
- *     Mail [ -i ] [ -r address ] [ -h number ] people ...
- */
-
+int
 main(argc, argv)
 main(argc, argv)
-       char **argv;
+       int argc;
+       char *argv[];
 {
 {
-       register char *ef, opt;
        register int i;
        struct name *to, *cc, *bcc, *smopts;
        register int i;
        struct name *to, *cc, *bcc, *smopts;
-       int mustsend, hdrstop(), (*prevint)(), f;
-       extern int getopt(), optind, opterr;
-       extern char *optarg;
+       char *subject;
+       char *ef;
+       char nosrc = 0;
+       void hdrstop();
+       sig_t prevint;
+       void sigchild();
 
        /*
         * Set up a reasonable environment.
 
        /*
         * Set up a reasonable environment.
-        * Figure out whether we are being run interactively, set up
-        * all the temporary files, buffer standard output, and so forth.
+        * Figure out whether we are being run interactively,
+        * start the SIGCHLD catcher, and so forth.
         */
         */
-
-       mypid = getpid();
+       (void) signal(SIGCHLD, sigchild);
        if (isatty(0))
                assign("interactive", "");
        image = -1;
        if (isatty(0))
                assign("interactive", "");
        image = -1;
-
        /*
         * Now, determine how we are being used.
        /*
         * Now, determine how we are being used.
-        * We successively pick off instances of -r, -h, -f, and -i.
-        * If called as "rmail" we note this fact for letter sending.
+        * We successively pick off - flags.
         * If there is anything left, it is the base of the list
         * of users to mail to.  Argp will be set to point to the
         * first of these users.
         */
         * If there is anything left, it is the base of the list
         * of users to mail to.  Argp will be set to point to the
         * first of these users.
         */
-
        ef = NOSTR;
        ef = NOSTR;
-       to = NULL;
-       cc = NULL;
-       bcc = NULL;
-       smopts = NULL;
-       mustsend = 0;
-       if (argc > 0 && **argv == 'r')
-               rmail++;
-       while ((opt = getopt(argc, argv, "INT:b:c:dfh:inr:s:u:v")) != EOF) {
-               switch (opt) {
-               case 'r':
-                       /*
-                        * Next argument is address to be sent along
-                        * to the mailer.
-                        */
-                       mustsend++;
-                       rflag = optarg;
-                       break;
+       to = NIL;
+       cc = NIL;
+       bcc = NIL;
+       smopts = NIL;
+       subject = NOSTR;
+       while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
+               switch (i) {
                case 'T':
                        /*
                         * Next argument is temp file to write which
                         * articles have been read/deleted for netnews.
                         */
                        Tflag = optarg;
                case 'T':
                        /*
                         * Next argument is temp file to write which
                         * articles have been read/deleted for netnews.
                         */
                        Tflag = optarg;
-                       if ((f = creat(Tflag, 0600)) < 0) {
+                       if ((i = creat(Tflag, 0600)) < 0) {
                                perror(Tflag);
                                exit(1);
                        }
                                perror(Tflag);
                                exit(1);
                        }
-                       close(f);
+                       close(i);
                        break;
                case 'u':
                        /*
                         * Next argument is person to pretend to be.
                         */
                        break;
                case 'u':
                        /*
                         * Next argument is person to pretend to be.
                         */
-                       strcpy(myname, optarg);
+                       myname = optarg;
                        break;
                case 'i':
                        /*
                        break;
                case 'i':
                        /*
@@ -118,27 +93,12 @@ main(argc, argv)
                case 'd':
                        debug++;
                        break;
                case 'd':
                        debug++;
                        break;
-               case 'h':
-                       /*
-                        * Specified sequence number for network.
-                        * This is the number of "hops" made so
-                        * far (count of times message has been
-                        * forwarded) to help avoid infinite mail loops.
-                        */
-                       mustsend++;
-                       hflag = atoi(optarg);
-                       if (hflag == 0) {
-                               fprintf(stderr, "-h needs non-zero number\n");
-                               exit(1);
-                       }
-                       break;
                case 's':
                        /*
                         * Give a subject field for sending from
                         * non terminal
                         */
                case 's':
                        /*
                         * Give a subject field for sending from
                         * non terminal
                         */
-                       mustsend++;
-                       sflag = optarg;
+                       subject = optarg;
                        break;
                case 'f':
                        /*
                        break;
                case 'f':
                        /*
@@ -183,15 +143,13 @@ main(argc, argv)
                        /*
                         * Get Carbon Copy Recipient list
                         */
                        /*
                         * Get Carbon Copy Recipient list
                         */
-                       cc = cat(cc, nalloc(optarg));
-                       mustsend++;
+                       cc = cat(cc, nalloc(optarg, GCC));
                        break;
                case 'b':
                        /*
                         * Get Blind Carbon Copy Recipient list
                         */
                        break;
                case 'b':
                        /*
                         * Get Blind Carbon Copy Recipient list
                         */
-                       bcc = cat(bcc, nalloc(optarg));
-                       mustsend++;
+                       bcc = cat(bcc, nalloc(optarg, GBCC));
                        break;
                case '?':
                        fputs("\
                        break;
                case '?':
                        fputs("\
@@ -204,85 +162,74 @@ Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
                }
        }
        for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
                }
        }
        for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
-               to = cat(to, nalloc(argv[i]));
+               to = cat(to, nalloc(argv[i], GTO));
        for (; argv[i]; i++)
        for (; argv[i]; i++)
-               smopts = cat(smopts, nalloc(argv[i]));
+               smopts = cat(smopts, nalloc(argv[i], 0));
        /*
         * Check for inconsistent arguments.
         */
        /*
         * Check for inconsistent arguments.
         */
-       if (!to && (cc || bcc)) {
-               fputs("You must also specify direct recipients of mail.\n", stderr);
+       if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
+               fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
                exit(1);
        }
                exit(1);
        }
-       if ((ef != NOSTR) && to) {
+       if (ef != NOSTR && to != NIL) {
                fprintf(stderr, "Cannot give -f and people to send to.\n");
                exit(1);
        }
                fprintf(stderr, "Cannot give -f and people to send to.\n");
                exit(1);
        }
-       if (mustsend && !to) {
-               fprintf(stderr, "The flags you gave make no sense since you're not sending mail.\n");
-               exit(1);
-       }
        tinit();
        setscreensize();
        input = stdin;
        rcvmode = !to;
        tinit();
        setscreensize();
        input = stdin;
        rcvmode = !to;
+       spreserve();
        if (!nosrc)
        if (!nosrc)
-               load(MASTER);
-       load(mailrc);
+               load(_PATH_MASTER_RC);
+       /*
+        * Expand returns a savestr, but load only uses the file name
+        * for fopen, so it's safe to do this.
+        */
+       load(expand("~/.mailrc"));
        if (!rcvmode) {
        if (!rcvmode) {
-               mail(to, cc, bcc, smopts);
-
+               mail(to, cc, bcc, smopts, subject);
                /*
                 * why wait?
                 */
                /*
                 * why wait?
                 */
-
                exit(senderr);
        }
                exit(senderr);
        }
-
        /*
         * Ok, we are reading mail.
         * Decide whether we are editing a mailbox or reading
         * the system mailbox, and open up the right stuff.
         */
        /*
         * Ok, we are reading mail.
         * Decide whether we are editing a mailbox or reading
         * the system mailbox, and open up the right stuff.
         */
-       if (ef != NOSTR)
-               edit++;
-       else
+       if (ef == NOSTR)
                ef = "%";
                ef = "%";
-       if ((ef = expand(ef)) == NOSTR)
+       if (setfile(ef) < 0)
                exit(1);                /* error already reported */
                exit(1);                /* error already reported */
-       if (setfile(ef, edit) < 0) {
-               if (edit)
-                       perror(ef);
-               else
-                       fprintf(stderr, "No mail for %s\n", myname);
-               exit(1);
-       }
        if (setjmp(hdrjmp) == 0) {
        if (setjmp(hdrjmp) == 0) {
+               extern char *version;
+
                if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
                        signal(SIGINT, hdrstop);
                if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
                        signal(SIGINT, hdrstop);
-               announce(!0);
+               if (value("quiet") == NOSTR)
+                       printf("Mail version %s.  Type ? for help.\n",
+                               version);
+               announce();
                fflush(stdout);
                signal(SIGINT, prevint);
        }
                fflush(stdout);
                signal(SIGINT, prevint);
        }
-       if (!edit && msgCount == 0) {
-               printf("No mail\n");
-               fflush(stdout);
-               exit(0);
-       }
        commands();
        commands();
-       if (!edit) {
-               signal(SIGHUP, SIG_IGN);
-               signal(SIGINT, SIG_IGN);
-               signal(SIGQUIT, SIG_IGN);
-               quit();
-       }
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       quit();
        exit(0);
 }
 
 /*
  * Interrupt printing of the headers.
  */
        exit(0);
 }
 
 /*
  * Interrupt printing of the headers.
  */
-hdrstop()
+void
+hdrstop(signo)
+       int signo;
 {
 
        fflush(stdout);
 {
 
        fflush(stdout);
@@ -298,16 +245,15 @@ hdrstop()
  *     If baud rate > 1200, use 24 or ws_row
  * Width is either 80 or ws_col;
  */
  *     If baud rate > 1200, use 24 or ws_row
  * Width is either 80 or ws_col;
  */
+void
 setscreensize()
 {
        struct sgttyb tbuf;
 setscreensize()
 {
        struct sgttyb tbuf;
-#ifdef TIOCGWINSZ
        struct winsize ws;
 
        if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
        struct winsize ws;
 
        if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
-#endif
                ws.ws_col = ws.ws_row = 0;
                ws.ws_col = ws.ws_row = 0;
-       if (gtty(1, &tbuf) < 0)
+       if (ioctl(1, TIOCGETP, &tbuf) < 0)
                tbuf.sg_ospeed = B9600;
        if (tbuf.sg_ospeed < B1200)
                screenheight = 9;
                tbuf.sg_ospeed = B9600;
        if (tbuf.sg_ospeed < B1200)
                screenheight = 9;