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