Added all of the MH sources, including RCS files, in
[mmh] / 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 @