📄 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 lintstatic char ident[] = "@(#)$Id: sbboards.c,v 1.2 90/11/25 19:05:43 sharpe 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/* */static int bb_fderr;static int bb_uid;static int bb_gid;int dst_rcpt ();#ifndef SPOPstatic char bb_from[BUFSIZ];static char bb_head[BUFSIZ];static char bb_home[BUFSIZ];static char bb_time[BUFSIZ];#ifdef DISTRIBUTEstatic char bb_rept[BUFSIZ];#endif DISTRIBUTE#else SPOP#define bb_head NULLCP#endif SPOPstatic struct bboard *bb[NBB];long lseek ();#ifdef SYS5struct passwd *getpwnam ();#endif SYS5/* hack */#define adios my_adiosstatic localmail(), arginit();static int lose(), copyfile();static void adios();/* *//* 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);}/* */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); }}/* */#ifndef SPOPstatic 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/* */#ifdef DISTRIBUTEstatic 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 ();}/* */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;}/* */static int dst_adrs (bp)register struct bboard *bp;{ if (getbbdist (bp, dst_rcpt)) return lose ("getbbdist failed: %s", getbberr ()); return OK;}/* */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)); }}/* */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"));}/* */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)); }}/* */static dst_lose (){ (void) sm_end (NOTOK);}/* *//* 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;}/* */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); }}/* *//* 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 = outbufstatic 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/* */#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/* */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;}/* */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;}/* *//* VARARGS3 */#ifdef MHMTS/* ARGSUSED */#endif MHMTSstatic 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}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -