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