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: #if !defined(lint) && defined(DOSCCS) 35: char copyright[] = 36: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 37: All rights reserved.\n"; 38: static char sccsid[] = "@(#)main.c 5.28.1 (2.11BSD) 1996/10/23"; 39: #endif 40: 41: #include "rcv.h" 42: #include <sys/stat.h> 43: 44: /* 45: * Mail -- a mail program 46: * 47: * Startup -- interface with user. 48: */ 49: 50: jmp_buf hdrjmp; 51: 52: main(argc, argv) 53: char **argv; 54: { 55: register int i; 56: struct name *to, *cc, *bcc, *smopts; 57: char *subject; 58: char *ef; 59: char nosrc = 0; 60: void hdrstop(); 61: sig_t prevint; 62: extern int getopt(), optind, opterr; 63: extern char *optarg; 64: void sigchild(); 65: 66: /* 67: * Set up a reasonable environment. 68: * Figure out whether we are being run interactively, 69: * start the SIGCHLD catcher, and so forth. 70: */ 71: (void) signal(SIGCHLD, sigchild); 72: if (isatty(0)) 73: assign("interactive", ""); 74: image = -1; 75: /* 76: * Now, determine how we are being used. 77: * We successively pick off - flags. 78: * If there is anything left, it is the base of the list 79: * of users to mail to. Argp will be set to point to the 80: * first of these users. 81: */ 82: ef = NOSTR; 83: to = NIL; 84: cc = NIL; 85: bcc = NIL; 86: smopts = NIL; 87: subject = NOSTR; 88: while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) { 89: switch (i) { 90: case 'T': 91: /* 92: * Next argument is temp file to write which 93: * articles have been read/deleted for netnews. 94: */ 95: Tflag = optarg; 96: if ((i = creat(Tflag, 0600)) < 0) { 97: perror(Tflag); 98: exit(1); 99: } 100: close(i); 101: break; 102: case 'u': 103: /* 104: * Next argument is person to pretend to be. 105: */ 106: myname = optarg; 107: break; 108: case 'i': 109: /* 110: * User wants to ignore interrupts. 111: * Set the variable "ignore" 112: */ 113: assign("ignore", ""); 114: break; 115: case 'd': 116: debug++; 117: break; 118: case 's': 119: /* 120: * Give a subject field for sending from 121: * non terminal 122: */ 123: subject = optarg; 124: break; 125: case 'f': 126: /* 127: * User is specifying file to "edit" with Mail, 128: * as opposed to reading system mailbox. 129: * If no argument is given after -f, we read his 130: * mbox file. 131: * 132: * getopt() can't handle optional arguments, so here 133: * is an ugly hack to get around it. 134: */ 135: if ((argv[optind]) && (argv[optind][0] != '-')) 136: ef = argv[optind++]; 137: else 138: ef = "&"; 139: break; 140: case 'n': 141: /* 142: * User doesn't want to source /etc/Mail.rc 143: */ 144: nosrc++; 145: break; 146: case 'N': 147: /* 148: * Avoid initial header printing. 149: */ 150: assign("noheader", ""); 151: break; 152: case 'v': 153: /* 154: * Send mailer verbose flag 155: */ 156: assign("verbose", ""); 157: break; 158: case 'I': 159: /* 160: * We're interactive 161: */ 162: assign("interactive", ""); 163: break; 164: case 'c': 165: /* 166: * Get Carbon Copy Recipient list 167: */ 168: cc = cat(cc, nalloc(optarg, GCC)); 169: break; 170: case 'b': 171: /* 172: * Get Blind Carbon Copy Recipient list 173: */ 174: bcc = cat(bcc, nalloc(optarg, GBCC)); 175: break; 176: case '?': 177: fputs("\ 178: Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\ 179: [- sendmail-options ...]\n\ 180: mail [-iInNv] -f [name]\n\ 181: mail [-iInNv] [-u user]\n", 182: stderr); 183: exit(1); 184: } 185: } 186: for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) 187: to = cat(to, nalloc(argv[i], GTO)); 188: for (; argv[i]; i++) 189: smopts = cat(smopts, nalloc(argv[i], 0)); 190: /* 191: * Check for inconsistent arguments. 192: */ 193: if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) { 194: fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr); 195: exit(1); 196: } 197: if (ef != NOSTR && to != NIL) { 198: fprintf(stderr, "Cannot give -f and people to send to.\n"); 199: exit(1); 200: } 201: tinit(); 202: setscreensize(); 203: input = stdin; 204: rcvmode = !to; 205: spreserve(); 206: if (!nosrc) 207: load(_PATH_MASTER_RC); 208: /* 209: * Expand returns a savestr, but load only uses the file name 210: * for fopen, so it's safe to do this. 211: */ 212: load(expand("~/.mailrc")); 213: if (!rcvmode) { 214: mail(to, cc, bcc, smopts, subject); 215: /* 216: * why wait? 217: */ 218: exit(senderr); 219: } 220: /* 221: * Ok, we are reading mail. 222: * Decide whether we are editing a mailbox or reading 223: * the system mailbox, and open up the right stuff. 224: */ 225: if (ef == NOSTR) 226: ef = "%"; 227: if (setfile(ef) < 0) 228: exit(1); /* error already reported */ 229: if (setjmp(hdrjmp) == 0) { 230: extern char *version; 231: 232: if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN) 233: signal(SIGINT, hdrstop); 234: if (value("quiet") == NOSTR) 235: printf("Mail version %s. Type ? for help.\n", 236: version); 237: announce(); 238: fflush(stdout); 239: signal(SIGINT, prevint); 240: } 241: commands(); 242: signal(SIGHUP, SIG_IGN); 243: signal(SIGINT, SIG_IGN); 244: signal(SIGQUIT, SIG_IGN); 245: quit(); 246: exit(0); 247: } 248: 249: /* 250: * Interrupt printing of the headers. 251: */ 252: void 253: hdrstop() 254: { 255: 256: fflush(stdout); 257: fprintf(stderr, "\nInterrupt\n"); 258: longjmp(hdrjmp, 1); 259: } 260: 261: /* 262: * Compute what the screen size for printing headers should be. 263: * We use the following algorithm for the height: 264: * If baud rate < 1200, use 9 265: * If baud rate = 1200, use 14 266: * If baud rate > 1200, use 24 or ws_row 267: * Width is either 80 or ws_col; 268: */ 269: setscreensize() 270: { 271: struct sgttyb tbuf; 272: struct winsize ws; 273: 274: if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) 275: ws.ws_col = ws.ws_row = 0; 276: if (ioctl(1, TIOCGETP, &tbuf) < 0) 277: tbuf.sg_ospeed = B9600; 278: if (tbuf.sg_ospeed < B1200) 279: screenheight = 9; 280: else if (tbuf.sg_ospeed == B1200) 281: screenheight = 14; 282: else if (ws.ws_row != 0) 283: screenheight = ws.ws_row; 284: else 285: screenheight = 24; 286: if ((realscreenheight = ws.ws_row) == 0) 287: realscreenheight = 24; 288: if ((screenwidth = ws.ws_col) == 0) 289: screenwidth = 80; 290: }