|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)main.c 2.12 (Berkeley) 8/11/83";
3: #endif
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:
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: * Added by ber 7/84 - optionally create a lock file in the reader's
21: * home directory so they can be told if they are already
22: * reading mail on another terminal.
23: *
24: * Command line syntax:
25: * Mail [ -i ] [ -r address ] [ -h number ] [ -f [ name ] ]
26: * or:
27: * Mail [ -i ] [ -r address ] [ -h number ] people ...
28: */
29:
30: main(argc, argv)
31: char **argv;
32: {
33: register char *ef;
34: register int i, argp;
35: int mustsend, uflag, hdrstop(), (*prevint)(), f;
36: FILE *ibuf, *ftat;
37: extern char _sobuf[];
38: struct sgttyb tbuf;
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;
49: #ifdef GETHOST
50: inithost();
51: #endif GETHOST
52: mypid = getpid();
53: intty = isatty(0);
54: outtty = isatty(1);
55: if (outtty) {
56: gtty(1, &tbuf);
57: baud = tbuf.sg_ospeed;
58: }
59: else
60: baud = B9600;
61: image = -1;
62: setbuf(stdout, _sobuf);
63:
64: /*
65: * Now, determine how we are being used.
66: * We successively pick off instances of -r, -h, -f, and -i.
67: * If called as "rmail" we note this fact for letter sending.
68: * If there is anything left, it is the base of the list
69: * of users to mail to. Argp will be set to point to the
70: * first of these users.
71: */
72:
73: ef = NOSTR;
74: argp = -1;
75: mustsend = 0;
76: if (argc > 0 && **argv == 'r')
77: rmail++;
78: for (i = 1; i < argc; i++) {
79:
80: /*
81: * If current argument is not a flag, then the
82: * rest of the arguments must be recipients.
83: */
84:
85: if (*argv[i] != '-') {
86: argp = i;
87: break;
88: }
89: switch (argv[i][1]) {
90: case 'r':
91: /*
92: * Next argument is address to be sent along
93: * to the mailer.
94: */
95: if (i >= argc - 1) {
96: fprintf(stderr, "Address required after -r\n");
97: exit(1);
98: }
99: mustsend++;
100: rflag = argv[i+1];
101: i++;
102: break;
103:
104: case 'T':
105: /*
106: * Next argument is temp file to write which
107: * articles have been read/deleted for netnews.
108: */
109: if (i >= argc - 1) {
110: fprintf(stderr, "Name required after -T\n");
111: exit(1);
112: }
113: Tflag = argv[i+1];
114: if ((f = creat(Tflag, 0600)) < 0) {
115: perror(Tflag);
116: exit(1);
117: }
118: close(f);
119: i++;
120: break;
121:
122: case 'u':
123: /*
124: * Next argument is person to pretend to be.
125: */
126: uflag++;
127: if (i >= argc - 1) {
128: fprintf(stderr, "Missing user name for -u\n");
129: exit(1);
130: }
131: strcpy(myname, argv[i+1]);
132: i++;
133: break;
134:
135: case 'i':
136: /*
137: * User wants to ignore interrupts.
138: * Set the variable "ignore"
139: */
140: assign("ignore", "");
141: break;
142:
143: case 'd':
144: debug++;
145: break;
146:
147: case 'h':
148: /*
149: * Specified sequence number for network.
150: * This is the number of "hops" made so
151: * far (count of times message has been
152: * forwarded) to help avoid infinite mail loops.
153: */
154: if (i >= argc - 1) {
155: fprintf(stderr, "Number required for -h\n");
156: exit(1);
157: }
158: mustsend++;
159: hflag = atoi(argv[i+1]);
160: if (hflag == 0) {
161: fprintf(stderr, "-h needs non-zero number\n");
162: exit(1);
163: }
164: i++;
165: break;
166:
167: case 's':
168: /*
169: * Give a subject field for sending from
170: * non terminal
171: */
172: if (i >= argc - 1) {
173: fprintf(stderr, "Subject req'd for -s\n");
174: exit(1);
175: }
176: mustsend++;
177: sflag = argv[i+1];
178: i++;
179: break;
180:
181: case 'f':
182: /*
183: * User is specifying file to "edit" with Mail,
184: * as opposed to reading system mailbox.
185: * If no argument is given after -f, we read his
186: * mbox file in his home directory.
187: */
188: if (i >= argc - 1)
189: ef = mbox;
190: else
191: ef = argv[i + 1];
192: i++;
193: break;
194:
195: case 'n':
196: /*
197: * User doesn't want to source /usr/lib/Mail.rc
198: */
199: nosrc++;
200: break;
201:
202: case 'N':
203: /*
204: * Avoid initial header printing.
205: */
206: noheader++;
207: break;
208:
209: case 'v':
210: /*
211: * Send mailer verbose flag
212: */
213: assign("verbose", "");
214: break;
215:
216: default:
217: fprintf(stderr, "Unknown flag: %s\n", argv[i]);
218: exit(1);
219: }
220: }
221:
222: /*
223: * Check for inconsistent arguments.
224: */
225:
226: if (ef != NOSTR && argp != -1) {
227: fprintf(stderr, "Cannot give -f and people to send to.\n");
228: exit(1);
229: }
230: if (mustsend && argp == -1) {
231: fprintf(stderr, "The flags you gave make no sense since you're not sending mail.\n");
232: exit(1);
233: }
234: tinit();
235: input = stdin;
236: rcvmode = argp == -1;
237: if (!nosrc)
238: load(MASTER);
239: load(mailrc);
240: if (argp != -1) {
241: mail(&argv[argp]);
242:
243: /*
244: * why wait?
245: */
246:
247: exit(senderr);
248: }
249:
250: /*
251: * Ok, we are reading mail.
252: * Decide whether we are editing a mailbox or reading
253: * the system mailbox, and open up the right stuff.
254: */
255:
256: if (ef != NOSTR) {
257: char *ename;
258:
259: edit++;
260: ename = expand(ef);
261: if (ename != ef) {
262: ef = (char *) calloc(1, strlen(ename) + 1);
263: strcpy(ef, ename);
264: }
265: editfile = ef;
266: strcpy(mailname, ef);
267: }
268: if (setfile(mailname, edit) < 0) {
269: if (edit)
270: perror(mailname);
271: else
272: fprintf(stderr, "No mail for %s\n", myname);
273: exit(1);
274: }
275: if (!edit && !noheader && value("noheader") == NOSTR) {
276: if (setjmp(hdrjmp) == 0) {
277: if ((prevint = sigset(SIGINT, SIG_IGN)) != SIG_IGN)
278: sigset(SIGINT, hdrstop);
279: announce(!0);
280: fflush(stdout);
281: sigset(SIGINT, prevint);
282: }
283: }
284: if (value("warn") != NOSTR)
285: {
286: struct stat sbuf;
287: FILE *fp;
288: int pid;
289: char tty[128];
290:
291: if (strlen(value("warn")) == 0)
292: sprintf(perslock, "%s/.Maillock", homedir);
293: else
294: strcpy(perslock, value("warn"));
295:
296: if (stat(perslock, &sbuf) >= 0) /* personal lock file exists */
297: {
298: fp = fopen(perslock, "r");
299: if (fp == NULL) /* but can't be read */
300: {
301: fprintf(stderr, "There is a personal mail lock file");
302: fprintf(stderr, " but it can't be read\n");
303: perror(perslock);
304: strcpy(perslock, NULL);
305: }
306: else
307: {
308: fscanf(fp, "%d %s", &pid, tty);
309: if (kill(pid, 0) == 0) /* and is valid */
310: {
311: fprintf(stderr,"You are already reading mail on %s!\n",tty);
312: fclose(fp);
313: strcpy(perslock, NULL);
314: }
315: else
316: {
317: wplock();
318: }
319: }
320: }
321: else /* no lock, we'll make one */
322: {
323: wplock();
324: }
325:
326: }
327: if (edit)
328: newfileinfo();
329: if (!edit && msgCount == 0) {
330: printf("No mail\n");
331: fflush(stdout);
332: exit(0);
333: }
334: commands();
335: if (!edit) {
336: sigset(SIGHUP, SIG_IGN);
337: sigset(SIGINT, SIG_IGN);
338: sigset(SIGQUIT, SIG_IGN);
339: quit();
340: }
341: if (value("warn") != NOSTR && strlen(perslock) > 0)
342: unlink(perslock);
343: exit(0);
344: }
345:
346: wplock()
347: {
348: FILE *fp;
349:
350: fp = fopen(perslock, "w");
351: if (fp == NULL)
352: {
353: fprintf(stderr, "Can't make a personal lock file for you\n");
354: perror(perslock);
355: strcpy(perslock, NULL);
356: }
357: else
358: {
359: fprintf(fp, "%d %s\n", getpid(), ttyname(2));
360: fclose(fp);
361: }
362: }
363:
364: /*
365: * Interrupt printing of the headers.
366: */
367: hdrstop()
368: {
369:
370: clrbuf(stdout);
371: printf("\nInterrupt\n");
372: fflush(stdout);
373: longjmp(hdrjmp, 1);
374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.