]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/RCS/rmail.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / RCS / rmail.c,v
1 head 1.3;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.3
9 date 93.08.25.17.27.43; author jromine; state Exp;
10 branches;
11 next 1.2;
12
13 1.2
14 date 92.11.04.00.59.59; author jromine; state Exp;
15 branches;
16 next 1.1;
17
18 1.1
19 date 92.11.04.00.59.14; author jromine; state Exp;
20 branches;
21 next ;
22
23
24 desc
25 @rmail
26 @
27
28
29 1.3
30 log
31 @off_t fixes for BSD44
32 @
33 text
34 @/* rmail.c - replacement for /bin/rmail */
35 #ifndef lint
36 static char ident[] = "@@(#)$Id: rmail.c,v 1.2 1992/11/04 00:59:59 jromine Exp jromine $";
37 #endif lint
38
39 /* This program has a long, long history. It started as UCB's rmail, and
40 was then modified by OBrien@@Rand-Unix to run with MMDF. Then DpK@@Brl
41 re-wrote it, and SmB@@Unc hacked it up a bit. After that
42 MRose.UCI@@Rand-Relay upgraded it to use the nifty MF (mail filtering)
43 system. Finally, the latter stripped it down to work with MH.
44
45 This program should be used ONLY if you have both "mts mh" and "uucp on"
46 set in your MH configuration.
47 */
48
49
50 #include "../h/mh.h"
51 #include "../h/addrsbr.h"
52 #include "../zotnet/mf.h"
53 #include "../zotnet/tws.h"
54 #include <stdio.h>
55 #include "../zotnet/mts.h"
56 #include <signal.h>
57 #ifdef LOCALE
58 #include <locale.h>
59 #endif
60
61
62 #define ADDROK 0 /* okay to use post to deliver message */
63 #define UUCP 1 /* okay to use uux to deliver message */
64 #define RETURN 2 /* message loses */
65
66 /* \f */
67 int pbroke; /* broken-pipe flag */
68 int rtnflag; /* note was sent back */
69
70 char date[BUFSIZ]; /* date of origination from uucp header */
71 char from[BUFSIZ]; /* accumulated path of sender */
72 char origsys[BUFSIZ]; /* originating system */
73 char origpath[BUFSIZ]; /* path from us to originating system */
74 char usrfrm[BUFSIZ]; /* the 822 version of from[] */
75 char Mailsys[BUFSIZ]; /* address of the mail agent */
76 char overseer[BUFSIZ]; /* address of the watchdog */
77
78 char mmdf[BUFSIZ]; /* filtered mail file */
79
80 char *rtnmessage[] = {
81 " Your message has been intercepted trying to access\n",
82 "a restricted access host (e.g. an ARPANET host). A copy\n",
83 "of your message has been sent to the system administrators.\n",
84 "The text of your message follows.\n\n",
85 NULL
86 };
87
88 char rtnbegin[] =
89 " ---------------- Returned Mail Follows --------------\n";
90 char rtnend[] =
91 " --------------- End of Returned Mail ---------------\n";
92
93 char *oopsmessage[] = {
94 "\n\n\tThe system administrators (%s) have been informed of\n",
95 "the problem, but have not been given a copy of your message.\n\n",
96 NULL
97 };
98
99 FILE * fromf; /* UUCP "From lines */
100 FILE * msgf; /* message text */
101 FILE * pipef; /* output for "post" or "uux" */
102
103
104 int pipeser ();
105
106
107 off_t lseek ();
108
109 /* \f */
110
111 main (argc, argv)
112 int argc;
113 char **argv;
114 {
115 int cpyback;
116 char *cp,
117 *fromptr,
118 fromwhom[BUFSIZ],
119 linebuf[BUFSIZ],
120 sys[BUFSIZ];
121
122 #ifdef LOCALE
123 setlocale(LC_ALL, "");
124 #endif
125 invo_name = r1bindex (*argv, '/');
126 m_foil (NULLCP);
127 mts_init (invo_name);
128
129 if (argc < 2)
130 adios (NULLCP, "usage: %s user [user ...]", invo_name);
131 (void) umask (0);
132 (void) setgid (1);
133 (void) setuid (1);
134
135 (void) sprintf (Mailsys, "%s@@%s", Mailer, LocalName ());
136 if (Overseer == NULL)
137 Overseer = Mailsys;
138 if (index (Overseer, '@@') == NULL) {
139 (void) sprintf (overseer, "%s@@%s", Overseer, LocalName ());
140 Overseer = overseer;
141 }
142
143 (void) mktemp (Errtmp);
144 if (freopen (Errtmp, "w", stderr) == NULL)
145 adios (Errtmp, "unable to create");
146 (void) dup2 (fileno (stderr), fileno (stdout));
147
148 (void) mktemp (Msgtmp);
149 if ((msgf = fdopen (creat (Msgtmp, Tmpmode), "w")) == NULL)
150 adios (Msgtmp, "unable to create");
151
152 (void) mktemp (Fromtmp);
153 if ((fromf = fdopen (creat (Fromtmp, Tmpmode), "w")) == NULL)
154 adios (Fromtmp, "unable to create");
155
156 /* \f */
157
158 for (;;) {
159 if (fgets (linebuf, sizeof linebuf, stdin) == NULL)
160 break;
161 if (strncmp (linebuf, "From ", 5)
162 && strncmp (linebuf, ">From ", 6))
163 break;
164
165 if (linebuf[0] != '>')
166 fputs (">", fromf);
167 fputs (linebuf, fromf);
168 cp = index (linebuf, ' ');
169 fromptr = ++cp;
170 cp = index (cp, ' ');
171 *cp++ = NULL;
172 (void) strcpy (fromwhom, fromptr);
173 (void) strncpy (date, cp, 24);
174
175 for (;;) {
176 if ((cp = index (cp + 1, 'r')) == NULL) {
177 if ((cp = rindex (fromwhom, '!')) != NULL) {
178 char *p;
179 *cp = NULL;
180 if ((p = rindex (fromwhom, '!')) != NULL)
181 (void) strcpy (origsys, p + 1);
182 else
183 (void) strcpy (origsys, fromwhom);
184 (void) strcat (from, fromwhom);
185 (void) strcat (from, "!");
186 (void) strcpy (fromwhom, cp + 1);
187 goto out;
188 }
189 (void) strcpy (sys, SystemName ());
190 (void) strcat (from, sys);
191 (void) strcpy (origsys, sys);
192 (void) strcat (from, "!");
193 goto out;
194 }
195 if (strncmp (cp, "remote from ", 12) == 0)
196 break;
197 }
198
199 (void) sscanf (cp, "remote from %s", sys);
200 (void) strcat (from, sys);
201 (void) strcpy (origsys, sys);
202 (void) strcat (from, "!");
203 out: ;
204 }
205 if (fromwhom[0] == NULL)
206 adios (NULLCP, "no from line");
207
208 /* \f */
209
210 (void) strcpy (origpath, from);
211 (void) strcat (from, fromwhom);
212 get_mmdf_addr (from, usrfrm);
213 if ((cp = rindex (usrfrm, '<')) != NULL) {
214 (void) strcpy (usrfrm, ++cp); /* sigh */
215 if ((cp = rindex (usrfrm, '>')) != NULL)
216 *cp = NULL;
217 }
218 if (usrfrm[0] == NULL)
219 (void) sprintf (usrfrm, "%s!%s%%%s@@%s%c",
220 SystemName (), from, UucpChan (), LocalName (), NULL);
221
222 fputs (linebuf, msgf);
223 if (txtcpy (stdin, msgf) == NOTOK)
224 fputs ("\n *** Problem during receipt from UUCP ***\n", msgf);
225
226 (void) freopen (Msgtmp, "r", msgf);
227 (void) freopen (Fromtmp, "r", fromf);
228 (void) unlink (Fromtmp);
229 mmdf[0] = NULL;
230
231 cpyback = 0;
232 for (argv++; --argc > 0;) {
233 rewind (fromf);
234 rewind (msgf);
235 rtnflag = 0;
236 if (deliver (*argv++) == NOTOK && !rtnflag)
237 cpyback++;
238 }
239
240 (void) fflush (stderr);
241 (void) fflush (stdout);
242
243 if (cpyback) {
244 rcpy ();
245 zcpy ();
246 }
247
248 (void) unlink (Msgtmp);
249 if (mmdf[0])
250 (void) unlink (mmdf);
251 (void) unlink (Errtmp);
252
253 exit (0);
254 }
255
256 /* \f */
257
258 deliver (to)
259 char *to;
260 {
261 int i,
262 replyval;
263 char tmpfil[BUFSIZ];
264
265 switch (adrcheck (to)) {
266 case ADDROK:
267 if (mmdf[0] == NULL && filter () == NOTOK)
268 (void) strcpy (mmdf, Msgtmp);
269 replyval = xpost (to, mmdf);
270 break;
271
272 case UUCP:
273 if ((replyval = xuucp (to)) == NOTOK)
274 break;
275
276 if ((replyval = txtcpy (fromf, pipef)) != NOTOK)
277 replyval = txtcpy (msgf, pipef);
278 i = (pclose (pipef) >> 8) & 0xff;
279 if (replyval != NOTOK)
280 replyval = (i != 0 ? NOTOK : OK);
281 break;
282
283 /* \f */
284
285 case RETURN:
286 rtnflag++;
287 switch (adrcheck (from)) {
288 case ADDROK:
289 case RETURN:
290 (void) strcpy (tmpfil, "/tmp/rmailXXXXXX");
291 (void) unlink (mktemp (tmpfil));
292 if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL)
293 return NOTOK;
294
295 fprintf (pipef, "Date: %s\nFrom: %s\n",
296 dtimenow (), Mailsys);
297 fprintf (pipef, "To: %s\ncc: %s\n", from, Overseer);
298 rtnmesg (to);
299 (void) fclose (pipef);
300
301 replyval = xpost (from, tmpfil);
302 (void) unlink (tmpfil);
303 break;
304
305 case UUCP:
306 if ((replyval = xuucp (from)) == NOTOK)
307 break;
308
309 fprintf (pipef, "To: %s\ncc: %s\n", from, Overseer);
310 rtnmesg (to);
311 i = (pclose (pipef) >> 8) & 0xff;
312 if (replyval != NOTOK)
313 replyval = (i != 0 ? NOTOK : OK);
314 break;
315 }
316 if (Syscpy) {
317 (void) strcpy (tmpfil, "/tmp/rmailXXXXXX");
318 (void) unlink (mktemp (tmpfil));
319 if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL)
320 return NOTOK;
321
322 fprintf (pipef, "Date: %s\nFrom: %s\n",
323 dtimenow (), Mailsys);
324 fprintf (pipef, "To: %s\ncc: %s\n", usrfrm, Overseer);
325 rtnmesg (to);
326 (void) fclose (pipef);
327
328 replyval = xpost (Overseer, tmpfil);
329 (void) unlink (tmpfil);
330 }
331 break;
332 }
333
334 return replyval;
335 }
336
337 /* \f */
338
339 adrcheck (adr)
340 char *adr;
341 {
342 int type;
343 char *cp,
344 host[BUFSIZ];
345 struct mailname *mp;
346
347 if ((cp = getname (adr)) == NULL)
348 return RETURN;
349 mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP);
350 while (getname (""))
351 continue;
352 if (mp == NULL)
353 return RETURN;
354
355 type = mp -> m_type;
356 (void) strcpy (host, mp -> m_host);
357 mnfree (mp);
358 if (mp -> m_mbox == NULL)
359 return RETURN;
360
361 switch (type) {
362 case LOCALHOST:
363 return ADDROK;
364
365 case UUCPHOST:
366 return (strcmp (host, SystemName ()) ? UUCP : ADDROK);
367
368 default:
369 if (lookup (origsys, Okhosts) == OK)
370 return ADDROK;
371 return (okhost (host) == NOTOK ? RETURN : ADDROK);
372 }
373 }
374
375 /* \f */
376
377 okhost (host)
378 char *host;
379 {
380 return (lookup (origsys, Okhosts) == OK
381 || lookup (host, Okhosts) == OK
382 || lookup (host, Okdests) == OK ? OK : NOTOK);
383 }
384
385
386 lookup (what, where)
387 char *what,
388 *where;
389 {
390 char *cp,
391 entry[BUFSIZ];
392 FILE * lookf;
393
394 if ((lookf = fopen (where, "r")) == NULL)
395 return NOTOK;
396 while (fgets (entry, sizeof entry, lookf) != NULL) {
397 cp = entry;
398 while (*cp != '\n' && *cp != ' ' && *cp != '\t')
399 cp++;
400 *cp = NULL;
401 if (uleq (what, entry)) {
402 (void) fclose (lookf);
403 return OK;
404 }
405 }
406 (void) fclose (lookf);
407
408 return NOTOK;
409 }
410
411
412 /* \f */
413
414 rtnmesg (badadr)
415 char *badadr;
416 {
417 int i;
418
419 fprintf (pipef, "Subject: Illegal Address (%s)\n\n", badadr);
420 for (i = 0; rtnmessage[i]; i++)
421 fputs (rtnmessage[i], pipef);
422 fputs (rtnbegin, pipef);
423
424 rewind (fromf);
425 (void) txtcpy (fromf, pipef);
426 rewind (msgf);
427 (void) txtcpy (msgf, pipef);
428
429 fputs (rtnend, pipef);
430 }
431
432
433 txtcpy (frm, to)
434 FILE * frm, *to;
435 {
436 int nread;
437 char buffer[BUFSIZ];
438
439 while (!pbroke
440 && (nread = fread (buffer, sizeof (*buffer), BUFSIZ, frm)) > 0)
441 (void) fwrite (buffer, sizeof (*buffer), nread, to);
442
443 return (ferror (frm) ? NOTOK : OK);
444 }
445
446 /* \f */
447
448 xpost (addr, file)
449 char *addr,
450 *file;
451 {
452 int i,
453 child_id;
454
455 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
456 sleep (5);
457 switch (child_id) {
458 case NOTOK:
459 return NOTOK;
460
461 case OK:
462 execlp (postproc, r1bindex (postproc, '/'),
463 "-deliver", addr, file, NULLCP);
464 fprintf (stderr, "unable to exec ");
465 perror (postproc);
466 _exit (1);
467
468 default:
469 return (pidwait (child_id, OK) ? NOTOK : OK);
470 }
471 }
472
473 /* \f */
474
475 xuucp (to)
476 char *to;
477 {
478 char *cp,
479 buffer[BUFSIZ],
480 cmdstr[BUFSIZ];
481
482 (void) strcpy (buffer, to);
483 if (cp = index (buffer, '!'))
484 *cp++ = NULL;
485 else {
486 fprintf (stderr, "internal error -- %s has no host\n", to);
487 return NOTOK;
488 }
489 (void) sprintf (cmdstr, "uux -p %s!rmail \\(%s\\)", buffer, cp);
490
491 if ((pipef = popen (cmdstr, "w")) == NULL)
492 return NOTOK;
493
494 (void) signal (SIGPIPE, pipeser);
495 pbroke = 0;
496
497 return OK;
498 }
499
500 /* \f */
501
502 #ifdef BSD42
503 /* ARGSUSED */
504 #endif BSD42
505
506 static int pipeser (i)
507 int i;
508 {
509 #ifndef BSD42
510 (void) signal (i, SIG_IGN);
511 #endif BSD42
512
513 pbroke = 1;
514 }
515
516 /* \f */
517
518 rcpy () {
519 int i;
520 char buffer[BUFSIZ],
521 tmpfil[BUFSIZ];
522 FILE * fp;
523
524 (void) strcpy (tmpfil, "/tmp/rmailXXXXXX");
525 (void) unlink (mktemp (tmpfil));
526 if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL)
527 return;
528
529 fprintf (pipef, "Date: %s\nFrom: %s\n", dtimenow (), Mailsys);
530 fprintf (pipef, "To: %s\n", usrfrm);
531 fprintf (pipef, "\nProblems sending mail:\n\n");
532 i = 0;
533 if ((fp = fopen (Errtmp, "r")) != NULL) {
534 while (fgets (buffer, sizeof buffer, fp) != NULL) {
535 if (ferror (pipef))
536 break;
537 fputs (buffer, pipef);
538 i++;
539 }
540 }
541 if (i == 0)
542 fprintf (pipef, "\tunknown problem\n");
543 for (i = 0; oopsmessage[i]; i++)
544 fprintf (pipef, oopsmessage[i], Overseer);
545 fputs (rtnbegin, pipef);
546
547 rewind (fromf);
548 (void) txtcpy (fromf, pipef);
549 rewind (msgf);
550 (void) txtcpy (msgf, pipef);
551
552 fputs (rtnend, pipef);
553 (void) fclose (pipef);
554
555 (void) xpost (usrfrm, tmpfil);
556 (void) unlink (tmpfil);
557 }
558
559 /* \f */
560
561 zcpy () {
562 int i;
563 char buffer[BUFSIZ],
564 tmpfil[BUFSIZ];
565 FILE * fp;
566
567 (void) strcpy (tmpfil, "/tmp/rmailXXXXXX");
568 (void) unlink (mktemp (tmpfil));
569 if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL)
570 return;
571
572 fprintf (pipef, "Date: %s\nFrom: %s\n", dtimenow (), Mailsys);
573 fprintf (pipef, "To: %s\n", Mailsys);
574 fprintf (pipef, "\nProblems sending mail for %s (aka %s):\n\n",
575 from, usrfrm);
576
577 i = 0;
578 if ((fp = fopen (Errtmp, "r")) != NULL) {
579 while (fgets (buffer, sizeof buffer, fp) != NULL) {
580 if (ferror (pipef))
581 break;
582 fputs (buffer, pipef);
583 i = 1;
584 }
585 (void) fclose (fp);
586 if (i == 0)
587 fprintf (pipef, "\tunknown problem\n");
588 }
589 else
590 fprintf (pipef, "\tunable to open %s\n", Errtmp);
591 (void) fclose (pipef);
592
593 (void) xpost (Mailsys, tmpfil);
594 (void) unlink (tmpfil);
595 }
596
597 /* \f */
598
599 filter () {
600 int i,
601 fd,
602 td;
603 char tmpfil[BUFSIZ],
604 mmdfil[BUFSIZ];
605 FILE * out;
606
607 (void) strcpy (tmpfil, "/tmp/rmailXXXXXX");
608 (void) unlink (mktemp (tmpfil));
609 if ((fd = creat (tmpfil, Tmpmode)) == NOTOK)
610 return NOTOK;
611 (void) close (fd);
612 if ((fd = open (tmpfil, 2)) == NOTOK)
613 return NOTOK;
614 if ((out = fdopen (fd, "w")) == NULL) {
615 (void) close (fd);
616 return NOTOK;
617 }
618 if ((td = dup (fd)) == NOTOK) {
619 (void) close (fd);
620 return NOTOK;
621 }
622
623 fprintf (out, "From %s %s\n", from, date);
624 if (txtcpy (msgf, out) == NOTOK) {
625 (void) close (fd);
626 (void) close (td);
627 return NOTOK;
628 }
629 (void) fclose (out);
630 (void) lseek (td, (off_t)0, 0);
631
632 (void) strcpy (mmdfil, "/tmp/mmdfXXXXXX");
633 (void) unlink (mktemp (mmdfil));
634 if ((fd = creat (mmdfil, Tmpmode)) == NOTOK) {
635 (void) close (td);
636 (void) unlink (tmpfil);
637 return NOTOK;
638 }
639 if ((fd = open (mmdfil, 2)) == NOTOK) {
640 (void) close (td);
641 (void) unlink (tmpfil);
642 return NOTOK;
643 }
644
645 /* \f */
646
647 switch (i = uucp2mmdf (td, fd, TRUE)) {
648 case OK:
649 (void) strcpy (mmdf, mmdfil);
650 break;
651
652 default:
653 mmdf[0] = NULL;
654 break;
655 }
656 (void) close (td);
657 (void) unlink (tmpfil);
658 (void) close (fd);
659
660 return (i != OK ? NOTOK : OK);
661 }
662
663 /* \f */
664
665 get_mmdf_addr (addr, to)
666 char *addr,
667 *to;
668 {
669 struct adrx *adrxp;
670
671 *to = NULL;
672 if ((adrxp = seekadrx (addr)) == NULL)
673 return;
674
675 addr_convert (adrxp, to, TRUE);
676 while (seekadrx (NULLCP))
677 continue;
678 }
679 @
680
681
682 1.2
683 log
684 @add ID
685 LOCALE
686 @
687 text
688 @d3 1
689 a3 1
690 static char ident[] = "@@(#)$Id: comp.c,v 1.6 1992/11/04 00:40:01 jromine Exp $";
691 d74 1
692 a74 1
693 long lseek ();
694 d597 1
695 a597 1
696 (void) lseek (td, 0L, 0);
697 @
698
699
700 1.1
701 log
702 @Initial revision
703 @
704 text
705 @d2 3
706 d24 3
707 d89 3
708 @