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

1.1       root        1: /* bbc.c - ZOTnet BBoard checker */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include "../zotnet/bboards.h"
                      5: #include <stdio.h>
                      6: #ifdef BPOP
                      7: #include "../zotnet/mts.h"
                      8: #endif BPOP
                      9: #include <errno.h>
                     10: #include <signal.h>
                     11: #ifndef        sigmask
                     12: #define        sigmask(s)      (1 << ((s) - 1))
                     13: #endif not sigmask
                     14: #include <sys/types.h>
                     15: #include <sys/stat.h>
                     16: #ifdef SIGTSTP
                     17: #include <sys/wait.h>
                     18: #include <sys/time.h>
                     19: #include <sys/resource.h>
                     20: #endif SIGTSTP
                     21: 
                     22: 
                     23: #define        RCFILE  ".bbrc"
                     24: 
                     25: #define        NBB     100
                     26: 
                     27: /*  */
                     28: 
                     29: static struct swit switches[] = {
                     30: #define        TOPICSW 0
                     31:     "topics", 6,
                     32: #define        CHECKSW 1
                     33:     "check", 5,
                     34: #define        READSW  2
                     35:     "read", 4,
                     36: 
                     37: #define        QUIETSW 3
                     38:     "quiet", 4,
                     39: #define        VERBOSW 4
                     40:     "verbose", 4,
                     41: 
                     42: #define ARCHSW 5
                     43:     "archive", 4,
                     44: #define NOARCH  6
                     45:     "noarchive", 3,
                     46: 
                     47: #define        PROTSW  7
                     48:     "protocol", 4,
                     49: #define        NPROTSW 8
                     50:     "noprotocol", 3,
                     51: 
                     52: #define        PROGSW  9
                     53:     "mshproc program", 4,
                     54: 
                     55: #define        RCSW    10
                     56:     "rcfile rcfile", 4,
                     57: #define        NRCSW   11
                     58:     "norcfile", 3,
                     59: 
                     60: #define        FILESW  12
                     61:     "file BBoardsfile", 4,
                     62: #define        USERSW  13
                     63:     "user BBoardsuser", 4,
                     64: 
                     65: #define        HOSTSW  14
                     66:     "host host",
                     67: #ifndef        BPOP
                     68:     -4,
                     69: #else  BPOP
                     70:     4,
                     71: #endif BPOP
                     72: #define        RPOPSW  15
                     73:     "rpop",
                     74: #ifndef        RPOP
                     75:        -4,
                     76: #else  RPOP
                     77:        4,
                     78: #endif RPOP
                     79: #define        NRPOPSW 16
                     80:     "norpop",
                     81: #ifndef        RPOP
                     82:        -6,
                     83: #else  RPOP
                     84:        6,
                     85: #endif RPOP
                     86: 
                     87: #define        HELPSW  17
                     88:     "help", 4,
                     89: 
                     90:     NULL, NULL
                     91: };
                     92: 
                     93: struct bbcount {
                     94:     char   *key;
                     95:     int     count;
                     96:     struct bbcount *left;
                     97:     struct bbcount *right;
                     98: };
                     99: 
                    100: /*  */
                    101: 
                    102: extern int  errno;
                    103: 
                    104: static int  changed = 0;
                    105: static int  quitting = 0;
                    106: 
                    107: static int  archivesw = 0;
                    108: static int  checksw = 0;
                    109: static int  protsw = 1;
                    110: static int  quietsw = 0;
                    111: static int  readsw = 0;
                    112: static int  topicsw = 0;
                    113: static int  verbosw = 0;
                    114: 
                    115: static int  didpop = OK;
                    116: static int  rpop = 1;
                    117: static char *user = BBOARDS;
                    118: static char *host = NULL;
                    119: #ifdef BPOP
                    120: extern char response[];
                    121: 
                    122: char   *getusr (), **getip ();
                    123: #endif BPOP
                    124: 
                    125: int    sigser (), action ();
                    126: #ifdef SIGTSTP
                    127: int    tstpid;
                    128: int    tstpser ();
                    129: #endif SIGTSTP
                    130: 
                    131: static char *rcfile;
                    132: 
                    133: 
                    134: static struct bbcount  *bbc = NULL;
                    135: static struct bboard   *bbl = NULL;
                    136: 
                    137: struct bbcount *add_count (), *seek_count ();
                    138: struct bboard *getbbaux (), *getbbvis ();
                    139: 
                    140: /*  */
                    141: 
                    142: /* ARGSUSED */
                    143: 
                    144: main (argc, argv)
                    145: int     argc;
                    146: char  **argv;
                    147: {
                    148:     int            bbp = 0,
                    149:            vecp = 1;
                    150:     char   *cp,
                    151:           *rc,
                    152:           **ap,
                    153:           **argp,
                    154:             buffer[80],
                    155:            *arguments[MAXARGS],
                    156:           *bbs[NBB + 1],
                    157:           *vec[MAXARGS];
                    158: 
                    159:     invo_name = r1bindex (argv[0], '/');
                    160: #ifdef BPOP
                    161:     mts_init (invo_name);
                    162:     if (popbbhost && *popbbhost)
                    163:        host = popbbhost;
                    164:     if (popbbuser && *popbbuser)
                    165:        user = popbbuser, rpop = 0;
                    166: #endif BPOP
                    167:     if ((cp = m_find (invo_name)) != NULL) {
                    168:        ap = brkstring (cp = getcpy (cp), " ", "\n");
                    169:        ap = copyip (ap, arguments);
                    170:     }
                    171:     else
                    172:        ap = arguments;
                    173:     (void) copyip (argv + 1, ap);
                    174:     argp = arguments;
                    175: 
                    176:     (void) setbbent (SB_STAY);
                    177: 
                    178: /*  */
                    179: 
                    180:     while (cp = *argp++) {
                    181:        if (*cp == '-')
                    182:            switch (smatch (++cp, switches)) {
                    183:                case AMBIGSW: 
                    184:                    ambigsw (cp, switches);
                    185:                    done (1);
                    186:                case UNKWNSW: 
                    187:                   vec[vecp++] = --cp;
                    188:                   continue;
                    189:                case HELPSW: 
                    190:                    (void) sprintf (buffer,
                    191:                        "%s [bboards ...] [switches] [switches for mshproc]",
                    192:                        invo_name);
                    193:                    help (buffer, switches);
                    194:                    done (1);
                    195: 
                    196:                case TOPICSW: 
                    197:                    topicsw++;
                    198:                    checksw = readsw = 0;
                    199:                    continue;
                    200:                case CHECKSW: 
                    201:                    checksw++;
                    202:                    readsw = topicsw = 0;
                    203:                    continue;
                    204:                case READSW: 
                    205:                    readsw++;
                    206:                    checksw = topicsw = 0;
                    207:                    continue;
                    208: 
                    209:                case ARCHSW: 
                    210:                    archivesw++;
                    211:                    continue;
                    212:                case NOARCH: 
                    213:                    archivesw = 0;
                    214:                    continue;
                    215: 
                    216:                case PROTSW: 
                    217:                    protsw++;
                    218:                    continue;
                    219:                case NPROTSW: 
                    220:                    protsw = 0;
                    221:                    continue;
                    222: 
                    223:                case QUIETSW: 
                    224:                    quietsw++;
                    225:                    verbosw = 0;
                    226:                    continue;
                    227:                case VERBOSW: 
                    228:                    verbosw++;
                    229:                    quietsw = 0;
                    230:                    continue;
                    231: 
                    232:                case PROGSW:
                    233:                    if (!(mshproc = *argp++) || *mshproc == '-')
                    234:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    235:                    continue;
                    236: 
                    237:                case RCSW:
                    238:                    if (!(rc = *argp++) || *rc == '-')
                    239:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    240:                    continue;
                    241:                case NRCSW:
                    242:                    rc = NULL;
                    243:                    continue;
                    244: 
                    245:                case FILESW:
                    246:                    if (!(cp = *argp++) || *cp == '-')
                    247:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    248:                    if (!setbbinfo (user, cp, 1))
                    249:                        adios (NULLCP, "setbbinfo(%s, %s, 1) failed -- %s",
                    250:                                user, cp, getbberr ());
                    251:                    continue;
                    252:                case USERSW:
                    253:                    if (!(user = *argp++) || *user == '-')
                    254:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    255:                    continue;
                    256: 
                    257:                case HOSTSW:
                    258:                    if (!(host = *argp++) || *host == '-')
                    259:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    260:                    didpop = NOTOK;
                    261:                    continue;
                    262:                case RPOPSW:
                    263:                    rpop++;
                    264:                    continue;
                    265:                case NRPOPSW:
                    266:                    rpop = 0;
                    267:                    continue;
                    268:            }
                    269:        if (bbp < NBB)
                    270:            bbs[bbp++] = cp;
                    271:        else
                    272:            adios (NULLCP, "too many bboards, starting with %s", cp);
                    273:     }
                    274:     bbs[bbp] = NULL;
                    275: 
                    276: /*  */
                    277: 
                    278: #ifdef BPOP
                    279:     if (!*host)
                    280:        host = NULL, didpop = OK;
                    281:     if (!host || !rpop)
                    282:        (void) setuid (getuid ());
                    283: #endif BPOP
                    284: 
                    285:     if (!m_find ("path"))
                    286:        free (path ("./", TFOLDER));
                    287: 
                    288:     rcinit (rc);
                    289: 
                    290:     for (bbp = 0; cp = bbs[bbp]; bbp++)
                    291:        add_bb (cp, NOTOK);
                    292: 
                    293:     if (topicsw)
                    294:        topics ();
                    295:     else {
                    296:        default_bboards ();
                    297:        if (checksw)
                    298:            check ();
                    299:        else
                    300:            process (vecp, vec);
                    301:     }
                    302: 
                    303: #ifdef BPOP
                    304:     if (didpop != OK && pop_quit () == NOTOK)
                    305:        adios (NULLCP, "%s", response);
                    306: #endif BPOP
                    307: 
                    308:     done (0);
                    309: }
                    310: 
                    311: /*  */
                    312: 
                    313: topics () {
                    314:     register char  *cp,
                    315:                   **ap;
                    316:     register struct bboard *bb;
                    317: 
                    318:     printf ("%16s %s   %s\n", "BBoard", "Items",
                    319:            verbosw ? "Interesting Facts" : "Last Update");
                    320:     printf ("%16s %s   %s\n", "------", "-----",
                    321:            verbosw ? "-----------------" : "-----------");
                    322: 
                    323:     for (bb = bbl ? bbl : getbbvis ();
                    324:            bb;
                    325:            bb = bbl ? bb -> bb_link : getbbvis ()) {
                    326:        printf ("%16s %5d   %s\n",
                    327:                bb -> bb_name, bb -> bb_maxima, bb -> bb_date);
                    328:        if (verbosw) {
                    329:            if (*bb -> bb_aka) {
                    330:                cp = NULL;
                    331:                for (ap = bb -> bb_aka; *ap; ap++)
                    332:                    cp = add (*ap, cp ? add (", ", cp) : cp);
                    333:                printv ("AKA", cp);
                    334:                free (cp);
                    335:            }
                    336: 
                    337:            printv ("Leaders", *bb -> bb_leader);
                    338:            for (ap = bb -> bb_leader + 1; *ap; ap++)
                    339:                printv (NULLCP, *ap);
                    340:            printv ("File", bb -> bb_file);
                    341:            printv ("Archive", bb -> bb_archive);
                    342:            printv ("Info", bb -> bb_info);
                    343:            printv ("Map", bb -> bb_map);
                    344:            printv ("Password", bb -> bb_passwd);
                    345:            if (strcmp (bb -> bb_name, bb -> bb_addr))
                    346:                printv ("Address", bb -> bb_addr);
                    347:            if (strcmp (*bb -> bb_leader, bb -> bb_request))
                    348:                printv ("Request", bb -> bb_request);
                    349:            if (*bb -> bb_relay)
                    350:                printv ("Relay", bb -> bb_relay);
                    351:            if (*bb -> bb_dist) {
                    352:                changed = 0;
                    353:                (void) getbbdist (bb, action);
                    354:                if (!changed)
                    355:                    printv ("Dist", "");
                    356:                if (cp = getbberr ())
                    357:                    printv ("Error", cp);
                    358:            }
                    359:            printb (bb -> bb_flags);
                    360:        }
                    361:     }
                    362: }
                    363: 
                    364: /*  */
                    365: 
                    366: printv (key, value)
                    367: register char   *key,
                    368:                *value;
                    369: {
                    370:     char    buffer[BUFSIZ];
                    371: 
                    372:     if (key)
                    373:        (void) sprintf (buffer, "%s: ", key);
                    374:     else
                    375:        buffer[0] = '\0';
                    376:     printf ("%*s%-*s", 25, "", 10, buffer);
                    377:     if (value && *value)
                    378:        printf ("%s", value);
                    379:     (void) putchar ('\n');
                    380: }
                    381: 
                    382: 
                    383: int     action (local, domain)
                    384: register char   *local,
                    385:                *domain;
                    386: {
                    387:     char    buffer[BUFSIZ];
                    388: 
                    389:     (void) sprintf (buffer, "%s@%s", local, domain);
                    390:     printv (changed++ ? NULL : "Dist", buffer);
                    391:     return 0;
                    392: }
                    393: 
                    394: 
                    395: printb (flags)
                    396: unsigned int flags;
                    397: {
                    398:     char buffer[BUFSIZ];
                    399: 
                    400:     printv ("Flags", sprintb (buffer, flags, BBITS));
                    401: }
                    402: 
                    403: /*  */
                    404: 
                    405: check () {
                    406: #define        grammar(a,b,c)  (a == 1 ? b : c)
                    407: #define        plural(d)       grammar(d, "", "s")
                    408: 
                    409:     int     diff;
                    410:     register struct bboard  *bb;
                    411: 
                    412:     for (bb = bbl; bb; bb = bb -> bb_link) {
                    413:        diff = bb -> bb_maxima - bb -> bb_count;
                    414:        if (quietsw) {
                    415:            if (diff > 0)
                    416:                printf ("%s -- %d item%s unseen\n",
                    417:                        bb -> bb_name, diff, plural (diff));
                    418:        }
                    419:        else
                    420:            if (bb -> bb_maxima == 0)
                    421:                printf ("%s -- empty\n", bb -> bb_name);
                    422:            else
                    423:                if (bb -> bb_count == 0)
                    424:                    printf ("%s -- %d item%sseen)\n",
                    425:                            bb -> bb_name, bb -> bb_maxima,
                    426:                            grammar (bb -> bb_maxima, " (un", "s (none "));
                    427:                else
                    428:                    if (diff <= 0)
                    429:                        printf ("%s -- %d item%s (all seen)\n",
                    430:                                bb -> bb_name, bb -> bb_maxima,
                    431:                                plural (bb -> bb_maxima));
                    432:                    else
                    433:                        printf ("%s -- %d item%s unseen\n",
                    434:                                bb -> bb_name, diff, plural (diff));
                    435:     }
                    436: }
                    437: 
                    438: /*  */
                    439: 
                    440: process (vecp, vec)
                    441: int    vecp;
                    442: char   *vec[];
                    443: {
                    444:     int     diff;
                    445: #ifdef SIGTSTP
                    446:     int            (*tstat) ();
                    447: #endif SIGTSTP
                    448:     register struct bboard *bb;
                    449: 
                    450:     vec[0] = r1bindex (mshproc, '/');
                    451: #ifdef SIGTSTP
                    452:     tstat = signal (SIGTSTP, tstpser);
                    453: #endif SIGTSTP
                    454: 
                    455:     for (bb = bbl; bb && !quitting; bb = bb -> bb_link) {
                    456:        diff = bb -> bb_maxima - bb -> bb_count;
                    457:        if (bb -> bb_maxima == 0) {
                    458:            if (!quietsw)
                    459:                printf ("%s -- empty\n", bb -> bb_name);
                    460:            continue;
                    461:        }
                    462:        else
                    463:            if (verbosw || archivesw || diff > 0)
                    464:                bbread (bb, vecp, vec);
                    465:            else
                    466:                if (!quietsw)
                    467:                    printf ("%s -- %d item%s (all seen)\n",
                    468:                            bb -> bb_name, bb -> bb_maxima,
                    469:                            plural (bb -> bb_maxima));
                    470: 
                    471:     };
                    472: 
                    473: #ifdef SIGTSTP
                    474:     (void) signal (SIGTSTP, tstat);
                    475: #endif SIGTSTP
                    476:     rcend ();
                    477: }
                    478: 
                    479: /*  */
                    480: 
                    481: #ifdef BPOP
                    482: /* ARGSUSED */
                    483: 
                    484: static int  xtnd1 (s)
                    485: char   *s;
                    486: {
                    487:     return OK;
                    488: }
                    489: #endif BPOP
                    490: 
                    491: /*  */
                    492: 
                    493: bbread (bb, vecp, vec)
                    494: register struct bboard  *bb;
                    495: int    vecp;
                    496: char   *vec[];
                    497: {
                    498:     int     child_id,
                    499:             pd[2];
                    500:     char    buf1[BUFSIZ],
                    501:             buf2[BUFSIZ],
                    502:             buf3[BUFSIZ];
                    503: #ifdef BPOP
                    504:     int            nmsgs,
                    505:            nbytes;
                    506:     char    buf4[BUFSIZ],
                    507:             buf5[BUFSIZ];
                    508: #endif BPOP
                    509:     struct stat st;
                    510: 
                    511: #ifdef BPOP
                    512:     if (bb -> bb_flags & BB_REMOTE) {
                    513:        if (pop_xtnd (xtnd1, "%s %s", archivesw ? "archive" : "bboards",
                    514:                        bb -> bb_name) == NOTOK) {
                    515:            advise (NULLCP, "%s", response);
                    516:            return;
                    517:        }
                    518:        if (pop_stat (&nmsgs, &nbytes) == NOTOK)
                    519:            adios (NULLCP, "%s", response);
                    520:        if (nmsgs == 0)
                    521:            return;
                    522:        if (pop_fd (buf4, buf5) == NOTOK)
                    523:            adios (NULLCP, "%s", response);
                    524:     }
                    525:     else
                    526: #endif BPOP
                    527:     if (stat (archivesw ? bb -> bb_archive : bb -> bb_file, &st) != NOTOK
                    528:            && st.st_size == 0)
                    529:        return;
                    530: 
                    531:     if (protsw) {
                    532:        if (pipe (pd) == NOTOK)
                    533:            adios ("pipe", "unable to");
                    534:        (void) sprintf (buf3, "%d", getpid ());
                    535:     }
                    536: 
                    537:     switch (child_id = fork ()) {
                    538:        case NOTOK: 
                    539:            adios ("fork", "unable to");
                    540: 
                    541:        case OK: 
                    542:            if (protsw) {
                    543:                (void) close (pd[0]);
                    544:                (void) sprintf (buf1, "%d", bb -> bb_count + 1);
                    545:                (void) sprintf (buf2, "%d", pd[1]);
                    546:                vec[vecp++] = "-idname";
                    547:                vec[vecp++] = bb -> bb_name;
                    548:                vec[vecp++] = "-idstart";
                    549:                vec[vecp++] = buf1;
                    550:                vec[vecp++] = "-idstop";
                    551:                vec[vecp++] = buf2;
                    552:                vec[vecp++] = "-idquit";
                    553:                vec[vecp++] = buf3;
                    554:            }
                    555: #ifdef BPOP
                    556:            if (bb -> bb_flags & BB_REMOTE) {
                    557:                vec[vecp++] = "-popread";
                    558:                vec[vecp++] = buf4;
                    559:                vec[vecp++] = "-popwrite";
                    560:                vec[vecp++] = buf5;
                    561:            }
                    562: #endif BPOP
                    563:            vec[vecp++] = archivesw ? bb -> bb_archive : bb -> bb_file;
                    564:            vec[vecp] = NULL;
                    565:            execvp (mshproc, vec);
                    566:            fprintf (stderr, "unable to exec ");
                    567:            perror (mshproc);
                    568:            _exit (-1);
                    569: 
                    570:        default: 
                    571: #ifdef SIGTSTP
                    572:            tstpid = child_id;
                    573: #endif SIGTSTP
                    574:            if (protsw) {
                    575:                (void) close (pd[1]);
                    576:                pgmread (pd[0], child_id, bb);
                    577:            }
                    578:            else
                    579:                (void) pidXwait (child_id, mshproc);
                    580:     }
                    581: }
                    582: 
                    583: /*  */
                    584: 
                    585: pgmread (pd, child_id, bb)
                    586: int     pd,
                    587:         child_id;
                    588: register struct bboard  *bb;
                    589: {
                    590:     int     i,
                    591:             j,
                    592:             n;
                    593:     int     (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
                    594:     char    buffer[BUFSIZ];
                    595:     struct bbcount *selected;
                    596: 
                    597:     estat = signal (SIGEMT, sigser);
                    598:     hstat = signal (SIGHUP, SIG_IGN);
                    599:     istat = signal (SIGINT, SIG_IGN);
                    600:     qstat = signal (SIGQUIT, SIG_IGN);
                    601:     tstat = signal (SIGTERM, sigser);
                    602: 
                    603:     while ((n = read (pd, buffer, sizeof buffer)) == NOTOK && errno == EINTR)
                    604:        continue;
                    605:     (void) close (pd);
                    606:     (void) pidXwait (child_id, mshproc);
                    607: 
                    608:     (void) signal (SIGEMT, estat);
                    609:     (void) signal (SIGHUP, hstat);
                    610:     (void) signal (SIGINT, istat);
                    611:     (void) signal (SIGQUIT, qstat);
                    612:     (void) signal (SIGTERM, tstat);
                    613: 
                    614:     if (n <= 0)
                    615:        return;
                    616:     if (sscanf (buffer, "%d %d", &i, &j) != 2 || i <= 0 || j <= 0)
                    617:        return;
                    618: 
                    619:     if ((selected = seek_count (bbc, bb -> bb_name)) == NULL) {
                    620:        bbc = add_count (bbc, bb -> bb_name, i);
                    621:        changed++;
                    622:     }
                    623:     else
                    624:        if (archivesw) {
                    625:            if (i > selected -> count) {
                    626:                selected -> count = i;
                    627:                changed++;
                    628:            }
                    629:        }
                    630:        else {
                    631:            if (bb -> bb_maxima > j && i >= j)/* bbl... */
                    632:                i = bb -> bb_maxima;
                    633:            if (i != selected -> count) {
                    634:                selected -> count = i;
                    635:                changed++;
                    636:            }
                    637:        }
                    638: }
                    639: 
                    640: 
                    641: /* ARGSUSED */
                    642: 
                    643: int    sigser (i)
                    644: int     i;
                    645: {
                    646: #ifndef        BSD42
                    647:     (void) signal (i, sigser);
                    648: #endif not BSD42
                    649:     quitting++;
                    650: }
                    651: 
                    652: /*  */
                    653: 
                    654: rcinit (rc)
                    655: register char  *rc;
                    656: {
                    657:     int     state;
                    658:     register char  *cp;
                    659:     char    key[NAMESZ],
                    660:             value[BUFSIZ];
                    661:     register FILE  *bbrc;
                    662: 
                    663:     if ((cp = rc ? rc : getenv ("MHBBRC")) && *cp) {
                    664:        rcfile = path (cp, TFILE);
                    665:        if (*cp != '/')
                    666:            (void) putenv ("MHBBRC", rcfile);
                    667:     }
                    668:     else
                    669:        rcfile = concat (mypath, "/", RCFILE, NULLCP);
                    670: 
                    671:     if ((bbrc = fopen (rcfile, "r")) == NULL)
                    672:        if (cp && *cp)
                    673:            adios (rcfile, "unable to read");
                    674:        else
                    675:            return;
                    676: 
                    677:     for (state = FLD;;) {
                    678:        switch (state = m_getfld (state, key, value, sizeof value, bbrc)) {
                    679:            case FLD: 
                    680:            case FLDEOF: 
                    681:                make_lower (key, key);
                    682:                bbc = add_count (bbc, key, atoi (value));
                    683:                if (state == FLDEOF)
                    684:                    break;
                    685:                continue;
                    686: 
                    687:            default: 
                    688:                admonish (NULLCP, "bad format: %s", rcfile);
                    689:            case FILEEOF:
                    690:                break;
                    691:        }
                    692: 
                    693:        break;
                    694:     }
                    695: 
                    696:     if (ferror (bbrc))
                    697:        admonish (rcfile, "error reading");
                    698:     (void) fclose (bbrc);
                    699: }
                    700: 
                    701: /*  */
                    702: 
                    703: rcend () {
                    704:     int     (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
                    705:     register FILE *bbrc;
                    706: 
                    707:     if (!changed)
                    708:        return;
                    709: 
                    710:     hstat = signal (SIGHUP, SIG_IGN);
                    711:     istat = signal (SIGINT, SIG_IGN);
                    712:     qstat = signal (SIGQUIT, SIG_IGN);
                    713:     tstat = signal (SIGTERM, SIG_IGN);
                    714: 
                    715:     if ((bbrc = fopen (rcfile, "w")) == NULL)
                    716:        adios (rcfile, "unable to write");
                    717:     rcput (bbrc, bbc);
                    718: 
                    719:     if (ferror (bbrc))
                    720:        adios (rcfile, "error writing");
                    721:     (void) fclose (bbrc);
                    722: 
                    723:     (void) signal (SIGHUP, hstat);
                    724:     (void) signal (SIGINT, istat);
                    725:     (void) signal (SIGQUIT, qstat);
                    726:     (void) signal (SIGTERM, tstat);
                    727: 
                    728:     changed = 0;
                    729: }
                    730: 
                    731: 
                    732: rcput (bbrc, p)
                    733: register FILE *bbrc;
                    734: register struct bbcount *p;
                    735: {
                    736:     if (p == NULL)
                    737:        return;
                    738: 
                    739:     fprintf (bbrc, "%s: %d\n", p -> key, p -> count);
                    740:     rcput (bbrc, p -> left);
                    741:     rcput (bbrc, p -> right);
                    742: }
                    743: 
                    744: /*  */
                    745: 
                    746: #ifdef SIGTSTP
                    747: static int  tstpser (sig)
                    748: int    sig;
                    749: {
                    750:     int            pid;
                    751:     union wait w;
                    752: 
                    753:     rcend ();
                    754: 
                    755:     while ((pid = wait3 (&w, WUNTRACED, (struct rusage *) 0)) != NOTOK
                    756:            && pid != tstpid)
                    757:        continue;
                    758: 
                    759:     (void) signal (SIGTSTP, SIG_DFL);
                    760: #ifdef BSD42
                    761:     (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
                    762: #endif BSD42
                    763: 
                    764:     (void) kill (getpid (), sig);
                    765: 
                    766: #ifdef BSD42
                    767:     (void) sigblock (sigmask (SIGTSTP));
                    768: #endif BSD42
                    769:     (void) signal (SIGTSTP, tstpser);
                    770: }
                    771: #endif SIGTSTP
                    772: 
                    773: /*  */
                    774: 
                    775: struct bbcount *add_count (p, w, i)
                    776: register struct bbcount *p;
                    777: register char   *w;
                    778: int     i;
                    779: {
                    780:     int     cond;
                    781: 
                    782:     if (p == NULL) {
                    783:        p = (struct bbcount *) malloc (sizeof *p);
                    784:        if (p == NULL)
                    785:            adios (NULLCP,"insufficient memory");
                    786:        p -> key = getcpy (w);
                    787:        p -> count = i;
                    788:        p -> left = p -> right = NULL;
                    789:     }
                    790:     else
                    791:        if ((cond = strcmp (w, p -> key)) < 0)
                    792:            p -> left = add_count (p -> left, w, i);
                    793:        else
                    794:            if (cond > 0)
                    795:                p -> right = add_count (p -> right, w, i);
                    796: 
                    797:     return p;
                    798: }
                    799: 
                    800: 
                    801: struct bbcount *seek_count (p, w)
                    802: register struct bbcount *p;
                    803: register char   *w;
                    804: {
                    805:     int     cond;
                    806: 
                    807:     if (p == NULL || (cond = strcmp (w, p -> key)) == 0)
                    808:        return p;
                    809:     else
                    810:        return seek_count (cond < 0 ? p -> left : p -> right, w);
                    811: }
                    812: 
                    813: /*  */
                    814: 
                    815: default_bboards () {
                    816:     register char  *cp,
                    817:                   **ap;
                    818: 
                    819:     if (bbl != NULL)
                    820:        return;
                    821: 
                    822:     if (!archivesw && ((cp = m_find ("bboards")) != NULL)) {
                    823: #ifndef        BPOP
                    824:        for (ap = brkstring (cp = getcpy (cp), " ", "\n"); *ap; ap++)
                    825: #else  BPOP
                    826:        for (ap = getip (cp); *ap; ap++)
                    827: #endif BPOP
                    828:            add_bb (*ap, OK);
                    829: #ifndef        BPOP
                    830:        free (cp);
                    831: #endif not BPOP
                    832:     }
                    833:     else
                    834:        add_bb ("system", NOTOK);
                    835: 
                    836:     if (bbl == NULL)
                    837:        done (1);
                    838: }
                    839: 
                    840: /*  */
                    841: 
                    842: add_bb (s, hush)
                    843: register char   *s;
                    844: int     hush;
                    845: {
                    846:     register struct bboard  *bb;
                    847:     static struct bboard   *tail = NULL;
                    848: 
                    849:     make_lower (s, s);
                    850:     if ((bb = getbbaux (s)) == NULL)
                    851:        if (hush == OK)
                    852:            return;
                    853:        else
                    854:            adios (NULLCP, "no such bboard as '%s'", s);
                    855: 
                    856:     if (tail != NULL)
                    857:        tail -> bb_link = bb;
                    858:     if (bbl == NULL)
                    859:        bbl = bb;
                    860:     tail = bb;
                    861: }
                    862: 
                    863: /*  */
                    864: 
                    865: #ifdef BPOP
                    866: static struct bboard   *Bhead = NULL;
                    867: static struct bboard   *Btail = NULL;
                    868: 
                    869: static int xtnd2 (s)
                    870: char   *s;
                    871: {
                    872:     int     maxima;
                    873:     char    name[BUFSIZ];
                    874:     register struct bboard *bb;
                    875: 
                    876:     if (sscanf (s, "%s %d", name, &maxima) != 2)
                    877:        adios (NULLCP, "XTND2 botch: %s", s);
                    878: 
                    879:     if ((bb = (struct bboard   *) calloc (1, sizeof *bb)) == NULL)
                    880:        adios (NULLCP, "insufficient memory");
                    881:     bb -> bb_name = getcpy (name);
                    882:     if ((bb -> bb_aka = (char **) calloc (1, sizeof *bb -> bb_aka)) == NULL)
                    883:        adios (NULLCP, "insufficient memory");
                    884:     *bb -> bb_aka = NULL;
                    885:     bb -> bb_file = bb -> bb_archive = bb -> bb_info = bb -> bb_map = "";
                    886:     bb -> bb_passwd = "";
                    887:     if ((bb -> bb_leader = (char **) calloc (1, sizeof *bb -> bb_leader))
                    888:            == NULL)
                    889:        adios (NULLCP, "insufficient memory");
                    890:     *bb -> bb_leader = NULL;
                    891:     bb -> bb_addr = bb -> bb_request = bb -> bb_relay = "";
                    892:     if ((bb -> bb_dist = (char **) calloc (1, sizeof *bb -> bb_dist)) == NULL)
                    893:        adios (NULLCP, "insufficient memory");
                    894:     *bb -> bb_dist = NULL;
                    895:     bb -> bb_flags = BB_REMOTE;
                    896:     bb -> bb_count = 0;
                    897:     bb -> bb_maxima = maxima;
                    898:     bb -> bb_date = "";
                    899:     bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL;
                    900: 
                    901:     if (Btail != NULL)
                    902:        Btail -> bb_chain = bb;
                    903:     if (Bhead == NULL)
                    904:        Bhead = bb;
                    905:     Btail = bb;
                    906: 
                    907:     return OK;
                    908: }
                    909: 
                    910: /*  */
                    911: 
                    912: static int xtnd3 (s)
                    913: char   *s;
                    914: {
                    915:     static int  bbs = 0;
                    916:     static struct bboard   *bb;
                    917: 
                    918:     switch (bbs++) {
                    919:        case 0: 
                    920:            for (bb = Bhead; bb; bb = bb -> bb_chain)
                    921:                if (strcmp (bb -> bb_name, s) == 0)
                    922:                    break;
                    923:            if (bb == NULL)
                    924:                adios (NULLCP, "XTND3 botch");
                    925: 
                    926:            free (bb -> bb_name);
                    927:            bb -> bb_name = getcpy (s);
                    928:            break;
                    929:        case 1: 
                    930:            if (bb -> bb_aka)
                    931:                free ((char *) bb -> bb_aka);
                    932:            bb -> bb_aka = getip (s);
                    933:            break;
                    934:        case 2: 
                    935:            bb -> bb_file = getcpy (s);
                    936:            break;
                    937:        case 3: 
                    938:            bb -> bb_archive = getcpy (s);
                    939:            break;
                    940:        case 4: 
                    941:            bb -> bb_info = getcpy (s);
                    942:            break;
                    943:        case 5: 
                    944:            bb -> bb_map = getcpy (s);
                    945:            break;
                    946:        case 6: 
                    947:            bb -> bb_passwd = getcpy (s);
                    948:            break;
                    949:        case 7: 
                    950:            if (bb -> bb_leader)
                    951:                free ((char *) bb -> bb_leader);
                    952:            bb -> bb_leader = getip (s);
                    953:            break;
                    954:        case 8: 
                    955:            bb -> bb_addr = getcpy (s);
                    956:            break;
                    957:        case 9: 
                    958:            bb -> bb_request = getcpy (s);
                    959:            break;
                    960:        case 10: 
                    961:            bb -> bb_relay = getcpy (s);
                    962:            break;
                    963:        case 11: 
                    964:            if (bb -> bb_dist)
                    965:                free ((char *) bb -> bb_dist);
                    966:            bb -> bb_dist = getip (s);
                    967:            break;
                    968:        case 12: 
                    969:            bb -> bb_flags = bb -> bb_maxima = 0;
                    970:            (void) sscanf (s, "%o %d", &bb -> bb_flags, &bb -> bb_maxima);
                    971:            bb -> bb_flags |= BB_REMOTE;
                    972:            break;
                    973:        case 13: 
                    974:            bb -> bb_date = getcpy (s);
                    975:            bbs = 0;
                    976:            break;
                    977:     }
                    978: 
                    979:     return OK;
                    980: }
                    981: 
                    982: 
                    983: static char **getip (s)
                    984: char   *s;
                    985: {
                    986:     register char **ap,
                    987:                   **p,
                    988:                   **q;
                    989: 
                    990:     for (p = ap = brkstring (getcpy (s), " ", "\n"); *p; p++)
                    991:        continue;
                    992: 
                    993:     q = (char **) calloc ((unsigned) (p - ap + 1), sizeof *q);
                    994:     if (q == NULL)
                    995:        adios (NULLCP, "insufficient memory");
                    996: 
                    997:     for (p = ap, ap = q; *p; *q++ = *p++)
                    998:        continue;
                    999:     *q = NULL;
                   1000: 
                   1001:     return ap;
                   1002: }
                   1003: 
                   1004: /*  */
                   1005: 
                   1006: static struct bboard   *rover = NULL;
                   1007: 
                   1008: struct bboard  *getbbpop () {
                   1009:     int     snoop;
                   1010:     char   *cp,
                   1011:            *pass = NULL;
                   1012:     register struct bboard *bb;
                   1013: 
                   1014:     if (didpop != NOTOK && ((bb = getbbent ()) || !host))
                   1015:        return bb;
                   1016: 
                   1017:     if (Bhead == NULL) {
                   1018:        snoop = (cp = getenv ("MHPOPDEBUG")) && *cp;
                   1019:        if (rpop) {
                   1020:            if (user == NULL)
                   1021:                user = getusr ();
                   1022:            pass = getusr ();
                   1023:        }
                   1024:        else
                   1025:            if (strcmp (user, popbbuser) == 0)
                   1026:                pass = user;
                   1027:            else
                   1028:                ruserpass (host, &user, &pass);
                   1029:        if (didpop != NOTOK)
                   1030:            didpop = DONE;
                   1031: 
                   1032:        if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
                   1033:            adios (NULLCP, "%s", response);
                   1034:        if (rpop)
                   1035:            (void) setuid (getuid ());
                   1036:        if (pop_xtnd (xtnd2, "bboards") == NOTOK)
                   1037:            adios (NULLCP, "%s", response);
                   1038:        if (topicsw && verbosw) /* could optimize here */
                   1039:            for (bb = Bhead; bb; bb = bb -> bb_chain)
                   1040:                if (pop_xtnd (xtnd3, "x-bboards %s", bb -> bb_name) == NOTOK)
                   1041:                    adios (NULLCP, "%s", response);
                   1042:        rover = Bhead;
                   1043:     }
                   1044: 
                   1045:     if (bb = rover)
                   1046:        rover = rover -> bb_chain;
                   1047:     return bb;
                   1048: }
                   1049: 
                   1050: #define        getbbent        getbbpop
                   1051: #endif BPOP
                   1052: 
                   1053: /*  */
                   1054: 
                   1055: struct bboard *getbbaux (s)
                   1056: register char  *s;
                   1057: {
                   1058: #ifdef BPOP
                   1059:     int            nlatch = host ? 1 : 0;
                   1060: #endif BPOP
                   1061:     register char  **ap;
                   1062:     register struct bbcount *selected;
                   1063:     register struct bboard *bb;
                   1064:     static struct bboard   *head = NULL,
                   1065:                            *tail = NULL;
                   1066: 
                   1067:     for (bb = head; bb; bb = bb -> bb_next) {
                   1068:        if (strcmp (bb -> bb_name, s) == 0)
                   1069:            return bb;
                   1070:        for (ap = bb -> bb_aka; *ap; ap++)
                   1071:            if (strcmp (*ap, s) == 0)
                   1072:                return bb;
                   1073:     }
                   1074: 
                   1075: #ifdef BPOP
                   1076: one_more_time: ;
                   1077: #endif BPOP
                   1078:     while (bb = getbbent ()) {
                   1079:        if ((selected = seek_count (bbc, bb -> bb_name)) != NULL)
                   1080:            bb -> bb_count = selected -> count;
                   1081: 
                   1082: #ifdef BPOP
                   1083:        if (!(bb -> bb_flags & BB_REMOTE))
                   1084: #endif BPOP
                   1085:        if ((bb = getbbcpy (bb)) == NULL)
                   1086:            adios (NULLCP, "insufficient memory");
                   1087:        if (tail != NULL)
                   1088:            tail -> bb_next = bb;
                   1089:        if (head == NULL)
                   1090:            head = bb;
                   1091:        tail = bb;
                   1092: 
                   1093:        if (strcmp (bb -> bb_name, s) == 0)
                   1094:            return bb;
                   1095:        for (ap = bb -> bb_aka; *ap; ap++)
                   1096:            if (strcmp (*ap, s) == 0)
                   1097:                return bb;
                   1098:     }
                   1099: 
                   1100: #ifdef BPOP
                   1101:     if (nlatch && pop_xtnd (xtnd2, "bboards %s", s) != NOTOK) {
                   1102:        rover = Bhead;
                   1103:        nlatch = 0;
                   1104:        goto one_more_time;
                   1105:     }
                   1106: #endif BPOP
                   1107: 
                   1108:     return NULL;
                   1109: }
                   1110: 
                   1111: 
                   1112: struct bboard *getbbvis () {
                   1113:     register struct bboard *bb;
                   1114: 
                   1115:     while (bb = getbbent ())
                   1116:        if (!(bb -> bb_flags & BB_INVIS)
                   1117:                && (access (bb -> bb_file, 04) != NOTOK || errno != EACCES))
                   1118:            break;
                   1119: 
                   1120:     return bb;
                   1121: }

unix.superglobalmegacorp.com

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