cleanups, add manual page
[unix-history] / usr / src / usr.bin / mail / main.c
CommitLineData
9552e6b8
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
0c5f72fb
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
acfc7e9b
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
9552e6b8
DF
16 */
17
acfc7e9b 18#ifndef lint
0c5f72fb 19char copyright[] =
9552e6b8
DF
20"@(#) Copyright (c) 1980 Regents of the University of California.\n\
21 All rights reserved.\n";
acfc7e9b 22#endif /* not lint */
9552e6b8 23
acfc7e9b 24#ifndef lint
e9d34eb2 25static char sccsid[] = "@(#)main.c 5.19 (Berkeley) %G%";
acfc7e9b 26#endif /* not lint */
83f7d6ec
KS
27
28#include "rcv.h"
29#include <sys/stat.h>
30
31/*
32 * Mail -- a mail program
33 *
34 * Startup -- interface with user.
35 */
36
5807729c 37jmp_buf hdrjmp;
83f7d6ec 38
83f7d6ec
KS
39main(argc, argv)
40 char **argv;
41{
790344bc
EW
42 register int i;
43 struct name *to, *cc, *bcc, *smopts;
3d6f01e5
EW
44 char *subject;
45 char *ef;
f674e088 46 char nosrc = 0;
3d6f01e5 47 int hdrstop(), (*prevint)();
322c8626 48 int sigchild();
790344bc
EW
49 extern int getopt(), optind, opterr;
50 extern char *optarg;
83f7d6ec 51
83f7d6ec 52 /*
828615a1 53 * Set up a reasonable environment.
322c8626
EW
54 * Figure out whether we are being run interactively,
55 * start the SIGCHLD catcher, and so forth.
83f7d6ec 56 */
322c8626 57 (void) signal(SIGCHLD, sigchild);
686f6134
EW
58 if (isatty(0))
59 assign("interactive", "");
83f7d6ec 60 image = -1;
83f7d6ec
KS
61 /*
62 * Now, determine how we are being used.
723b83d3 63 * We successively pick off - flags.
83f7d6ec
KS
64 * If there is anything left, it is the base of the list
65 * of users to mail to. Argp will be set to point to the
66 * first of these users.
67 */
83f7d6ec 68 ef = NOSTR;
3d6f01e5
EW
69 to = NIL;
70 cc = NIL;
71 bcc = NIL;
72 smopts = NIL;
73 subject = NOSTR;
723b83d3
EW
74 while ((i = getopt(argc, argv, "INT:b:c:dfins:u:v")) != EOF) {
75 switch (i) {
12a8dbc7
KS
76 case 'T':
77 /*
78 * Next argument is temp file to write which
79 * articles have been read/deleted for netnews.
80 */
790344bc 81 Tflag = optarg;
723b83d3 82 if ((i = creat(Tflag, 0600)) < 0) {
e3d4be91
KS
83 perror(Tflag);
84 exit(1);
85 }
723b83d3 86 close(i);
12a8dbc7 87 break;
83f7d6ec
KS
88 case 'u':
89 /*
90 * Next argument is person to pretend to be.
91 */
f674e088 92 myname = optarg;
83f7d6ec 93 break;
83f7d6ec
KS
94 case 'i':
95 /*
96 * User wants to ignore interrupts.
97 * Set the variable "ignore"
98 */
99 assign("ignore", "");
100 break;
83f7d6ec
KS
101 case 'd':
102 debug++;
103 break;
83f7d6ec
KS
104 case 's':
105 /*
106 * Give a subject field for sending from
107 * non terminal
108 */
3d6f01e5 109 subject = optarg;
83f7d6ec 110 break;
83f7d6ec
KS
111 case 'f':
112 /*
113 * User is specifying file to "edit" with Mail,
114 * as opposed to reading system mailbox.
115 * If no argument is given after -f, we read his
2a0f6531 116 * mbox file.
790344bc
EW
117 *
118 * getopt() can't handle optional arguments, so here
119 * is an ugly hack to get around it.
83f7d6ec 120 */
209a87d1 121 if ((argv[optind]) && (argv[optind][0] != '-'))
790344bc 122 ef = argv[optind++];
83f7d6ec 123 else
2a0f6531 124 ef = "&";
83f7d6ec 125 break;
83f7d6ec
KS
126 case 'n':
127 /*
128 * User doesn't want to source /usr/lib/Mail.rc
129 */
130 nosrc++;
131 break;
da8590df
KS
132 case 'N':
133 /*
134 * Avoid initial header printing.
135 */
209a87d1 136 assign("noheader", "");
da8590df 137 break;
843ac7dd
CL
138 case 'v':
139 /*
140 * Send mailer verbose flag
141 */
142 assign("verbose", "");
143 break;
0f016ad0
S
144 case 'I':
145 /*
146 * We're interactive
147 */
686f6134 148 assign("interactive", "");
0f016ad0 149 break;
790344bc
EW
150 case 'c':
151 /*
152 * Get Carbon Copy Recipient list
153 */
3d6f01e5 154 cc = cat(cc, nalloc(optarg, GCC));
790344bc
EW
155 break;
156 case 'b':
157 /*
158 * Get Blind Carbon Copy Recipient list
159 */
3d6f01e5 160 bcc = cat(bcc, nalloc(optarg, GBCC));
790344bc
EW
161 break;
162 case '?':
ecedbe81
EW
163 fputs("\
164Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
165 [- sendmail-options ...]\n\
166 mail [-iInNv] -f [name]\n\
167 mail [-iInNv] [-u user]\n",
168 stderr);
83f7d6ec
KS
169 exit(1);
170 }
171 }
209a87d1 172 for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
3d6f01e5 173 to = cat(to, nalloc(argv[i], GTO));
790344bc 174 for (; argv[i]; i++)
3d6f01e5 175 smopts = cat(smopts, nalloc(argv[i], 0));
83f7d6ec
KS
176 /*
177 * Check for inconsistent arguments.
178 */
3d6f01e5
EW
179 if (to == NIL && (subject != NOSTR || cc != NIL || bcc != NIL)) {
180 fputs("You must specify direct recipients with -s, -c, or -b.\n", stderr);
790344bc
EW
181 exit(1);
182 }
3d6f01e5 183 if (ef != NOSTR && to != NIL) {
83f7d6ec
KS
184 fprintf(stderr, "Cannot give -f and people to send to.\n");
185 exit(1);
186 }
83f7d6ec 187 tinit();
828615a1 188 setscreensize();
5807729c 189 input = stdin;
790344bc 190 rcvmode = !to;
f674e088 191 spreserve();
5807729c
KS
192 if (!nosrc)
193 load(MASTER);
e9d34eb2
EW
194 /*
195 * Expand returns a savestr, but load only uses the file name
196 * for fopen, so it's save to do this.
197 */
198 load(expand("~/.mailrc"));
790344bc 199 if (!rcvmode) {
3d6f01e5 200 mail(to, cc, bcc, smopts, subject);
83f7d6ec
KS
201 /*
202 * why wait?
203 */
83f7d6ec
KS
204 exit(senderr);
205 }
83f7d6ec
KS
206 /*
207 * Ok, we are reading mail.
208 * Decide whether we are editing a mailbox or reading
209 * the system mailbox, and open up the right stuff.
210 */
2a0f6531 211 if (ef != NOSTR)
83f7d6ec 212 edit++;
2a0f6531
EW
213 else
214 ef = "%";
215 if ((ef = expand(ef)) == NOSTR)
216 exit(1); /* error already reported */
217 if (setfile(ef, edit) < 0) {
b57443b2 218 if (edit)
2a0f6531 219 perror(ef);
b57443b2
KS
220 else
221 fprintf(stderr, "No mail for %s\n", myname);
83f7d6ec 222 exit(1);
b57443b2 223 }
209a87d1 224 if (setjmp(hdrjmp) == 0) {
4d20fb09
EW
225 extern char *version;
226
209a87d1
EW
227 if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
228 signal(SIGINT, hdrstop);
4d20fb09
EW
229 if (value("quiet") == NOSTR)
230 printf("Mail version %s. Type ? for help.\n",
231 version);
232 announce();
209a87d1
EW
233 fflush(stdout);
234 signal(SIGINT, prevint);
5807729c 235 }
ab9ca2ea
KS
236 if (!edit && msgCount == 0) {
237 printf("No mail\n");
238 fflush(stdout);
239 exit(0);
240 }
83f7d6ec 241 commands();
714288d2 242 if (!edit) {
828615a1
EW
243 signal(SIGHUP, SIG_IGN);
244 signal(SIGINT, SIG_IGN);
245 signal(SIGQUIT, SIG_IGN);
83f7d6ec 246 quit();
714288d2 247 }
83f7d6ec
KS
248 exit(0);
249}
5807729c
KS
250
251/*
252 * Interrupt printing of the headers.
253 */
254hdrstop()
255{
256
5807729c 257 fflush(stdout);
80187484 258 fprintf(stderr, "\nInterrupt\n");
5807729c
KS
259 longjmp(hdrjmp, 1);
260}
828615a1
EW
261
262/*
d56fd190 263 * Compute what the screen size for printing headers should be.
828615a1
EW
264 * We use the following algorithm for the height:
265 * If baud rate < 1200, use 9
266 * If baud rate = 1200, use 14
267 * If baud rate > 1200, use 24 or ws_row
268 * Width is either 80 or ws_col;
269 */
270setscreensize()
271{
d56fd190 272 struct sgttyb tbuf;
828615a1
EW
273#ifdef TIOCGWINSZ
274 struct winsize ws;
275
686f6134 276 if (ioctl(1, TIOCGWINSZ, (char *) &ws) < 0)
828615a1 277#endif
d56fd190 278 ws.ws_col = ws.ws_row = 0;
686f6134 279 if (gtty(1, &tbuf) < 0)
d56fd190
EW
280 tbuf.sg_ospeed = B9600;
281 if (tbuf.sg_ospeed < B1200)
828615a1 282 screenheight = 9;
d56fd190 283 else if (tbuf.sg_ospeed == B1200)
828615a1 284 screenheight = 14;
828615a1
EW
285 else if (ws.ws_row != 0)
286 screenheight = ws.ws_row;
828615a1
EW
287 else
288 screenheight = 24;
d56fd190
EW
289 if ((realscreenheight = ws.ws_row) == 0)
290 realscreenheight = 24;
291 if ((screenwidth = ws.ws_col) == 0)
828615a1
EW
292 screenwidth = 80;
293}