19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1980, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 359b50d902SRodney W. Grimes static char copyright[] = 369b50d902SRodney W. Grimes "@(#) Copyright (c) 1980, 1993\n\ 379b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 389b50d902SRodney W. Grimes #endif /* not lint */ 399b50d902SRodney W. Grimes 409b50d902SRodney W. Grimes #ifndef lint 419b50d902SRodney W. Grimes static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; 429b50d902SRodney W. Grimes #endif /* not lint */ 439b50d902SRodney W. Grimes 449b50d902SRodney W. Grimes #include "rcv.h" 459b50d902SRodney W. Grimes #include <fcntl.h> 469b50d902SRodney W. Grimes #include "extern.h" 479b50d902SRodney W. Grimes 489b50d902SRodney W. Grimes /* 499b50d902SRodney W. Grimes * Mail -- a mail program 509b50d902SRodney W. Grimes * 519b50d902SRodney W. Grimes * Startup -- interface with user. 529b50d902SRodney W. Grimes */ 539b50d902SRodney W. Grimes 549b50d902SRodney W. Grimes jmp_buf hdrjmp; 559b50d902SRodney W. Grimes 569b50d902SRodney W. Grimes int 579b50d902SRodney W. Grimes main(argc, argv) 589b50d902SRodney W. Grimes int argc; 599b50d902SRodney W. Grimes char *argv[]; 609b50d902SRodney W. Grimes { 619b50d902SRodney W. Grimes register int i; 629b50d902SRodney W. Grimes struct name *to, *cc, *bcc, *smopts; 639b50d902SRodney W. Grimes char *subject; 649b50d902SRodney W. Grimes char *ef; 659b50d902SRodney W. Grimes char nosrc = 0; 669b50d902SRodney W. Grimes void hdrstop(); 679b50d902SRodney W. Grimes sig_t prevint; 689b50d902SRodney W. Grimes void sigchild(); 699b50d902SRodney W. Grimes 709b50d902SRodney W. Grimes /* 719b50d902SRodney W. Grimes * Set up a reasonable environment. 729b50d902SRodney W. Grimes * Figure out whether we are being run interactively, 739b50d902SRodney W. Grimes * start the SIGCHLD catcher, and so forth. 749b50d902SRodney W. Grimes */ 759b50d902SRodney W. Grimes (void) signal(SIGCHLD, sigchild); 769b50d902SRodney W. Grimes if (isatty(0)) 779b50d902SRodney W. Grimes assign("interactive", ""); 789b50d902SRodney W. Grimes image = -1; 799b50d902SRodney W. Grimes /* 809b50d902SRodney W. Grimes * Now, determine how we are being used. 819b50d902SRodney W. Grimes * We successively pick off - flags. 829b50d902SRodney W. Grimes * If there is anything left, it is the base of the list 839b50d902SRodney W. Grimes * of users to mail to. Argp will be set to point to the 849b50d902SRodney W. Grimes * first of these users. 859b50d902SRodney W. Grimes */ 869b50d902SRodney W. Grimes ef = NOSTR; 879b50d902SRodney W. Grimes to = NIL; 889b50d902SRodney W. Grimes cc = NIL; 899b50d902SRodney W. Grimes bcc = NIL; 909b50d902SRodney W. Grimes smopts = NIL; 919b50d902SRodney W. Grimes subject = NOSTR; 929b50d902SRodney W. Grimes while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) { 939b50d902SRodney W. Grimes switch (i) { 949b50d902SRodney W. Grimes case 'T': 959b50d902SRodney W. Grimes /* 969b50d902SRodney W. Grimes * Next argument is temp file to write which 979b50d902SRodney W. Grimes * articles have been read/deleted for netnews. 989b50d902SRodney W. Grimes */ 999b50d902SRodney W. Grimes Tflag = optarg; 1009b50d902SRodney W. Grimes if ((i = creat(Tflag, 0600)) < 0) { 1019b50d902SRodney W. Grimes perror(Tflag); 1029b50d902SRodney W. Grimes exit(1); 1039b50d902SRodney W. Grimes } 1049b50d902SRodney W. Grimes close(i); 1059b50d902SRodney W. Grimes break; 1069b50d902SRodney W. Grimes case 'u': 1079b50d902SRodney W. Grimes /* 1089b50d902SRodney W. Grimes * Next argument is person to pretend to be. 1099b50d902SRodney W. Grimes */ 1109b50d902SRodney W. Grimes myname = optarg; 1119b50d902SRodney W. Grimes break; 1129b50d902SRodney W. Grimes case 'i': 1139b50d902SRodney W. Grimes /* 1149b50d902SRodney W. Grimes * User wants to ignore interrupts. 1159b50d902SRodney W. Grimes * Set the variable "ignore" 1169b50d902SRodney W. Grimes */ 1179b50d902SRodney W. Grimes assign("ignore", ""); 1189b50d902SRodney W. Grimes break; 1199b50d902SRodney W. Grimes case 'd': 1209b50d902SRodney W. Grimes debug++; 1219b50d902SRodney W. Grimes break; 1229b50d902SRodney W. Grimes case 's': 1239b50d902SRodney W. Grimes /* 1249b50d902SRodney W. Grimes * Give a subject field for sending from 1259b50d902SRodney W. Grimes * non terminal 1269b50d902SRodney W. Grimes */ 1279b50d902SRodney W. Grimes subject = optarg; 1289b50d902SRodney W. Grimes break; 1299b50d902SRodney W. Grimes case 'f': 1309b50d902SRodney W. Grimes /* 1319b50d902SRodney W. Grimes * User is specifying file to "edit" with Mail, 1329b50d902SRodney W. Grimes * as opposed to reading system mailbox. 1339b50d902SRodney W. Grimes * If no argument is given after -f, we read his 1349b50d902SRodney W. Grimes * mbox file. 1359b50d902SRodney W. Grimes * 1369b50d902SRodney W. Grimes * getopt() can't handle optional arguments, so here 1379b50d902SRodney W. Grimes * is an ugly hack to get around it. 1389b50d902SRodney W. Grimes */ 1399b50d902SRodney W. Grimes if ((argv[optind]) && (argv[optind][0] != '-')) 1409b50d902SRodney W. Grimes ef = argv[optind++]; 1419b50d902SRodney W. Grimes else 1429b50d902SRodney W. Grimes ef = "&"; 1439b50d902SRodney W. Grimes break; 1449b50d902SRodney W. Grimes case 'n': 1459b50d902SRodney W. Grimes /* 1469b50d902SRodney W. Grimes * User doesn't want to source /usr/lib/Mail.rc 1479b50d902SRodney W. Grimes */ 1489b50d902SRodney W. Grimes nosrc++; 1499b50d902SRodney W. Grimes break; 1509b50d902SRodney W. Grimes case 'N': 1519b50d902SRodney W. Grimes /* 1529b50d902SRodney W. Grimes * Avoid initial header printing. 1539b50d902SRodney W. Grimes */ 1549b50d902SRodney W. Grimes assign("noheader", ""); 1559b50d902SRodney W. Grimes break; 1569b50d902SRodney W. Grimes case 'v': 1579b50d902SRodney W. Grimes /* 1589b50d902SRodney W. Grimes * Send mailer verbose flag 1599b50d902SRodney W. Grimes */ 1609b50d902SRodney W. Grimes assign("verbose", ""); 1619b50d902SRodney W. Grimes break; 1629b50d902SRodney W. Grimes case 'I': 1639b50d902SRodney W. Grimes /* 1649b50d902SRodney W. Grimes * We're interactive 1659b50d902SRodney W. Grimes */ 1669b50d902SRodney W. Grimes assign("interactive", ""); 1679b50d902SRodney W. Grimes break; 1689b50d902SRodney W. Grimes case 'c': 1699b50d902SRodney W. Grimes /* 1709b50d902SRodney W. Grimes * Get Carbon Copy Recipient list 1719b50d902SRodney W. Grimes */ 1729b50d902SRodney W. Grimes cc = cat(cc, nalloc(optarg, GCC)); 1739b50d902SRodney W. Grimes break; 1749b50d902SRodney W. Grimes case 'b': 1759b50d902SRodney W. Grimes /* 1769b50d902SRodney W. Grimes * Get Blind Carbon Copy Recipient list 1779b50d902SRodney W. Grimes */ 1789b50d902SRodney W. Grimes bcc = cat(bcc, nalloc(optarg, GBCC)); 1799b50d902SRodney W. Grimes break; 1809b50d902SRodney W. Grimes case '?': 1819b50d902SRodney W. Grimes fputs("\ 1829b50d902SRodney W. Grimes Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\ 1839b50d902SRodney W. Grimes [- sendmail-options ...]\n\ 1849b50d902SRodney W. Grimes mail [-iInNv] -f [name]\n\ 1859b50d902SRodney W. Grimes mail [-iInNv] [-u user]\n", 1869b50d902SRodney W. Grimes stderr); 1879b50d902SRodney W. Grimes exit(1); 1889b50d902SRodney W. Grimes } 1899b50d902SRodney W. Grimes } 1909b50d902SRodney W. Grimes for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) 1919b50d902SRodney W. Grimes to = cat(to, nalloc(argv[i], GTO)); 1929b50d902SRodney W. Grimes for (; argv[i]; i++) 1939b50d902SRodney W. Grimes smopts = cat(smopts, nalloc(argv[i], 0)); 1949b50d902SRodney W. Grimes /* 1959b50d902SRodney W. Grimes * Check for inconsistent arguments. 1969b50d902SRodney W. Grimes */ 1979b50d902SRodney W. Grimes if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) { 1989b50d902SRodney W. Grimes fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr); 1999b50d902SRodney W. Grimes exit(1); 2009b50d902SRodney W. Grimes } 2019b50d902SRodney W. Grimes if (ef != NOSTR && to != NIL) { 2029b50d902SRodney W. Grimes fprintf(stderr, "Cannot give -f and people to send to.\n"); 2039b50d902SRodney W. Grimes exit(1); 2049b50d902SRodney W. Grimes } 2059b50d902SRodney W. Grimes tinit(); 2069b50d902SRodney W. Grimes setscreensize(); 2079b50d902SRodney W. Grimes input = stdin; 2089b50d902SRodney W. Grimes rcvmode = !to; 2099b50d902SRodney W. Grimes spreserve(); 2109b50d902SRodney W. Grimes if (!nosrc) 2119b50d902SRodney W. Grimes load(_PATH_MASTER_RC); 2129b50d902SRodney W. Grimes /* 2139b50d902SRodney W. Grimes * Expand returns a savestr, but load only uses the file name 2149b50d902SRodney W. Grimes * for fopen, so it's safe to do this. 2159b50d902SRodney W. Grimes */ 2169b50d902SRodney W. Grimes load(expand("~/.mailrc")); 2179b50d902SRodney W. Grimes if (!rcvmode) { 2189b50d902SRodney W. Grimes mail(to, cc, bcc, smopts, subject); 2199b50d902SRodney W. Grimes /* 2209b50d902SRodney W. Grimes * why wait? 2219b50d902SRodney W. Grimes */ 2229b50d902SRodney W. Grimes exit(senderr); 2239b50d902SRodney W. Grimes } 2249b50d902SRodney W. Grimes /* 2259b50d902SRodney W. Grimes * Ok, we are reading mail. 2269b50d902SRodney W. Grimes * Decide whether we are editing a mailbox or reading 2279b50d902SRodney W. Grimes * the system mailbox, and open up the right stuff. 2289b50d902SRodney W. Grimes */ 2299b50d902SRodney W. Grimes if (ef == NOSTR) 2309b50d902SRodney W. Grimes ef = "%"; 2319b50d902SRodney W. Grimes if (setfile(ef) < 0) 2329b50d902SRodney W. Grimes exit(1); /* error already reported */ 2339b50d902SRodney W. Grimes if (setjmp(hdrjmp) == 0) { 2349b50d902SRodney W. Grimes extern char *version; 2359b50d902SRodney W. Grimes 2369b50d902SRodney W. Grimes if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN) 2379b50d902SRodney W. Grimes signal(SIGINT, hdrstop); 2389b50d902SRodney W. Grimes if (value("quiet") == NOSTR) 2399b50d902SRodney W. Grimes printf("Mail version %s. Type ? for help.\n", 2409b50d902SRodney W. Grimes version); 2419b50d902SRodney W. Grimes announce(); 2429b50d902SRodney W. Grimes fflush(stdout); 2439b50d902SRodney W. Grimes signal(SIGINT, prevint); 2449b50d902SRodney W. Grimes } 2459b50d902SRodney W. Grimes commands(); 2469b50d902SRodney W. Grimes signal(SIGHUP, SIG_IGN); 2479b50d902SRodney W. Grimes signal(SIGINT, SIG_IGN); 2489b50d902SRodney W. Grimes signal(SIGQUIT, SIG_IGN); 2499b50d902SRodney W. Grimes quit(); 2509b50d902SRodney W. Grimes exit(0); 2519b50d902SRodney W. Grimes } 2529b50d902SRodney W. Grimes 2539b50d902SRodney W. Grimes /* 2549b50d902SRodney W. Grimes * Interrupt printing of the headers. 2559b50d902SRodney W. Grimes */ 2569b50d902SRodney W. Grimes void 2579b50d902SRodney W. Grimes hdrstop(signo) 2589b50d902SRodney W. Grimes int signo; 2599b50d902SRodney W. Grimes { 2609b50d902SRodney W. Grimes 2619b50d902SRodney W. Grimes fflush(stdout); 2629b50d902SRodney W. Grimes fprintf(stderr, "\nInterrupt\n"); 2639b50d902SRodney W. Grimes longjmp(hdrjmp, 1); 2649b50d902SRodney W. Grimes } 2659b50d902SRodney W. Grimes 2669b50d902SRodney W. Grimes /* 2679b50d902SRodney W. Grimes * Compute what the screen size for printing headers should be. 2689b50d902SRodney W. Grimes * We use the following algorithm for the height: 2699b50d902SRodney W. Grimes * If baud rate < 1200, use 9 2709b50d902SRodney W. Grimes * If baud rate = 1200, use 14 2719b50d902SRodney W. Grimes * If baud rate > 1200, use 24 or ws_row 2729b50d902SRodney W. Grimes * Width is either 80 or ws_col; 2739b50d902SRodney W. Grimes */ 2749b50d902SRodney W. Grimes void 2759b50d902SRodney W. Grimes setscreensize() 2769b50d902SRodney W. Grimes { 2779b50d902SRodney W. Grimes struct sgttyb tbuf; 2789b50d902SRodney W. Grimes struct winsize ws; 2799b50d902SRodney W. Grimes 2809b50d902SRodney W. Grimes if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) 2819b50d902SRodney W. Grimes ws.ws_col = ws.ws_row = 0; 2829b50d902SRodney W. Grimes if (ioctl(1, TIOCGETP, &tbuf) < 0) 2839b50d902SRodney W. Grimes tbuf.sg_ospeed = B9600; 2849b50d902SRodney W. Grimes if (tbuf.sg_ospeed < B1200) 2859b50d902SRodney W. Grimes screenheight = 9; 2869b50d902SRodney W. Grimes else if (tbuf.sg_ospeed == B1200) 2879b50d902SRodney W. Grimes screenheight = 14; 2889b50d902SRodney W. Grimes else if (ws.ws_row != 0) 2899b50d902SRodney W. Grimes screenheight = ws.ws_row; 2909b50d902SRodney W. Grimes else 2919b50d902SRodney W. Grimes screenheight = 24; 2929b50d902SRodney W. Grimes if ((realscreenheight = ws.ws_row) == 0) 2939b50d902SRodney W. Grimes realscreenheight = 24; 2949b50d902SRodney W. Grimes if ((screenwidth = ws.ws_col) == 0) 2959b50d902SRodney W. Grimes screenwidth = 80; 2969b50d902SRodney W. Grimes } 297