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

Defined functions

IF defined in line 244; never used
add_newsgroup defined in line 380; used 2 times
cleanup_rc defined in line 685; used 3 times
get_old_rc defined in line 928; used 2 times
hash defined in line 815; used 3 times
list_newsgroups defined in line 625; used 3 times
newsrc_check defined in line 842; used 2 times
rcstuff_init defined in line 42; used 2 times
relocate_newsgroup defined in line 404; used 4 times
sethash defined in line 785; used 3 times

Defined variables

hashtbl defined in line 39; used 13 times
prime defined in line 812; used 1 times
rcbname defined in line 34; used 5 times
rcname defined in line 32; used 11 times
rctname defined in line 33; used 6 times
softname defined in line 35; used 4 times
Last modified: 1986-03-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3354
Valid CSS Valid XHTML 1.0 Strict