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