1: #ifndef SPOP
   2: /* sbboards.c - MH style mailer to write to a ZOTnet BBoard */
   3: #else   SPOP
   4: /* spop.c - MH style mailer to write to a POP subscriber */
   5: #endif	SPOP
   6: 
   7: #ifndef SPOP
   8: 
   9: /* This program acts like the MMDF ch_bboards channel: it does local
  10:    delivery to a ZOTnet BBoard and/or addition re-distribution to other
  11:    recipients of the BBoard.  This program can function both as a SendMail
  12:    mailer and an MH .mh_receive file, depending on whether SENDMTS or
  13:    MHMTS is set.  Currently, the MHMTS version of this program does not do
  14:    re-distribution.
  15: 
  16:    This program should be used ONLY if you have "bboards on" set in your
  17:    MH configuration, and if you have "mts sendmail" or "mts mh" set as well.
  18:  */
  19: 
  20: #else   SPOP
  21: 
  22: /* This program acts like the MMDF-II ch_pop channel: it does local
  23:    delivery for non-local users.  These users are known as POP subscribers
  24:    and use the Post Office Protocol with a POP server in order to access
  25:    their maildrop.
  26:  */
  27: 
  28: #endif	SPOP
  29: 
  30: #undef  DISTRIBUTE
  31: #ifdef  SENDMTS
  32: #ifndef SPOP
  33: #define DISTRIBUTE
  34: #endif	not SPOP
  35: #endif	SENDMTS
  36: 
  37: #include "../h/mh.h"
  38: #ifndef SPOP
  39: #include "../h/addrsbr.h"
  40: #endif	not SPOP
  41: #include "../h/dropsbr.h"
  42: #include "../zotnet/bboards.h"
  43: #include "../zotnet/tws.h"
  44: #include <stdio.h>
  45: #include "../zotnet/mts.h"
  46: #include <pwd.h>
  47: #ifndef SYS5
  48: #include <sysexits.h>
  49: #else   SYS5
  50: #define EX_CANTCREAT    1
  51: #define EX_IOERR    1
  52: #define EX_NOINPUT  1
  53: #define EX_NOUSER   1
  54: #define EX_OK       0
  55: #define EX_OSERR    1
  56: #define EX_OSFILE   1
  57: #define EX_UNAVAILABLE  1
  58: #define EX_USAGE    1
  59: #endif	SYS5
  60: #ifdef  DISTRIBUTE
  61: #include "../mts/sendmail/smail.h"
  62: #endif	DISTRIBUTE
  63: 
  64: 
  65: #define NBB 100
  66: 
  67: #ifndef SPOP
  68: #define ENTITY  "bboard"
  69: #else   SPOP
  70: #define ENTITY  "subscriber"
  71: #endif	SPOP
  72: 
  73: /*  */
  74: 
  75: static int  bb_fderr;
  76: 
  77: static int  bb_uid;
  78: static int  bb_gid;
  79: 
  80: int    dst_rcpt ();
  81: 
  82: 
  83: #ifndef SPOP
  84: static char bb_from[BUFSIZ];
  85: static char bb_head[BUFSIZ];
  86: static char bb_home[BUFSIZ];
  87: static char bb_time[BUFSIZ];
  88: #ifdef  DISTRIBUTE
  89: static char bb_rept[BUFSIZ];
  90: #endif	DISTRIBUTE
  91: #else   SPOP
  92: #define bb_head NULLCP
  93: #endif	SPOP
  94: 
  95: static struct bboard  *bb[NBB];
  96: 
  97: 
  98: long    lseek ();
  99: 
 100: #ifdef  SYS5
 101: struct passwd  *getpwnam ();
 102: #endif	SYS5
 103: 
 104: /*  */
 105: 
 106: /* ARGSUSED */
 107: 
 108: main (argc, argv, envp)
 109: int     argc;
 110: char  **argv,
 111:       **envp;
 112: {
 113:     int     fd;
 114:     char    tmpfil[BUFSIZ];
 115: 
 116: #ifdef  MHMTS
 117:     if (argc != 5)
 118:     adios (EX_USAGE, NULL, "you lose really big");
 119: #endif	MHMTS
 120:     arginit (argv);
 121: 
 122:     fd = copyfile (fileno (stdin), tmpfil);
 123:     (void) unlink (tmpfil);
 124: 
 125:     localmail (fd);
 126: #ifdef  DISTRIBUTE
 127:     distribute (fd);
 128:     notify (fd);
 129: #endif	DISTRIBUTE
 130: 
 131:     exit (EX_OK);
 132: }
 133: 
 134: /*  */
 135: 
 136: static  localmail (fd)
 137: int     fd;
 138: {
 139:     int     i,
 140:             md;
 141:     register struct bboard  *bp;
 142: 
 143:     for (i = 0; bp = bb[i]; i++)
 144:     if (bp -> bb_file && *bp -> bb_file) {
 145:         (void) lseek (fd, 0L, 0);
 146: #ifndef SPOP
 147:         if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, BBMODE))
 148: #else   SPOP
 149:         if ((md = mbx_open (bp -> bb_file, bb_uid, bb_gid, POMODE))
 150: #endif	SPOP
 151:             == NOTOK) {
 152:         (void) lose ("unable to open %s", bp -> bb_file);
 153:         continue;
 154:         }
 155: #ifndef SPOP
 156:         if (mbx_init (bp) != NOTOK)
 157: #endif	not SPOP
 158:         (void) mbx_copy (bp -> bb_file, md, fd, 1, bb_head, 0);
 159:         (void) mbx_close (bp -> bb_file, md);
 160:     }
 161: }
 162: 
 163: /*  */
 164: 
 165: #ifndef SPOP
 166: static int  mbx_init (bp)
 167: register struct bboard  *bp;
 168: {
 169:     int     fd,
 170:         clear;
 171:     register struct bboard  *ip;
 172:     register FILE *fp;
 173: 
 174:     if ((fd = mbx_Xopen (bp -> bb_info, bb_uid, bb_gid, BBMODE, &clear))
 175:         == NOTOK)
 176:     return lose ("unable to lock and open %s", bp -> bb_info);
 177:     if ((fp = fdopen (fd, "w")) == NULL) {
 178:         (void) mbx_close (bp -> bb_info, fd);
 179:     return lose ("unable to fdopen %s", bp -> bb_info);
 180:     }
 181: 
 182:     if ((ip = getbbnam (bp -> bb_name)) == NULL) {
 183:     (void) lkfclose (fp, bp -> bb_info);
 184:     return lose ("unable to get information on BBoard %s", bp -> bb_name);
 185:     }
 186:     (void) strcpy (bb_time, dtimenow ());
 187:     (void) sprintf (bb_head, "BBoard-ID: %d\nBB-Posted: %s\n",
 188:         bp -> bb_maxima = ++ip -> bb_maxima, bb_time);
 189: 
 190:     fprintf (fp, "%d\n%s\n", bp -> bb_maxima, bb_time);
 191:     (void) lkfclose (fp, bp -> bb_info);
 192: 
 193:     return OK;
 194: }
 195: #endif	not SPOP
 196: 
 197: /*  */
 198: 
 199: #ifdef  DISTRIBUTE
 200: static  distribute (fd)
 201: int     fd;
 202: {
 203:     int     i;
 204:     register struct bboard  *bp;
 205: 
 206:     for (i = 0; bp = bb[i]; i++)
 207:     if (bp -> bb_dist && *bp -> bb_dist)
 208:         break;
 209:     if (bp == NULL)
 210:     return;
 211: 
 212:     if (dst_init () == NOTOK) {
 213:     dst_lose ();
 214:     return;
 215:     }
 216:     for (i = 0; bp = bb[i]; i++)
 217:     if (bp -> bb_dist && *bp -> bb_dist)
 218:         if (dst_adrs (bp) == NOTOK) {
 219:         dst_lose ();
 220:         return;
 221:         }
 222:     if (dst_text (fd) == NOTOK || dst_end () == NOTOK)
 223:     dst_lose ();
 224: }
 225: 
 226: /*  */
 227: 
 228: static int  dst_init ()
 229: {
 230:     int     retval;
 231: 
 232:     if (rp_isbad (retval = sm_init (NULLCP, NULLCP, 0, 0, 0))
 233:         || rp_isbad (retval = sm_winit (S_MAIL, bb_from)))
 234:     return lose ("problem initializing SendMail; %s",
 235:         rp_string (retval));
 236: 
 237:     return OK;
 238: }
 239: 
 240: /*  */
 241: 
 242: static int  dst_adrs (bp)
 243: register struct bboard  *bp;
 244: {
 245:     if (getbbdist (bp, dst_rcpt))
 246:     return lose ("getbbdist failed: %s", getbberr ());
 247: 
 248:     return OK;
 249: }
 250: 
 251: /*  */
 252: 
 253: static int  dst_rcpt (mbox, host)
 254: register char   *mbox,
 255:         *host;
 256: {
 257:     int     retval;
 258: 
 259:     switch (retval = sm_wadr (mbox, host, NULLCP)) {
 260:     case RP_OK:
 261:         return OK;
 262: 
 263:     case RP_NO:
 264:     case RP_USER:
 265:         (void) lose ("%s@%s: loses; %s", mbox, host, rp_string (retval));
 266:         return OK;      /* fail-soft */
 267: 
 268:     default:
 269:         return lose ("%s@%s: unexpected response; %s",
 270:             mbox, host, rp_string (retval));
 271:     }
 272: }
 273: 
 274: /*  */
 275: 
 276: static int  dst_text (fd)
 277: int     fd;
 278: {
 279:     int     i,
 280:             retval;
 281:     char    buffer[BUFSIZ];
 282: 
 283:     if (rp_isbad (retval = sm_waend ()))
 284:     return lose ("problem ending addresses; %s", rp_string (retval));
 285: 
 286:     (void) lseek (fd, 0L, 0);
 287:     while ((i = read (fd, buffer, sizeof buffer)) > 0)
 288:     if (rp_isbad (retval = sm_wtxt (buffer, i)))
 289:         return lose ("problem writing text; %s", rp_string (retval));
 290: 
 291:     return (i != NOTOK ? OK : lose ("error reading from file"));
 292: }
 293: 
 294: /*  */
 295: 
 296: static int  dst_end ()
 297: {
 298:     int     retval;
 299: 
 300:     switch (retval = sm_wtend ()) {
 301:     case RP_OK:
 302:         (void) sm_end (OK);
 303:         return OK;
 304: 
 305:     case RP_NO:
 306:     case RP_NDEL:
 307:         return lose ("posting failed; %s", rp_string (retval));
 308: 
 309:     default:
 310:         return lose ("unexpected response; %s", rp_string (retval));
 311:     }
 312: }
 313: 
 314: /*  */
 315: 
 316: static  dst_lose ()
 317: {
 318:     (void) sm_end (NOTOK);
 319: }
 320: 
 321: /*  */
 322: 
 323: /* VARARGS1 */
 324: 
 325: static int  lose (fmt, a, b, c, d)
 326: char   *fmt,
 327:        *a,
 328:        *b,
 329:        *c,
 330:        *d;
 331: {
 332:     int     fd,
 333:             i;
 334:     char   *bp,
 335:         buffer[BUFSIZ];
 336: 
 337:     if (bb_fderr == NOTOK) {
 338:     if ((fd = open ("/dev/null", 0)) == NOTOK)
 339:         adios (EX_OSERR, "/dev/null", "unable to open");
 340:     bb_fderr = copyfile (fd, bb_rept);
 341:     }
 342: 
 343:     (void) sprintf (bp = buffer, fmt, a, b, c, d);
 344:     bp += strlen (bp);
 345:     bp += strlen (strcpy(bp, "\n"));
 346:     i = bp - buffer;
 347:     if (write (bb_fderr, buffer, i) != i)
 348:     adios (EX_IOERR, bb_rept, "error writing");
 349: 
 350:     return NOTOK;
 351: }
 352: 
 353: /*  */
 354: 
 355: static  notify (fd)
 356: int     fd;
 357: {
 358:     int     i;
 359:     char    buffer[BUFSIZ];
 360: 
 361:     if (bb_fderr == NOTOK)
 362:     return;
 363: 
 364:     if (rp_isbad (sm_init (NULLCP, NULLCP, 0, 0, 0))
 365:         || rp_isbad (sm_winit (S_MAIL, bb_from)))
 366:     goto sm_err;
 367: 
 368:     switch (sm_wadr (bb_from, NULLCP, NULLCP)) {
 369:     case RP_OK:
 370:         for (i = 0; bb[i]; i++) {
 371:         (void) sprintf (buffer, "local-%s-request", bb[i] -> bb_name);
 372:         (void) sm_wadr (buffer, LocalName (), NULLCP);
 373:         }
 374:         break;
 375: 
 376:     default:
 377:         goto sm_err;
 378:     }
 379: 
 380:     if (rp_isbad (sm_waend ()))
 381:     goto sm_err;
 382: 
 383:     (void) sprintf (buffer,
 384:         "Date: %s\nFrom: %s\nTo: %s\nSubject: BBoards Failure\n\n",
 385:         dtimenow (), bb_from, bb_from);
 386:     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
 387:     goto sm_err;
 388: 
 389:     for (i = 0; bb[i]; i++) {
 390:     (void) sprintf (buffer, "BBoard %s\n", bb[i] -> bb_name);
 391:     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
 392:         goto sm_err;
 393:     }
 394: 
 395:     (void) lseek (bb_fderr, 0L, 0);
 396:     while ((i = read (bb_fderr, buffer, sizeof buffer)) > 0)
 397:     if (rp_isbad (sm_wtxt (buffer, i)))
 398:         goto sm_err;
 399: 
 400:     (void) strcpy (buffer, "\n------- Forwarded Message\n\n");
 401:     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))) || encap (fd) == NOTOK)
 402:     goto sm_err;
 403:     (void) strcpy (buffer, "\n------- End of Forwarded Message\n\n");
 404:     if (rp_isbad (sm_wtxt (buffer, strlen (buffer))))
 405:     goto sm_err;
 406: 
 407:     switch (sm_wtend ()) {
 408:     case RP_OK:
 409:         (void) unlink (bb_rept);
 410:         (void) sm_end (OK);
 411:         return;
 412: 
 413:     default:
 414:     sm_err: ;
 415:         adios (EX_UNAVAILABLE, NULLCP,
 416:             "failed and unable to post advisory, see %s for details",
 417:             bb_rept);
 418:     }
 419: }
 420: 
 421: /*  */
 422: 
 423: /* very similar to sbr/cpydgst.c */
 424: 
 425: #define S1  0
 426: #define S2  1
 427: 
 428: #define output(c)   if (bp >= dp) flush (), *bp++ = c; else *bp++ = c
 429: #define flush()     if ((j = bp - outbuf) \
 430:                 && rp_isbad (sm_wtxt (outbuf, j))) \
 431:                 return NOTOK; \
 432:             else \
 433:                 bp = outbuf
 434: 
 435: static int  encap (fd)
 436: register int    fd;
 437: {
 438:     register int    i,
 439:                     state;
 440:     register char  *cp,
 441:                    *ep;
 442:     char    buffer[BUFSIZ];
 443:     register int    j;
 444:     register char  *bp,
 445:                    *dp;
 446:     char    outbuf[BUFSIZ];
 447: 
 448:     (void) lseek (fd, 0L, 0);
 449: 
 450:     dp = (bp = outbuf) + sizeof outbuf;
 451:     for (state = S1; (i = read (fd, buffer, sizeof buffer)) > 0;)
 452:     for (ep = (cp = buffer) + i; cp < ep; cp++) {
 453:         if (*cp == NULL)
 454:         continue;
 455:         switch (state) {
 456:         case S1:
 457:             if (*cp == '-') {
 458:             output ('-');
 459:             output (' ');
 460:             }
 461:             state = S2; /* fall */
 462: 
 463:         case S2:
 464:             output (*cp);
 465:             if (*cp == '\n')
 466:             state = S1;
 467:             break;
 468:         }
 469:     }
 470: 
 471:     if (i == NOTOK)
 472:     return NOTOK;
 473:     flush ();
 474: 
 475:     return OK;
 476: }
 477: #endif	DISTRIBUTE
 478: 
 479: /*  */
 480: 
 481: #ifndef DISTRIBUTE
 482: /* VARARGS1 */
 483: 
 484: static int  lose (fmt, a, b, c, d)
 485: char   *fmt,
 486:        *a,
 487:        *b,
 488:        *c,
 489:        *d;
 490: {
 491:     adios (EX_UNAVAILABLE, NULLCP, fmt, a, b, c, d);/* NOTREACHED */
 492: }
 493: #endif	not DISTRIBUTE
 494: 
 495: /*  */
 496: 
 497: static  arginit (vec)
 498: register char  **vec;
 499: {
 500:     register int    i;
 501: #ifdef  MHMTS
 502:     register char  *ap;
 503: #endif	MHMTS
 504:     char    addr[BUFSIZ];
 505:     register struct bboard *bp;
 506:     register struct passwd *pw;
 507: 
 508:     invo_name = r1bindex (*vec++, '/');
 509:     m_foil (NULLCP);
 510:     mts_init (invo_name);
 511: 
 512: #ifndef SPOP
 513:     if ((pw = getpwnam (BBOARDS)) == NULL)
 514:     adios (EX_OSFILE, NULLCP, "no entry for ~%s", BBOARDS);
 515: #else   SPOP
 516:     if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1))
 517:     adios (EX_OSFILE, NULLCP, "%s", pw ? getbberr () : "POP user-id unknown");
 518: #endif	SPOP
 519: 
 520:     if (pw -> pw_uid != geteuid ())
 521: #ifndef SPOP
 522:     adios (EX_OSERR, NULLCP, "not running setuid to %s", BBOARDS);
 523: #else   SPOP
 524:     adios (EX_OSERR, NULLCP, "not running setuid to %s", POPUID);
 525: #endif	SPOP
 526: 
 527:     bb_uid = pw -> pw_uid;
 528:     bb_gid = pw -> pw_gid;
 529: #ifndef SPOP
 530:     (void) strcpy (bb_from, adrsprintf (pw -> pw_name, LocalName ()));
 531:     (void) strcpy (bb_home, pw -> pw_dir);
 532: #endif	not SPOP
 533: 
 534: #ifdef  MHMTS
 535:     vec += 3;
 536: #endif	MHMTS
 537:     if (*vec == NULL)
 538:     adios (EX_USAGE, NULLCP, "usage: %s %s [%s ...]",
 539:         invo_name, ENTITY, ENTITY);
 540: 
 541:     for (i = 0; *vec; vec++) {
 542: #ifdef  MHMTS
 543:     if (ap = index (*vec, '.'))
 544:         *vec = ++ap;
 545: #endif	MHMTS
 546:     make_lower (addr, *vec);
 547: 
 548:     if ((bp = getbbnam (addr)) == NULL
 549:         && (bp = getbbaka (addr)) == NULL)
 550:         adios (EX_NOUSER, NULLCP, "no such %s as %s", ENTITY, *vec);
 551:     if ((bb[i++] = getbbcpy (bp)) == NULL)
 552:         adios (EX_UNAVAILABLE, NULLCP, "insufficient memory on %s", *vec);
 553: 
 554:     if (i >= NBB - 1)
 555:         adios (EX_USAGE, NULLCP, "too many %ss, starting with %s",
 556:             ENTITY, *vec);
 557:     }
 558:     bb[i] = NULL;
 559: 
 560:     (void) umask (0022);
 561: 
 562:     bb_fderr = NOTOK;
 563: }
 564: 
 565: /*  */
 566: 
 567: static int  copyfile (qd, tmpfil)
 568: int     qd;
 569: register char   *tmpfil;
 570: {
 571:     int     i,
 572:             fd;
 573:     char    buffer[BUFSIZ];
 574: 
 575:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
 576:     if ((fd = creat (tmpfil, 0600)) == NOTOK)
 577:     adios (EX_CANTCREAT, tmpfil, "unable to create");
 578:     (void) close (fd);
 579:     if ((fd = open (tmpfil, 2)) == NOTOK)
 580:     adios (EX_NOINPUT, tmpfil, "unable to re-open");
 581: 
 582:     (void) lseek (qd, 0L, 0);
 583:     while ((i = read (qd, buffer, sizeof buffer)) > 0)
 584:     if (write (fd, buffer, i) != i)
 585:         adios (EX_IOERR, tmpfil, "error writing");
 586:     if (i == NOTOK)
 587:     adios (EX_IOERR, "input", "error reading");
 588: 
 589:     (void) lseek (fd, 0L, 0);
 590: 
 591:     return fd;
 592: }
 593: 
 594: /*  */
 595: 
 596: /* VARARGS3 */
 597: 
 598: #ifdef  MHMTS
 599: /* ARGSUSED */
 600: #endif	MHMTS
 601: 
 602: static  void adios (code, what, fmt, a, b, c, d, e, f)
 603: int     code;
 604: char   *what,
 605:        *fmt,
 606:        *a,
 607:        *b,
 608:        *c,
 609:        *d,
 610:        *e,
 611:        *f;
 612: {
 613:     advise (what, fmt, a, b, c, d, e, f);
 614: #ifdef  SENDMTS
 615:     done (code);
 616: #endif	SENDMTS
 617: #ifdef  MHMTS
 618:     done (1);
 619: #endif	MHMTS
 620: }

