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