|
|
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: SIGDECL sigser(); ! 126: int action(); ! 127: #ifdef SIGTSTP ! 128: int tstpid; ! 129: static SIGDECL tstpser(); ! 130: #endif SIGTSTP ! 131: ! 132: static char *rcfile; ! 133: ! 134: ! 135: static struct bbcount *bbc = NULL; ! 136: static struct bboard *bbl = NULL; ! 137: ! 138: struct bbcount *add_count (), *seek_count (); ! 139: struct bboard *getbbaux (), *getbbvis (); ! 140: ! 141: /* */ ! 142: ! 143: /* ARGSUSED */ ! 144: ! 145: main(argc, argv) ! 146: int argc; ! 147: char **argv; ! 148: { ! 149: int bbp = 0, ! 150: vecp = 1; ! 151: char *cp, ! 152: *rc, ! 153: **ap, ! 154: **argp, ! 155: buffer[80], ! 156: *arguments[MAXARGS], ! 157: *bbs[NBB + 1], ! 158: *vec[MAXARGS]; ! 159: ! 160: invo_name = r1bindex (argv[0], '/'); ! 161: #ifdef BPOP ! 162: mts_init (invo_name); ! 163: if (popbbhost && *popbbhost) ! 164: host = popbbhost; ! 165: if (popbbuser && *popbbuser) ! 166: user = popbbuser, rpop = 0; ! 167: #endif BPOP ! 168: if ((cp = m_find (invo_name)) != NULL) { ! 169: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 170: ap = copyip (ap, arguments); ! 171: } ! 172: else ! 173: ap = arguments; ! 174: (void) copyip (argv + 1, ap); ! 175: argp = arguments; ! 176: ! 177: (void) setbbent (SB_STAY); ! 178: ! 179: /* */ ! 180: ! 181: while (cp = *argp++) { ! 182: if (*cp == '-') ! 183: switch (smatch (++cp, switches)) { ! 184: case AMBIGSW: ! 185: ambigsw (cp, switches); ! 186: done (1); ! 187: case UNKWNSW: ! 188: vec[vecp++] = --cp; ! 189: continue; ! 190: case HELPSW: ! 191: (void) sprintf (buffer, ! 192: "%s [bboards ...] [switches] [switches for mshproc]", ! 193: invo_name); ! 194: help (buffer, switches); ! 195: done (1); ! 196: ! 197: case TOPICSW: ! 198: topicsw++; ! 199: checksw = readsw = 0; ! 200: continue; ! 201: case CHECKSW: ! 202: checksw++; ! 203: readsw = topicsw = 0; ! 204: continue; ! 205: case READSW: ! 206: readsw++; ! 207: checksw = topicsw = 0; ! 208: continue; ! 209: ! 210: case ARCHSW: ! 211: archivesw++; ! 212: continue; ! 213: case NOARCH: ! 214: archivesw = 0; ! 215: continue; ! 216: ! 217: case PROTSW: ! 218: protsw++; ! 219: continue; ! 220: case NPROTSW: ! 221: protsw = 0; ! 222: continue; ! 223: ! 224: case QUIETSW: ! 225: quietsw++; ! 226: verbosw = 0; ! 227: continue; ! 228: case VERBOSW: ! 229: verbosw++; ! 230: quietsw = 0; ! 231: continue; ! 232: ! 233: case PROGSW: ! 234: if (!(mshproc = *argp++) || *mshproc == '-') ! 235: adios (NULLCP, "missing argument to %s", argp[-2]); ! 236: continue; ! 237: ! 238: case RCSW: ! 239: if (!(rc = *argp++) || *rc == '-') ! 240: adios (NULLCP, "missing argument to %s", argp[-2]); ! 241: continue; ! 242: case NRCSW: ! 243: rc = NULL; ! 244: continue; ! 245: ! 246: case FILESW: ! 247: if (!(cp = *argp++) || *cp == '-') ! 248: adios (NULLCP, "missing argument to %s", argp[-2]); ! 249: if (!setbbinfo (user, cp, 1)) ! 250: adios (NULLCP, "setbbinfo(%s, %s, 1) failed -- %s", ! 251: user, cp, getbberr ()); ! 252: continue; ! 253: case USERSW: ! 254: if (!(user = *argp++) || *user == '-') ! 255: adios (NULLCP, "missing argument to %s", argp[-2]); ! 256: continue; ! 257: ! 258: case HOSTSW: ! 259: if (!(host = *argp++) || *host == '-') ! 260: adios (NULLCP, "missing argument to %s", argp[-2]); ! 261: didpop = NOTOK; ! 262: continue; ! 263: case RPOPSW: ! 264: rpop++; ! 265: continue; ! 266: case NRPOPSW: ! 267: rpop = 0; ! 268: continue; ! 269: } ! 270: if (bbp < NBB) ! 271: bbs[bbp++] = cp; ! 272: else ! 273: adios (NULLCP, "too many bboards, starting with %s", cp); ! 274: } ! 275: bbs[bbp] = NULL; ! 276: ! 277: /* */ ! 278: ! 279: #ifdef BPOP ! 280: if (!*host) ! 281: host = NULL, didpop = OK; ! 282: if (!host || !rpop) ! 283: (void) setuid (getuid ()); ! 284: #endif BPOP ! 285: ! 286: if (!m_find ("path")) ! 287: free (path ("./", TFOLDER)); ! 288: ! 289: rcinit (rc); ! 290: ! 291: for (bbp = 0; cp = bbs[bbp]; bbp++) ! 292: add_bb (cp, NOTOK); ! 293: ! 294: if (topicsw) ! 295: topics (); ! 296: else { ! 297: default_bboards (); ! 298: if (checksw) ! 299: check (); ! 300: else ! 301: process (vecp, vec); ! 302: } ! 303: ! 304: #ifdef BPOP ! 305: if (didpop != OK && pop_quit () == NOTOK) ! 306: adios (NULLCP, "%s", response); ! 307: #endif BPOP ! 308: ! 309: done (0); ! 310: } ! 311: ! 312: /* */ ! 313: ! 314: topics() ! 315: { ! 316: register char *cp, ! 317: **ap; ! 318: register struct bboard *bb; ! 319: ! 320: printf ("%16s %s %s\n", "BBoard", "Items", ! 321: verbosw ? "Interesting Facts" : "Last Update"); ! 322: printf ("%16s %s %s\n", "------", "-----", ! 323: verbosw ? "-----------------" : "-----------"); ! 324: ! 325: for (bb = bbl ? bbl : getbbvis (); ! 326: bb; ! 327: bb = bbl ? bb -> bb_link : getbbvis ()) { ! 328: printf ("%16s %5d %s\n", ! 329: bb -> bb_name, bb -> bb_maxima, bb -> bb_date); ! 330: if (verbosw) { ! 331: if (*bb -> bb_aka) { ! 332: cp = NULL; ! 333: for (ap = bb -> bb_aka; *ap; ap++) ! 334: cp = add (*ap, cp ? add (", ", cp) : cp); ! 335: printv ("AKA", cp); ! 336: free (cp); ! 337: } ! 338: ! 339: printv ("Leaders", *bb -> bb_leader); ! 340: for (ap = bb -> bb_leader + 1; *ap; ap++) ! 341: printv (NULLCP, *ap); ! 342: printv ("File", bb -> bb_file); ! 343: printv ("Archive", bb -> bb_archive); ! 344: printv ("Info", bb -> bb_info); ! 345: printv ("Map", bb -> bb_map); ! 346: printv ("Password", bb -> bb_passwd); ! 347: if (strcmp (bb -> bb_name, bb -> bb_addr)) ! 348: printv ("Address", bb -> bb_addr); ! 349: if (strcmp (*bb -> bb_leader, bb -> bb_request)) ! 350: printv ("Request", bb -> bb_request); ! 351: if (*bb -> bb_relay) ! 352: printv ("Relay", bb -> bb_relay); ! 353: if (*bb -> bb_dist) { ! 354: changed = 0; ! 355: (void) getbbdist (bb, action); ! 356: if (!changed) ! 357: printv ("Dist", ""); ! 358: if (cp = getbberr ()) ! 359: printv ("Error", cp); ! 360: } ! 361: printb (bb -> bb_flags); ! 362: } ! 363: } ! 364: } ! 365: ! 366: /* */ ! 367: ! 368: printv(key, value) ! 369: register char *key, *value; ! 370: { ! 371: char buffer[BUFSIZ]; ! 372: ! 373: if (key) ! 374: (void) sprintf (buffer, "%s: ", key); ! 375: else ! 376: buffer[0] = '\0'; ! 377: printf ("%*s%-*s", 25, "", 10, buffer); ! 378: if (value && *value) ! 379: printf ("%s", value); ! 380: (void) putchar ('\n'); ! 381: } ! 382: ! 383: action(local, domain) ! 384: register char *local, *domain; ! 385: { ! 386: char buffer[BUFSIZ]; ! 387: ! 388: (void) sprintf (buffer, "%s@%s", local, domain); ! 389: printv (changed++ ? NULL : "Dist", buffer); ! 390: return 0; ! 391: } ! 392: ! 393: ! 394: printb(flags) ! 395: unsigned int flags; ! 396: { ! 397: char buffer[BUFSIZ]; ! 398: ! 399: printv ("Flags", sprintb (buffer, flags, BBITS)); ! 400: } ! 401: ! 402: /* */ ! 403: ! 404: check() ! 405: { ! 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: SIGDECL (*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 ! 485: xtnd1(s) ! 486: char *s; ! 487: { ! 488: return OK; ! 489: } ! 490: #endif BPOP ! 491: ! 492: /* */ ! 493: ! 494: bbread(bb, vecp, vec) ! 495: register struct bboard *bb; ! 496: int vecp; ! 497: char *vec[]; ! 498: { ! 499: int child_id, ! 500: pd[2]; ! 501: char buf1[BUFSIZ], ! 502: buf2[BUFSIZ], ! 503: buf3[BUFSIZ]; ! 504: #ifdef BPOP ! 505: int nmsgs, ! 506: nbytes; ! 507: char buf4[BUFSIZ], ! 508: buf5[BUFSIZ]; ! 509: #endif BPOP ! 510: struct stat st; ! 511: ! 512: #ifdef BPOP ! 513: if (bb -> bb_flags & BB_REMOTE) { ! 514: if (pop_xtnd (xtnd1, "%s %s", archivesw ? "archive" : "bboards", ! 515: bb -> bb_name) == NOTOK) { ! 516: advise (NULLCP, "%s", response); ! 517: return; ! 518: } ! 519: if (pop_stat (&nmsgs, &nbytes) == NOTOK) ! 520: adios (NULLCP, "%s", response); ! 521: if (nmsgs == 0) ! 522: return; ! 523: if (pop_fd (buf4, buf5) == NOTOK) ! 524: adios (NULLCP, "%s", response); ! 525: } ! 526: else ! 527: #endif BPOP ! 528: if (stat (archivesw ? bb -> bb_archive : bb -> bb_file, &st) != NOTOK ! 529: && st.st_size == 0) ! 530: return; ! 531: ! 532: if (protsw) { ! 533: if (pipe (pd) == NOTOK) ! 534: adios ("pipe", "unable to"); ! 535: (void) sprintf (buf3, "%d", getpid ()); ! 536: } ! 537: ! 538: switch (child_id = fork ()) { ! 539: case NOTOK: ! 540: adios ("fork", "unable to"); ! 541: ! 542: case OK: ! 543: if (protsw) { ! 544: (void) close (pd[0]); ! 545: (void) sprintf (buf1, "%d", bb -> bb_count + 1); ! 546: (void) sprintf (buf2, "%d", pd[1]); ! 547: vec[vecp++] = "-idname"; ! 548: vec[vecp++] = bb -> bb_name; ! 549: vec[vecp++] = "-idstart"; ! 550: vec[vecp++] = buf1; ! 551: vec[vecp++] = "-idstop"; ! 552: vec[vecp++] = buf2; ! 553: vec[vecp++] = "-idquit"; ! 554: vec[vecp++] = buf3; ! 555: } ! 556: #ifdef BPOP ! 557: if (bb -> bb_flags & BB_REMOTE) { ! 558: vec[vecp++] = "-popread"; ! 559: vec[vecp++] = buf4; ! 560: vec[vecp++] = "-popwrite"; ! 561: vec[vecp++] = buf5; ! 562: } ! 563: #endif BPOP ! 564: vec[vecp++] = archivesw ? bb -> bb_archive : bb -> bb_file; ! 565: vec[vecp] = NULL; ! 566: execvp (mshproc, vec); ! 567: fprintf (stderr, "unable to exec "); ! 568: perror (mshproc); ! 569: _exit (-1); ! 570: ! 571: default: ! 572: #ifdef SIGTSTP ! 573: tstpid = child_id; ! 574: #endif SIGTSTP ! 575: if (protsw) { ! 576: (void) close (pd[1]); ! 577: pgmread (pd[0], child_id, bb); ! 578: } ! 579: else ! 580: (void) pidXwait (child_id, mshproc); ! 581: } ! 582: } ! 583: ! 584: /* */ ! 585: ! 586: pgmread(pd, child_id, bb) ! 587: int pd, child_id; ! 588: register struct bboard *bb; ! 589: { ! 590: int i, ! 591: j, ! 592: n; ! 593: SIGDECL (*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: SIGDECL ! 644: sigser(i) ! 645: int i; ! 646: { ! 647: #ifndef BSD42 ! 648: (void) signal (i, sigser); ! 649: #endif not BSD42 ! 650: quitting++; ! 651: } ! 652: ! 653: /* */ ! 654: ! 655: rcinit(rc) ! 656: register char *rc; ! 657: { ! 658: int state; ! 659: register char *cp; ! 660: char key[NAMESZ], ! 661: value[BUFSIZ]; ! 662: register FILE *bbrc; ! 663: ! 664: if ((cp = rc ? rc : getenv ("MHBBRC")) && *cp) { ! 665: rcfile = path (cp, TFILE); ! 666: if (*cp != '/') ! 667: (void) putenv ("MHBBRC", rcfile); ! 668: } ! 669: else ! 670: rcfile = concat (mypath, "/", RCFILE, NULLCP); ! 671: ! 672: if ((bbrc = fopen (rcfile, "r")) == NULL) ! 673: if (cp && *cp) ! 674: adios (rcfile, "unable to read"); ! 675: else ! 676: return; ! 677: ! 678: for (state = FLD;;) { ! 679: switch (state = m_getfld (state, key, value, sizeof value, bbrc)) { ! 680: case FLD: ! 681: case FLDEOF: ! 682: make_lower (key, key); ! 683: bbc = add_count (bbc, key, atoi (value)); ! 684: if (state == FLDEOF) ! 685: break; ! 686: continue; ! 687: ! 688: default: ! 689: admonish (NULLCP, "bad format: %s", rcfile); ! 690: case FILEEOF: ! 691: break; ! 692: } ! 693: ! 694: break; ! 695: } ! 696: ! 697: if (ferror (bbrc)) ! 698: admonish (rcfile, "error reading"); ! 699: (void) fclose (bbrc); ! 700: } ! 701: ! 702: /* */ ! 703: ! 704: rcend() ! 705: { ! 706: SIGDECL (*hstat)(), (*istat)(), (*qstat)(), (*tstat)(); ! 707: register FILE *bbrc; ! 708: ! 709: if (!changed) ! 710: return; ! 711: ! 712: hstat = signal (SIGHUP, SIG_IGN); ! 713: istat = signal (SIGINT, SIG_IGN); ! 714: qstat = signal (SIGQUIT, SIG_IGN); ! 715: tstat = signal (SIGTERM, SIG_IGN); ! 716: ! 717: if ((bbrc = fopen (rcfile, "w")) == NULL) ! 718: adios (rcfile, "unable to write"); ! 719: rcput (bbrc, bbc); ! 720: ! 721: if (ferror (bbrc)) ! 722: adios (rcfile, "error writing"); ! 723: (void) fclose (bbrc); ! 724: ! 725: (void) signal (SIGHUP, hstat); ! 726: (void) signal (SIGINT, istat); ! 727: (void) signal (SIGQUIT, qstat); ! 728: (void) signal (SIGTERM, tstat); ! 729: ! 730: changed = 0; ! 731: } ! 732: ! 733: rcput(bbrc, p) ! 734: register FILE *bbrc; ! 735: register struct bbcount *p; ! 736: { ! 737: if (p == NULL) ! 738: return; ! 739: ! 740: fprintf (bbrc, "%s: %d\n", p -> key, p -> count); ! 741: rcput (bbrc, p -> left); ! 742: rcput (bbrc, p -> right); ! 743: } ! 744: ! 745: /* */ ! 746: ! 747: #ifdef SIGTSTP ! 748: static SIGDECL ! 749: tstpser(sig) ! 750: int sig; ! 751: { ! 752: int pid; ! 753: union wait w; ! 754: ! 755: rcend (); ! 756: ! 757: while ((pid = wait3 (&w, WUNTRACED, (struct rusage *) 0)) != NOTOK ! 758: && pid != tstpid) ! 759: continue; ! 760: ! 761: (void) signal (SIGTSTP, SIG_DFL); ! 762: #ifdef BSD42 ! 763: (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP)); ! 764: #endif BSD42 ! 765: ! 766: (void) kill (getpid (), sig); ! 767: ! 768: #ifdef BSD42 ! 769: (void) sigblock (sigmask (SIGTSTP)); ! 770: #endif BSD42 ! 771: (void) signal (SIGTSTP, tstpser); ! 772: } ! 773: #endif SIGTSTP ! 774: ! 775: /* */ ! 776: ! 777: struct bbcount * ! 778: add_count(p, w, i) ! 779: register struct bbcount *p; ! 780: register char *w; ! 781: int i; ! 782: { ! 783: int cond; ! 784: ! 785: if (p == NULL) { ! 786: p = (struct bbcount *) malloc (sizeof *p); ! 787: if (p == NULL) ! 788: adios (NULLCP,"insufficient memory"); ! 789: p -> key = getcpy (w); ! 790: p -> count = i; ! 791: p -> left = p -> right = NULL; ! 792: } ! 793: else ! 794: if ((cond = strcmp (w, p -> key)) < 0) ! 795: p -> left = add_count (p -> left, w, i); ! 796: else ! 797: if (cond > 0) ! 798: p -> right = add_count (p -> right, w, i); ! 799: ! 800: return p; ! 801: } ! 802: ! 803: struct bbcount * ! 804: seek_count(p, w) ! 805: register struct bbcount *p; ! 806: register char *w; ! 807: { ! 808: int cond; ! 809: ! 810: if (p == NULL || (cond = strcmp (w, p -> key)) == 0) ! 811: return p; ! 812: else ! 813: return seek_count (cond < 0 ? p -> left : p -> right, w); ! 814: } ! 815: ! 816: /* */ ! 817: ! 818: default_bboards() ! 819: { ! 820: register char *cp, ! 821: **ap; ! 822: ! 823: if (bbl != NULL) ! 824: return; ! 825: ! 826: if (!archivesw && ((cp = m_find ("bboards")) != NULL)) { ! 827: #ifndef BPOP ! 828: for (ap = brkstring (cp = getcpy (cp), " ", "\n"); *ap; ap++) ! 829: #else BPOP ! 830: for (ap = getip (cp); *ap; ap++) ! 831: #endif BPOP ! 832: add_bb (*ap, OK); ! 833: #ifndef BPOP ! 834: free (cp); ! 835: #endif not BPOP ! 836: } ! 837: else ! 838: add_bb ("system", NOTOK); ! 839: ! 840: if (bbl == NULL) ! 841: done (1); ! 842: } ! 843: ! 844: /* */ ! 845: ! 846: add_bb(s, hush) ! 847: register char *s; ! 848: int hush; ! 849: { ! 850: register struct bboard *bb; ! 851: static struct bboard *tail = NULL; ! 852: ! 853: make_lower (s, s); ! 854: if ((bb = getbbaux (s)) == NULL) ! 855: if (hush == OK) ! 856: return; ! 857: else ! 858: adios (NULLCP, "no such bboard as '%s'", s); ! 859: ! 860: if (tail != NULL) ! 861: tail -> bb_link = bb; ! 862: if (bbl == NULL) ! 863: bbl = bb; ! 864: tail = bb; ! 865: } ! 866: ! 867: /* */ ! 868: ! 869: #ifdef BPOP ! 870: static struct bboard *Bhead = NULL; ! 871: static struct bboard *Btail = NULL; ! 872: ! 873: static int ! 874: xtnd2(s) ! 875: char *s; ! 876: { ! 877: int maxima; ! 878: char name[BUFSIZ]; ! 879: register struct bboard *bb; ! 880: ! 881: if (sscanf (s, "%s %d", name, &maxima) != 2) ! 882: adios (NULLCP, "XTND2 botch: %s", s); ! 883: ! 884: if ((bb = (struct bboard *) calloc (1, sizeof *bb)) == NULL) ! 885: adios (NULLCP, "insufficient memory"); ! 886: bb -> bb_name = getcpy (name); ! 887: if ((bb -> bb_aka = (char **) calloc (1, sizeof *bb -> bb_aka)) == NULL) ! 888: adios (NULLCP, "insufficient memory"); ! 889: *bb -> bb_aka = NULL; ! 890: bb -> bb_file = bb -> bb_archive = bb -> bb_info = bb -> bb_map = ""; ! 891: bb -> bb_passwd = ""; ! 892: if ((bb -> bb_leader = (char **) calloc (1, sizeof *bb -> bb_leader)) ! 893: == NULL) ! 894: adios (NULLCP, "insufficient memory"); ! 895: *bb -> bb_leader = NULL; ! 896: bb -> bb_addr = bb -> bb_request = bb -> bb_relay = ""; ! 897: if ((bb -> bb_dist = (char **) calloc (1, sizeof *bb -> bb_dist)) == NULL) ! 898: adios (NULLCP, "insufficient memory"); ! 899: *bb -> bb_dist = NULL; ! 900: bb -> bb_flags = BB_REMOTE; ! 901: bb -> bb_count = 0; ! 902: bb -> bb_maxima = maxima; ! 903: bb -> bb_date = ""; ! 904: bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL; ! 905: ! 906: if (Btail != NULL) ! 907: Btail -> bb_chain = bb; ! 908: if (Bhead == NULL) ! 909: Bhead = bb; ! 910: Btail = bb; ! 911: ! 912: return OK; ! 913: } ! 914: ! 915: /* */ ! 916: ! 917: static int ! 918: xtnd3(s) ! 919: char *s; ! 920: { ! 921: static int bbs = 0; ! 922: static struct bboard *bb; ! 923: ! 924: switch (bbs++) { ! 925: case 0: ! 926: for (bb = Bhead; bb; bb = bb -> bb_chain) ! 927: if (strcmp (bb -> bb_name, s) == 0) ! 928: break; ! 929: if (bb == NULL) ! 930: adios (NULLCP, "XTND3 botch"); ! 931: ! 932: free (bb -> bb_name); ! 933: bb -> bb_name = getcpy (s); ! 934: break; ! 935: case 1: ! 936: if (bb -> bb_aka) ! 937: free ((char *) bb -> bb_aka); ! 938: bb -> bb_aka = getip (s); ! 939: break; ! 940: case 2: ! 941: bb -> bb_file = getcpy (s); ! 942: break; ! 943: case 3: ! 944: bb -> bb_archive = getcpy (s); ! 945: break; ! 946: case 4: ! 947: bb -> bb_info = getcpy (s); ! 948: break; ! 949: case 5: ! 950: bb -> bb_map = getcpy (s); ! 951: break; ! 952: case 6: ! 953: bb -> bb_passwd = getcpy (s); ! 954: break; ! 955: case 7: ! 956: if (bb -> bb_leader) ! 957: free ((char *) bb -> bb_leader); ! 958: bb -> bb_leader = getip (s); ! 959: break; ! 960: case 8: ! 961: bb -> bb_addr = getcpy (s); ! 962: break; ! 963: case 9: ! 964: bb -> bb_request = getcpy (s); ! 965: break; ! 966: case 10: ! 967: bb -> bb_relay = getcpy (s); ! 968: break; ! 969: case 11: ! 970: if (bb -> bb_dist) ! 971: free ((char *) bb -> bb_dist); ! 972: bb -> bb_dist = getip (s); ! 973: break; ! 974: case 12: ! 975: bb -> bb_flags = bb -> bb_maxima = 0; ! 976: (void) sscanf (s, "%o %d", &bb -> bb_flags, &bb -> bb_maxima); ! 977: bb -> bb_flags |= BB_REMOTE; ! 978: break; ! 979: case 13: ! 980: bb -> bb_date = getcpy (s); ! 981: bbs = 0; ! 982: break; ! 983: } ! 984: ! 985: return OK; ! 986: } ! 987: ! 988: ! 989: static char ** ! 990: getip(s) ! 991: char *s; ! 992: { ! 993: register char **ap, ! 994: **p, ! 995: **q; ! 996: ! 997: for (p = ap = brkstring (getcpy (s), " ", "\n"); *p; p++) ! 998: continue; ! 999: ! 1000: q = (char **) calloc ((unsigned) (p - ap + 1), sizeof *q); ! 1001: if (q == NULL) ! 1002: adios (NULLCP, "insufficient memory"); ! 1003: ! 1004: for (p = ap, ap = q; *p; *q++ = *p++) ! 1005: continue; ! 1006: *q = NULL; ! 1007: ! 1008: return ap; ! 1009: } ! 1010: ! 1011: /* */ ! 1012: ! 1013: static struct bboard *rover = NULL; ! 1014: ! 1015: struct bboard * ! 1016: getbbpop() ! 1017: { ! 1018: int snoop; ! 1019: char *cp, ! 1020: *pass = NULL; ! 1021: register struct bboard *bb; ! 1022: ! 1023: if (didpop != NOTOK && ((bb = getbbent ()) || !host)) ! 1024: return bb; ! 1025: ! 1026: if (Bhead == NULL) { ! 1027: snoop = (cp = getenv ("MHPOPDEBUG")) && *cp; ! 1028: if (rpop) { ! 1029: if (user == NULL) ! 1030: user = getusr (); ! 1031: pass = getusr (); ! 1032: } ! 1033: else ! 1034: if (strcmp (user, popbbuser) == 0) ! 1035: pass = user; ! 1036: else ! 1037: ruserpass (host, &user, &pass); ! 1038: if (didpop != NOTOK) ! 1039: didpop = DONE; ! 1040: ! 1041: if (pop_init (host, user, pass, snoop, rpop) == NOTOK) ! 1042: adios (NULLCP, "%s", response); ! 1043: if (rpop) ! 1044: (void) setuid (getuid ()); ! 1045: if (pop_xtnd (xtnd2, "bboards") == NOTOK) ! 1046: adios (NULLCP, "%s", response); ! 1047: if (topicsw && verbosw) /* could optimize here */ ! 1048: for (bb = Bhead; bb; bb = bb -> bb_chain) ! 1049: if (pop_xtnd (xtnd3, "x-bboards %s", bb -> bb_name) == NOTOK) ! 1050: adios (NULLCP, "%s", response); ! 1051: rover = Bhead; ! 1052: } ! 1053: ! 1054: if (bb = rover) ! 1055: rover = rover -> bb_chain; ! 1056: return bb; ! 1057: } ! 1058: ! 1059: #define getbbent getbbpop ! 1060: #endif BPOP ! 1061: ! 1062: /* */ ! 1063: ! 1064: struct bboard * ! 1065: getbbaux(s) ! 1066: register char *s; ! 1067: { ! 1068: #ifdef BPOP ! 1069: int nlatch = host ? 1 : 0; ! 1070: #endif BPOP ! 1071: register char **ap; ! 1072: register struct bbcount *selected; ! 1073: register struct bboard *bb; ! 1074: static struct bboard *head = NULL, ! 1075: *tail = NULL; ! 1076: ! 1077: for (bb = head; bb; bb = bb -> bb_next) { ! 1078: if (strcmp (bb -> bb_name, s) == 0) ! 1079: return bb; ! 1080: for (ap = bb -> bb_aka; *ap; ap++) ! 1081: if (strcmp (*ap, s) == 0) ! 1082: return bb; ! 1083: } ! 1084: ! 1085: #ifdef BPOP ! 1086: one_more_time: ; ! 1087: #endif BPOP ! 1088: while (bb = getbbent ()) { ! 1089: if ((selected = seek_count (bbc, bb -> bb_name)) != NULL) ! 1090: bb -> bb_count = selected -> count; ! 1091: ! 1092: #ifdef BPOP ! 1093: if (!(bb -> bb_flags & BB_REMOTE)) ! 1094: #endif BPOP ! 1095: if ((bb = getbbcpy (bb)) == NULL) ! 1096: adios (NULLCP, "insufficient memory"); ! 1097: if (tail != NULL) ! 1098: tail -> bb_next = bb; ! 1099: if (head == NULL) ! 1100: head = bb; ! 1101: tail = bb; ! 1102: ! 1103: if (strcmp (bb -> bb_name, s) == 0) ! 1104: return bb; ! 1105: for (ap = bb -> bb_aka; *ap; ap++) ! 1106: if (strcmp (*ap, s) == 0) ! 1107: return bb; ! 1108: } ! 1109: ! 1110: #ifdef BPOP ! 1111: if (nlatch && pop_xtnd (xtnd2, "bboards %s", s) != NOTOK) { ! 1112: rover = Bhead; ! 1113: nlatch = 0; ! 1114: goto one_more_time; ! 1115: } ! 1116: #endif BPOP ! 1117: ! 1118: return NULL; ! 1119: } ! 1120: ! 1121: struct bboard * ! 1122: getbbvis() ! 1123: { ! 1124: register struct bboard *bb; ! 1125: ! 1126: while (bb = getbbent ()) ! 1127: if (!(bb -> bb_flags & BB_INVIS) ! 1128: && (access (bb -> bb_file, 04) != NOTOK || errno != EACCES)) ! 1129: break; ! 1130: ! 1131: return bb; ! 1132: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.