Annotation of 43BSD/contrib/nntp/rrn/rcstuff.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.