|
|
1.1 ! root 1: /* $Header: rcstuff.c,v 4.3.1.3 85/05/29 09:13:25 lwall Exp $ ! 2: * ! 3: * $Log: rcstuff.c,v $ ! 4: * Revision 4.3.1.3 85/05/29 09:13:25 lwall ! 5: * %d that should be %ld. ! 6: * ! 7: * Revision 4.3.1.2 85/05/17 11:40:08 lwall ! 8: * Sped up "rn -c" by not mallocing unnecessarily. ! 9: * ! 10: * Revision 4.3.1.1 85/05/10 11:37:18 lwall ! 11: * Branch for patches. ! 12: * ! 13: * Revision 4.3 85/05/01 11:45:56 lwall ! 14: * Baseline for release with 4.3bsd. ! 15: * ! 16: */ ! 17: ! 18: #include "EXTERN.h" ! 19: #include "common.h" ! 20: #include "util.h" ! 21: #include "ngdata.h" ! 22: #include "term.h" ! 23: #include "final.h" ! 24: #include "rn.h" ! 25: #include "intrp.h" ! 26: #include "only.h" ! 27: #include "rcln.h" ! 28: #include "server.h" ! 29: #include "INTERN.h" ! 30: #include "rcstuff.h" ! 31: ! 32: char *rcname INIT(Nullch); /* path name of .newsrc file */ ! 33: char *rctname INIT(Nullch); /* path name of temp .newsrc file */ ! 34: char *rcbname INIT(Nullch); /* path name of backup .newsrc file */ ! 35: char *softname INIT(Nullch); /* path name of .rnsoft file */ ! 36: FILE *rcfp INIT(Nullfp); /* .newsrc file pointer */ ! 37: ! 38: #ifdef HASHNG ! 39: short hashtbl[HASHSIZ]; ! 40: #endif ! 41: ! 42: bool ! 43: rcstuff_init() ! 44: { ! 45: register NG_NUM newng; ! 46: register char *s; ! 47: register int i; ! 48: register bool foundany = FALSE; ! 49: char *some_buf; ! 50: long length; ! 51: #ifdef SERVER ! 52: char *cp; ! 53: #endif ! 54: ! 55: #ifdef HASHNG ! 56: for (i=0; i<HASHSIZ; i++) ! 57: hashtbl[i] = -1; ! 58: #endif ! 59: ! 60: /* make filenames */ ! 61: ! 62: #ifdef SERVER ! 63: if (cp = getenv("NEWSRC")) ! 64: rcname = savestr(filexp(cp)); ! 65: else ! 66: rcname = savestr(filexp(RCNAME)); ! 67: #else /* not SERVER */ ! 68: rcname = savestr(filexp(RCNAME)); ! 69: #endif ! 70: rctname = savestr(filexp(RCTNAME)); ! 71: rcbname = savestr(filexp(RCBNAME)); ! 72: softname = savestr(filexp(SOFTNAME)); ! 73: ! 74: /* make sure the .newsrc file exists */ ! 75: ! 76: newsrc_check(); ! 77: ! 78: /* open .rnsoft file containing soft ptrs to active file */ ! 79: ! 80: tmpfp = fopen(softname,"r"); ! 81: if (tmpfp == Nullfp) ! 82: writesoft = TRUE; ! 83: ! 84: /* read in the .newsrc file */ ! 85: ! 86: for (nextrcline = 0; ! 87: (some_buf = get_a_line(buf,LBUFLEN,rcfp)) != Nullch; ! 88: nextrcline++) { ! 89: /* for each line in .newsrc */ ! 90: char tmpbuf[10]; ! 91: ! 92: newng = nextrcline; /* get it into a register */ ! 93: length = len_last_line_got; /* side effect of get_a_line */ ! 94: if (length <= 1) { /* only a newline??? */ ! 95: nextrcline--; /* compensate for loop increment */ ! 96: continue; ! 97: } ! 98: if (newng >= MAXRCLINE) { /* check for overflow */ ! 99: fputs("Too many lines in .newsrc\n",stdout) FLUSH; ! 100: finalize(1); ! 101: } ! 102: if (tmpfp != Nullfp && fgets(tmpbuf,10,tmpfp) != Nullch) ! 103: softptr[newng] = atoi(tmpbuf); ! 104: else ! 105: softptr[newng] = 0; ! 106: some_buf[--length] = '\0'; /* wipe out newline */ ! 107: if (checkflag) /* no extra mallocs for -c */ ! 108: rcline[newng] = some_buf; ! 109: else if (some_buf == buf) { ! 110: rcline[newng] = savestr(some_buf); ! 111: /* make a semipermanent copy */ ! 112: } ! 113: else { ! 114: /*NOSTRICT*/ ! 115: #ifndef lint ! 116: some_buf = saferealloc(some_buf,(MEM_SIZE)(length+1)); ! 117: #endif lint ! 118: rcline[newng] = some_buf; ! 119: } ! 120: #ifdef NOTDEF ! 121: if (strnEQ(some_buf,"to.",3)) { /* is this a non-newsgroup? */ ! 122: nextrcline--; /* destroy this line */ ! 123: continue; ! 124: } ! 125: #endif ! 126: if (*some_buf == ' ' || ! 127: *some_buf == '\t' || ! 128: strnEQ(some_buf,"options",7)) { /* non-useful line? */ ! 129: toread[newng] = TR_JUNK; ! 130: rcchar[newng] = ' '; ! 131: rcnums[newng] = 0; ! 132: continue; ! 133: } ! 134: for (s = rcline[newng]; *s && *s != ':' && *s != NEGCHAR; s++) ; ! 135: if (!*s && !checkflag) { ! 136: #ifndef lint ! 137: rcline[newng] = saferealloc(rcline[newng],(MEM_SIZE)length+2); ! 138: #endif lint ! 139: s = rcline[newng] + length; ! 140: *s = ':'; ! 141: *(s+1) = '\0'; ! 142: } ! 143: rcchar[newng] = *s; /* salt away the : or ! */ ! 144: rcnums[newng] = (char)(s - rcline[newng]); ! 145: rcnums[newng]++; /* remember where it was */ ! 146: *s = '\0'; /* null terminate newsgroup name */ ! 147: #ifdef HASHNG ! 148: if (!checkflag) ! 149: sethash(newng); ! 150: #endif ! 151: if (rcchar[newng] == NEGCHAR) { ! 152: toread[newng] = TR_UNSUB; ! 153: continue; ! 154: } ! 155: ! 156: /* now find out how much there is to read */ ! 157: ! 158: if (!inlist(buf) || (suppress_cn && foundany && !paranoid)) ! 159: toread[newng] = TR_NONE; /* no need to calculate now */ ! 160: else ! 161: set_toread(newng); ! 162: #ifdef VERBOSE ! 163: if (!checkflag && softmisses == 1) { ! 164: softmisses++; /* lie a little */ ! 165: fputs("(Revising soft pointers--be patient.)\n",stdout) FLUSH; ! 166: } ! 167: #endif ! 168: if (toread[newng] > TR_NONE) { /* anything unread? */ ! 169: if (!foundany) { ! 170: starthere = newng; ! 171: foundany = TRUE; /* remember that fact*/ ! 172: } ! 173: if (suppress_cn) { /* if no listing desired */ ! 174: if (checkflag) { /* if that is all they wanted */ ! 175: finalize(1); /* then bomb out */ ! 176: } ! 177: } ! 178: else { ! 179: #ifdef VERBOSE ! 180: IF(verbose) ! 181: printf("Unread news in %-20s %5ld article%s\n", ! 182: rcline[newng],(long)toread[newng], ! 183: toread[newng]==TR_ONE ? nullstr : "s") FLUSH; ! 184: ELSE ! 185: #endif ! 186: #ifdef TERSE ! 187: printf("%s: %ld article%s\n", ! 188: rcline[newng],(long)toread[newng], ! 189: toread[newng]==TR_ONE ? nullstr : "s") FLUSH; ! 190: #endif ! 191: if (int_count) { ! 192: countdown = 1; ! 193: int_count = 0; ! 194: } ! 195: if (countdown) { ! 196: if (! --countdown) { ! 197: fputs("etc.\n",stdout) FLUSH; ! 198: if (checkflag) ! 199: finalize(1); ! 200: suppress_cn = TRUE; ! 201: } ! 202: } ! 203: } ! 204: } ! 205: } ! 206: fclose(rcfp); /* close .newsrc */ ! 207: if (tmpfp != Nullfp) ! 208: fclose(tmpfp); /* close .rnsoft */ ! 209: if (checkflag) { /* were we just checking? */ ! 210: finalize(foundany); /* tell them what we found */ ! 211: } ! 212: if (paranoid) ! 213: cleanup_rc(); ! 214: ! 215: #ifdef DEBUGGING ! 216: if (debug & DEB_HASH) { ! 217: page_init(); ! 218: for (i=0; i<HASHSIZ; i++) { ! 219: sprintf(buf,"%d %d",i,hashtbl[i]); ! 220: print_lines(buf,NOMARKING); ! 221: } ! 222: } ! 223: #endif ! 224: ! 225: return foundany; ! 226: } ! 227: ! 228: /* try to find or add an explicitly specified newsgroup */ ! 229: /* returns TRUE if found or added, FALSE if not. */ ! 230: /* assumes that we are chdir'ed to SPOOL */ ! 231: ! 232: bool ! 233: get_ng(what,do_reloc) ! 234: char *what; ! 235: bool do_reloc; ! 236: { ! 237: char *ntoforget; ! 238: char promptbuf[128]; ! 239: #ifdef SERVER ! 240: char ser_line[256]; ! 241: #endif ! 242: ! 243: #ifdef VERBOSE ! 244: IF(verbose) ! 245: ntoforget = "Type n to forget about this newsgroup.\n"; ! 246: ELSE ! 247: #endif ! 248: #ifdef TERSE ! 249: ntoforget = "n to forget it.\n"; ! 250: #endif ! 251: if (index(what,'/')) { ! 252: dingaling(); ! 253: printf("\nBad newsgroup name.\n") FLUSH; ! 254: return FALSE; ! 255: } ! 256: set_ngname(what); ! 257: ng = find_ng(ngname); ! 258: if (ng == nextrcline) { /* not in .newsrc? */ ! 259: #ifndef SERVER ! 260: if (eaccess(ngdir,0) || ! 261: (softptr[ng] = findact(buf,ngname,strlen(ngname),0L)) < 0 ) { ! 262: #else /* SERVER */ ! 263: sprintf(ser_line, "GROUP %s", ngname); ! 264: put_server(ser_line); ! 265: if (get_server(ser_line, sizeof(ser_line)) < 0) { ! 266: fprintf(stderr, "rrn: Unexpected close of server socket.\n"); ! 267: finalize(1); ! 268: } ! 269: if (*ser_line != CHAR_OK) { ! 270: #endif /* SERVER */ ! 271: dingaling(); ! 272: #ifdef VERBOSE ! 273: IF(verbose) ! 274: printf("\nNewsgroup %s does not exist!\n",ngname) FLUSH; ! 275: ELSE ! 276: #endif ! 277: #ifdef TERSE ! 278: printf("\nNo %s!\n",ngname) FLUSH; ! 279: #endif ! 280: sleep(2); ! 281: return FALSE; ! 282: } ! 283: #ifdef VERBOSE ! 284: IF(verbose) ! 285: sprintf(promptbuf,"\nNewsgroup %s not in .newsrc--add? [yn] ",ngname); ! 286: ELSE ! 287: #endif ! 288: #ifdef TERSE ! 289: sprintf(promptbuf,"\nAdd %s? [yn] ",ngname); ! 290: #endif ! 291: reask_add: ! 292: in_char(promptbuf); ! 293: putchar('\n') FLUSH; ! 294: setdef(buf,"y"); ! 295: #ifdef VERIFY ! 296: printcmd(); ! 297: #endif ! 298: if (*buf == 'h') { ! 299: #ifdef VERBOSE ! 300: IF(verbose) ! 301: printf("Type y or SP to add %s to your .newsrc.\n", ngname) ! 302: FLUSH; ! 303: ELSE ! 304: #endif ! 305: #ifdef TERSE ! 306: fputs("y or SP to add\n",stdout) FLUSH; ! 307: #endif ! 308: fputs(ntoforget,stdout) FLUSH; ! 309: goto reask_add; ! 310: } ! 311: else if (*buf == 'n' || *buf == 'q') { ! 312: return FALSE; ! 313: } ! 314: else if (*buf == 'y') { ! 315: ng = add_newsgroup(ngname); ! 316: do_reloc = FALSE; ! 317: } ! 318: else { ! 319: fputs(hforhelp,stdout) FLUSH; ! 320: settle_down(); ! 321: goto reask_add; ! 322: } ! 323: } ! 324: else if (rcchar[ng] == NEGCHAR) { /* unsubscribed? */ ! 325: #ifdef VERBOSE ! 326: IF(verbose) ! 327: sprintf(promptbuf, ! 328: "\nNewsgroup %s is currently unsubscribed to--resubscribe? [yn] ",ngname) ! 329: FLUSH; ! 330: ELSE ! 331: #endif ! 332: #ifdef TERSE ! 333: sprintf(promptbuf,"\n%s unsubscribed--resubscribe? [yn] ",ngname) ! 334: FLUSH; ! 335: #endif ! 336: reask_unsub: ! 337: in_char(promptbuf); ! 338: putchar('\n') FLUSH; ! 339: setdef(buf,"y"); ! 340: #ifdef VERIFY ! 341: printcmd(); ! 342: #endif ! 343: if (*buf == 'h') { ! 344: #ifdef VERBOSE ! 345: IF(verbose) ! 346: printf("Type y or SP to resubscribe to %s.\n", ngname) FLUSH; ! 347: ELSE ! 348: #endif ! 349: #ifdef TERSE ! 350: fputs("y or SP to resubscribe.\n",stdout) FLUSH; ! 351: #endif ! 352: fputs(ntoforget,stdout) FLUSH; ! 353: goto reask_unsub; ! 354: } ! 355: else if (*buf == 'n' || *buf == 'q') { ! 356: return FALSE; ! 357: } ! 358: else if (*buf == 'y') { ! 359: rcchar[ng] = ':'; ! 360: } ! 361: else { ! 362: fputs(hforhelp,stdout) FLUSH; ! 363: settle_down(); ! 364: goto reask_unsub; ! 365: } ! 366: } ! 367: ! 368: /* now calculate how many unread articles in newsgroup */ ! 369: ! 370: set_toread(ng); ! 371: #ifdef RELOCATE ! 372: if (do_reloc) ! 373: ng = relocate_newsgroup(ng,-1); ! 374: #endif ! 375: return toread[ng] >= TR_NONE; ! 376: } ! 377: ! 378: /* add a newsgroup to the .newsrc file (eventually) */ ! 379: ! 380: NG_NUM ! 381: add_newsgroup(ngn) ! 382: char *ngn; ! 383: { ! 384: register NG_NUM newng = nextrcline++; ! 385: /* increment max rcline index */ ! 386: ! 387: rcnums[newng] = strlen(ngn) + 1; ! 388: rcline[newng] = safemalloc((MEM_SIZE)(rcnums[newng] + 1)); ! 389: strcpy(rcline[newng],ngn); /* and copy over the name */ ! 390: *(rcline[newng] + rcnums[newng]) = '\0'; ! 391: rcchar[newng] = ':'; /* call it subscribed */ ! 392: toread[newng] = TR_NONE; /* just for prettiness */ ! 393: #ifdef HASHNG ! 394: sethash(newng); /* so we can find it again */ ! 395: #endif ! 396: #ifdef RELOCATE ! 397: return relocate_newsgroup(newng,-1); ! 398: #else ! 399: return newng; ! 400: #endif ! 401: } ! 402: ! 403: #ifdef RELOCATE ! 404: NG_NUM ! 405: relocate_newsgroup(ngx,newng) ! 406: NG_NUM ngx; ! 407: NG_NUM newng; ! 408: { ! 409: char *dflt = (ngx!=current_ng ? "$^.L" : "$^L"); ! 410: char *tmprcline; ! 411: ART_UNREAD tmptoread; ! 412: char tmprcchar; ! 413: char tmprcnums; ! 414: ACT_POS tmpsoftptr; ! 415: register NG_NUM i; ! 416: #ifdef DEBUGGING ! 417: ART_NUM tmpngmax; ! 418: #endif ! 419: #ifdef CACHEFIRST ! 420: ART_NUM tmpabs1st; ! 421: #endif ! 422: ! 423: starthere = 0; /* Disable this optimization */ ! 424: writesoft = TRUE; /* Update soft pointer file */ ! 425: if (ngx < nextrcline-1) { ! 426: #ifdef HASHNG ! 427: for (i=0; i<HASHSIZ; i++) { ! 428: if (hashtbl[i] > ngx) ! 429: --hashtbl[i]; ! 430: else if (hashtbl[i] == ngx) ! 431: hashtbl[i] = nextrcline-1; ! 432: } ! 433: #endif ! 434: tmprcline = rcline[ngx]; ! 435: tmptoread = toread[ngx]; ! 436: tmprcchar = rcchar[ngx]; ! 437: tmprcnums = rcnums[ngx]; ! 438: tmpsoftptr = softptr[ngx]; ! 439: #ifdef DEBUGGING ! 440: tmpngmax = ngmax[ngx]; ! 441: #endif ! 442: #ifdef CACHEFIRST ! 443: tmpabs1st = abs1st[ngx]; ! 444: #endif ! 445: for (i=ngx+1; i<nextrcline; i++) { ! 446: rcline[i-1] = rcline[i]; ! 447: toread[i-1] = toread[i]; ! 448: rcchar[i-1] = rcchar[i]; ! 449: rcnums[i-1] = rcnums[i]; ! 450: softptr[i-1] = softptr[i]; ! 451: #ifdef DEBUGGING ! 452: ngmax[i-1] = ngmax[i]; ! 453: #endif ! 454: #ifdef CACHEFIRST ! 455: abs1st[i-1] = abs1st[i]; ! 456: #endif ! 457: } ! 458: rcline[nextrcline-1] = tmprcline; ! 459: toread[nextrcline-1] = tmptoread; ! 460: rcchar[nextrcline-1] = tmprcchar; ! 461: rcnums[nextrcline-1] = tmprcnums; ! 462: softptr[nextrcline-1] = tmpsoftptr; ! 463: #ifdef DEBUGGING ! 464: ngmax[nextrcline-1] = tmpngmax; ! 465: #endif ! 466: #ifdef CACHEFIRST ! 467: abs1st[nextrcline-1] = tmpabs1st; ! 468: #endif ! 469: } ! 470: if (current_ng > ngx) ! 471: current_ng--; ! 472: if (newng < 0) { ! 473: reask_reloc: ! 474: unflush_output(); /* disable any ^O in effect */ ! 475: #ifdef VERBOSE ! 476: IF(verbose) ! 477: printf("\nPut newsgroup where? [%s] ", dflt); ! 478: ELSE ! 479: #endif ! 480: #ifdef TERSE ! 481: printf("\nPut where? [%s] ", dflt); ! 482: #endif ! 483: fflush(stdout); ! 484: reinp_reloc: ! 485: eat_typeahead(); ! 486: getcmd(buf); ! 487: if (errno || *buf == '\f') { ! 488: /* if return from stop signal */ ! 489: goto reask_reloc; /* give them a prompt again */ ! 490: } ! 491: setdef(buf,dflt); ! 492: #ifdef VERIFY ! 493: printcmd(); ! 494: #endif ! 495: if (*buf == 'h') { ! 496: #ifdef VERBOSE ! 497: IF(verbose) { ! 498: printf("\n\n\ ! 499: Type ^ to put the newsgroup first (position 0).\n\ ! 500: Type $ to put the newsgroup last (position %d).\n", nextrcline-1); ! 501: printf("\ ! 502: Type . to put it before the current newsgroup (position %d).\n", current_ng); ! 503: printf("\ ! 504: Type -newsgroup name to put it before that newsgroup.\n\ ! 505: Type +newsgroup name to put it after that newsgroup.\n\ ! 506: Type a number between 0 and %d to put it at that position.\n", nextrcline-1); ! 507: printf("\ ! 508: Type L for a listing of newsgroups and their positions.\n") FLUSH; ! 509: } ! 510: ELSE ! 511: #endif ! 512: #ifdef TERSE ! 513: { ! 514: printf("\n\n\ ! 515: ^ to put newsgroup first (pos 0).\n\ ! 516: $ to put last (pos %d).\n", nextrcline-1); ! 517: printf("\ ! 518: . to put before current newsgroup (pos %d).\n", current_ng); ! 519: printf("\ ! 520: -newsgroup to put before newsgroup.\n\ ! 521: +newsgroup to put after.\n\ ! 522: number in 0-%d to put at that pos.\n", nextrcline-1); ! 523: printf("\ ! 524: L for list of .newsrc.\n") FLUSH; ! 525: } ! 526: #endif ! 527: goto reask_reloc; ! 528: } ! 529: else if (*buf == 'L') { ! 530: putchar('\n') FLUSH; ! 531: list_newsgroups(); ! 532: goto reask_reloc; ! 533: } ! 534: else if (isdigit(*buf)) { ! 535: if (!finish_command(TRUE)) /* get rest of command */ ! 536: goto reinp_reloc; ! 537: newng = atoi(buf); ! 538: if (newng < 0) ! 539: newng = 0; ! 540: if (newng >= nextrcline) ! 541: return nextrcline-1; ! 542: } ! 543: else if (*buf == '^') { ! 544: putchar('\n') FLUSH; ! 545: newng = 0; ! 546: } ! 547: else if (*buf == '$') { ! 548: putchar('\n') FLUSH; ! 549: return nextrcline-1; ! 550: } ! 551: else if (*buf == '.') { ! 552: putchar('\n') FLUSH; ! 553: newng = current_ng; ! 554: } ! 555: else if (*buf == '-' || *buf == '+') { ! 556: if (!finish_command(TRUE)) /* get rest of command */ ! 557: goto reinp_reloc; ! 558: newng = find_ng(buf+1); ! 559: if (newng == nextrcline) { ! 560: fputs("Not found.",stdout) FLUSH; ! 561: goto reask_reloc; ! 562: } ! 563: if (*buf == '+') ! 564: newng++; ! 565: } ! 566: else { ! 567: printf("\n%s",hforhelp) FLUSH; ! 568: settle_down(); ! 569: goto reask_reloc; ! 570: } ! 571: } ! 572: if (newng < nextrcline-1) { ! 573: #ifdef HASHNG ! 574: for (i=0; i<HASHSIZ; i++) { ! 575: if (hashtbl[i] == nextrcline-1) ! 576: hashtbl[i] = newng; ! 577: else if (hashtbl[i] >= newng) ! 578: ++hashtbl[i]; ! 579: } ! 580: #endif ! 581: tmprcline = rcline[nextrcline-1]; ! 582: tmptoread = toread[nextrcline-1]; ! 583: tmprcchar = rcchar[nextrcline-1]; ! 584: tmprcnums = rcnums[nextrcline-1]; ! 585: tmpsoftptr = softptr[nextrcline-1]; ! 586: #ifdef DEBUGGING ! 587: tmpngmax = ngmax[nextrcline-1]; ! 588: #endif ! 589: #ifdef CACHEFIRST ! 590: tmpabs1st = abs1st[nextrcline-1]; ! 591: #endif ! 592: for (i=nextrcline-2; i>=newng; i--) { ! 593: rcline[i+1] = rcline[i]; ! 594: toread[i+1] = toread[i]; ! 595: rcchar[i+1] = rcchar[i]; ! 596: rcnums[i+1] = rcnums[i]; ! 597: softptr[i+1] = softptr[i]; ! 598: #ifdef DEBUGGING ! 599: ngmax[i+1] = ngmax[i]; ! 600: #endif ! 601: #ifdef CACHEFIRST ! 602: abs1st[i+1] = abs1st[i]; ! 603: #endif ! 604: } ! 605: rcline[newng] = tmprcline; ! 606: toread[newng] = tmptoread; ! 607: rcchar[newng] = tmprcchar; ! 608: rcnums[newng] = tmprcnums; ! 609: softptr[newng] = tmpsoftptr; ! 610: #ifdef DEBUGGING ! 611: ngmax[newng] = tmpngmax; ! 612: #endif ! 613: #ifdef CACHEFIRST ! 614: abs1st[newng] = tmpabs1st; ! 615: #endif ! 616: } ! 617: if (current_ng >= newng) ! 618: current_ng++; ! 619: return newng; ! 620: } ! 621: #endif ! 622: ! 623: /* List out the newsrc with annotations */ ! 624: ! 625: void ! 626: list_newsgroups() ! 627: { ! 628: register NG_NUM i; ! 629: char tmpbuf[2048]; ! 630: static char *status[] = {"(READ)","(UNSUB)","(BOGUS)","(JUNK)"}; ! 631: int cmd; ! 632: ! 633: page_init(); ! 634: print_lines("\ ! 635: # Status Newsgroup\n\ ! 636: ",STANDOUT); ! 637: for (i=0; i<nextrcline && !int_count; i++) { ! 638: if (toread[i] >= 0) ! 639: set_toread(i); ! 640: *(rcline[i] + rcnums[i] - 1) = rcchar[i]; ! 641: if (toread[i] > 0) ! 642: sprintf(tmpbuf,"%3d %6ld ",i,(long)toread[i]); ! 643: else ! 644: sprintf(tmpbuf,"%3d %7s ",i,status[-toread[i]]); ! 645: safecpy(tmpbuf+13,rcline[i],2034); ! 646: *(rcline[i] + rcnums[i] - 1) = '\0'; ! 647: if (cmd = print_lines(tmpbuf,NOMARKING)) { ! 648: if (cmd > 0) ! 649: pushchar(cmd); ! 650: break; ! 651: } ! 652: } ! 653: int_count = 0; ! 654: } ! 655: ! 656: /* find a newsgroup in .newsrc */ ! 657: ! 658: NG_NUM ! 659: find_ng(ngnam) ! 660: char *ngnam; ! 661: { ! 662: register NG_NUM ngnum; ! 663: #ifdef HASHNG ! 664: register int hashix = hash(ngnam); ! 665: register int incr = 1; ! 666: ! 667: while ((ngnum = hashtbl[hashix]) >= 0) { ! 668: if (strEQ(rcline[ngnum], ngnam) && toread[ngnum] >= TR_UNSUB) ! 669: return ngnum; ! 670: hashix = (hashix + incr) % HASHSIZ; ! 671: incr += 2; /* offsets from original are in n*2 */ ! 672: } ! 673: return nextrcline; /* = notfound */ ! 674: ! 675: #else /* just do linear search */ ! 676: ! 677: for (ngnum = 0; ngnum < nextrcline; ngnum++) { ! 678: if (strEQ(rcline[ngnum],ngnam)) ! 679: break; ! 680: } ! 681: return ngnum; ! 682: #endif ! 683: } ! 684: ! 685: void ! 686: cleanup_rc() ! 687: { ! 688: register NG_NUM ngx; ! 689: register NG_NUM bogosity = 0; ! 690: ! 691: #ifdef VERBOSE ! 692: IF(verbose) ! 693: fputs("Checking out your .newsrc--hang on a second...\n",stdout) ! 694: FLUSH; ! 695: ELSE ! 696: #endif ! 697: #ifdef TERSE ! 698: fputs("Checking .newsrc--hang on...\n",stdout) FLUSH; ! 699: #endif ! 700: for (ngx = 0; ngx < nextrcline; ngx++) { ! 701: if (toread[ngx] >= TR_UNSUB) { ! 702: set_toread(ngx); /* this may reset newsgroup */ ! 703: /* or declare it bogus */ ! 704: } ! 705: if (toread[ngx] == TR_BOGUS) ! 706: bogosity++; ! 707: } ! 708: for (ngx = nextrcline-1; ngx >= 0 && toread[ngx] == TR_BOGUS; ngx--) ! 709: bogosity--; /* discount already moved ones */ ! 710: if (nextrcline > 5 && bogosity > nextrcline / 2) { ! 711: fputs( ! 712: "It looks like the active file is messed up. Contact your news administrator,\n\ ! 713: ",stdout); ! 714: fputs( ! 715: "leave the \"bogus\" groups alone, and they may come back to normal. Maybe.\n\ ! 716: ",stdout) FLUSH; ! 717: } ! 718: #ifdef RELOCATE ! 719: else if (bogosity) { ! 720: #ifdef VERBOSE ! 721: IF(verbose) ! 722: fputs("Moving bogus newsgroups to the end of your .newsrc.\n", ! 723: stdout) FLUSH; ! 724: ELSE ! 725: #endif ! 726: #ifdef TERSE ! 727: fputs("Moving boguses to the end.\n",stdout) FLUSH; ! 728: #endif ! 729: for (; ngx >= 0; ngx--) { ! 730: if (toread[ngx] == TR_BOGUS) ! 731: relocate_newsgroup(ngx,nextrcline-1); ! 732: } ! 733: #ifdef DELBOGUS ! 734: reask_bogus: ! 735: in_char("Delete bogus newsgroups? [ny] "); ! 736: putchar('\n') FLUSH; ! 737: setdef(buf,"n"); ! 738: #ifdef VERIFY ! 739: printcmd(); ! 740: #endif ! 741: if (*buf == 'h') { ! 742: #ifdef VERBOSE ! 743: IF(verbose) ! 744: fputs("\ ! 745: Type y to delete bogus newsgroups.\n\ ! 746: Type n or SP to leave them at the end in case they return.\n\ ! 747: ",stdout) FLUSH; ! 748: ELSE ! 749: #endif ! 750: #ifdef TERSE ! 751: fputs("y to delete, n to keep\n",stdout) FLUSH; ! 752: #endif ! 753: goto reask_bogus; ! 754: } ! 755: else if (*buf == 'n' || *buf == 'q') ! 756: ; ! 757: else if (*buf == 'y') { ! 758: while (toread[nextrcline-1] == TR_BOGUS && nextrcline > 0) ! 759: --nextrcline; /* real tough, huh? */ ! 760: } ! 761: else { ! 762: fputs(hforhelp,stdout) FLUSH; ! 763: settle_down(); ! 764: goto reask_bogus; ! 765: } ! 766: #endif ! 767: } ! 768: #else ! 769: #ifdef VERBOSE ! 770: IF(verbose) ! 771: fputs("You should edit bogus newsgroups out of your .newsrc.\n", ! 772: stdout) FLUSH; ! 773: ELSE ! 774: #endif ! 775: #ifdef TERSE ! 776: fputs("Edit boguses from .newsrc.\n",stdout) FLUSH; ! 777: #endif ! 778: #endif ! 779: paranoid = FALSE; ! 780: } ! 781: ! 782: #ifdef HASHNG ! 783: /* make an entry in the hash table for the current newsgroup */ ! 784: ! 785: void ! 786: sethash(thisng) ! 787: NG_NUM thisng; ! 788: { ! 789: register int hashix = hash(rcline[thisng]); ! 790: register int incr = 1; ! 791: #ifdef DEBUGGING ! 792: static int hashhits = 0, hashtries = 0; ! 793: #endif ! 794: ! 795: #ifdef DEBUGGING ! 796: hashtries++; ! 797: #endif ! 798: while (hashtbl[hashix] >= 0) { ! 799: #ifdef DEBUGGING ! 800: hashhits++; ! 801: if (debug & DEB_HASH) { ! 802: printf(" Hash hits: %d / %d\n",hashhits, hashtries) FLUSH; ! 803: } ! 804: hashtries++; ! 805: #endif ! 806: hashix = (hashix + incr) % HASHSIZ; ! 807: incr += 2; /* offsets from original are in n*2 */ ! 808: } ! 809: hashtbl[hashix] = thisng; ! 810: } ! 811: ! 812: short prime[] = {1,2,-3,-5,7,11,-13,-17,19,23,-29,-31,37,41,-43,-47,53,57,-59, ! 813: -61,67,71,-73,-79,83,89,-97,-101,1,1,1,1,1,1,1,1,1,1,1,1}; ! 814: ! 815: int ! 816: hash(ngnam) ! 817: register char *ngnam; ! 818: { ! 819: register int i = 0; ! 820: register int ch; ! 821: register int sum = 0; ! 822: #ifdef DEBUGGING ! 823: char *ngn = ngnam; ! 824: #endif ! 825: ! 826: while (ch = *ngnam++) { ! 827: sum += (ch + i) * prime[i]; /* gives ~ 10% hits at 25% full */ ! 828: i++; ! 829: } ! 830: #ifdef DEBUGGING ! 831: if (debug & DEB_HASH) ! 832: printf("hash(%s) => %d => %d\n",ngn, sum, (sum<0?-sum:sum)%HASHSIZ) ! 833: FLUSH; ! 834: #endif ! 835: if (sum < 0) ! 836: sum = -sum; ! 837: return sum % HASHSIZ; ! 838: } ! 839: ! 840: #endif ! 841: ! 842: void ! 843: newsrc_check() ! 844: { ! 845: rcfp = fopen(rcname,"r"); /* open it */ ! 846: if (rcfp == Nullfp) { /* not there? */ ! 847: #ifdef VERBOSE ! 848: IF(verbose) ! 849: fputs("\ ! 850: Trying to set up a .newsrc file--running newsetup...\n\n\ ! 851: ",stdout) FLUSH; ! 852: ELSE ! 853: #endif ! 854: #ifdef TERSE ! 855: fputs("Setting up .newsrc...\n",stdout) FLUSH; ! 856: #endif ! 857: if (doshell(sh,filexp(NEWSETUP)) || ! 858: (rcfp = fopen(rcname,"r")) == Nullfp) { ! 859: #ifdef VERBOSE ! 860: IF(verbose) ! 861: fputs("\ ! 862: Can't create a .newsrc--you must do it yourself.\n\ ! 863: ",stdout) FLUSH; ! 864: ELSE ! 865: #endif ! 866: #ifdef TERSE ! 867: fputs("(Fatal)\n",stdout) FLUSH; ! 868: #endif ! 869: finalize(1); ! 870: } ! 871: } ! 872: else { ! 873: UNLINK(rcbname); /* unlink backup file name */ ! 874: link(rcname,rcbname); /* and backup current name */ ! 875: } ! 876: } ! 877: ! 878: /* write out the (presumably) revised .newsrc */ ! 879: ! 880: void ! 881: write_rc() ! 882: { ! 883: register NG_NUM tmpng; ! 884: register char *delim; ! 885: ! 886: rcfp = fopen(rctname, "w"); /* open .newsrc */ ! 887: if (rcfp == Nullfp) { ! 888: printf("Can't recreate .newsrc\n") FLUSH; ! 889: finalize(1); ! 890: } ! 891: ! 892: /* write out each line*/ ! 893: ! 894: for (tmpng = 0; tmpng < nextrcline; tmpng++) { ! 895: if (rcnums[tmpng]) { ! 896: delim = rcline[tmpng] + rcnums[tmpng] - 1; ! 897: *delim = rcchar[tmpng]; ! 898: } ! 899: else ! 900: delim = Nullch; ! 901: #ifdef DEBUGGING ! 902: if (debug & DEB_NEWSRC_LINE) ! 903: printf("%s\n",rcline[tmpng]) FLUSH; ! 904: #endif ! 905: fprintf(rcfp,"%s\n",rcline[tmpng]); ! 906: if (delim) ! 907: *delim = '\0'; /* might still need this line */ ! 908: } ! 909: ! 910: fclose(rcfp); /* close .newsrc */ ! 911: UNLINK(rcname); ! 912: link(rctname,rcname); ! 913: UNLINK(rctname); ! 914: ! 915: if (writesoft) { ! 916: tmpfp = fopen(filexp(softname), "w"); /* open .rnsoft */ ! 917: if (tmpfp == Nullfp) { ! 918: printf(cantcreate,filexp(softname)) FLUSH; ! 919: return; ! 920: } ! 921: for (tmpng = 0; tmpng < nextrcline; tmpng++) { ! 922: fprintf(tmpfp,"%ld\n",(long)softptr[tmpng]); ! 923: } ! 924: fclose(tmpfp); ! 925: } ! 926: } ! 927: ! 928: void ! 929: get_old_rc() ! 930: { ! 931: UNLINK(rctname); ! 932: link(rcname,rctname); ! 933: UNLINK(rcname); ! 934: link(rcbname,rcname); ! 935: UNLINK(rcbname); ! 936: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.