# 2.11BSD#431 - /usr/src/new/rn/rcstuff.c

##### Functions

    IF                X
    add_newsgroup     X
    cleanup_rc        X
    find_ng           X
    get_ng            X
    get_old_rc        X
    hash              X
    list_newsgroups   X
    newsrc_check      X
    rcstuff_init      X
    relocate_newsgroupX
    sethash           X
    write_rc          X

##### Variables

    hashtbl           X
    prime             X
    rcbname           X
    rcname            X
    rctname           X
    softname          X

       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

- in line 308, 344, 353
- in /usr/src/new/rn/rcstuff.h line 28

cleanup_rc defined in line 736; used 3 times

- in line 224
- in /usr/src/new/rn/rcstuff.h line 34
- in /usr/src/new/rn/rn.c line 165

find_ng defined in line 709; used 9 times

- in line 272, 609
- in /usr/src/new/rn/addng.c line 77-83(3)
- in /usr/src/new/rn/rcln.c line 62, 191
- in /usr/src/new/rn/rcstuff.h line 33
- in /usr/src/new/rn/rn.c line 96

get_ng defined in line 247; used 4 times

- in /usr/src/new/rn/addng.c line 112
- in /usr/src/new/rn/rcstuff.h line 27
- in /usr/src/new/rn/rn.c line 318-320(2)

get_old_rc defined in line 979; used 2 times

- in /usr/src/new/rn/rcstuff.h line 39
- in /usr/src/new/rn/rn.c line 509

hash defined in line 866; used 3 times

- in line 715, 840
- in /usr/src/new/rn/rcstuff.h line 36

list_newsgroups defined in line 676; used 3 times

- in line 582
- in /usr/src/new/rn/rcstuff.h line 32
- in /usr/src/new/rn/rn.c line 267

newsrc_check defined in line 893; used 2 times

- in line 87
- in /usr/src/new/rn/rcstuff.h line 37

rcstuff_init defined in line 48; used 2 times

- in /usr/src/new/rn/init.c line 164
- in /usr/src/new/rn/rcstuff.h line 26

relocate_newsgroup defined in line 446; used 4 times

- in line 415, 439, 782
- in /usr/src/new/rn/rcstuff.h line 30

sethash defined in line 836; used 3 times

- in line 160, 436
- in /usr/src/new/rn/rcstuff.h line 35

write_rc defined in line 931; used 6 times

- in /usr/src/new/rn/bits.c line 71
- in /usr/src/new/rn/final.c line 161
- in /usr/src/new/rn/ng.c line 524
- in /usr/src/new/rn/rcln.c line 51
- in /usr/src/new/rn/rcstuff.h line 38
- in /usr/src/new/rn/rn.c line 506

#### Defined variables

addnewbydefault defined in line 244; used 3 times

- in line 306, 351, 518

hashtbl defined in line 45; used 13 times

- in line 63, 230, 470-473(4), 626-629(4), 718, 849, 860

prime defined in line 863; used 1 times

- in line 878

rcbname defined in line 40; used 5 times

- in line 82, 924-925(2), 985-986(2)

rcname defined in line 38; used 11 times

- in line 71-77(3), 896, 909, 925, 962-963(2), 983-985(3)

rctname defined in line 39; used 6 times

- in line 81, 937, 963-964(2), 982-983(2)

softname defined in line 41; used 4 times

- in line 83, 91, 967-969(2)

Last modified: 1992-06-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2848 |