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