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

Defined functions

IF defined in line 259; never used
add_newsgroup defined in line 422; used 4 times
cleanup_rc defined in line 736; used 3 times
find_ng defined in line 709; used 9 times
get_ng defined in line 247; used 4 times
get_old_rc defined in line 979; used 2 times
hash defined in line 866; used 3 times
list_newsgroups defined in line 676; used 3 times
newsrc_check defined in line 893; used 2 times
rcstuff_init defined in line 48; used 2 times
relocate_newsgroup defined in line 446; used 4 times
sethash defined in line 836; used 3 times

Defined variables

addnewbydefault defined in line 244; used 3 times
hashtbl defined in line 45; used 13 times
prime defined in line 863; used 1 times
rcbname defined in line 40; used 5 times
rcname defined in line 38; used 11 times
rctname defined in line 39; used 6 times
softname defined in line 41; used 4 times
Last modified: 1992-06-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3131
Valid CSS Valid XHTML 1.0 Strict