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