122459Sdist /*
262083Sbostic * Copyright (c) 1980, 1993
362083Sbostic * The Regents of the University of California. All rights reserved.
433499Sbostic *
542741Sbostic * %sccs.include.redist.c%
622459Sdist */
722459Sdist
834905Sbostic #ifndef lint
962083Sbostic static char copyright[] =
1062083Sbostic "@(#) Copyright (c) 1980, 1993\n\
1162083Sbostic The Regents of the University of California. All rights reserved.\n";
1234905Sbostic #endif /* not lint */
131240Skas
1434905Sbostic #ifndef lint
15*68818Sdab static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 04/20/95";
1634905Sbostic #endif /* not lint */
1722459Sdist
181240Skas #include "rcv.h"
1954505Sbostic #include <fcntl.h>
2054505Sbostic #include "extern.h"
211240Skas
221240Skas /*
231240Skas * Mail -- a mail program
241240Skas *
251240Skas * Startup -- interface with user.
261240Skas */
271240Skas
285780Skurt jmp_buf hdrjmp;
295780Skurt
3054505Sbostic int
main(argc,argv)311240Skas main(argc, argv)
3254505Sbostic int argc;
3354505Sbostic char *argv[];
341240Skas {
3534702Sedward register int i;
3634702Sedward struct name *to, *cc, *bcc, *smopts;
3734800Sedward char *subject;
3834800Sedward char *ef;
3934968Sedward char nosrc = 0;
4047708Sbostic void hdrstop();
4139612Sedward sig_t prevint;
4247708Sbostic void sigchild();
43*68818Sdab char *rc;
441240Skas
451240Skas /*
4631142Sedward * Set up a reasonable environment.
4734976Sedward * Figure out whether we are being run interactively,
4834976Sedward * start the SIGCHLD catcher, and so forth.
491240Skas */
5034976Sedward (void) signal(SIGCHLD, sigchild);
5134751Sedward if (isatty(0))
5234751Sedward assign("interactive", "");
531240Skas image = -1;
541240Skas /*
551240Skas * Now, determine how we are being used.
5634787Sedward * We successively pick off - flags.
571240Skas * If there is anything left, it is the base of the list
581240Skas * of users to mail to. Argp will be set to point to the
591240Skas * first of these users.
601240Skas */
611240Skas ef = NOSTR;
6234800Sedward to = NIL;
6334800Sedward cc = NIL;
6434800Sedward bcc = NIL;
6534800Sedward smopts = NIL;
6634800Sedward subject = NOSTR;
6734787Sedward while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
6834787Sedward switch (i) {
694019Skurt case 'T':
704019Skurt /*
714019Skurt * Next argument is temp file to write which
724019Skurt * articles have been read/deleted for netnews.
734019Skurt */
7434702Sedward Tflag = optarg;
7534787Sedward if ((i = creat(Tflag, 0600)) < 0) {
765966Skurt perror(Tflag);
775966Skurt exit(1);
785966Skurt }
7934787Sedward close(i);
804019Skurt break;
811240Skas case 'u':
821240Skas /*
831240Skas * Next argument is person to pretend to be.
841240Skas */
8534968Sedward myname = optarg;
861240Skas break;
871240Skas case 'i':
881240Skas /*
891240Skas * User wants to ignore interrupts.
901240Skas * Set the variable "ignore"
911240Skas */
921240Skas assign("ignore", "");
931240Skas break;
941240Skas case 'd':
951240Skas debug++;
961240Skas break;
971240Skas case 's':
981240Skas /*
991240Skas * Give a subject field for sending from
1001240Skas * non terminal
1011240Skas */
10234800Sedward subject = optarg;
1031240Skas break;
1041240Skas case 'f':
1051240Skas /*
1061240Skas * User is specifying file to "edit" with Mail,
1071240Skas * as opposed to reading system mailbox.
1081240Skas * If no argument is given after -f, we read his
10934753Sedward * mbox file.
11034702Sedward *
11134702Sedward * getopt() can't handle optional arguments, so here
11234702Sedward * is an ugly hack to get around it.
1131240Skas */
11434704Sedward if ((argv[optind]) && (argv[optind][0] != '-'))
11534702Sedward ef = argv[optind++];
11634702Sedward else
11734753Sedward ef = "&";
1181240Skas break;
1191240Skas case 'n':
1201240Skas /*
1211240Skas * User doesn't want to source /usr/lib/Mail.rc
1221240Skas */
1231240Skas nosrc++;
1241240Skas break;
1252353Skas case 'N':
1262353Skas /*
1272353Skas * Avoid initial header printing.
1282353Skas */
12934704Sedward assign("noheader", "");
1302353Skas break;
13110581Sleres case 'v':
13210581Sleres /*
13310581Sleres * Send mailer verbose flag
13410581Sleres */
13510581Sleres assign("verbose", "");
13610581Sleres break;
13721091Sserge case 'I':
13821091Sserge /*
13921091Sserge * We're interactive
14021091Sserge */
14134751Sedward assign("interactive", "");
14221091Sserge break;
14334702Sedward case 'c':
14434702Sedward /*
14534702Sedward * Get Carbon Copy Recipient list
14634702Sedward */
14734800Sedward cc = cat(cc, nalloc(optarg, GCC));
14834702Sedward break;
14934702Sedward case 'b':
15034702Sedward /*
15134702Sedward * Get Blind Carbon Copy Recipient list
15234702Sedward */
15334800Sedward bcc = cat(bcc, nalloc(optarg, GBCC));
15434702Sedward break;
15534702Sedward case '?':
15634703Sedward fputs("\
15734703Sedward Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
15834703Sedward [- sendmail-options ...]\n\
15934703Sedward mail [-iInNv] -f [name]\n\
16034703Sedward mail [-iInNv] [-u user]\n",
16134703Sedward stderr);
1621240Skas exit(1);
1631240Skas }
1641240Skas }
16534704Sedward for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
16634800Sedward to = cat(to, nalloc(argv[i], GTO));
16734702Sedward for (; argv[i]; i++)
16834800Sedward smopts = cat(smopts, nalloc(argv[i], 0));
1691240Skas /*
1701240Skas * Check for inconsistent arguments.
1711240Skas */
17234800Sedward if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
17334800Sedward fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
17434702Sedward exit(1);
17534702Sedward }
17634800Sedward if (ef != NOSTR && to != NIL) {
1771240Skas fprintf(stderr, "Cannot give -f and people to send to.\n");
1781240Skas exit(1);
1791240Skas }
1801240Skas tinit();
18131142Sedward setscreensize();
1825780Skurt input = stdin;
18334702Sedward rcvmode = !to;
18434968Sedward spreserve();
1855780Skurt if (!nosrc)
18637870Sbostic load(_PATH_MASTER_RC);
18735374Sedward /*
18835374Sedward * Expand returns a savestr, but load only uses the file name
18943865Sedward * for fopen, so it's safe to do this.
19035374Sedward */
191*68818Sdab if ((rc = getenv("MAILRC")) == 0)
192*68818Sdab rc = "~/.mailrc";
193*68818Sdab load(expand(rc));
19434702Sedward if (!rcvmode) {
19534800Sedward mail(to, cc, bcc, smopts, subject);
1961240Skas /*
1971240Skas * why wait?
1981240Skas */
1991240Skas exit(senderr);
2001240Skas }
2011240Skas /*
2021240Skas * Ok, we are reading mail.
2031240Skas * Decide whether we are editing a mailbox or reading
2041240Skas * the system mailbox, and open up the right stuff.
2051240Skas */
20636734Sedward if (ef == NOSTR)
20734753Sedward ef = "%";
20836734Sedward if (setfile(ef) < 0)
20934753Sedward exit(1); /* error already reported */
21034704Sedward if (setjmp(hdrjmp) == 0) {
21134754Sedward extern char *version;
21234754Sedward
21334704Sedward if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
21434704Sedward signal(SIGINT, hdrstop);
21534754Sedward if (value("quiet") == NOSTR)
21634754Sedward printf("Mail version %s. Type ? for help.\n",
21734754Sedward version);
21834754Sedward announce();
21934704Sedward fflush(stdout);
22034704Sedward signal(SIGINT, prevint);
2215780Skurt }
2221240Skas commands();
22336554Sedward signal(SIGHUP, SIG_IGN);
22436554Sedward signal(SIGINT, SIG_IGN);
22536554Sedward signal(SIGQUIT, SIG_IGN);
22636554Sedward quit();
2271240Skas exit(0);
2281240Skas }
2295780Skurt
2305780Skurt /*
2315780Skurt * Interrupt printing of the headers.
2325780Skurt */
23347708Sbostic void
hdrstop(signo)23454505Sbostic hdrstop(signo)
23554505Sbostic int signo;
2365780Skurt {
2375780Skurt
2385780Skurt fflush(stdout);
23916859Sralph fprintf(stderr, "\nInterrupt\n");
2405780Skurt longjmp(hdrjmp, 1);
2415780Skurt }
24231142Sedward
24331142Sedward /*
24434749Sedward * Compute what the screen size for printing headers should be.
24531142Sedward * We use the following algorithm for the height:
24631142Sedward * If baud rate < 1200, use 9
24731142Sedward * If baud rate = 1200, use 14
24831142Sedward * If baud rate > 1200, use 24 or ws_row
24931142Sedward * Width is either 80 or ws_col;
25031142Sedward */
25154505Sbostic void
setscreensize()25231142Sedward setscreensize()
25331142Sedward {
254*68818Sdab struct termios tbuf;
25531142Sedward struct winsize ws;
256*68818Sdab int ospeed;
25731142Sedward
25834751Sedward if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
25931142Sedward ws.ws_col = ws.ws_row = 0;
260*68818Sdab if (ioctl(1, TIOCGETA, &tbuf) < 0)
261*68818Sdab ospeed = B9600;
262*68818Sdab else
263*68818Sdab ospeed = cfgetospeed(&tbuf);
264*68818Sdab if (ospeed < B1200)
26531142Sedward screenheight = 9;
266*68818Sdab else if (ospeed == B1200)
26731142Sedward screenheight = 14;
26831142Sedward else if (ws.ws_row != 0)
26931142Sedward screenheight = ws.ws_row;
27031142Sedward else
27131142Sedward screenheight = 24;
27234749Sedward if ((realscreenheight = ws.ws_row) == 0)
27334749Sedward realscreenheight = 24;
27434749Sedward if ((screenwidth = ws.ws_col) == 0)
27531142Sedward screenwidth = 80;
27631142Sedward }
277