2 /* sbboards.c - MH style mailer to write to a ZOTnet BBoard */
4 /* spop.c - MH style mailer to write to a POP subscriber */
7 static char ident[] = "@(#)$Id: sbboards.c,v 1.9 1993/08/25 17:27:54 jromine Exp $";
12 /* This program acts like the MMDF ch_bboards channel: it does local
13 delivery to a ZOTnet BBoard and/or addition re-distribution to other
14 recipients of the BBoard. This program can function both as a SendMail
15 mailer and an MH .mh_receive file, depending on whether SENDMTS or
16 MHMTS is set. Currently, the MHMTS version of this program does not do
19 This program should be used ONLY if you have "bboards on" set in your
20 MH configuration, and if you have "mts sendmail" or "mts mh" set as well.
25 /* This program acts like the MMDF-II ch_pop channel: it does local
26 delivery for non-local users. These users are known as POP subscribers
27 and use the Post Office Protocol with a POP server in order to access
42 #include "../h/addrsbr.h"
44 #include "../h/dropsbr.h"
45 #include "../zotnet/bboards.h"
46 #include "../zotnet/tws.h"
48 #include "../zotnet/mts.h"
53 #define EX_CANTCREAT 1
60 #define EX_UNAVAILABLE 1
64 #include "../mts/sendmail/smail.h"
74 #define ENTITY "bboard"
76 #define ENTITY "subscriber"
86 static int dst_rcpt ();
90 static char bb_from[BUFSIZ];
91 static char bb_head[BUFSIZ];
92 static char bb_home[BUFSIZ];
93 static char bb_time[BUFSIZ];
95 static char bb_rept[BUFSIZ];
98 #define bb_head NULLCP
101 static struct bboard *bb[NBB];
108 struct passwd *getpwnam ();
113 static int mbx_init();
116 static int distribute(), notify(), encap(),
117 dst_init(), dst_text(),
118 dst_end(), dst_lose(), dst_adrs();
122 #define adios my_adios
123 static localmail(), arginit();
124 static int lose(), copyfile();
130 main (argc, argv, envp)
139 setlocale(LC_ALL, "");
143 adios (EX_USAGE, NULL, "you lose really big");
148 discard (stdout); /* XXX: reference discard to help loader */
150 fd = copyfile (fileno (stdin), tmpfil);
151 (void) unlink (tmpfil);
164 static localmail (fd)
169 register struct bboard *bp;
171 for (i = 0; bp = bb[i]; i++)
172 if (bp -> bb_file && *bp -> bb_file) {
173 (void) lseek (fd, (off_t)0, 0);
175 if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, BBMODE))
177 if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, POMODE))
180 (void) lose ("unable to open %s", bp -> bb_file);
184 if (mbx_init (bp) != NOTOK)
186 (void) mbx_copy (bp -> bb_file, md, fd, 1, bb_head, 0);
187 (void) mbx_close (bp -> bb_file, md);
194 static int mbx_init (bp)
195 register struct bboard *bp;
199 register struct bboard *ip;
202 if ((fd = mbx_Xopen (bp -> bb_info, bb_uid, bb_gid, BBMODE, &clear))
204 return lose ("unable to lock and open %s", bp -> bb_info);
205 if ((fp = fdopen (fd, "w")) == NULL) {
206 (void) mbx_close (bp -> bb_info, fd);
207 return lose ("unable to fdopen %s", bp -> bb_info);
210 if ((ip = getbbnam (bp -> bb_name)) == NULL) {
211 (void) lkfclose (fp, bp -> bb_info);
212 return lose ("unable to get information on BBoard %s", bp -> bb_name);
214 (void) strcpy (bb_time, dtimenow ());
215 (void) sprintf (bb_head, "BBoard-ID: %d\nBB-Posted: %s\n",
216 bp -> bb_maxima = ++ip -> bb_maxima, bb_time);
218 fprintf (fp, "%d\n%s\n", bp -> bb_maxima, bb_time);
219 (void) lkfclose (fp, bp -> bb_info);
228 static distribute (fd)
232 register struct bboard *bp;
234 for (i = 0; bp = bb[i]; i++)
235 if (bp -> bb_dist && *bp -> bb_dist)
240 if (dst_init () == NOTOK) {
244 for (i = 0; bp = bb[i]; i++)
245 if (bp -> bb_dist && *bp -> bb_dist)
246 if (dst_adrs (bp) == NOTOK) {
250 if (dst_text (fd) == NOTOK || dst_end () == NOTOK)
256 static int dst_init ()
260 if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
261 || rp_isbad (retval = sm_winit (S_MAIL, bb_from)))
262 return lose ("problem initializing SendMail; %s",
270 static int dst_adrs (bp)
271 register struct bboard *bp;
273 if (getbbdist (bp, dst_rcpt))
274 return lose ("getbbdist failed: %s", getbberr ());
281 static int dst_rcpt (mbox, host)
287 switch (retval = sm_wadr (mbox, host, NULLCP)) {
293 (void) lose ("%s@%s: loses; %s", mbox, host, rp_string (retval));
294 return OK; /* fail-soft */
297 return lose ("%s@%s: unexpected response; %s",
298 mbox, host, rp_string (retval));
304 static int dst_text (fd)
311 if (rp_isbad (retval = sm_waend ()))
312 return lose ("problem ending addresses; %s", rp_string (retval));
314 (void) lseek (fd, (off_t)0, 0);
315 while ((i = read (fd, buffer, sizeof buffer)) > 0)
316 if (rp_isbad (retval = sm_wtxt (buffer, i)))
317 return lose ("problem writing text; %s", rp_string (retval));
319 return (i != NOTOK ? OK : lose ("error reading from file"));
324 static int dst_end ()
328 switch (retval = sm_wtend ()) {
335 return lose ("posting failed; %s", rp_string (retval));
338 return lose ("unexpected response; %s", rp_string (retval));
346 (void) sm_end (NOTOK);
353 static int lose (fmt, a, b, c, d)
365 if (bb_fderr == NOTOK) {
366 if ((fd = open ("/dev/null", 0)) == NOTOK)
367 adios (EX_OSERR, "/dev/null", "unable to open");
368 bb_fderr = copyfile (fd, bb_rept);
371 (void) sprintf (bp = buffer, fmt, a, b, c, d);
373 bp += strlen (strcpy(bp, "\n"));
375 if (write (bb_fderr, buffer, i) != i)
376 adios (EX_IOERR, bb_rept, "error writing");
389 if (bb_fderr == NOTOK)
392 if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
393 || rp_isbad (sm_winit (S_MAIL, bb_from)))
396 switch (sm_wadr (bb_from, NULLCP, NULLCP)) {
398 for (i = 0; bb[i]; i++) {
399 (void) sprintf (buffer, "local-%s-request", bb[i] -> bb_name);
400 (void) sm_wadr (buffer, LocalName (), NULLCP);
408 if (rp_isbad (sm_waend ()))
411 (void) sprintf (buffer,
412 "Date: %s\nFrom: %s\nTo: %s\nSubject: BBoards Failure\n\n",
413 dtimenow (), bb_from, bb_from);
414 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
417 for (i = 0; bb[i]; i++) {
418 (void) sprintf (buffer, "BBoard %s\n", bb[i] -> bb_name);
419 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
423 (void) lseek (bb_fderr, (off_t)0, 0);
424 while ((i = read (bb_fderr, buffer, sizeof buffer)) > 0)
425 if (rp_isbad (sm_wtxt (buffer, i)))
428 (void) strcpy (buffer, "\n------- Forwarded Message\n\n");
429 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))) || encap (fd) == NOTOK)
431 (void) strcpy (buffer, "\n------- End of Forwarded Message\n\n");
432 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
435 switch (sm_wtend ()) {
437 (void) unlink (bb_rept);
443 adios (EX_UNAVAILABLE, NULLCP,
444 "failed and unable to post advisory, see %s for details",
451 /* very similar to sbr/cpydgst.c */
456 #define output(c) if (bp >= dp) flush (), *bp++ = c; else *bp++ = c
457 #define flush() if ((j = bp - outbuf) \
458 && rp_isbad (sm_wtxt (outbuf, j))) \
463 static int encap (fd)
476 (void) lseek (fd, (off_t)0, 0);
478 dp = (bp = outbuf) + sizeof outbuf;
479 for (state = S1; (i = read (fd, buffer, sizeof buffer)) > 0;)
480 for (ep = (cp = buffer) + i; cp < ep; cp++) {
489 state = S2; /* fall */
512 static int lose (fmt, a, b, c, d)
519 adios (EX_UNAVAILABLE, NULLCP, fmt, a, b, c, d);/* NOTREACHED */
521 #endif not DISTRIBUTE
533 register struct bboard *bp;
534 register struct passwd *pw;
536 invo_name = r1bindex (*vec++, '/');
538 mts_init (invo_name);
541 if ((pw = getpwnam (BBOARDS)) == NULL)
542 adios (EX_OSFILE, NULLCP, "no entry for ~%s", BBOARDS);
544 if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1))
545 adios (EX_OSFILE, NULLCP, "%s", pw ? getbberr () : "POP user-id unknown");
548 if (pw -> pw_uid != geteuid ())
550 adios (EX_OSERR, NULLCP, "not running setuid to %s", BBOARDS);
552 adios (EX_OSERR, NULLCP, "not running setuid to %s", POPUID);
555 bb_uid = pw -> pw_uid;
556 bb_gid = pw -> pw_gid;
558 (void) strcpy (bb_from, adrsprintf (pw -> pw_name, LocalName ()));
559 (void) strcpy (bb_home, pw -> pw_dir);
566 adios (EX_USAGE, NULLCP, "usage: %s %s [%s ...]",
567 invo_name, ENTITY, ENTITY);
569 for (i = 0; *vec; vec++) {
571 if (ap = index (*vec, '.'))
574 make_lower (addr, *vec);
576 if ((bp = getbbnam (addr)) == NULL
577 && (bp = getbbaka (addr)) == NULL)
578 adios (EX_NOUSER, NULLCP, "no such %s as %s", ENTITY, *vec);
579 if ((bb[i++] = getbbcpy (bp)) == NULL)
580 adios (EX_UNAVAILABLE, NULLCP, "insufficient memory on %s", *vec);
583 adios (EX_USAGE, NULLCP, "too many %ss, starting with %s",
595 static int copyfile (qd, tmpfil)
597 register char *tmpfil;
603 (void) strcpy (tmpfil, m_tmpfil (invo_name));
604 if ((fd = creat (tmpfil, 0600)) == NOTOK)
605 adios (EX_CANTCREAT, tmpfil, "unable to create");
607 if ((fd = open (tmpfil, 2)) == NOTOK)
608 adios (EX_NOINPUT, tmpfil, "unable to re-open");
610 (void) lseek (qd, (off_t)0, 0);
611 while ((i = read (qd, buffer, sizeof buffer)) > 0)
612 if (write (fd, buffer, i) != i)
613 adios (EX_IOERR, tmpfil, "error writing");
615 adios (EX_IOERR, "input", "error reading");
617 (void) lseek (fd, (off_t)0, 0);
630 static void adios (code, what, fmt, a, b, c, d, e, f)
641 advise (what, fmt, a, b, c, d, e, f);