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: spop.c,v 1.8 1993/08/25 17:28:24 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"
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 #define adios my_adios
114 static localmail(), arginit();
115 static int lose(), copyfile();
121 main (argc, argv, envp)
130 setlocale(LC_ALL, "");
134 adios (EX_USAGE, NULL, "you lose really big");
139 discard (stdout); /* XXX: reference discard to help loader */
141 fd = copyfile (fileno (stdin), tmpfil);
142 (void) unlink (tmpfil);
155 static localmail (fd)
160 register struct bboard *bp;
162 for (i = 0; bp = bb[i]; i++)
163 if (bp -> bb_file && *bp -> bb_file) {
164 (void) lseek (fd, (off_t)0, 0);
166 if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, BBMODE))
168 if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, POMODE))
171 (void) lose ("unable to open %s", bp -> bb_file);
175 if (mbx_init (bp) != NOTOK)
177 (void) mbx_copy (bp -> bb_file, md, fd, 1, bb_head, 0);
178 (void) mbx_close (bp -> bb_file, md);
185 static int mbx_init (bp)
186 register struct bboard *bp;
190 register struct bboard *ip;
193 if ((fd = mbx_Xopen (bp -> bb_info, bb_uid, bb_gid, BBMODE, &clear))
195 return lose ("unable to lock and open %s", bp -> bb_info);
196 if ((fp = fdopen (fd, "w")) == NULL) {
197 (void) mbx_close (bp -> bb_info, fd);
198 return lose ("unable to fdopen %s", bp -> bb_info);
201 if ((ip = getbbnam (bp -> bb_name)) == NULL) {
202 (void) lkfclose (fp, bp -> bb_info);
203 return lose ("unable to get information on BBoard %s", bp -> bb_name);
205 (void) strcpy (bb_time, dtimenow ());
206 (void) sprintf (bb_head, "BBoard-ID: %d\nBB-Posted: %s\n",
207 bp -> bb_maxima = ++ip -> bb_maxima, bb_time);
209 fprintf (fp, "%d\n%s\n", bp -> bb_maxima, bb_time);
210 (void) lkfclose (fp, bp -> bb_info);
219 static distribute (fd)
223 register struct bboard *bp;
225 for (i = 0; bp = bb[i]; i++)
226 if (bp -> bb_dist && *bp -> bb_dist)
231 if (dst_init () == NOTOK) {
235 for (i = 0; bp = bb[i]; i++)
236 if (bp -> bb_dist && *bp -> bb_dist)
237 if (dst_adrs (bp) == NOTOK) {
241 if (dst_text (fd) == NOTOK || dst_end () == NOTOK)
247 static int dst_init ()
251 if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
252 || rp_isbad (retval = sm_winit (S_MAIL, bb_from)))
253 return lose ("problem initializing SendMail; %s",
261 static int dst_adrs (bp)
262 register struct bboard *bp;
264 if (getbbdist (bp, dst_rcpt))
265 return lose ("getbbdist failed: %s", getbberr ());
272 static int dst_rcpt (mbox, host)
278 switch (retval = sm_wadr (mbox, host, NULLCP)) {
284 (void) lose ("%s@%s: loses; %s", mbox, host, rp_string (retval));
285 return OK; /* fail-soft */
288 return lose ("%s@%s: unexpected response; %s",
289 mbox, host, rp_string (retval));
295 static int dst_text (fd)
302 if (rp_isbad (retval = sm_waend ()))
303 return lose ("problem ending addresses; %s", rp_string (retval));
305 (void) lseek (fd, (off_t)0, 0);
306 while ((i = read (fd, buffer, sizeof buffer)) > 0)
307 if (rp_isbad (retval = sm_wtxt (buffer, i)))
308 return lose ("problem writing text; %s", rp_string (retval));
310 return (i != NOTOK ? OK : lose ("error reading from file"));
315 static int dst_end ()
319 switch (retval = sm_wtend ()) {
326 return lose ("posting failed; %s", rp_string (retval));
329 return lose ("unexpected response; %s", rp_string (retval));
337 (void) sm_end (NOTOK);
344 static int lose (fmt, a, b, c, d)
356 if (bb_fderr == NOTOK) {
357 if ((fd = open ("/dev/null", 0)) == NOTOK)
358 adios (EX_OSERR, "/dev/null", "unable to open");
359 bb_fderr = copyfile (fd, bb_rept);
362 (void) sprintf (bp = buffer, fmt, a, b, c, d);
364 bp += strlen (strcpy(bp, "\n"));
366 if (write (bb_fderr, buffer, i) != i)
367 adios (EX_IOERR, bb_rept, "error writing");
380 if (bb_fderr == NOTOK)
383 if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0, 0, 0))
384 || rp_isbad (sm_winit (S_MAIL, bb_from)))
387 switch (sm_wadr (bb_from, NULLCP, NULLCP)) {
389 for (i = 0; bb[i]; i++) {
390 (void) sprintf (buffer, "local-%s-request", bb[i] -> bb_name);
391 (void) sm_wadr (buffer, LocalName (), NULLCP);
399 if (rp_isbad (sm_waend ()))
402 (void) sprintf (buffer,
403 "Date: %s\nFrom: %s\nTo: %s\nSubject: BBoards Failure\n\n",
404 dtimenow (), bb_from, bb_from);
405 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
408 for (i = 0; bb[i]; i++) {
409 (void) sprintf (buffer, "BBoard %s\n", bb[i] -> bb_name);
410 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
414 (void) lseek (bb_fderr, (off_t)0, 0);
415 while ((i = read (bb_fderr, buffer, sizeof buffer)) > 0)
416 if (rp_isbad (sm_wtxt (buffer, i)))
419 (void) strcpy (buffer, "\n------- Forwarded Message\n\n");
420 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))) || encap (fd) == NOTOK)
422 (void) strcpy (buffer, "\n------- End of Forwarded Message\n\n");
423 if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
426 switch (sm_wtend ()) {
428 (void) unlink (bb_rept);
434 adios (EX_UNAVAILABLE, NULLCP,
435 "failed and unable to post advisory, see %s for details",
442 /* very similar to sbr/cpydgst.c */
447 #define output(c) if (bp >= dp) flush (), *bp++ = c; else *bp++ = c
448 #define flush() if ((j = bp - outbuf) \
449 && rp_isbad (sm_wtxt (outbuf, j))) \
454 static int encap (fd)
467 (void) lseek (fd, (off_t)0, 0);
469 dp = (bp = outbuf) + sizeof outbuf;
470 for (state = S1; (i = read (fd, buffer, sizeof buffer)) > 0;)
471 for (ep = (cp = buffer) + i; cp < ep; cp++) {
480 state = S2; /* fall */
503 static int lose (fmt, a, b, c, d)
510 adios (EX_UNAVAILABLE, NULLCP, fmt, a, b, c, d);/* NOTREACHED */
512 #endif not DISTRIBUTE
524 register struct bboard *bp;
525 register struct passwd *pw;
527 invo_name = r1bindex (*vec++, '/');
529 mts_init (invo_name);
532 if ((pw = getpwnam (BBOARDS)) == NULL)
533 adios (EX_OSFILE, NULLCP, "no entry for ~%s", BBOARDS);
535 if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1))
536 adios (EX_OSFILE, NULLCP, "%s", pw ? getbberr () : "POP user-id unknown");
539 if (pw -> pw_uid != geteuid ())
541 adios (EX_OSERR, NULLCP, "not running setuid to %s", BBOARDS);
543 adios (EX_OSERR, NULLCP, "not running setuid to %s", POPUID);
546 bb_uid = pw -> pw_uid;
547 bb_gid = pw -> pw_gid;
549 (void) strcpy (bb_from, adrsprintf (pw -> pw_name, LocalName ()));
550 (void) strcpy (bb_home, pw -> pw_dir);
557 adios (EX_USAGE, NULLCP, "usage: %s %s [%s ...]",
558 invo_name, ENTITY, ENTITY);
560 for (i = 0; *vec; vec++) {
562 if (ap = index (*vec, '.'))
565 make_lower (addr, *vec);
567 if ((bp = getbbnam (addr)) == NULL
568 && (bp = getbbaka (addr)) == NULL)
569 adios (EX_NOUSER, NULLCP, "no such %s as %s", ENTITY, *vec);
570 if ((bb[i++] = getbbcpy (bp)) == NULL)
571 adios (EX_UNAVAILABLE, NULLCP, "insufficient memory on %s", *vec);
574 adios (EX_USAGE, NULLCP, "too many %ss, starting with %s",
586 static int copyfile (qd, tmpfil)
588 register char *tmpfil;
594 (void) strcpy (tmpfil, m_tmpfil (invo_name));
595 if ((fd = creat (tmpfil, 0600)) == NOTOK)
596 adios (EX_CANTCREAT, tmpfil, "unable to create");
598 if ((fd = open (tmpfil, 2)) == NOTOK)
599 adios (EX_NOINPUT, tmpfil, "unable to re-open");
601 (void) lseek (qd, (off_t)0, 0);
602 while ((i = read (qd, buffer, sizeof buffer)) > 0)
603 if (write (fd, buffer, i) != i)
604 adios (EX_IOERR, tmpfil, "error writing");
606 adios (EX_IOERR, "input", "error reading");
608 (void) lseek (fd, (off_t)0, 0);
621 static void adios (code, what, fmt, a, b, c, d, e, f)
632 advise (what, fmt, a, b, c, d, e, f);