|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 12971 (0x32ab)
Types: TextFile
Names: »sbboards.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦3658e588a⟧ »EurOpenD3/mail/mh/mh-6.7.tar.Z«
└─⟦c75e36ecb⟧
└─⟦this⟧ »mh-6.7/uip/sbboards.c«
#ifndef SPOP
/* sbboards.c - MH style mailer to write to a ZOTnet BBoard */
#else SPOP
/* spop.c - MH style mailer to write to a POP subscriber */
#endif SPOP
#ifndef lint
static char ident[] = "@(#)$Id: sbboards.c,v 1.3 90/04/05 15:04:02 sources Exp $";
#endif lint
#ifndef SPOP
/* This program acts like the MMDF ch_bboards channel: it does local
delivery to a ZOTnet BBoard and/or addition re-distribution to other
recipients of the BBoard. This program can function both as a SendMail
mailer and an MH .mh_receive file, depending on whether SENDMTS or
MHMTS is set. Currently, the MHMTS version of this program does not do
re-distribution.
This program should be used ONLY if you have "bboards on" set in your
MH configuration, and if you have "mts sendmail" or "mts mh" set as well.
*/
#else SPOP
/* This program acts like the MMDF-II ch_pop channel: it does local
delivery for non-local users. These users are known as POP subscribers
and use the Post Office Protocol with a POP server in order to access
their maildrop.
*/
#endif SPOP
#undef DISTRIBUTE
#ifdef SENDMTS
#ifndef SPOP
#define DISTRIBUTE
#endif not SPOP
#endif SENDMTS
#include "../h/mh.h"
#ifndef SPOP
#include "../h/addrsbr.h"
#endif not SPOP
#include "../h/dropsbr.h"
#include "../zotnet/bboards.h"
#include "../zotnet/tws.h"
#include <stdio.h>
#include "../zotnet/mts.h"
#include <pwd.h>
#ifndef SYS5
#include <sysexits.h>
#else SYS5
#define EX_CANTCREAT 1
#define EX_IOERR 1
#define EX_NOINPUT 1
#define EX_NOUSER 1
#define EX_OK 0
#define EX_OSERR 1
#define EX_OSFILE 1
#define EX_UNAVAILABLE 1
#define EX_USAGE 1
#endif SYS5
#ifdef DISTRIBUTE
#include "../mts/sendmail/smail.h"
#endif DISTRIBUTE
#define NBB 100
#ifndef SPOP
#define ENTITY "bboard"
#else SPOP
#define ENTITY "subscriber"
#endif SPOP
/* \f
*/
static int bb_fderr;
static int bb_uid;
static int bb_gid;
int dst_rcpt ();
#ifndef SPOP
static char bb_from[BUFSIZ];
static char bb_head[BUFSIZ];
static char bb_home[BUFSIZ];
static char bb_time[BUFSIZ];
#ifdef DISTRIBUTE
static char bb_rept[BUFSIZ];
#endif DISTRIBUTE
#else SPOP
#define bb_head NULLCP
#endif SPOP
static struct bboard *bb[NBB];
long lseek ();
#ifdef SYS5
struct passwd *getpwnam ();
#endif SYS5
/* hack */
#define adios my_adios
static localmail(), arginit();
static int lose(), copyfile();
static void adios();
/* \f
*/
/* ARGSUSED */
main (argc, argv, envp)
int argc;
char **argv,
**envp;
{
int fd;
char tmpfil[BUFSIZ];
#ifdef MHMTS
if (argc != 5)
adios (EX_USAGE, NULL, "you lose really big");
#endif MHMTS
arginit (argv);
fflush (stdout);
discard (stdout); /* XXX: reference discard to help loader */
fd = copyfile (fileno (stdin), tmpfil);
(void) unlink (tmpfil);
localmail (fd);
#ifdef DISTRIBUTE
distribute (fd);
notify (fd);
#endif DISTRIBUTE
exit (EX_OK);
}
/* \f
*/
static localmail (fd)
int fd;
{
int i,
md;
register struct bboard *bp;
for (i = 0; bp = bb[i]; i++)
if (bp -> bb_file && *bp -> bb_file) {
(void) lseek (fd, 0L, 0);
#ifndef SPOP
if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, BBMODE))
#else SPOP
if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, POMODE))
#endif SPOP
== NOTOK) {
(void) lose ("unable to open %s", bp -> bb_file);
continue;
}
#ifndef SPOP
if (mbx_init (bp) != NOTOK)
#endif not SPOP
(void) mbx_copy (bp -> bb_file, md, fd, 1, bb_head, 0);
(void) mbx_close (bp -> bb_file, md);
}
}
/* \f
*/
#ifndef SPOP
static int mbx_init (bp)
register struct bboard *bp;
{
int fd,
clear;
register struct bboard *ip;
register FILE *fp;
if ((fd = mbx_Xopen (bp -> bb_info, bb_uid, bb_gid, BBMODE, &clear))
== NOTOK)
return lose ("unable to lock and open %s", bp -> bb_info);
if ((fp = fdopen (fd, "w")) == NULL) {
(void) mbx_close (bp -> bb_info, fd);
return lose ("unable to fdopen %s", bp -> bb_info);
}
if ((ip = getbbnam (bp -> bb_name)) == NULL) {
(void) lkfclose (fp, bp -> bb_info);
return lose ("unable to get information on BBoard %s", bp -> bb_name);
}
(void) strcpy (bb_time, dtimenow ());
(void) sprintf (bb_head, "BBoard-ID: %d\nBB-Posted: %s\n",
bp -> bb_maxima = ++ip -> bb_maxima, bb_time);
fprintf (fp, "%d\n%s\n", bp -> bb_maxima, bb_time);
(void) lkfclose (fp, bp -> bb_info);
return OK;
}
#endif not SPOP
/* \f
*/
#ifdef DISTRIBUTE
static distribute (fd)
int fd;
{
int i;
register struct bboard *bp;
for (i = 0; bp = bb[i]; i++)
if (bp -> bb_dist && *bp -> bb_dist)
break;
if (bp == NULL)
return;
if (dst_init () == NOTOK) {
dst_lose ();
return;
}
for (i = 0; bp = bb[i]; i++)
if (bp -> bb_dist && *bp -> bb_dist)
if (dst_adrs (bp) == NOTOK) {
dst_lose ();
return;
}
if (dst_text (fd) == NOTOK || dst_end () == NOTOK)
dst_lose ();
}
/* \f
*/
static int dst_init ()
{
int retval;
if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0))
|| rp_isbad (retval = sm_winit (S_MAIL, bb_from)))
return lose ("problem initializing SendMail; %s",
rp_string (retval));
return OK;
}
/* \f
*/
static int dst_adrs (bp)
register struct bboard *bp;
{
if (getbbdist (bp, dst_rcpt))
return lose ("getbbdist failed: %s", getbberr ());
return OK;
}
/* \f
*/
static int dst_rcpt (mbox, host)
register char *mbox,
*host;
{
int retval;
switch (retval = sm_wadr (mbox, host, NULLCP)) {
case RP_OK:
return OK;
case RP_NO:
case RP_USER:
(void) lose ("%s@%s: loses; %s", mbox, host, rp_string (retval));
return OK; /* fail-soft */
default:
return lose ("%s@%s: unexpected response; %s",
mbox, host, rp_string (retval));
}
}
/* \f
*/
static int dst_text (fd)
int fd;
{
int i,
retval;
char buffer[BUFSIZ];
if (rp_isbad (retval = sm_waend ()))
return lose ("problem ending addresses; %s", rp_string (retval));
(void) lseek (fd, 0L, 0);
while ((i = read (fd, buffer, sizeof buffer)) > 0)
if (rp_isbad (retval = sm_wtxt (buffer, i)))
return lose ("problem writing text; %s", rp_string (retval));
return (i != NOTOK ? OK : lose ("error reading from file"));
}
/* \f
*/
static int dst_end ()
{
int retval;
switch (retval = sm_wtend ()) {
case RP_OK:
(void) sm_end (OK);
return OK;
case RP_NO:
case RP_NDEL:
return lose ("posting failed; %s", rp_string (retval));
default:
return lose ("unexpected response; %s", rp_string (retval));
}
}
/* \f
*/
static dst_lose ()
{
(void) sm_end (NOTOK);
}
/* \f
*/
/* VARARGS1 */
static int lose (fmt, a, b, c, d)
char *fmt,
*a,
*b,
*c,
*d;
{
int fd,
i;
char *bp,
buffer[BUFSIZ];
if (bb_fderr == NOTOK) {
if ((fd = open ("/dev/null", 0)) == NOTOK)
adios (EX_OSERR, "/dev/null", "unable to open");
bb_fderr = copyfile (fd, bb_rept);
}
(void) sprintf (bp = buffer, fmt, a, b, c, d);
bp += strlen (bp);
bp += strlen (strcpy(bp, "\n"));
i = bp - buffer;
if (write (bb_fderr, buffer, i) != i)
adios (EX_IOERR, bb_rept, "error writing");
return NOTOK;
}
/* \f
*/
static notify (fd)
int fd;
{
int i;
char buffer[BUFSIZ];
if (bb_fderr == NOTOK)
return;
if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0))
|| rp_isbad (sm_winit (S_MAIL, bb_from)))
goto sm_err;
switch (sm_wadr (bb_from, NULLCP, NULLCP)) {
case RP_OK:
for (i = 0; bb[i]; i++) {
(void) sprintf (buffer, "local-%s-request", bb[i] -> bb_name);
(void) sm_wadr (buffer, LocalName (), NULLCP);
}
break;
default:
goto sm_err;
}
if (rp_isbad (sm_waend ()))
goto sm_err;
(void) sprintf (buffer,
"Date: %s\nFrom: %s\nTo: %s\nSubject: BBoards Failure\n\n",
dtimenow (), bb_from, bb_from);
if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
goto sm_err;
for (i = 0; bb[i]; i++) {
(void) sprintf (buffer, "BBoard %s\n", bb[i] -> bb_name);
if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
goto sm_err;
}
(void) lseek (bb_fderr, 0L, 0);
while ((i = read (bb_fderr, buffer, sizeof buffer)) > 0)
if (rp_isbad (sm_wtxt (buffer, i)))
goto sm_err;
(void) strcpy (buffer, "\n------- Forwarded Message\n\n");
if (rp_isbad (sm_wtxt (buffer, strlen (buffer))) || encap (fd) == NOTOK)
goto sm_err;
(void) strcpy (buffer, "\n------- End of Forwarded Message\n\n");
if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
goto sm_err;
switch (sm_wtend ()) {
case RP_OK:
(void) unlink (bb_rept);
(void) sm_end (OK);
return;
default:
sm_err: ;
adios (EX_UNAVAILABLE, NULLCP,
"failed and unable to post advisory, see %s for details",
bb_rept);
}
}
/* \f
*/
/* very similar to sbr/cpydgst.c */
#define S1 0
#define S2 1
#define output(c) if (bp >= dp) flush (), *bp++ = c; else *bp++ = c
#define flush() if ((j = bp - outbuf) \
&& rp_isbad (sm_wtxt (outbuf, j))) \
return NOTOK; \
else \
bp = outbuf
static int encap (fd)
register int fd;
{
register int i,
state;
register char *cp,
*ep;
char buffer[BUFSIZ];
register int j;
register char *bp,
*dp;
char outbuf[BUFSIZ];
(void) lseek (fd, 0L, 0);
dp = (bp = outbuf) + sizeof outbuf;
for (state = S1; (i = read (fd, buffer, sizeof buffer)) > 0;)
for (ep = (cp = buffer) + i; cp < ep; cp++) {
if (*cp == NULL)
continue;
switch (state) {
case S1:
if (*cp == '-') {
output ('-');
output (' ');
}
state = S2; /* fall */
case S2:
output (*cp);
if (*cp == '\n')
state = S1;
break;
}
}
if (i == NOTOK)
return NOTOK;
flush ();
return OK;
}
#endif DISTRIBUTE
/* \f
*/
#ifndef DISTRIBUTE
/* VARARGS1 */
static int lose (fmt, a, b, c, d)
char *fmt,
*a,
*b,
*c,
*d;
{
adios (EX_UNAVAILABLE, NULLCP, fmt, a, b, c, d);/* NOTREACHED */
}
#endif not DISTRIBUTE
/* \f
*/
static arginit (vec)
register char **vec;
{
register int i;
#ifdef MHMTS
register char *ap;
#endif MHMTS
char addr[BUFSIZ];
register struct bboard *bp;
register struct passwd *pw;
invo_name = r1bindex (*vec++, '/');
m_foil (NULLCP);
mts_init (invo_name);
#ifndef SPOP
if ((pw = getpwnam (BBOARDS)) == NULL)
adios (EX_OSFILE, NULLCP, "no entry for ~%s", BBOARDS);
#else SPOP
if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1))
adios (EX_OSFILE, NULLCP, "%s", pw ? getbberr () : "POP user-id unknown");
#endif SPOP
if (pw -> pw_uid != geteuid ())
#ifndef SPOP
adios (EX_OSERR, NULLCP, "not running setuid to %s", BBOARDS);
#else SPOP
adios (EX_OSERR, NULLCP, "not running setuid to %s", POPUID);
#endif SPOP
bb_uid = pw -> pw_uid;
bb_gid = pw -> pw_gid;
#ifndef SPOP
(void) strcpy (bb_from, adrsprintf (pw -> pw_name, LocalName ()));
(void) strcpy (bb_home, pw -> pw_dir);
#endif not SPOP
#ifdef MHMTS
vec += 3;
#endif MHMTS
if (*vec == NULL)
adios (EX_USAGE, NULLCP, "usage: %s %s [%s ...]",
invo_name, ENTITY, ENTITY);
for (i = 0; *vec; vec++) {
#ifdef MHMTS
if (ap = index (*vec, '.'))
*vec = ++ap;
#endif MHMTS
make_lower (addr, *vec);
if ((bp = getbbnam (addr)) == NULL
&& (bp = getbbaka (addr)) == NULL)
adios (EX_NOUSER, NULLCP, "no such %s as %s", ENTITY, *vec);
if ((bb[i++] = getbbcpy (bp)) == NULL)
adios (EX_UNAVAILABLE, NULLCP, "insufficient memory on %s", *vec);
if (i >= NBB - 1)
adios (EX_USAGE, NULLCP, "too many %ss, starting with %s",
ENTITY, *vec);
}
bb[i] = NULL;
(void) umask (0022);
bb_fderr = NOTOK;
}
/* \f
*/
static int copyfile (qd, tmpfil)
int qd;
register char *tmpfil;
{
int i,
fd;
char buffer[BUFSIZ];
(void) strcpy (tmpfil, m_tmpfil (invo_name));
if ((fd = creat (tmpfil, 0600)) == NOTOK)
adios (EX_CANTCREAT, tmpfil, "unable to create");
(void) close (fd);
if ((fd = open (tmpfil, 2)) == NOTOK)
adios (EX_NOINPUT, tmpfil, "unable to re-open");
(void) lseek (qd, 0L, 0);
while ((i = read (qd, buffer, sizeof buffer)) > 0)
if (write (fd, buffer, i) != i)
adios (EX_IOERR, tmpfil, "error writing");
if (i == NOTOK)
adios (EX_IOERR, "input", "error reading");
(void) lseek (fd, 0L, 0);
return fd;
}
/* \f
*/
/* VARARGS3 */
#ifdef MHMTS
/* ARGSUSED */
#endif MHMTS
static void adios (code, what, fmt, a, b, c, d, e, f)
int code;
char *what,
*fmt,
*a,
*b,
*c,
*d,
*e,
*f;
{
advise (what, fmt, a, b, c, d, e, f);
#ifdef SENDMTS
done (code);
#endif SENDMTS
#ifdef MHMTS
done (1);
#endif MHMTS
}