new template
[unix-history] / usr / src / usr.bin / mail / main.c
CommitLineData
9552e6b8
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
2fd8b883 8char *copyright =
9552e6b8
DF
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
2ae9f53f 13#ifndef lint
828615a1 14static char *sccsid = "@(#)main.c 5.4 (Berkeley) %G%";
9552e6b8 15#endif not lint
83f7d6ec
KS
16
17#include "rcv.h"
18#include <sys/stat.h>
19
20/*
21 * Mail -- a mail program
22 *
23 * Startup -- interface with user.
24 */
25
5807729c 26jmp_buf hdrjmp;
83f7d6ec
KS
27
28/*
29 * Find out who the user is, copy his mail file (if exists) into
30 * /tmp/Rxxxxx and set up the message pointers. Then, print out the
31 * message headers and read user commands.
32 *
33 * Command line syntax:
34 * Mail [ -i ] [ -r address ] [ -h number ] [ -f [ name ] ]
35 * or:
36 * Mail [ -i ] [ -r address ] [ -h number ] people ...
37 */
38
39main(argc, argv)
40 char **argv;
41{
42 register char *ef;
43 register int i, argp;
828615a1 44 int mustsend, hdrstop(), (*prevint)(), f;
6b3e20dc 45 struct sgttyb tbuf;
83f7d6ec 46
83f7d6ec 47 /*
828615a1
EW
48 * Set up a reasonable environment.
49 * Figure out whether we are being run interactively, set up
83f7d6ec
KS
50 * all the temporary files, buffer standard output, and so forth.
51 */
52
15609a06
KM
53#ifdef GETHOST
54 inithost();
55#endif GETHOST
83f7d6ec
KS
56 mypid = getpid();
57 intty = isatty(0);
58 outtty = isatty(1);
6b3e20dc
KS
59 if (outtty) {
60 gtty(1, &tbuf);
61 baud = tbuf.sg_ospeed;
828615a1 62 } else
6b3e20dc 63 baud = B9600;
83f7d6ec 64 image = -1;
83f7d6ec
KS
65
66 /*
67 * Now, determine how we are being used.
68 * We successively pick off instances of -r, -h, -f, and -i.
69 * If called as "rmail" we note this fact for letter sending.
70 * If there is anything left, it is the base of the list
71 * of users to mail to. Argp will be set to point to the
72 * first of these users.
73 */
74
75 ef = NOSTR;
76 argp = -1;
77 mustsend = 0;
78 if (argc > 0 && **argv == 'r')
79 rmail++;
80 for (i = 1; i < argc; i++) {
81
82 /*
83 * If current argument is not a flag, then the
84 * rest of the arguments must be recipients.
85 */
86
87 if (*argv[i] != '-') {
88 argp = i;
89 break;
90 }
91 switch (argv[i][1]) {
92 case 'r':
93 /*
94 * Next argument is address to be sent along
95 * to the mailer.
96 */
97 if (i >= argc - 1) {
98 fprintf(stderr, "Address required after -r\n");
99 exit(1);
100 }
101 mustsend++;
102 rflag = argv[i+1];
103 i++;
104 break;
105
12a8dbc7
KS
106 case 'T':
107 /*
108 * Next argument is temp file to write which
109 * articles have been read/deleted for netnews.
110 */
111 if (i >= argc - 1) {
112 fprintf(stderr, "Name required after -T\n");
113 exit(1);
114 }
115 Tflag = argv[i+1];
e3d4be91
KS
116 if ((f = creat(Tflag, 0600)) < 0) {
117 perror(Tflag);
118 exit(1);
119 }
120 close(f);
12a8dbc7
KS
121 i++;
122 break;
123
83f7d6ec
KS
124 case 'u':
125 /*
126 * Next argument is person to pretend to be.
127 */
83f7d6ec 128 if (i >= argc - 1) {
5807729c 129 fprintf(stderr, "Missing user name for -u\n");
83f7d6ec
KS
130 exit(1);
131 }
132 strcpy(myname, argv[i+1]);
133 i++;
134 break;
135
136 case 'i':
137 /*
138 * User wants to ignore interrupts.
139 * Set the variable "ignore"
140 */
141 assign("ignore", "");
142 break;
143
144 case 'd':
145 debug++;
146 break;
147
148 case 'h':
149 /*
150 * Specified sequence number for network.
151 * This is the number of "hops" made so
152 * far (count of times message has been
153 * forwarded) to help avoid infinite mail loops.
154 */
155 if (i >= argc - 1) {
156 fprintf(stderr, "Number required for -h\n");
157 exit(1);
158 }
159 mustsend++;
160 hflag = atoi(argv[i+1]);
161 if (hflag == 0) {
162 fprintf(stderr, "-h needs non-zero number\n");
163 exit(1);
164 }
165 i++;
166 break;
167
168 case 's':
169 /*
170 * Give a subject field for sending from
171 * non terminal
172 */
173 if (i >= argc - 1) {
174 fprintf(stderr, "Subject req'd for -s\n");
175 exit(1);
176 }
177 mustsend++;
178 sflag = argv[i+1];
179 i++;
180 break;
181
182 case 'f':
183 /*
184 * User is specifying file to "edit" with Mail,
185 * as opposed to reading system mailbox.
186 * If no argument is given after -f, we read his
187 * mbox file in his home directory.
188 */
189 if (i >= argc - 1)
190 ef = mbox;
191 else
192 ef = argv[i + 1];
193 i++;
194 break;
195
196 case 'n':
197 /*
198 * User doesn't want to source /usr/lib/Mail.rc
199 */
200 nosrc++;
201 break;
202
da8590df
KS
203 case 'N':
204 /*
205 * Avoid initial header printing.
206 */
207 noheader++;
208 break;
209
843ac7dd
CL
210 case 'v':
211 /*
212 * Send mailer verbose flag
213 */
214 assign("verbose", "");
215 break;
216
0f016ad0
S
217 case 'I':
218 /*
219 * We're interactive
220 */
221 intty = 1;
222 break;
223
83f7d6ec
KS
224 default:
225 fprintf(stderr, "Unknown flag: %s\n", argv[i]);
226 exit(1);
227 }
228 }
229
230 /*
231 * Check for inconsistent arguments.
232 */
233
83f7d6ec
KS
234 if (ef != NOSTR && argp != -1) {
235 fprintf(stderr, "Cannot give -f and people to send to.\n");
236 exit(1);
237 }
238 if (mustsend && argp == -1) {
239 fprintf(stderr, "The flags you gave make no sense since you're not sending mail.\n");
240 exit(1);
241 }
242 tinit();
828615a1 243 setscreensize();
5807729c
KS
244 input = stdin;
245 rcvmode = argp == -1;
246 if (!nosrc)
247 load(MASTER);
248 load(mailrc);
83f7d6ec 249 if (argp != -1) {
83f7d6ec
KS
250 mail(&argv[argp]);
251
252 /*
253 * why wait?
254 */
255
256 exit(senderr);
257 }
258
259 /*
260 * Ok, we are reading mail.
261 * Decide whether we are editing a mailbox or reading
262 * the system mailbox, and open up the right stuff.
263 */
264
83f7d6ec 265 if (ef != NOSTR) {
5807729c
KS
266 char *ename;
267
83f7d6ec 268 edit++;
5807729c
KS
269 ename = expand(ef);
270 if (ename != ef) {
828615a1 271 ef = malloc((unsigned) strlen(ename) + 1);
5807729c
KS
272 strcpy(ef, ename);
273 }
927ecb14
KS
274 editfile = ef;
275 strcpy(mailname, ef);
83f7d6ec 276 }
b57443b2
KS
277 if (setfile(mailname, edit) < 0) {
278 if (edit)
279 perror(mailname);
280 else
281 fprintf(stderr, "No mail for %s\n", myname);
83f7d6ec 282 exit(1);
b57443b2 283 }
a86e9bce 284 if (!noheader && value("noheader") == NOSTR) {
5807729c 285 if (setjmp(hdrjmp) == 0) {
828615a1
EW
286 if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
287 signal(SIGINT, hdrstop);
843ac7dd 288 announce(!0);
5807729c 289 fflush(stdout);
828615a1 290 signal(SIGINT, prevint);
5807729c
KS
291 }
292 }
ab9ca2ea
KS
293 if (!edit && msgCount == 0) {
294 printf("No mail\n");
295 fflush(stdout);
296 exit(0);
297 }
83f7d6ec 298 commands();
714288d2 299 if (!edit) {
828615a1
EW
300 signal(SIGHUP, SIG_IGN);
301 signal(SIGINT, SIG_IGN);
302 signal(SIGQUIT, SIG_IGN);
83f7d6ec 303 quit();
714288d2 304 }
83f7d6ec
KS
305 exit(0);
306}
5807729c
KS
307
308/*
309 * Interrupt printing of the headers.
310 */
311hdrstop()
312{
313
5807729c 314 fflush(stdout);
80187484 315 fprintf(stderr, "\nInterrupt\n");
5807729c
KS
316 longjmp(hdrjmp, 1);
317}
828615a1
EW
318
319/*
320 * Compute what the screen size should be.
321 * We use the following algorithm for the height:
322 * If baud rate < 1200, use 9
323 * If baud rate = 1200, use 14
324 * If baud rate > 1200, use 24 or ws_row
325 * Width is either 80 or ws_col;
326 */
327setscreensize()
328{
329#ifdef TIOCGWINSZ
330 struct winsize ws;
331
332 if (ioctl(fileno(stdout), TIOCGWINSZ, (char *) &ws) < 0)
333 ws.ws_col = ws.ws_row = 0;
334#endif
335 if (baud < B1200)
336 screenheight = 9;
337 else if (baud == B1200)
338 screenheight = 14;
339#ifdef TIOCGWINSZ
340 else if (ws.ws_row != 0)
341 screenheight = ws.ws_row;
342#endif
343 else
344 screenheight = 24;
345#ifdef TIOCGWINSZ
346 if (ws.ws_col != 0)
347 screenwidth = ws.ws_col;
348 else
349#endif
350 screenwidth = 80;
351}