Annotation of 43BSD/contrib/mh/uip/spop.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.