xref: /original-bsd/usr.bin/mail/main.c (revision 92d3de31)
1 #
2 
3 #include "rcv.h"
4 #include <sys/stat.h>
5 
6 /*
7  * Mail -- a mail program
8  *
9  * Startup -- interface with user.
10  */
11 
12 static char *SccsId = "@(#)main.c	2.10 01/22/83";
13 
14 jmp_buf	hdrjmp;
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 
27 main(argc, argv)
28 	char **argv;
29 {
30 	register char *ef;
31 	register int i, argp;
32 	int mustsend, uflag, hdrstop(), (*prevint)(), f;
33 	FILE *ibuf, *ftat;
34 	extern char _sobuf[];
35 	struct sgttyb tbuf;
36 
37 #ifdef signal
38 	Siginit();
39 #endif
40 
41 	/*
42 	 * Set up a reasonable environment.  We clobber the last
43 	 * element of argument list for compatibility with version 6,
44 	 * figure out whether we are being run interactively, set up
45 	 * all the temporary files, buffer standard output, and so forth.
46 	 */
47 
48 	uflag = 0;
49 	argv[argc] = (char *) -1;
50 #ifdef	GETHOST
51 	inithost();
52 #endif	GETHOST
53 	mypid = getpid();
54 	intty = isatty(0);
55 	outtty = isatty(1);
56 	if (outtty) {
57 		gtty(1, &tbuf);
58 		baud = tbuf.sg_ospeed;
59 	}
60 	else
61 		baud = B9600;
62 	image = -1;
63 	setbuf(stdout, _sobuf);
64 
65 	/*
66 	 * Now, determine how we are being used.
67 	 * We successively pick off instances of -r, -h, -f, and -i.
68 	 * If called as "rmail" we note this fact for letter sending.
69 	 * If there is anything left, it is the base of the list
70 	 * of users to mail to.  Argp will be set to point to the
71 	 * first of these users.
72 	 */
73 
74 	ef = NOSTR;
75 	argp = -1;
76 	mustsend = 0;
77 	if (argc > 0 && **argv == 'r')
78 		rmail++;
79 	for (i = 1; i < argc; i++) {
80 
81 		/*
82 		 * If current argument is not a flag, then the
83 		 * rest of the arguments must be recipients.
84 		 */
85 
86 		if (*argv[i] != '-') {
87 			argp = i;
88 			break;
89 		}
90 		switch (argv[i][1]) {
91 		case 'r':
92 			/*
93 			 * Next argument is address to be sent along
94 			 * to the mailer.
95 			 */
96 			if (i >= argc - 1) {
97 				fprintf(stderr, "Address required after -r\n");
98 				exit(1);
99 			}
100 			mustsend++;
101 			rflag = argv[i+1];
102 			i++;
103 			break;
104 
105 		case 'T':
106 			/*
107 			 * Next argument is temp file to write which
108 			 * articles have been read/deleted for netnews.
109 			 */
110 			if (i >= argc - 1) {
111 				fprintf(stderr, "Name required after -T\n");
112 				exit(1);
113 			}
114 			Tflag = argv[i+1];
115 			if ((f = creat(Tflag, 0600)) < 0) {
116 				perror(Tflag);
117 				exit(1);
118 			}
119 			close(f);
120 			i++;
121 			break;
122 
123 		case 'u':
124 			/*
125 			 * Next argument is person to pretend to be.
126 			 */
127 			uflag++;
128 			if (i >= argc - 1) {
129 				fprintf(stderr, "Missing user name for -u\n");
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 
203 		case 'N':
204 			/*
205 			 * Avoid initial header printing.
206 			 */
207 			noheader++;
208 			break;
209 
210 		case 'v':
211 			/*
212 			 * Send mailer verbose flag
213 			 */
214 			assign("verbose", "");
215 			break;
216 
217 		default:
218 			fprintf(stderr, "Unknown flag: %s\n", argv[i]);
219 			exit(1);
220 		}
221 	}
222 
223 	/*
224 	 * Check for inconsistent arguments.
225 	 */
226 
227 	if (ef != NOSTR && argp != -1) {
228 		fprintf(stderr, "Cannot give -f and people to send to.\n");
229 		exit(1);
230 	}
231 	if (mustsend && argp == -1) {
232 		fprintf(stderr, "The flags you gave make no sense since you're not sending mail.\n");
233 		exit(1);
234 	}
235 	tinit();
236 	input = stdin;
237 	rcvmode = argp == -1;
238 	if (!nosrc)
239 		load(MASTER);
240 	load(mailrc);
241 	if (argp != -1) {
242 		mail(&argv[argp]);
243 
244 		/*
245 		 * why wait?
246 		 */
247 
248 		exit(senderr);
249 	}
250 
251 	/*
252 	 * Ok, we are reading mail.
253 	 * Decide whether we are editing a mailbox or reading
254 	 * the system mailbox, and open up the right stuff.
255 	 */
256 
257 	if (ef != NOSTR) {
258 		char *ename;
259 
260 		edit++;
261 		ename = expand(ef);
262 		if (ename != ef) {
263 			ef = (char *) calloc(1, strlen(ename) + 1);
264 			strcpy(ef, ename);
265 		}
266 		editfile = ef;
267 		strcpy(mailname, ef);
268 	}
269 	if (setfile(mailname, edit) < 0) {
270 		if (edit)
271 			perror(mailname);
272 		else
273 			fprintf(stderr, "No mail for %s\n", myname);
274 		exit(1);
275 	}
276 	if (!edit && !noheader && value("noheader") == NOSTR) {
277 		if (setjmp(hdrjmp) == 0) {
278 			if ((prevint = sigset(SIGINT, SIG_IGN)) != SIG_IGN)
279 				sigset(SIGINT, hdrstop);
280 			announce(!0);
281 			fflush(stdout);
282 			sigset(SIGINT, prevint);
283 		}
284 	}
285 	if (edit)
286 		newfileinfo();
287 	if (!edit && msgCount == 0) {
288 		printf("No mail\n");
289 		fflush(stdout);
290 		exit(0);
291 	}
292 	commands();
293 	if (!edit) {
294 		sigset(SIGHUP, SIG_IGN);
295 		sigset(SIGINT, SIG_IGN);
296 		sigset(SIGQUIT, SIG_IGN);
297 		quit();
298 	}
299 	exit(0);
300 }
301 
302 /*
303  * Interrupt printing of the headers.
304  */
305 hdrstop()
306 {
307 
308 	clrbuf(stdout);
309 	printf("\nInterrupt\n");
310 	fflush(stdout);
311 	sigrelse(SIGINT);
312 	longjmp(hdrjmp, 1);
313 }
314