Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / spop.c,v
1 head    1.8;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.8
9 date    93.08.25.17.28.24;      author jromine; state Exp;
10 branches;
11 next    1.7;
12
13 1.7
14 date    93.08.20.15.55.23;      author jromine; state Exp;
15 branches;
16 next    1.6;
17
18 1.6
19 date    92.11.04.01.04.35;      author jromine; state Exp;
20 branches;
21 next    1.5;
22
23 1.5
24 date    92.02.03.17.57.22;      author jromine; state Exp;
25 branches;
26 next    1.4;
27
28 1.4
29 date    90.04.05.15.02.39;      author sources; state Exp;
30 branches;
31 next    1.3;
32
33 1.3
34 date    90.04.02.16.34.57;      author sources; state Exp;
35 branches;
36 next    1.2;
37
38 1.2
39 date    90.02.06.13.32.29;      author sources; state Exp;
40 branches;
41 next    1.1;
42
43 1.1
44 date    90.02.06.13.32.13;      author sources; state Exp;
45 branches;
46 next    ;
47
48
49 desc
50 @@
51
52
53 1.8
54 log
55 @off_t fixes for BSD44
56 @
57 text
58 @#ifndef        SPOP
59 /* sbboards.c - MH style mailer to write to a ZOTnet BBoard */
60 #else   SPOP
61 /* spop.c - MH style mailer to write to a POP subscriber */
62 #endif  SPOP
63 #ifndef lint
64 static char ident[] = "@@(#)$Id: spop.c,v 1.7 1993/08/20 15:55:23 jromine Exp jromine $";
65 #endif  lint
66
67 #ifndef SPOP
68
69 /* This program acts like the MMDF ch_bboards channel: it does local
70    delivery to a ZOTnet BBoard and/or addition re-distribution to other
71    recipients of the BBoard.  This program can function both as a SendMail
72    mailer and an MH .mh_receive file, depending on whether SENDMTS or
73    MHMTS is set.  Currently, the MHMTS version of this program does not do
74    re-distribution.
75
76    This program should be used ONLY if you have "bboards on" set in your
77    MH configuration, and if you have "mts sendmail" or "mts mh" set as well.
78  */
79
80 #else   SPOP
81
82 /* This program acts like the MMDF-II ch_pop channel: it does local
83    delivery for non-local users.  These users are known as POP subscribers
84    and use the Post Office Protocol with a POP server in order to access
85    their maildrop.
86  */
87
88 #endif  SPOP
89
90 #undef  DISTRIBUTE
91 #ifdef  SENDMTS
92 #ifndef SPOP
93 #define DISTRIBUTE
94 #endif  not SPOP
95 #endif  SENDMTS
96
97 #include "../h/mh.h"
98 #ifndef SPOP
99 #include "../h/addrsbr.h"
100 #endif  not SPOP
101 #include "../h/dropsbr.h"
102 #include "../zotnet/bboards.h"
103 #include "../zotnet/tws.h"
104 #include <stdio.h>
105 #include "../zotnet/mts.h"
106 #include <pwd.h>
107 #ifndef SYS5
108 #include <sysexits.h>
109 #else   SYS5
110 #define EX_CANTCREAT    1
111 #define EX_IOERR        1
112 #define EX_NOINPUT      1
113 #define EX_NOUSER       1
114 #define EX_OK           0
115 #define EX_OSERR        1
116 #define EX_OSFILE       1
117 #define EX_UNAVAILABLE  1
118 #define EX_USAGE        1
119 #endif  SYS5
120 #ifdef  DISTRIBUTE
121 #include "../mts/sendmail/smail.h"
122 #endif  DISTRIBUTE
123 #ifdef LOCALE
124 #include        <locale.h>
125 #endif
126
127
128 #define NBB     100
129
130 #ifndef SPOP
131 #define ENTITY  "bboard"
132 #else   SPOP
133 #define ENTITY  "subscriber"
134 #endif  SPOP
135
136 /* \f */
137
138 static int  bb_fderr;
139
140 static int  bb_uid;
141 static int  bb_gid;
142
143 int    dst_rcpt ();
144
145
146 #ifndef SPOP
147 static char bb_from[BUFSIZ];
148 static char bb_head[BUFSIZ];
149 static char bb_home[BUFSIZ];
150 static char bb_time[BUFSIZ];
151 #ifdef  DISTRIBUTE
152 static char bb_rept[BUFSIZ];
153 #endif  DISTRIBUTE
154 #else   SPOP
155 #define bb_head NULLCP
156 #endif  SPOP
157
158 static struct bboard  *bb[NBB];
159
160
161 off_t   lseek ();
162
163 #ifndef __STDC__
164 #ifdef  SYS5
165 struct passwd  *getpwnam ();
166 #endif  /* SYS5 */
167 #endif
168
169 /* hack */
170 #define adios   my_adios
171 static  localmail(), arginit();
172 static int      lose(), copyfile();
173 static void     adios();
174 /* \f */
175
176 /* ARGSUSED */
177
178 main (argc, argv, envp)
179 int     argc;
180 char  **argv,
181       **envp;
182 {
183     int     fd;
184     char    tmpfil[BUFSIZ];
185
186 #ifdef LOCALE
187         setlocale(LC_ALL, "");
188 #endif
189 #ifdef  MHMTS
190     if (argc != 5)
191         adios (EX_USAGE, NULL, "you lose really big");
192 #endif  MHMTS
193     arginit (argv);
194
195     fflush (stdout);
196     discard (stdout);           /* XXX: reference discard to help loader */
197
198     fd = copyfile (fileno (stdin), tmpfil);
199     (void) unlink (tmpfil);
200
201     localmail (fd);
202 #ifdef  DISTRIBUTE
203     distribute (fd);
204     notify (fd);
205 #endif  DISTRIBUTE
206
207     exit (EX_OK);
208 }
209
210 /* \f */
211
212 static  localmail (fd)
213 int     fd;
214 {
215     int     i,
216             md;
217     register struct bboard  *bp;
218
219     for (i = 0; bp = bb[i]; i++)
220         if (bp -> bb_file && *bp -> bb_file) {
221             (void) lseek (fd, (off_t)0, 0);
222 #ifndef SPOP
223             if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, BBMODE))
224 #else   SPOP
225             if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, POMODE))
226 #endif  SPOP
227                     == NOTOK) {
228                 (void) lose ("unable to open %s", bp -> bb_file);
229                 continue;
230             }
231 #ifndef SPOP
232             if (mbx_init (bp) != NOTOK)
233 #endif  not SPOP
234                 (void) mbx_copy (bp -> bb_file, md, fd, 1, bb_head, 0);
235             (void) mbx_close (bp -> bb_file, md);
236         }
237 }
238
239 /* \f */
240
241 #ifndef SPOP
242 static int  mbx_init (bp)
243 register struct bboard  *bp;
244 {
245     int     fd,
246             clear;
247     register struct bboard  *ip;
248     register FILE *fp;
249
250     if ((fd = mbx_Xopen (bp -> bb_info, bb_uid, bb_gid, BBMODE, &clear))
251             == NOTOK)
252         return lose ("unable to lock and open %s", bp -> bb_info);
253     if ((fp = fdopen (fd, "w")) == NULL) {
254         (void) mbx_close (bp -> bb_info, fd);
255         return lose ("unable to fdopen %s", bp -> bb_info);
256     }
257
258     if ((ip = getbbnam (bp -> bb_name)) == NULL) {
259         (void) lkfclose (fp, bp -> bb_info);
260         return lose ("unable to get information on BBoard %s", bp -> bb_name);
261     }
262     (void) strcpy (bb_time, dtimenow ());
263     (void) sprintf (bb_head, "BBoard-ID: %d\nBB-Posted: %s\n",
264             bp -> bb_maxima = ++ip -> bb_maxima, bb_time);
265
266     fprintf (fp, "%d\n%s\n", bp -> bb_maxima, bb_time);
267     (void) lkfclose (fp, bp -> bb_info);
268
269     return OK;
270 }
271 #endif  not SPOP
272
273 /* \f */
274
275 #ifdef  DISTRIBUTE
276 static  distribute (fd)
277 int     fd;
278 {
279     int     i;
280     register struct bboard  *bp;
281
282     for (i = 0; bp = bb[i]; i++)
283         if (bp -> bb_dist && *bp -> bb_dist)
284             break;
285     if (bp == NULL)
286         return;
287
288     if (dst_init () == NOTOK) {
289         dst_lose ();
290         return;
291     }
292     for (i = 0; bp = bb[i]; i++)
293         if (bp -> bb_dist && *bp -> bb_dist)
294             if (dst_adrs (bp) == NOTOK) {
295                 dst_lose ();
296                 return;
297             }
298     if (dst_text (fd) == NOTOK || dst_end () == NOTOK)
299         dst_lose ();
300 }
301
302 /* \f */
303
304 static int  dst_init ()
305 {
306     int     retval;
307
308     if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
309             || rp_isbad (retval = sm_winit (S_MAIL, bb_from)))
310         return lose ("problem initializing SendMail; %s",
311                 rp_string (retval));
312
313     return OK;
314 }
315
316 /* \f */
317
318 static int  dst_adrs (bp)
319 register struct bboard  *bp;
320 {
321     if (getbbdist (bp, dst_rcpt))
322         return lose ("getbbdist failed: %s", getbberr ());
323
324     return OK;
325 }
326
327 /* \f */
328
329 static int  dst_rcpt (mbox, host)
330 register char   *mbox,
331                 *host;
332 {
333     int     retval;
334
335     switch (retval = sm_wadr (mbox, host, NULLCP)) {
336         case RP_OK:
337             return OK;
338
339         case RP_NO:
340         case RP_USER:
341             (void) lose ("%s@@%s: loses; %s", mbox, host, rp_string (retval));
342             return OK;          /* fail-soft */
343
344         default:
345             return lose ("%s@@%s: unexpected response; %s",
346                     mbox, host, rp_string (retval));
347     }
348 }
349
350 /* \f */
351
352 static int  dst_text (fd)
353 int     fd;
354 {
355     int     i,
356             retval;
357     char    buffer[BUFSIZ];
358
359     if (rp_isbad (retval = sm_waend ()))
360         return lose ("problem ending addresses; %s", rp_string (retval));
361
362     (void) lseek (fd, (off_t)0, 0);
363     while ((i = read (fd, buffer, sizeof buffer)) > 0)
364         if (rp_isbad (retval = sm_wtxt (buffer, i)))
365             return lose ("problem writing text; %s", rp_string (retval));
366
367     return (i != NOTOK ? OK : lose ("error reading from file"));
368 }
369
370 /* \f */
371
372 static int  dst_end ()
373 {
374     int     retval;
375
376     switch (retval = sm_wtend ()) {
377         case RP_OK:
378             (void) sm_end (OK);
379             return OK;
380
381         case RP_NO:
382         case RP_NDEL:
383             return lose ("posting failed; %s", rp_string (retval));
384
385         default:
386             return lose ("unexpected response; %s", rp_string (retval));
387     }
388 }
389
390 /* \f */
391
392 static  dst_lose ()
393 {
394     (void) sm_end (NOTOK);
395 }
396
397 /* \f */
398
399 /* VARARGS1 */
400
401 static int  lose (fmt, a, b, c, d)
402 char   *fmt,
403        *a,
404        *b,
405        *c,
406        *d;
407 {
408     int     fd,
409             i;
410     char   *bp,
411             buffer[BUFSIZ];
412
413     if (bb_fderr == NOTOK) {
414         if ((fd = open ("/dev/null", 0)) == NOTOK)
415             adios (EX_OSERR, "/dev/null", "unable to open");
416         bb_fderr = copyfile (fd, bb_rept);
417     }
418
419     (void) sprintf (bp = buffer, fmt, a, b, c, d);
420     bp += strlen (bp);
421     bp += strlen (strcpy(bp, "\n"));
422     i = bp - buffer;
423     if (write (bb_fderr, buffer, i) != i)
424         adios (EX_IOERR, bb_rept, "error writing");
425
426     return NOTOK;
427 }
428
429 /* \f */
430
431 static  notify (fd)
432 int     fd;
433 {
434     int     i;
435     char    buffer[BUFSIZ];
436
437     if (bb_fderr == NOTOK)
438         return;
439
440     if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
441             || rp_isbad (sm_winit (S_MAIL, bb_from)))
442         goto sm_err;
443
444     switch (sm_wadr (bb_from, NULLCP, NULLCP)) {
445         case RP_OK:
446             for (i = 0; bb[i]; i++) {
447                 (void) sprintf (buffer, "local-%s-request", bb[i] -> bb_name);
448                 (void) sm_wadr (buffer, LocalName (), NULLCP);
449             }
450             break;
451
452         default:
453             goto sm_err;
454     }
455
456     if (rp_isbad (sm_waend ()))
457         goto sm_err;
458
459     (void) sprintf (buffer,
460             "Date: %s\nFrom: %s\nTo: %s\nSubject: BBoards Failure\n\n",
461             dtimenow (), bb_from, bb_from);
462     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
463         goto sm_err;
464
465     for (i = 0; bb[i]; i++) {
466         (void) sprintf (buffer, "BBoard %s\n", bb[i] -> bb_name);
467         if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
468             goto sm_err;
469     }
470
471     (void) lseek (bb_fderr, (off_t)0, 0);
472     while ((i = read (bb_fderr, buffer, sizeof buffer)) > 0)
473         if (rp_isbad (sm_wtxt (buffer, i)))
474             goto sm_err;
475
476     (void) strcpy (buffer, "\n------- Forwarded Message\n\n");
477     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))) || encap (fd) == NOTOK)
478         goto sm_err;
479     (void) strcpy (buffer, "\n------- End of Forwarded Message\n\n");
480     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
481         goto sm_err;
482
483     switch (sm_wtend ()) {
484         case RP_OK:
485             (void) unlink (bb_rept);
486             (void) sm_end (OK);
487             return;
488
489         default:
490     sm_err: ;
491             adios (EX_UNAVAILABLE, NULLCP,
492                     "failed and unable to post advisory, see %s for details",
493                     bb_rept);
494     }
495 }
496
497 /* \f */
498
499 /* very similar to sbr/cpydgst.c */
500
501 #define S1      0
502 #define S2      1
503
504 #define output(c)       if (bp >= dp) flush (), *bp++ = c; else *bp++ = c
505 #define flush()         if ((j = bp - outbuf) \
506                                 && rp_isbad (sm_wtxt (outbuf, j))) \
507                             return NOTOK; \
508                         else \
509                             bp = outbuf
510
511 static int  encap (fd)
512 register int    fd;
513 {
514     register int    i,
515                     state;
516     register char  *cp,
517                    *ep;
518     char    buffer[BUFSIZ];
519     register int    j;
520     register char  *bp,
521                    *dp;
522     char    outbuf[BUFSIZ];
523
524     (void) lseek (fd, (off_t)0, 0);
525
526     dp = (bp = outbuf) + sizeof outbuf;
527     for (state = S1; (i = read (fd, buffer, sizeof buffer)) > 0;)
528         for (ep = (cp = buffer) + i; cp < ep; cp++) {
529             if (*cp == NULL)
530                 continue;
531             switch (state) {
532                 case S1: 
533                     if (*cp == '-') {
534                         output ('-');
535                         output (' ');
536                     }
537                     state = S2; /* fall */
538
539                 case S2: 
540                     output (*cp);
541                     if (*cp == '\n')
542                         state = S1;
543                     break;
544             }
545         }
546
547     if (i == NOTOK)
548         return NOTOK;
549     flush ();
550
551     return OK;
552 }
553 #endif  DISTRIBUTE
554
555 /* \f */
556
557 #ifndef DISTRIBUTE
558 /* VARARGS1 */
559
560 static int  lose (fmt, a, b, c, d)
561 char   *fmt,
562        *a,
563        *b,
564        *c,
565        *d;
566 {
567     adios (EX_UNAVAILABLE, NULLCP, fmt, a, b, c, d);/* NOTREACHED */
568 }
569 #endif  not DISTRIBUTE
570
571 /* \f */
572
573 static  arginit (vec)
574 register char  **vec;
575 {
576     register int    i;
577 #ifdef  MHMTS
578     register char  *ap;
579 #endif  MHMTS
580     char    addr[BUFSIZ];
581     register struct bboard *bp;
582     register struct passwd *pw;
583
584     invo_name = r1bindex (*vec++, '/');
585     m_foil (NULLCP);
586     mts_init (invo_name);
587
588 #ifndef SPOP
589     if ((pw = getpwnam (BBOARDS)) == NULL)
590         adios (EX_OSFILE, NULLCP, "no entry for ~%s", BBOARDS);
591 #else   SPOP
592     if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1))
593         adios (EX_OSFILE, NULLCP, "%s", pw ? getbberr () : "POP user-id unknown");
594 #endif  SPOP
595
596     if (pw -> pw_uid != geteuid ())
597 #ifndef SPOP
598     adios (EX_OSERR, NULLCP, "not running setuid to %s", BBOARDS);
599 #else   SPOP
600     adios (EX_OSERR, NULLCP, "not running setuid to %s", POPUID);
601 #endif  SPOP
602
603     bb_uid = pw -> pw_uid;
604     bb_gid = pw -> pw_gid;
605 #ifndef SPOP
606     (void) strcpy (bb_from, adrsprintf (pw -> pw_name, LocalName ()));
607     (void) strcpy (bb_home, pw -> pw_dir);
608 #endif  not SPOP
609
610 #ifdef  MHMTS
611     vec += 3;
612 #endif  MHMTS
613     if (*vec == NULL)
614         adios (EX_USAGE, NULLCP, "usage: %s %s [%s ...]",
615                 invo_name, ENTITY, ENTITY);
616
617     for (i = 0; *vec; vec++) {
618 #ifdef  MHMTS
619         if (ap = index (*vec, '.'))
620             *vec = ++ap;
621 #endif  MHMTS
622         make_lower (addr, *vec);
623
624         if ((bp = getbbnam (addr)) == NULL
625                 && (bp = getbbaka (addr)) == NULL)
626             adios (EX_NOUSER, NULLCP, "no such %s as %s", ENTITY, *vec);
627         if ((bb[i++] = getbbcpy (bp)) == NULL)
628             adios (EX_UNAVAILABLE, NULLCP, "insufficient memory on %s", *vec);
629
630         if (i >= NBB - 1)
631             adios (EX_USAGE, NULLCP, "too many %ss, starting with %s",
632                     ENTITY, *vec);
633     }
634     bb[i] = NULL;
635
636     (void) umask (0022);
637
638     bb_fderr = NOTOK;
639 }
640
641 /* \f */
642
643 static int  copyfile (qd, tmpfil)
644 int     qd;
645 register char   *tmpfil;
646 {
647     int     i,
648             fd;
649     char    buffer[BUFSIZ];
650
651     (void) strcpy (tmpfil, m_tmpfil (invo_name));
652     if ((fd = creat (tmpfil, 0600)) == NOTOK)
653         adios (EX_CANTCREAT, tmpfil, "unable to create");
654     (void) close (fd);
655     if ((fd = open (tmpfil, 2)) == NOTOK)
656         adios (EX_NOINPUT, tmpfil, "unable to re-open");
657
658     (void) lseek (qd, (off_t)0, 0);
659     while ((i = read (qd, buffer, sizeof buffer)) > 0)
660         if (write (fd, buffer, i) != i)
661             adios (EX_IOERR, tmpfil, "error writing");
662     if (i == NOTOK)
663         adios (EX_IOERR, "input", "error reading");
664
665     (void) lseek (fd, (off_t)0, 0);
666
667     return fd;
668 }
669
670 /* \f */
671
672 /* VARARGS3 */
673
674 #ifdef  MHMTS
675 /* ARGSUSED */
676 #endif  MHMTS
677
678 static  void adios (code, what, fmt, a, b, c, d, e, f)
679 int     code;
680 char   *what,
681        *fmt,
682        *a,
683        *b,
684        *c,
685        *d,
686        *e,
687        *f;
688 {
689     advise (what, fmt, a, b, c, d, e, f);
690 #ifdef  SENDMTS
691     done (code);
692 #endif  SENDMTS
693 #ifdef  MHMTS
694     done (1);
695 #endif  MHMTS
696 }
697 @
698
699
700 1.7
701 log
702 @fixup for onex/queued interface
703 @
704 text
705 @d7 1
706 a7 1
707 static char ident[] = "@@(#)$Id: spop.c,v 1.6 1992/11/04 01:04:35 jromine Exp jromine $";
708 d104 1
709 a104 1
710 long    lseek ();
711 d164 1
712 a164 1
713             (void) lseek (fd, 0L, 0);
714 d305 1
715 a305 1
716     (void) lseek (fd, 0L, 0);
717 d414 1
718 a414 1
719     (void) lseek (bb_fderr, 0L, 0);
720 d467 1
721 a467 1
722     (void) lseek (fd, 0L, 0);
723 d601 1
724 a601 1
725     (void) lseek (qd, 0L, 0);
726 d608 1
727 a608 1
728     (void) lseek (fd, 0L, 0);
729 @
730
731
732 1.6
733 log
734 @LOCALE
735 isupper with isalpha
736 @
737 text
738 @d7 1
739 a7 1
740 static char ident[] = "@@(#)$Id: spop.c,v 1.5 1992/02/03 17:57:22 jromine Exp jromine $";
741 d251 1
742 a251 1
743     if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0))
744 d383 1
745 a383 1
746     if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0))
747 @
748
749
750 1.5
751 log
752 @STDC/SYS5/getpw
753 @
754 text
755 @d7 1
756 a7 1
757 static char ident[] = "@@(#)$Id: spop.c,v 1.4 1990/04/05 15:02:39 sources Exp jromine $";
758 d66 3
759 d129 3
760 @
761
762
763 1.4
764 log
765 @add ID
766 @
767 text
768 @d7 1
769 a7 1
770 static char ident[] = "@@(#)$Id:$";
771 d103 1
772 d106 2
773 a107 1
774 #endif  SYS5
775 @
776
777
778 1.3
779 log
780 @adios -> myadios
781 @
782 text
783 @d6 3
784 @
785
786
787 1.2
788 log
789 @ANSI Compilance
790 @
791 text
792 @d104 2
793 @
794
795
796 1.1
797 log
798 @Initial revision
799 @
800 text
801 @d104 3
802 @