|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.