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