]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/RCS/spop.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / 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 @