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