home *** CD-ROM | disk | FTP | other *** search
- #ifndef POP
- /* bb_wtmail.c - write mail to a BBoard */
- #else /* POP */
- /* po_wtmail.c - write mail for a POP subscriber */
- #endif /* POP */
-
-
- #include "util.h"
- #include "mmdf.h"
- #include "bboards.h"
- #include "cnvtdate.h"
- #include "ch.h"
- #include "phs.h"
- #include <pwd.h>
- #include <sys/stat.h>
-
- /* */
-
- #ifndef RP_DOK
- #define submitopts "vmth%s*"
- #else /* RP_DOK */
- #define submitopts "vkmth%s*"
- #endif /* RP_DOK */
-
- #ifndef POP
- #define RP_NOPE RP_AOK
-
- #define MBXMODE BBMODE
- #else /* POP */
- #define RP_NOPE RP_USER
-
- #define MBXMODE sentprotect
-
- extern int sentprotect;
- #endif /* POP */
-
-
- int err_fd = NOTOK;
-
- int ds_address ();
-
- extern int errno;
-
- int bbrduid, bbrdgid;
-
- char *chnlname,
- chnlinfo[LINESIZE];
- #ifndef POP
- char bbrdaddr[LINESIZE],
- bbrdfrom[LINESIZE],
- bbrdheader[LINESIZE],
- bbrdhome[LINESIZE],
- bbrdtime[LINESIZE];
- #endif /* not POP */
-
- extern char *qu_msgfile,
- *delim1,
- *delim2,
- *lckdfldir,
- *locfullmachine,
- *locfullname,
- *sitesignature,
- *supportaddr;
-
- struct bboard *curbb;
-
- extern LLog *logptr;
-
- FILE *lk_fopen();
-
- long lseek ();
- char *index (), *rindex ();
- #ifdef SYS5
- int sprintf ();
- #else
- char *sprintf ();
- #endif
- struct passwd *getpwnam ();
-
- /* */
-
- bb_init (chanptr)
- Chan * chanptr;
- {
- int uid,
- eid;
- struct passwd *pw;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_init(chanptr=%s)", chanptr -> ch_name);
- #endif
-
- chnlname = chanptr -> ch_name;
- #ifndef notdef
- sprintf (chnlinfo, submitopts, chnlname);
- #else /* notdef /* the following is probably a BAD idea */
- if (chanptr -> ch_host == NULL)
- chnlinfo[0] = NULL; /* local delivery ONLY */
- else
- sprintf (chnlinfo, submitopts, chanptr -> ch_host);
- #endif /* notdef */
-
- #ifndef POP
- if ((pw = getpwnam (BBOARDS)) == NULL)
- err_abrt (RP_BHST, "no passwd entry for '%s'", BBOARDS);
- #else /* POP */
- if ((pw = getpwnam (POPUID)) == NULL)
- err_abrt (RP_BHST, "no passwd entry for '%s'", POPUID);
- #endif /* POP */
-
- bbrduid = pw -> pw_uid;
- bbrdgid = pw -> pw_gid;
- #ifndef POP
- if (isstr (locfullmachine))
- sprintf (bbrdfrom, "%s@%s", pw -> pw_name, locfullmachine);
- else
- sprintf (bbrdfrom, "%s@%s", pw -> pw_name, locfullname);
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "distributing as '%s'", bbrdfrom);
- #endif
- sprintf (bbrdhome, pw -> pw_dir);
- #endif /* not POP */
-
- #ifndef POP
- if (!setbbent ())
- err_abrt (RP_BHST, "setbbent() failed");
- #else /* POP */
- if (!setpwinfo (pw, POPDB, 1))
- err_abrt (RP_BHST, "setbbinfo(%s, %s, 1) failed",
- pw -> pw_name, POPDB);
- #endif /* POP */
-
- getwho (&uid, &eid);
- if (eid != 0)
- err_abrt (RP_BHST, "not running as root");
-
- return RP_OK;
- }
-
-
- bb_end (result)
- short result;
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_end(result=0%o)", result);
- #endif
-
- return RP_OK;
- }
-
- /* */
-
- bb_sbinit () {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_sbinit()");
- #endif
-
- return RP_OK;
- }
-
-
- bb_sbend () {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_sbend()");
- #endif
-
- return RP_OK;
- }
-
- /* */
-
- bb_winit (info, sender)
- char *info,
- *sender;
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_winit(info='%s',sender='%s')",
- info, sender);
- #endif
-
- return RP_OK;
- }
-
- /* */
-
- bb_wtadr (host, adr)
- char *host,
- *adr;
- {
- short count,
- result;
- int len,
- md,
- offset,
- size;
- long start,
- stop,
- pos;
- char *cp,
- buffer[BUFSIZ];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_wtadr(host=%s,adr=%s)", host, adr);
- #endif
-
- if ((cp = index (adr, '@')) != NULL)
- *cp = NULL;
- make_lower (adr, adr);
- if ((curbb = getbbnam (adr)) == NULL)
- return RP_USER;
- #ifndef POP
- if (isstr (locfullmachine))
- sprintf(bbrdaddr,"local-%s-request@%s", curbb->bb_name, locfullmachine);
- else
- sprintf(bbrdaddr,"local-%s-request@%s", curbb->bb_name, locfullname);
- #endif /* not POP */
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "=> BBoard %s: file='%s' info='%s'",
- curbb -> bb_name, curbb -> bb_file, curbb -> bb_info);
- #endif
-
- if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
- return RP_NOPE;
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "begin local delivery...");
- #endif
- printx ("\r\nperforming local delivery to file %s...\n",
- curbb -> bb_file);
-
- qu_rtinit (0L);
-
- if ((md = mbx_open (curbb -> bb_file, bbrduid, bbrdgid, MBXMODE)) == NOTOK)
- return RP_FIO;
-
- #ifndef POP
- if (rp_isbad (result = mbx_init ())) {
- mbx_close (curbb -> bb_file, md);
- return result;
- }
- #endif /* not POP */
-
- pos = lseek (md, 0L, 1);
- count = strlen (delim1);
- if (write (md, delim1, count) != count) {
- ll_log (logptr, LLOGTMP, "error writing delim1");
- result = NOTOK;
- goto clean_up;
- }
- start = lseek (md, 0L, 1);
- size = 0;
-
- #ifndef POP
- count = strlen (bbrdheader);
- if (write (md, bbrdheader, count) != count) {
- ll_log (logptr, LLOGTMP, "error writing BBoard information");
- result = NOTOK;
- goto clean_up;
- }
- for (cp = bbrdheader; *cp; cp++, size++)
- if (*cp == '\n')
- size++;
- #endif /* not POP */
-
- for (len = BUFSIZ;
- rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
- len = BUFSIZ) {
- for (offset = 0;
- (offset = strindex (delim1, buffer)) >= 0;
- buffer[offset]++)
- continue;
- for (offset = 0;
- (offset = strindex (delim2, buffer)) >= 0;
- buffer[offset]++)
- continue;
- if (write (md, buffer, len) != len) {
- ll_log (logptr, LLOGTMP, "error writing to file '%s'",
- curbb -> bb_file);
- result = NOTOK;
- goto clean_up;
- }
- for (offset = 0, cp = buffer; offset < len; offset++, size++)
- if (*cp++ == '\n')
- size++;
- }
-
- if (result < 0)
- ll_log (logptr, LLOGTMP, "error reading from message file '%s'",
- qu_msgfile);
- clean_up: ;
-
- stop = lseek (md, 0L, 1);
- count = strlen (delim2);
- if (write (md, delim2, count) != count)
- ll_log (logptr, LLOGTMP, "error writing delim2");
- map_write (curbb -> bb_file, md, curbb -> bb_maxima, start, stop, pos,
- size, 0);
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "end local delivery...");
- #endif
-
- if (result < 0)
- mbx_close (curbb -> bb_file, md);
- else
- result = mbx_close (curbb -> bb_file, md);
-
- return (result != NOTOK ? RP_OK : RP_FIO);
- }
-
- /* */
-
- bb_txtcpy () {
- #ifndef POP
- short result;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "bb_txtcpy()");
- #endif
-
- if (curbb -> bb_dist == NULL
- || *curbb -> bb_dist == NULL
- || chnlinfo[0] == NULL)
- return RP_MOK;
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "begin distribution...");
- #endif
- if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
- printx ("\r\n");
- printx("\rperforming remote distribution\n");
-
- if (rp_isbad (result = dist_init ())
- || rp_isbad (result = dist_adrs ())
- || rp_isbad (result = dist_text ())
- || rp_isbad (result = dist_end ()))
- return dist_lose (result);
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "end distribution...");
- #endif
-
- if (err_fd != NOTOK)
- dist_lose (RP_MOK);
- else
- printx ("\rmessage distributed\n");
- #endif /* not POP */
-
- return RP_MOK;
- }
-
- /* */
-
- #ifndef POP
- /* **************** (dist_) BBOARD DISTRIBUTION **************** */
-
- dist_init () {
- short result;
- #ifdef RP_NS
- int len;
- struct rp_bufstruct reply;
- #endif /* RP_NS */
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dist_init()");
- #endif
-
- if (rp_isbad (result = mm_init ()))
- return ds_log (result, LLOGFAT, "mm_init() failed [%s]",
- rp_valstr (result));
- if (rp_isbad (result = mm_sbinit ()))
- return ds_log (result, LLOGFAT, "mm_sbinit() failed [%s]",
- rp_valstr (result));
- if (rp_isbad (result = mm_winit (chnlname, chnlinfo, bbrdaddr)))
- return ds_log (result, LLOGFAT,
- "mm_winit('%s','%s','%s') failed [%s]",
- chnlname, chnlinfo, bbrdaddr, rp_valstr (result));
- #ifdef RP_NS
- if (rp_isbad (result = mm_rrply (&reply, &len)))
- return ds_log (result, LLOGFAT, "problem with sender address [%s]",
- rp_valstr (result));
- #endif /* RP_NS */
-
- return result;
- }
-
- /* */
-
- dist_adrs ()
- {
- short result;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dist_adrs()");
- #endif
-
- if (getbbdist (curbb, ds_address))
- return ds_log (RP_NO, LLOGTMP, "getbbdist failed: %s", getbberr ());
-
- if (rp_isbad (result = mm_waend ()))
- return ds_log (result, LLOGFAT, "mm_waend() failed [%s]",
- rp_valstr (result));
-
- return result;
- }
-
- /* */
-
- ds_address (addr, host)
- char *addr, /* local part */
- *host; /* rest */
- {
- short result;
- int len;
- struct rp_bufstruct reply;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "ds_address(addr='%s',host='%s')", addr, host);
- #endif
-
- printx ("\rperforming distribution to %s@%s...\n", addr, host);
- if (rp_isbad (result = mm_wadr (host, addr))) {
- ds_log (result, LLOGFAT, "mm_wadr('%s','%s') failed [%s]",
- host, addr, rp_valstr (result));
- return NOTOK;
- }
- if (rp_isbad (result = mm_rrply (&reply, &len))) {
- ds_log (result, LLOGFAT,
- "mm_rrply() failed [%s] getting status of '%s@%s'",
- rp_valstr (result), addr, host);
- return NOTOK;
- }
-
- switch (rp_gval (reply.rp_val)) {
- case RP_AOK:
- #ifdef RP_DOK
- case RP_DOK:
- #endif /* RP_DOK */
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "address '%s@%s' [%s] -- %s",
- addr, host, rp_valstr (reply.rp_val), reply.rp_line);
- #endif
- return OK;
-
- case RP_NO:
- #ifdef RP_NS
- case RP_NS:
- #endif /* RP_NS */
- case RP_USER:
- case RP_NDEL:
- case RP_AGN:
- case RP_NOOP:
- ds_log (reply.rp_val, LLOGTMP, "address '%s@%s' [%s] -- %s",
- addr, host, rp_valstr (reply.rp_val), reply.rp_line);
- return OK; /* fail-soft */
-
- default:
- ds_log (reply.rp_val, LLOGFAT, "unexpected reply [%s] -- %s",
- rp_valstr (reply.rp_val), reply.rp_line);
- return NOTOK;
- }
- }
-
- /* */
-
- dist_text ()
- {
- short result;
- int len;
- char buffer[BUFSIZ];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dist_text()");
- #endif
-
- qu_rtinit (0L);
- for (len = BUFSIZ;
- rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
- len = BUFSIZ)
- if (rp_isbad (result = mm_wtxt (buffer, len)))
- return ds_log (result, LLOGFAT, "mm_wtxt() failed [%s]",
- rp_valstr (result));
-
- if (result < 0)
- return ds_log (RP_FIO, LLOGTMP,
- "error reading from message file '%s'", qu_msgfile);
-
- if (rp_isbad (result = mm_wtend ()))
- return ds_log (result, LLOGFAT, "mm_wtend() failed [%s]",
- rp_valstr (result));
-
- return result;
- }
-
- /* */
-
- dist_end ()
- {
- short result;
- int len;
- struct rp_bufstruct reply;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dist_end()");
- #endif
-
- if (rp_isbad (result = mm_rrply (&reply, &len)))
- return ds_log (result, LLOGFAT,
- "mm_rrply() failed [%s] getting final status",
- rp_valstr (result));
-
- switch (rp_gval (reply.rp_val)) {
- case RP_OK:
- case RP_MOK:
- #ifdef DEBUG
- ll_log (logptr, LLOGGEN, "message [%s] -- %s",
- rp_valstr (reply.rp_val), reply.rp_line);
- #endif
- mm_sbend ();
- mm_end (OK);
- return result;
-
- case RP_NO:
- case RP_NDEL:
- case RP_AGN:
- case RP_NOOP:
- return ds_log (RP_NO, LLOGTMP, "not delivered [%s] -- %s",
- rp_valstr (reply.rp_val), reply.rp_line);
-
- default:
- return ds_log (RP_RPLY, LLOGFAT,
- "unexpected final reply [%s] -- %s",
- rp_valstr (reply.rp_val), reply.rp_line);
- }
- }
-
- /* */
-
- dist_lose (result)
- short result;
- {
- int i;
- char *cp,
- intro[BUFSIZ],
- buffer[BUFSIZ];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dist_lose(result=0%o)", result);
- #endif /* DEBUG */
-
- mm_end (NOTOK);
-
- printx ("\rerrors during distribution: ");
- if (domsg)
- (void) fflush (stdout);
- (void) sprintf (intro, "bboards%d distribution for %s failed [%s]\n",
- getpid (), curbb -> bb_name, rp_valstr (result));
- if (loseaux (bbrdaddr, bbrdfrom, intro) != OK
- && loseaux (bbrdfrom, (char *) 0, intro) != OK) {
- printx ("unable to post advisory.\n");
- ll_log (logptr, LLOGFAT, "unable to post failure notice");
- if (err_fd != NOTOK) {
- (void) lseek (err_fd, 0L, 0);
- if ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
- buffer[i] = NULL;
- if (cp = index (buffer, '\n'))
- *cp = NULL;
- ll_log (logptr, LLOGFAT, "info: %s", buffer);
- }
- }
- if (loseaux (supportaddr, (char *) 0, intro) != NOTOK)
- ll_log (logptr, LLOGFAT, "unable to advise %s of failure!",
- supportaddr);
- }
- else
- printx ("advisory posted.\n");
- if (domsg)
- (void) fflush (stdout);
-
- if (err_fd != NOTOK) {
- close (err_fd);
- err_fd = NOTOK;
- }
- return RP_MOK;
- }
-
- /* */
-
- int loseaux (to, cc, intro)
- char *to,
- *cc,
- *intro;
- {
- int i;
- char buffer[BUFSIZ];
-
- if (ml_init (NO, NO, sitesignature, "Re-distribution Failure") != OK
- || ml_adr (to) != OK)
- return NOTOK;
- if (cc && (ml_cc () != OK || ml_adr (cc) != OK))
- return NOTOK;
- if (ml_aend () != OK || ml_tinit () != OK)
- return NOTOK;
-
- ml_txt (intro);
- if (err_fd != NOTOK) {
- lseek (err_fd, 0L, 0);
- while ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
- buffer[i] = NULL;
- ml_txt (buffer);
- }
- }
- encap ();
-
- return ml_end (OK);
- }
-
- /* */
-
- /* 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 (bp - outbuf) \
- *bp = NULL, ml_txt (outbuf), bp = outbuf
-
- static encap () {
- register int state;
- short result;
- int len,
- init;
- register char *cp,
- *ep;
- char buffer[BUFSIZ];
- register char *bp,
- *dp;
- char outbuf[BUFSIZ];
-
- qu_rtinit (0L);
-
- dp = (bp = outbuf) + sizeof outbuf;
- init = 0;
- for (state = S1, len = BUFSIZ;
- rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
- len = BUFSIZ)
- for (ep = (cp = buffer) + len; cp < ep; cp++) {
- if (*cp == NULL)
- continue;
- switch (state) {
- case S1:
- if (*cp == '-') {
- if (init == 0) {
- ml_txt ("\n------- Forwarded Message\n\n");
- init++;
- }
- output ('-');
- output (' ');
- }
- state = S2; /* fall */
-
- case S2:
- if (init == 0) {
- ml_txt ("\n------- Forwarded Message\n\n");
- init++;
- }
- output (*cp);
- if (*cp == '\n')
- state = S1;
- break;
- }
- }
-
- flush ();
-
- if (result < 0) {
- ll_log (logptr, LLOGTMP, "error reading message when noting failure");
- if (init)
- ml_txt ("\n------- End of Forwarded Message\n\n");
- ml_txt ("[ error reading message ]\n");
- }
- else
- if (init)
- ml_txt ("\n------- End of Forwarded Message\n\n");
- else {
- ll_log (logptr, LLOGTMP, "message empty when noting failure");
- ml_txt ("[ message empty ]\n");
- }
- }
-
- /* */
-
- /* VARARGS3 */
-
- ds_log (result, level, fmt, a, b, c, d, e)
- short result;
- int level;
- char *fmt,
- *a,
- *b,
- *c,
- *d,
- *e;
- {
- int i;
- char buffer[BUFSIZ],
- tmpfil[BUFSIZ];
-
- ll_log (logptr, level, fmt, a, b, c, d, e);
-
- sprintf (buffer, fmt, a, b, c, d, e);
- strcat (buffer, "\n");
-
- printx ("\rerror: %s", buffer);
-
- if (err_fd == NOTOK) {
- unlink (mktemp (strcpy (tmpfil, "/tmp/bboardsXXXXXX")));
- if ((err_fd = creat (tmpfil, 0600)) == NOTOK)
- return result;
- close (err_fd);
- if ((err_fd = open (tmpfil, 2)) == NOTOK)
- return result;
- unlink (tmpfil);
- lseek (err_fd, 0L, 0);
- }
- i = strlen (buffer);
- write (err_fd, buffer, i);
-
- return result;
- }
- #endif /* not POP */
-
- /* */
-
- /* mbx_ local mailbox routines */
-
- #ifndef POP
- mbx_init () {
- int fd,
- clear;
- char name[BUFSIZ];
- FILE * fp;
-
- if ((fd = mbx_Xopen (curbb -> bb_info, bbrduid, bbrdgid, MBXMODE, &clear))
- == NOTOK) {
- if (errno == ETXTBSY) {
- printx ("\runable to lock %s\n", curbb -> bb_info);
- ll_err (logptr, LLOGTMP, "unable to lock %s",
- curbb -> bb_info);
- return RP_LOCK;
- }
- printx ("\runable to open '%s'", curbb -> bb_info);
- ll_log (logptr, LLOGTMP, "unable to open '%s'", curbb -> bb_info);
- return RP_FOPN;
- }
- if ((fp = fdopen (fd, "w")) == (FILE *) NULL) {
- printx ("\runable to fdopen '%s'", curbb -> bb_info);
- ll_err (logptr, LLOGTMP, "unable to fdopen '%s'", curbb -> bb_info);
- mbx_close (curbb -> bb_info, fd);
- return RP_LIO;
- }
-
- strcpy (name, curbb -> bb_name);
- if ((curbb = getbbnam (name)) == (struct bboard *) NULL) {
- printx ("\runable to get information on BBoard %s\n", name);
- ll_err (logptr, LLOGFAT, "unable to get info on %s", name);
- lkfclose (fp, curbb -> bb_info);
- return RP_LIO;
- }
- sprintf (bbrdheader, "BBoard-ID: %d\nBB-Posted: %s\n",
- ++curbb -> bb_maxima, cnvtdate (TIMREG, bbrdtime));
- fprintf (fp, "%d\n%s\n", curbb -> bb_maxima, bbrdtime);
-
- lkfclose (fp, curbb -> bb_info);
-
- return RP_OK;
- }
- #endif /* not POP */
-