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

Defined functions

add_newsgroup defined in line 359; used 2 times
cleanup_rc defined in line 664; used 3 times
find_ng defined in line 637; used 7 times
get_ng defined in line 224; used 4 times
get_old_rc defined in line 907; used 2 times
hash defined in line 794; used 3 times
list_newsgroups defined in line 604; used 3 times
newsrc_check defined in line 821; used 2 times
rcstuff_init defined in line 44; used 2 times
relocate_newsgroup defined in line 383; used 4 times
sethash defined in line 764; used 3 times

Defined variables

hashtbl defined in line 41; used 13 times
prime defined in line 791; used 1 times
rcbname defined in line 36; used 5 times
rcname defined in line 34; used 9 times
rctname defined in line 35; used 6 times
softname defined in line 37; used 4 times
Last modified: 1985-11-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3725
Valid CSS Valid XHTML 1.0 Strict