home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / mail / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  7.1 KB  |  294 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)main.c    5.28 (Berkeley) 4/1/91";
  42. #endif /* not lint */
  43.  
  44. #include "rcv.h"
  45. #include <sys/stat.h>
  46.  
  47. /*
  48.  * Mail -- a mail program
  49.  *
  50.  * Startup -- interface with user.
  51.  */
  52.  
  53. jmp_buf    hdrjmp;
  54.  
  55. main(argc, argv)
  56.     char **argv;
  57. {
  58.     register int i;
  59.     struct name *to, *cc, *bcc, *smopts;
  60.     char *subject;
  61.     char *ef;
  62.     char nosrc = 0;
  63.     void hdrstop();
  64.     sig_t prevint;
  65.     extern int getopt(), optind, opterr;
  66.     extern char *optarg;
  67.     void sigchild();
  68.  
  69.     /*
  70.      * Set up a reasonable environment.
  71.      * Figure out whether we are being run interactively,
  72.      * start the SIGCHLD catcher, and so forth.
  73.      */
  74.     (void) signal(SIGCHLD, sigchild);
  75.     if (isatty(0))
  76.         assign("interactive", "");
  77.     image = -1;
  78.     /*
  79.      * Now, determine how we are being used.
  80.      * We successively pick off - flags.
  81.      * If there is anything left, it is the base of the list
  82.      * of users to mail to.  Argp will be set to point to the
  83.      * first of these users.
  84.      */
  85.     ef = NOSTR;
  86.     to = NIL;
  87.     cc = NIL;
  88.     bcc = NIL;
  89.     smopts = NIL;
  90.     subject = NOSTR;
  91.     while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
  92.         switch (i) {
  93.         case 'T':
  94.             /*
  95.              * Next argument is temp file to write which
  96.              * articles have been read/deleted for netnews.
  97.              */
  98.             Tflag = optarg;
  99.             if ((i = creat(Tflag, 0600)) < 0) {
  100.                 perror(Tflag);
  101.                 exit(1);
  102.             }
  103.             close(i);
  104.             break;
  105.         case 'u':
  106.             /*
  107.              * Next argument is person to pretend to be.
  108.              */
  109.             myname = optarg;
  110.             break;
  111.         case 'i':
  112.             /*
  113.              * User wants to ignore interrupts.
  114.              * Set the variable "ignore"
  115.              */
  116.             assign("ignore", "");
  117.             break;
  118.         case 'd':
  119.             debug++;
  120.             break;
  121.         case 's':
  122.             /*
  123.              * Give a subject field for sending from
  124.              * non terminal
  125.              */
  126.             subject = optarg;
  127.             break;
  128.         case 'f':
  129.             /*
  130.              * User is specifying file to "edit" with Mail,
  131.              * as opposed to reading system mailbox.
  132.              * If no argument is given after -f, we read his
  133.              * mbox file.
  134.              *
  135.              * getopt() can't handle optional arguments, so here
  136.              * is an ugly hack to get around it.
  137.              */
  138.             if ((argv[optind]) && (argv[optind][0] != '-'))
  139.                 ef = argv[optind++];
  140.             else
  141.                 ef = "&";
  142.             break;
  143.         case 'n':
  144.             /*
  145.              * User doesn't want to source /usr/lib/Mail.rc
  146.              */
  147.             nosrc++;
  148.             break;
  149.         case 'N':
  150.             /*
  151.              * Avoid initial header printing.
  152.              */
  153.             assign("noheader", "");
  154.             break;
  155.         case 'v':
  156.             /*
  157.              * Send mailer verbose flag
  158.              */
  159.             assign("verbose", "");
  160.             break;
  161.         case 'I':
  162.             /*
  163.              * We're interactive
  164.              */
  165.             assign("interactive", "");
  166.             break;
  167.         case 'c':
  168.             /*
  169.              * Get Carbon Copy Recipient list
  170.              */
  171.             cc = cat(cc, nalloc(optarg, GCC));
  172.             break;
  173.         case 'b':
  174.             /*
  175.              * Get Blind Carbon Copy Recipient list
  176.              */
  177.             bcc = cat(bcc, nalloc(optarg, GBCC));
  178.             break;
  179.         case '?':
  180.             fputs("\
  181. Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
  182.             [- sendmail-options ...]\n\
  183.        mail [-iInNv] -f [name]\n\
  184.        mail [-iInNv] [-u user]\n",
  185.                 stderr);
  186.             exit(1);
  187.         }
  188.     }
  189.     for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
  190.         to = cat(to, nalloc(argv[i], GTO));
  191.     for (; argv[i]; i++)
  192.         smopts = cat(smopts, nalloc(argv[i], 0));
  193.     /*
  194.      * Check for inconsistent arguments.
  195.      */
  196.     if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
  197.         fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
  198.         exit(1);
  199.     }
  200.     if (ef != NOSTR && to != NIL) {
  201.         fprintf(stderr, "Cannot give -f and people to send to.\n");
  202.         exit(1);
  203.     }
  204.     tinit();
  205.     setscreensize();
  206.     input = stdin;
  207.     rcvmode = !to;
  208.     spreserve();
  209.     if (!nosrc)
  210.         load(_PATH_MASTER_RC);
  211.     /*
  212.      * Expand returns a savestr, but load only uses the file name
  213.      * for fopen, so it's safe to do this.
  214.      */
  215.     load(expand("~/.mailrc"));
  216.     if (!rcvmode) {
  217.         mail(to, cc, bcc, smopts, subject);
  218.         /*
  219.          * why wait?
  220.          */
  221.         exit(senderr);
  222.     }
  223.     /*
  224.      * Ok, we are reading mail.
  225.      * Decide whether we are editing a mailbox or reading
  226.      * the system mailbox, and open up the right stuff.
  227.      */
  228.     if (ef == NOSTR)
  229.         ef = "%";
  230.     if (setfile(ef) < 0)
  231.         exit(1);        /* error already reported */
  232.     if (setjmp(hdrjmp) == 0) {
  233.         extern char *version;
  234.  
  235.         if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
  236.             signal(SIGINT, hdrstop);
  237.         if (value("quiet") == NOSTR)
  238.             printf("Mail version %s.  Type ? for help.\n",
  239.                 version);
  240.         announce();
  241.         fflush(stdout);
  242.         signal(SIGINT, prevint);
  243.     }
  244.     commands();
  245.     signal(SIGHUP, SIG_IGN);
  246.     signal(SIGINT, SIG_IGN);
  247.     signal(SIGQUIT, SIG_IGN);
  248.     quit();
  249.     exit(0);
  250. }
  251.  
  252. /*
  253.  * Interrupt printing of the headers.
  254.  */
  255. void
  256. hdrstop()
  257. {
  258.  
  259.     fflush(stdout);
  260.     fprintf(stderr, "\nInterrupt\n");
  261.     longjmp(hdrjmp, 1);
  262. }
  263.  
  264. /*
  265.  * Compute what the screen size for printing headers should be.
  266.  * We use the following algorithm for the height:
  267.  *    If baud rate < 1200, use  9
  268.  *    If baud rate = 1200, use 14
  269.  *    If baud rate > 1200, use 24 or ws_row
  270.  * Width is either 80 or ws_col;
  271.  */
  272. setscreensize()
  273. {
  274.     struct sgttyb tbuf;
  275.     struct winsize ws;
  276.  
  277.     if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
  278.         ws.ws_col = ws.ws_row = 0;
  279.     if (ioctl(1, TIOCGETP, &tbuf) < 0)
  280.         tbuf.sg_ospeed = B9600;
  281.     if (tbuf.sg_ospeed < B1200)
  282.         screenheight = 9;
  283.     else if (tbuf.sg_ospeed == B1200)
  284.         screenheight = 14;
  285.     else if (ws.ws_row != 0)
  286.         screenheight = ws.ws_row;
  287.     else
  288.         screenheight = 24;
  289.     if ((realscreenheight = ws.ws_row) == 0)
  290.         realscreenheight = 24;
  291.     if ((screenwidth = ws.ws_col) == 0)
  292.         screenwidth = 80;
  293. }
  294.