Defined functions

adios defined in line 602; used 17 times
arginit defined in line 497; used 1 times
copyfile defined in line 567; used 2 times
distribute defined in line 200; used 1 times
dst_adrs defined in line 242; used 1 times
dst_end defined in line 296; used 1 times
dst_init defined in line 228; used 1 times
dst_lose defined in line 316; used 3 times
dst_rcpt defined in line 253; used 2 times
dst_text defined in line 276; used 1 times
encap defined in line 435; used 1 times
localmail defined in line 136; used 1 times
lose defined in line 484; used 13 times
main defined in line 108; never used
mbx_init defined in line 166; used 1 times
notify defined in line 355; used 1 times

Defined variables

bb defined in line 95; used 9 times
bb_fderr defined in line 75; used 7 times
bb_from defined in line 84; used 6 times
bb_gid defined in line 78; used 4 times
bb_head defined in line 85; never used
bb_home defined in line 86; used 1 times
bb_rept defined in line 89; used 4 times
bb_time defined in line 87; used 3 times
bb_uid defined in line 77; used 4 times

Defined macros

DISTRIBUTE defined in line 33; used 6 times
ENTITY defined in line 70; used 4 times
EX_CANTCREAT defined in line 50; used 1 times
EX_IOERR defined in line 51; used 3 times
EX_NOINPUT defined in line 52; used 1 times
EX_NOUSER defined in line 53; used 1 times
EX_OK defined in line 54; used 1 times
EX_OSERR defined in line 55; used 3 times
EX_OSFILE defined in line 56; used 2 times
EX_UNAVAILABLE defined in line 57; used 3 times
EX_USAGE defined in line 58; used 3 times
NBB defined in line 65; used 2 times
S1 defined in line 425; used 2 times
S2 defined in line 426; used 1 times
bb_head defined in line 92; used 2 times
flush defined in line 429; used 2 times
output defined in line 428; used 3 times
Last modified: 1986-02-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2096
Valid CSS Valid XHTML 1.0 Strict