2 /* bb_wtmail.c - write mail to a BBoard */
4 /* po_wtmail.c - write mail for a POP subscriber */
7 static char Id[] = "@(#)$Id: po_wtmail.c,v 1.3 1993/08/25 17:43:26 jromine Exp $";
23 #define submitopts "vmth%s*"
25 #define submitopts "vkmth%s*"
29 #define RP_NOPE RP_AOK
31 #define MBXMODE BBMODE
33 #define RP_NOPE RP_USER
35 #define MBXMODE sentprotect
37 extern int sentprotect;
52 char bbrdaddr[LINESIZE],
59 extern char *qu_msgfile,
76 char *index (), *rindex (), *sprintf ();
77 struct passwd *getpwnam ();
89 ll_log (logptr, LLOGBTR, "bb_init(chanptr=%s)", chanptr -> ch_name);
92 chnlname = chanptr -> ch_name;
94 sprintf (chnlinfo, submitopts, chnlname);
95 #else notdef /* the following is probably a BAD idea */
96 if (chanptr -> ch_host == NULL)
97 chnlinfo[0] = NULL; /* local delivery ONLY */
99 sprintf (chnlinfo, submitopts, chanptr -> ch_host);
103 if ((pw = getpwnam (BBOARDS)) == NULL)
104 err_abrt (RP_BHST, "no passwd entry for '%s'", BBOARDS);
106 if ((pw = getpwnam (POPUID)) == NULL)
107 err_abrt (RP_BHST, "no passwd entry for '%s'", POPUID);
110 bbrduid = pw -> pw_uid;
111 bbrdgid = pw -> pw_gid;
113 if (isstr (locmachine))
114 sprintf (bbrdfrom, "%s@%s.%s.%s", pw -> pw_name, locmachine, locname,
117 sprintf (bbrdfrom, "%s@%s.%s", pw -> pw_name, locname, locdomain);
119 ll_log (logptr, LLOGGEN, "distributing as '%s'", bbrdfrom);
121 sprintf (bbrdhome, pw -> pw_dir);
126 err_abrt (RP_BHST, "setbbent() failed");
128 if (!setpwinfo (pw, POPDB, 1))
129 err_abrt (RP_BHST, "setbbinfo(%s, %s, 1) failed",
130 pw -> pw_name, POPDB);
135 err_abrt (RP_BHST, "not running as root");
145 ll_log (logptr, LLOGBTR, "bb_end(result=0%o)", result);
155 ll_log (logptr, LLOGBTR, "bb_sbinit()");
164 ll_log (logptr, LLOGBTR, "bb_sbend()");
172 bb_winit (info, sender)
177 ll_log (logptr, LLOGBTR, "bb_winit(info='%s',sender='%s')",
203 ll_log (logptr, LLOGBTR, "bb_wtadr(host=%s,adr=%s)", host, adr);
206 if ((cp = index (adr, '@')) != NULL)
208 make_lower (adr, adr);
209 if ((curbb = getbbnam (adr)) == NULL)
212 if (isstr (locmachine))
213 sprintf (bbrdaddr, "local-%s-request@%s.%s.%s", curbb -> bb_name,
214 locmachine, locname, locdomain);
216 sprintf (bbrdaddr, "local-%s-request@%s.%s", curbb -> bb_name, locname,
220 ll_log (logptr, LLOGGEN, "=> BBoard %s: file='%s' info='%s'",
221 curbb -> bb_name, curbb -> bb_file, curbb -> bb_info);
224 if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
227 ll_log (logptr, LLOGGEN, "begin local delivery...");
229 printx ("\r\nperforming local delivery to file %s...\n",
234 if ((md = mbx_open (curbb -> bb_file, bbrduid, bbrdgid, MBXMODE)) == NOTOK)
238 if (rp_isbad (result = mbx_init ())) {
239 mbx_close (curbb -> bb_file, md);
244 pos = (long) lseek (md, (off_t)0, 1);
245 count = strlen (delim1);
246 if (write (md, delim1, count) != count) {
247 ll_log (logptr, LLOGTMP, "error writing delim1");
251 start = (long) lseek (md, (off_t)0, 1);
255 count = strlen (bbrdheader);
256 if (write (md, bbrdheader, count) != count) {
257 ll_log (logptr, LLOGTMP, "error writing BBoard information");
261 for (cp = bbrdheader; *cp; cp++, size++)
267 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
270 (offset = strindex (delim1, buffer)) >= 0;
274 (offset = strindex (delim2, buffer)) >= 0;
277 if (write (md, buffer, len) != len) {
278 ll_log (logptr, LLOGTMP, "error writing to file '%s'",
283 for (offset = 0, cp = buffer; offset < len; offset++, size++)
289 ll_log (logptr, LLOGTMP, "error reading from message file '%s'",
293 stop = (long) lseek (md, (off_t)0, 1);
294 count = strlen (delim2);
295 if (write (md, delim2, count) != count)
296 ll_log (logptr, LLOGTMP, "error writing delim2");
297 map_write (curbb -> bb_file, md, curbb -> bb_maxima, start, stop, pos,
300 ll_log (logptr, LLOGGEN, "end local delivery...");
304 mbx_close (curbb -> bb_file, md);
306 result = mbx_close (curbb -> bb_file, md);
308 return (result != NOTOK ? RP_OK : RP_FIO);
318 ll_log (logptr, LLOGBTR, "bb_txtcpy()");
321 if (curbb -> bb_dist == NULL
322 || *curbb -> bb_dist == NULL
323 || chnlinfo[0] == NULL)
326 ll_log (logptr, LLOGGEN, "begin distribution...");
328 if (curbb -> bb_file == NULL || *curbb -> bb_file == NULL)
330 printx("\rperforming remote distribution\n");
332 if (rp_isbad (result = dist_init ())
333 || rp_isbad (result = dist_adrs ())
334 || rp_isbad (result = dist_text ())
335 || rp_isbad (result = dist_end ()))
336 return dist_lose (result);
338 ll_log (logptr, LLOGGEN, "end distribution...");
344 printx ("\rmessage distributed\n");
353 /* **************** (dist_) BBOARD DISTRIBUTION **************** */
359 struct rp_bufstruct reply;
363 ll_log (logptr, LLOGBTR, "dist_init()");
366 if (rp_isbad (result = mm_init ()))
367 return ds_log (result, LLOGFAT, "mm_init() failed [%s]",
369 if (rp_isbad (result = mm_sbinit ()))
370 return ds_log (result, LLOGFAT, "mm_sbinit() failed [%s]",
372 if (rp_isbad (result = mm_winit (chnlname, chnlinfo, bbrdaddr)))
373 return ds_log (result, LLOGFAT,
374 "mm_winit('%s','%s','%s') failed [%s]",
375 chnlname, chnlinfo, bbrdaddr, rp_valstr (result));
377 if (rp_isbad (result = mm_rrply (&reply, &len)))
378 return ds_log (result, LLOGFAT, "problem with sender address [%s]",
392 ll_log (logptr, LLOGBTR, "dist_adrs()");
395 if (getbbdist (curbb, ds_address))
396 return ds_log (RP_NO, LLOGTMP, "getbbdist failed: %s", getbberr ());
398 if (rp_isbad (result = mm_waend ()))
399 return ds_log (result, LLOGFAT, "mm_waend() failed [%s]",
407 ds_address (addr, host)
408 char *addr, /* local part */
413 struct rp_bufstruct reply;
416 ll_log (logptr, LLOGBTR, "ds_address(addr='%s',host='%s')", addr, host);
419 printx ("\rperforming distribution to %s@%s...\n", addr, host);
420 if (rp_isbad (result = mm_wadr (host, addr))) {
421 ds_log (result, LLOGFAT, "mm_wadr('%s','%s') failed [%s]",
422 host, addr, rp_valstr (result));
425 if (rp_isbad (result = mm_rrply (&reply, &len))) {
426 ds_log (result, LLOGFAT,
427 "mm_rrply() failed [%s] getting status of '%s@%s'",
428 rp_valstr (result), addr, host);
432 switch (rp_gval (reply.rp_val)) {
438 ll_log (logptr, LLOGGEN, "address '%s@%s' [%s] -- %s",
439 addr, host, rp_valstr (reply.rp_val), reply.rp_line);
451 ds_log (reply.rp_val, LLOGTMP, "address '%s@%s' [%s] -- %s",
452 addr, host, rp_valstr (reply.rp_val), reply.rp_line);
453 return OK; /* fail-soft */
456 ds_log (reply.rp_val, LLOGFAT, "unexpected reply [%s] -- %s",
457 rp_valstr (reply.rp_val), reply.rp_line);
471 ll_log (logptr, LLOGBTR, "dist_text()");
476 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
478 if (rp_isbad (result = mm_wtxt (buffer, len)))
479 return ds_log (result, LLOGFAT, "mm_wtxt() failed [%s]",
483 return ds_log (RP_FIO, LLOGTMP,
484 "error reading from message file '%s'", qu_msgfile);
486 if (rp_isbad (result = mm_wtend ()))
487 return ds_log (result, LLOGFAT, "mm_wtend() failed [%s]",
499 struct rp_bufstruct reply;
502 ll_log (logptr, LLOGBTR, "dist_end()");
505 if (rp_isbad (result = mm_rrply (&reply, &len)))
506 return ds_log (result, LLOGFAT,
507 "mm_rrply() failed [%s] getting final status",
510 switch (rp_gval (reply.rp_val)) {
514 ll_log (logptr, LLOGGEN, "message [%s] -- %s",
515 rp_valstr (reply.rp_val), reply.rp_line);
525 return ds_log (RP_NO, LLOGTMP, "not delivered [%s] -- %s",
526 rp_valstr (reply.rp_val), reply.rp_line);
529 return ds_log (RP_RPLY, LLOGFAT,
530 "unexpected final reply [%s] -- %s",
531 rp_valstr (reply.rp_val), reply.rp_line);
546 ll_log (logptr, LLOGBTR, "dist_lose(result=0%o)", result);
551 printx ("\rerrors during distribution: ");
553 (void) fflush (stdout);
554 (void) sprintf (intro, "bboards%d distribution for %s failed [%s]\n",
555 getpid (), curbb -> bb_name, rp_valstr (result));
556 if (loseaux (bbrdaddr, bbrdfrom, intro) != OK
557 && loseaux (bbrdfrom, (char *) 0, intro) != OK) {
558 printx ("unable to post advisory.\n");
559 ll_log (logptr, LLOGFAT, "unable to post failure notice");
560 if (err_fd != NOTOK) {
561 (void) lseek (err_fd, (off_t)0, 0);
562 if ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
564 if (cp = index (buffer, '\n'))
566 ll_log (logptr, LLOGFAT, "info: %s", buffer);
569 if (loseaux (supportaddr, (char *) 0, intro) != NOTOK)
570 ll_log (logptr, LLOGFAT, "unable to advise %s of failure!",
574 printx ("advisory posted.\n");
576 (void) fflush (stdout);
578 if (err_fd != NOTOK) {
587 int loseaux (to, cc, intro)
595 if (ml_init (NO, NO, sitesignature, "Re-distribution Failure") != OK
596 || ml_adr (to) != OK)
598 if (cc && (ml_cc () != OK || ml_adr (cc) != OK))
600 if (ml_aend () != OK || ml_tinit () != OK)
604 if (err_fd != NOTOK) {
605 lseek (err_fd, (off_t)0, 0);
606 while ((i = read (err_fd, buffer, sizeof buffer)) > 0) {
618 /* very similar to sbr/cpydgst.c */
623 #define output(c) if (bp >= dp) {flush (); *bp++ = c;} else *bp++ = c
624 #define flush() if (bp - outbuf) \
625 *bp = NULL, ml_txt (outbuf), bp = outbuf
641 dp = (bp = outbuf) + sizeof outbuf;
643 for (state = S1, len = BUFSIZ;
644 rp_gval (result = qu_rtxt (buffer, &len)) == RP_OK;
646 for (ep = (cp = buffer) + len; cp < ep; cp++) {
653 ml_txt ("\n------- Forwarded Message\n\n");
659 state = S2; /* fall */
663 ml_txt ("\n------- Forwarded Message\n\n");
676 ll_log (logptr, LLOGTMP, "error reading message when noting failure");
678 ml_txt ("\n------- End of Forwarded Message\n\n");
679 ml_txt ("[ error reading message ]\n");
683 ml_txt ("\n------- End of Forwarded Message\n\n");
685 ll_log (logptr, LLOGTMP, "message empty when noting failure");
686 ml_txt ("[ message empty ]\n");
694 ds_log (result, level, fmt, a, b, c, d, e)
708 ll_log (logptr, level, fmt, a, b, c, d, e);
710 sprintf (buffer, fmt, a, b, c, d, e);
711 strcat (buffer, "\n");
713 printx ("\rerror: %s", buffer);
715 if (err_fd == NOTOK) {
716 unlink (mktemp (strcpy (tmpfil, "/tmp/bboardsXXXXXX")));
717 if ((err_fd = creat (tmpfil, 0600)) == NOTOK)
720 if ((err_fd = open (tmpfil, 2)) == NOTOK)
723 lseek (err_fd, (off_t)0, 0);
726 write (err_fd, buffer, i);
734 /* mbx_ local mailbox routines */
743 if ((fd = mbx_Xopen (curbb -> bb_info, bbrduid, bbrdgid, MBXMODE, &clear))
745 if (errno == ETXTBSY) {
746 printx ("\runable to lock %s\n", curbb -> bb_info);
747 ll_err (logptr, LLOGTMP, "unable to lock %s",
751 printx ("\runable to open '%s'", curbb -> bb_info);
752 ll_log (logptr, LLOGTMP, "unable to open '%s'", curbb -> bb_info);
755 if ((fp = fdopen (fd, "w")) == (FILE *) NULL) {
756 printx ("\runable to fdopen '%s'", curbb -> bb_info);
757 ll_err (logptr, LLOGTMP, "unable to fdopen '%s'", curbb -> bb_info);
758 mbx_close (curbb -> bb_info, fd);
762 strcpy (name, curbb -> bb_name);
763 if ((curbb = getbbnam (name)) == (struct bboard *) NULL) {
764 printx ("\runable to get information on BBoard %s\n", name);
765 ll_err (logptr, LLOGFAT, "unable to get info on %s", name);
766 lkfclose (fp, curbb -> bb_info);
769 sprintf (bbrdheader, "BBoard-ID: %d\nBB-Posted: %s\n",
770 ++curbb -> bb_maxima, cnvtdate (TIMREG, bbrdtime));
771 fprintf (fp, "%d\n%s\n", curbb -> bb_maxima, bbrdtime);
773 lkfclose (fp, curbb -> bb_info);