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: }