Annotation of 43BSD/contrib/news/src/rfuncs.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This software is Copyright (c) 1986 by Rick Adams.
        !             3:  *
        !             4:  * Permission is hereby granted to copy, reproduce, redistribute or
        !             5:  * otherwise use this software as long as: there is no monetary
        !             6:  * profit gained specifically from the use or reproduction or this
        !             7:  * software, it is not sold, rented, traded or otherwise marketed, and
        !             8:  * this copyright notice is included prominently in any copy
        !             9:  * made.
        !            10:  *
        !            11:  * The author make no claims as to the fitness or correctness of
        !            12:  * this software for any use whatsoever, and it is provided as is. 
        !            13:  * Any use of this software is at the user's own risk.
        !            14:  *
        !            15:  * rfuncs - functions for readnews.
        !            16:  */
        !            17: 
        !            18: #ifdef SCCSID
        !            19: static char    *SccsId = "@(#)rfuncs.c 2.29    3/19/86";
        !            20: #endif /* SCCSID */
        !            21: 
        !            22: /*LINTLIBRARY*/
        !            23: 
        !            24: #include "rparams.h"
        !            25: 
        !            26: char lentab[LINES];    /* length of newsgroupname for each rcline */
        !            27: long nngsize;          /* The next upcoming value of ngsize. */
        !            28: long nminartno;                /* Smallest article number in this group */
        !            29: int BITMAPSIZE = 0;
        !            30: 
        !            31: nextng()
        !            32: {
        !            33:        long    curpos;
        !            34: #ifdef DEBUG
        !            35:        fprintf(stderr, "nextng()\n");
        !            36: #endif
        !            37:        curpos = ftell(actfp);
        !            38: 
        !            39: next:
        !            40: #ifdef DEBUG
        !            41:        fprintf(stderr, "next:\n");
        !            42: #endif
        !            43:        if (actdirect == BACKWARD) {
        !            44:                if (back()) {
        !            45:                        (void) fseek(actfp, curpos, 0);
        !            46:                        return 1;
        !            47:                }
        !            48:                if (back()) {
        !            49:                        (void) fseek(actfp, curpos, 0);
        !            50:                        return 1;
        !            51:                }
        !            52:        }
        !            53:        if (fgets(afline, BUFLEN, actfp) == NULL)
        !            54:                return 1;
        !            55:        if (sscanf(afline, "%s %ld %ld", bfr, &nngsize, &nminartno) < 3) {
        !            56:                bfr[0] = '\0';
        !            57:                nngsize = 0;
        !            58:                nminartno = 0;
        !            59:        }
        !            60: #ifdef DEBUG
        !            61:        fprintf(stderr, "bfr = '%s'\n", bfr);
        !            62: #endif
        !            63: 
        !            64:        if (!ngmatch(bfr, header.nbuf))
        !            65:                goto next;
        !            66:        if (xflag)
        !            67:                readmode = SPEC;
        !            68:        else
        !            69:                readmode = NEXT;
        !            70:        if (selectng(bfr, TRUE, FALSE))
        !            71:                goto next;
        !            72:        return 0;
        !            73: }
        !            74: 
        !            75: 
        !            76: selectng(name, fastcheck, resubscribe)
        !            77: char   *name;
        !            78: {
        !            79:        register char   *ptr, punct = ',';
        !            80:        register int    i;
        !            81:        register char   *p;
        !            82:        register long   cur;
        !            83:        long    next = 0;
        !            84:        FILE *af;
        !            85:        long s, sm;
        !            86:        char buf[100], n[100];
        !            87: 
        !            88: #ifdef DEBUG
        !            89:        fprintf(stderr,"selectng: groupdir = %s\n", groupdir);
        !            90: #endif /* DEBUG */
        !            91:        if (*groupdir)
        !            92:                updaterc();
        !            93:        last = 1;
        !            94:        if (strcmp(name, bfr)) {
        !            95:                af = xfopen(ACTIVE, "r");
        !            96:                while (fgets(buf, sizeof buf, af) != NULL) {
        !            97:                        if (sscanf(buf, "%s %ld %ld", n, &s, &sm) == 3 &&
        !            98:                             strcmp(n, name) == 0) {
        !            99:                                ngsize = s;
        !           100:                                minartno = sm;
        !           101:                                break;
        !           102:                        }
        !           103:                }
        !           104:                (void) fclose(af);
        !           105:        } else {
        !           106:                ngsize = nngsize;
        !           107:                minartno = nminartno;
        !           108:        }
        !           109: #ifdef DEBUG
        !           110:        fprintf(stderr, "selectng(%s) sets ngsize to %ld, minartno to %ld\n",
        !           111:                name, ngsize, minartno);
        !           112: #endif
        !           113:        (void) strcpy(groupdir, name);
        !           114:        if (!xflag) {
        !           115:                i = findrcline(name);
        !           116:                if (i >= 0) {
        !           117:                        if (p = index(rcline[i], '!')) {
        !           118:                                switch (resubscribe) {
        !           119:                                case FALSE:
        !           120:                                        groupdir[0] = 0;
        !           121:                                        return 1;
        !           122:                                case TRUE:
        !           123:                                        *p = ':';
        !           124:                                        break;
        !           125:                                case PERHAPS:
        !           126:                                        zapng = TRUE;
        !           127:                                        break;
        !           128:                                }
        !           129:                        } else
        !           130:                                p = index(rcline[i], ':');
        !           131:                        if (!p) /* shouldn't happen */
        !           132:                                p = rcline[i];
        !           133:                        while (*++p == ' ')
        !           134:                                ;
        !           135:                        (void) sprintf(rcbuf, "%s%s%ld", rcline[i],
        !           136:                                *p == '\0' ? " " : ",", ngsize+1);
        !           137:                }
        !           138:                else
        !           139:                        (void) sprintf(rcbuf, "ng: %ld", ngsize+1);
        !           140:        } else
        !           141:                (void) sprintf(rcbuf, "ng: %ld", ngsize+1);
        !           142: #ifdef DEBUG
        !           143:        fprintf(stderr, "rcbuf set to %s\n", rcbuf);
        !           144: #endif /* DEBUG */
        !           145: 
        !           146:        /*
        !           147:         * Fast check for common case: 1-###
        !           148:         */
        !           149:        if (fastcheck) {
        !           150:                p = rcbuf;
        !           151:                while (*p != ' ')
        !           152:                        p++;
        !           153:                while (*p == ' ')
        !           154:                        p++;
        !           155:                if (*p++ == '1' && *p++ == '-') {
        !           156:                        cur = 0;
        !           157:                        while (isdigit(*p))
        !           158:                                cur = 10 * cur + *p++ - '0';
        !           159:                        if (*p == ',' && cur == ngsize) {
        !           160: #ifdef DEBUG
        !           161:                                fprintf(stderr, "Group: %s, all read\n", groupdir);
        !           162: #endif
        !           163:                                groupdir[0] = 0;
        !           164:                                return 1;
        !           165:                        }
        !           166:                        if (cur > ngsize) {
        !           167:                                /*
        !           168:                                 * Claim to have read articles
        !           169:                                 * which "active" believes have
        !           170:                                 * never existed - we believe "active"
        !           171:                                 */
        !           172:                                fprintf(stderr,
        !           173:                                        "%s %s...\r\n\t%s %ld to %ld\r\n",
        !           174:                                        "Warning: newsgroup", groupdir,
        !           175:                                        "last article claimed read reset from",
        !           176:                                        cur, ngsize);
        !           177:                        }
        !           178:                }
        !           179:        }
        !           180: 
        !           181: /*
        !           182:  * The key to understanding this piece of code is that a bit is set iff
        !           183:  * that article has NOT been read.  Thus, we fill in the holes when
        !           184:  * commas are found (e.g. 1-20,30-35 will result in filling in the 21-29
        !           185:  * holes), and so we assume the newsrc file is properly ordered, the way
        !           186:  * we write it out.
        !           187:  */
        !           188:        if ((ngsize-minartno) > BITMAPSIZE) {
        !           189:                /* This should never happen */
        !           190:                (void) xerror("Bitmap not large enough for newsgroup %s", groupdir);
        !           191:        }
        !           192: 
        !           193:        cur = 0;
        !           194:        bzero(bitmap, (int) (ngsize-minartno)/8+1); /* 8 bits per character */
        !           195: 
        !           196:        /* Decode the .newsrc line indicating what we have read. */
        !           197:        for (ptr = rcbuf; *ptr && *ptr != ':'; ptr++)
        !           198:                ;
        !           199:        while (*ptr) {
        !           200:                while (!isdigit(*ptr) && *ptr)
        !           201:                        ptr++;
        !           202:                if (!*ptr)
        !           203:                        break;
        !           204:                (void) sscanf(ptr, "%ld", &next);
        !           205:                if (punct == ',') {
        !           206:                        while (++cur < next) {
        !           207:                                set(cur);
        !           208:                        }
        !           209:                }
        !           210:                cur = next;
        !           211:                while (!ispunct(*ptr) && *ptr)
        !           212:                        ptr++;
        !           213:                punct = *ptr;
        !           214:        }
        !           215:        if (rflag)
        !           216:                bit = ngsize+1;
        !           217:        else
        !           218:                bit = minartno -1;
        !           219:        nextbit();
        !           220:        ngrp = 1;
        !           221:        return 0;
        !           222: }
        !           223: 
        !           224: #ifdef TMAIL
        !           225: catchterm()
        !           226: {
        !           227:        (void) unlink(infile);
        !           228:        (void) unlink(outfile);
        !           229:        xxit(0);
        !           230: }
        !           231: 
        !           232: 
        !           233: /*
        !           234:  * The -M (Mail) interface.  This code is a reasonably simple model for
        !           235:  * writing other interfaces.  We write out all relevant articles to
        !           236:  * a temp file, then invoke Mail with an option to have it tell us which
        !           237:  * articles it read.  Finally we count those articles as really read.
        !           238:  */
        !           239: Mail()
        !           240: {
        !           241:        register FILE *fp = NULL, *ofp;
        !           242:        struct hbuf h;
        !           243:        register char   *ptr, *fname;
        !           244:        int     news = 0;
        !           245:        register int i;
        !           246: 
        !           247:        for(i=0;i<NUNREC;i++)
        !           248:                h.unrec[i] = NULL;
        !           249: 
        !           250:        ofp = xfopen(mktemp(outfile), "w");
        !           251:        if (aflag && *datebuf)
        !           252:                if ((atime = cgtdate(datebuf)) == -1)
        !           253:                        xerror("Cannot parse date string");
        !           254:        while (!nextng())
        !           255:                while (bit <= ngsize) {
        !           256:                        (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit);
        !           257:                        if (access(filename, 4)
        !           258:                        || ((fp = fopen(filename, "r")) == NULL)
        !           259:                        || (hread(&h, fp, TRUE) == NULL)
        !           260:                        || !aselect(&h, FALSE)) {
        !           261: #ifdef DEBUG
        !           262:                                fprintf(stderr, "Bad article '%s'\n", filename);
        !           263: #endif
        !           264:                                if (fp != NULL) {
        !           265:                                        (void) fclose(fp);
        !           266:                                        fp = NULL;
        !           267:                                }
        !           268:                                clear(bit);
        !           269:                                nextbit();
        !           270:                                continue;
        !           271:                        }
        !           272:                        fname = ptr = index(h.from, '(');
        !           273:                        if (fname) {
        !           274:                                while (ptr && ptr[-1] == ' ')
        !           275:                                        ptr--;
        !           276:                                if (ptr)
        !           277:                                        *ptr = 0;
        !           278:                                fname++;
        !           279:                                ptr = fname + strlen(fname) - 1;
        !           280:                                if (*ptr == ')')
        !           281:                                        *ptr = 0;
        !           282:                        }
        !           283:                        h.subtime = cgtdate(h.subdate);
        !           284:                        fprintf(ofp, "From %s %s",
        !           285: #ifdef INTERNET
        !           286:                            h.from[0] ? h.from :
        !           287: #endif
        !           288:                            h.path, ctime(&h.subtime));
        !           289:                        if (fname)
        !           290:                                fprintf(ofp, "Full-Name: %s\n", fname);
        !           291:                        fprintf(ofp, "Newsgroups: %s\n", h.nbuf);
        !           292:                        fprintf(ofp, "Subject: %s\n", h.title);
        !           293:                        fprintf(ofp, "Article-ID: %s/%ld\n\n", groupdir, bit);
        !           294:                        tprint(fp, ofp, TRUE);
        !           295:                        putc('\n', ofp);
        !           296:                        news = TRUE;
        !           297:                        (void) fclose(fp);
        !           298:                        fp = NULL;
        !           299:                        nextbit();
        !           300:                }
        !           301:        updaterc();
        !           302:        (void) fclose(ofp);
        !           303:        if (!news) {
        !           304:                if (!checkngs())
        !           305:                        fprintf(stderr, "No news.\n");
        !           306:                (void) unlink(outfile);
        !           307:                return;
        !           308:        }
        !           309:        (void) signal(SIGHUP, catchterm);
        !           310:        (void) signal(SIGTERM, catchterm);
        !           311:        (void) sprintf(bfr, "%s -f %s -T %s", TMAIL, outfile, mktemp(infile));
        !           312:        fwait(fsubr(ushell, bfr, (char *)NULL));
        !           313:        ofp = xfopen(infile, "r");
        !           314:        (void) fseek(actfp, 0L, 0);
        !           315:        while (fgets(afline, BUFLEN, actfp) != NULL) {
        !           316:                last = 0;
        !           317:                if (sscanf(afline, "%s %ld", bfr, &nngsize) < 2) {
        !           318:                        bfr[0] = '\0';
        !           319:                        nngsize = 0;
        !           320:                }
        !           321:                if (!ngmatch(bfr, header.nbuf))
        !           322:                        continue;
        !           323:                *groupdir = 0;
        !           324:                if (selectng(bfr, TRUE, FALSE))
        !           325:                        continue;
        !           326:                (void) fseek(ofp, 0L, 0);
        !           327:                while (fgets(groupdir, BUFLEN, ofp) != NULL) {
        !           328:                        (void) nstrip(groupdir);
        !           329:                        ptr = index(groupdir, '/');
        !           330:                        *ptr = 0;
        !           331:                        if (strcmp(bfr, groupdir))
        !           332:                                continue;
        !           333:                        (void) sscanf(++ptr, "%ld", &last);
        !           334:                        clear(last);
        !           335:                }
        !           336:                if (last) {
        !           337:                        (void) strcpy(groupdir, bfr);
        !           338:                        updaterc();
        !           339:                }
        !           340:        }
        !           341:        (void) unlink(infile);
        !           342:        (void) unlink(outfile);
        !           343: }
        !           344: #endif
        !           345: 
        !           346: updaterc()
        !           347: {
        !           348:        register long   cur = 1, next = 1;
        !           349:        register int i;
        !           350:        register char   *ptr;
        !           351:        char    oldptr;
        !           352: 
        !           353:        sprintf(rcbuf, "%s%c ", groupdir, zapng ? '!' : ':');
        !           354: 
        !           355:        zapng = FALSE;
        !           356: again:
        !           357:        ptr = &rcbuf[strlen(rcbuf)];
        !           358:        while (get(next) && next <= ngsize)
        !           359:                next++;
        !           360:        cur = next;
        !           361:        while (!(get(next)) && next <= ngsize)
        !           362:                next++;
        !           363:        if (cur == next) {
        !           364:                next = ngsize + 1;
        !           365:                goto skip;
        !           366:        }
        !           367:        if (ptr[-1] != ' ')
        !           368:                *ptr++ = ',';
        !           369:        if (cur + 1 == next)
        !           370:                (void) sprintf(ptr, "%ld", cur);
        !           371:        else
        !           372:                (void) sprintf(ptr, "%ld-%ld", cur, next - 1);
        !           373: skip:
        !           374:        if ((long) next > ngsize) {
        !           375:                if (strpbrk(rcbuf, ":!") == NULL)       /* bad line, huh?? */
        !           376:                        return;
        !           377:                ptr = index(rcbuf, ' ');
        !           378:                if (ptr == NULL)                        /* impossible */
        !           379:                        return;
        !           380:                ptr--;
        !           381:                oldptr = *ptr;
        !           382:                ptr[0] = ':';
        !           383:                ptr[1] = '\0';
        !           384:                i = findrcline(groupdir);
        !           385:                if (i >= 0) {
        !           386:                        ptr[0] = oldptr;
        !           387:                        ptr[1] = ' ';
        !           388:                        rcline[i] = realloc(rcline[i], (unsigned)(strlen(rcbuf) + 1));
        !           389:                        if (rcline[i] == NULL)
        !           390:                                xerror("Cannot realloc");
        !           391:                        (void) strcpy(rcline[i], rcbuf);
        !           392: #ifdef DEBUG
        !           393:                        fprintf(stderr," new rcline = %s\n", rcline[i]);
        !           394: #endif /* DEBUG */
        !           395:                        return;
        !           396:                }
        !           397:                if (++line > LINES)
        !           398:                        xerror("Too many newsgroups");
        !           399:                ptr[0] = oldptr;
        !           400:                ptr[1] = ' ';
        !           401:                if ((rcline[line] = malloc((unsigned)(strlen(rcbuf) + 1))) == NULL)
        !           402:                        xerror("Not enough memory");
        !           403:                (void) strcpy(rcline[line], rcbuf);
        !           404: #ifdef DEBUG
        !           405:                fprintf(stderr," new rcline2 = %s\n", rcline[line]);
        !           406: #endif /* DEBUG */
        !           407:                return;
        !           408:        }
        !           409:        cur = next;
        !           410:        goto again;
        !           411: }
        !           412: 
        !           413: newrc(rcname)
        !           414: char *rcname;
        !           415: {
        !           416:        register FILE *fp;
        !           417: 
        !           418:        if (close(creat(rcname, 0666))) {
        !           419:                (void) sprintf(bfr, "Cannot create %s", newsrc);
        !           420:                xerror(bfr);
        !           421:        }
        !           422: 
        !           423:        sprintf(bfr, "%s/users", LIB);
        !           424:        if ((fp = fopen(bfr, "a")) != NULL) {
        !           425:                fprintf(fp, "%s\n", username);
        !           426:                (void) fclose(fp);
        !           427:                (void) chmod(bfr, 0666);
        !           428:        }
        !           429: }
        !           430: 
        !           431: nextbit()
        !           432: {
        !           433: #ifdef DEBUG
        !           434:        fprintf(stderr,"nextbit() bit = %ld\n", bit);
        !           435: #endif /* DEBUG */
        !           436:        last = bit;
        !           437:        if (readmode == SPEC || xflag) {
        !           438:                if (rflag)
        !           439:                        bit--;
        !           440:                else
        !           441:                        bit++;
        !           442:                return;
        !           443:        }
        !           444:        if (rflag)
        !           445:                while (--bit, !get(bit) && bit > minartno)
        !           446:                        ;
        !           447:        else
        !           448:                while (++bit, !get(bit) && bit <= ngsize)
        !           449:                        ;
        !           450: #ifdef DEBUG
        !           451:        fprintf(stderr,"nextng leaves bit as %ld\n", bit);
        !           452: #endif /* DEBUG */
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Return TRUE if the user has not ruled out this article.
        !           457:  */
        !           458: aselect(hp, insist)
        !           459: register struct hbuf *hp;
        !           460: int    insist;
        !           461: {
        !           462:        if (insist)
        !           463:                return TRUE;
        !           464:        if (tflag && !titmat(hp, header.title))
        !           465:                return FALSE;
        !           466:        if (aflag && cgtdate(hp->subdate) < atime)
        !           467:                return FALSE;
        !           468:        if (index(hp->nbuf, ',') && !rightgroup(hp))
        !           469:                return FALSE;
        !           470:        if (fflag && (hp->followid[0] || prefix(hp->title, "Re:")))
        !           471:                return FALSE;
        !           472:        return TRUE;
        !           473: }
        !           474: 
        !           475: /*
        !           476:  * Code to avoid showing multiple articles for news.
        !           477:  * Works even if you exit news.
        !           478:  * Returns nonzero if we should show this article.
        !           479:  */
        !           480: rightgroup(hp)
        !           481: struct hbuf *hp;
        !           482: {
        !           483:        char ng[BUFLEN];
        !           484:        register char *p, *g;
        !           485:        int i, flag;
        !           486: 
        !           487:        strcpy(ng, hp->nbuf);
        !           488:        g = ng;
        !           489:        flag = 1;
        !           490:        while (g != NULL) {
        !           491:                p = index(g, ',');
        !           492:                if (p != NULL) {
        !           493:                        *p++ = '\0';
        !           494:                        while (*p == ' ')
        !           495:                                p++;
        !           496:                }
        !           497:                if (strcmp(g, groupdir) == 0)
        !           498:                        return flag;
        !           499:                if (ngmatch(g, header.nbuf)
        !           500:                    && ((i = findrcline(g)) >= 0
        !           501:                    && index(rcline[i], '!') == NULL))
        !           502:                        flag = 0;
        !           503:                g = p;
        !           504:        }
        !           505:        /* we must be in "junk" or "control" */
        !           506:        return TRUE;
        !           507: }
        !           508: 
        !           509: back()
        !           510: {
        !           511:        while (fseek(actfp, -2L, 1) != -1 && ftell(actfp) > 0L) {
        !           512:                if (getc(actfp) == '\n')
        !           513:                        return 0;
        !           514:        }
        !           515:        if (ftell(actfp) == 0L)
        !           516:                return 0;
        !           517:        return 1;
        !           518: }
        !           519: 
        !           520: /*
        !           521:  * Trap interrupts.
        !           522:  */
        !           523: onsig(n)
        !           524: int    n;
        !           525: {
        !           526:        (void) signal(n, onsig);
        !           527:        SigTrap = n;
        !           528:        if (rcreadok < 2) {
        !           529:                fprintf(stderr, "Aborted early\n");
        !           530:                xxit(0);
        !           531:        }
        !           532: }
        !           533: 
        !           534: /*
        !           535:  * finds the line in your .newsrc file (actually the in-core "rcline"
        !           536:  * copy of it) and returns the index into the array where it was found.
        !           537:  * -1 means it didn't find it.
        !           538:  *
        !           539:  * We play clever games here to make this faster.  It's inherently
        !           540:  * quadratic - we spend lots of CPU time here because we search through
        !           541:  * the whole .newsrc for each line.  The "prev" variable remembers where
        !           542:  * the last match was found; we start the search there and loop around
        !           543:  * to the beginning, in the hopes that the calls will be roughly in order.
        !           544:  */
        !           545: int
        !           546: findrcline(name)
        !           547: register char *name;
        !           548: {
        !           549:        register char * p;
        !           550:        register int    i;
        !           551:        register int    top;
        !           552:        register int    len;
        !           553:        static int      prev;
        !           554:        static int      didthru;
        !           555: 
        !           556:        for ( ; didthru <= line; ++didthru)
        !           557:                if ((p = index(rcline[didthru], '!')) != 0 ||
        !           558:                        (p = index(rcline[didthru], ':')) != 0) {
        !           559:                                lentab[didthru] = (int)(p - rcline[didthru]);
        !           560:                }
        !           561:        len = strlen(name);
        !           562:        top = line;
        !           563:        i = prev;
        !           564: loop:
        !           565:        for ( ; i <= top; ++i)
        !           566:                if (lentab[i] == len && rcline[i] != NULL &&
        !           567:                        strncmp(name, rcline[i], len) == 0)
        !           568:                        return prev = i;
        !           569:        if (i > line && line > prev - 1) {
        !           570:                i = 0;
        !           571:                top = prev - 1;
        !           572:                goto loop;
        !           573:        }
        !           574:        return -1;
        !           575: }
        !           576: 
        !           577: /*
        !           578:  * sortactive - make a local copy of the active file, sorted according
        !           579:  *   to the user's preferences, according to his .newsrc file.
        !           580:  */
        !           581: 
        !           582: struct table_elt {
        !           583:        int     rcindex;
        !           584:        long    maxart, minart;
        !           585:        char    yn;
        !           586: };
        !           587: 
        !           588: #ifdef SORTACTIVE
        !           589: static int
        !           590: rcsort(a, b)
        !           591: char *a, *b;
        !           592: {
        !           593:        return(((struct table_elt *)a)->rcindex -
        !           594:               ((struct table_elt *)b)->rcindex);
        !           595: }
        !           596: 
        !           597: static char *newactivename = "/tmp/newsaXXXXXX";
        !           598: #endif /* SORTACTIVE */
        !           599: 
        !           600: sortactive()
        !           601: {
        !           602:        register struct table_elt *tp;
        !           603:        register char *p;
        !           604:        register FILE *nfp, *afp;
        !           605:        char aline[BUFLEN], ngname[BUFLEN];
        !           606:        struct table_elt table[LINES];
        !           607:        int nlines = 0, i, delta, lastline;
        !           608: 
        !           609: #ifdef SORTACTIVE
        !           610:        /* make a new sorted copy of ACTIVE */
        !           611:        nfp = fopen(mktemp(newactivename), "w");
        !           612:        (void) chmod(newactivename, 0600);
        !           613:        if (nfp == NULL) {
        !           614:                perror(newactivename);
        !           615:                return;
        !           616:        }
        !           617: 
        !           618:        /* look up all the lines in ACTIVE, finding their positions in .newsrc */
        !           619:        p = ACTIVE;
        !           620:        ACTIVE = newactivename;
        !           621:        afp = xfopen(p, "r");
        !           622:        tp = table;
        !           623: #else /* !SORTACTIVE */
        !           624:        afp = xfopen(ACTIVE, "r");
        !           625: #endif /* !SORTACTIVE */
        !           626:        while (fgets(aline, sizeof aline, afp) != NULL) {
        !           627:                if (sscanf(aline,"%s %ld %ld %c", ngname, &tp->maxart, &tp->minart, &tp->yn) != 4) 
        !           628:                        xerror("Active file corrupt");
        !           629:                delta = tp->maxart - tp->minart;
        !           630:                if (delta >= BITMAPSIZE)
        !           631:                        BITMAPSIZE = delta+ 1;
        !           632: #ifdef SORTACTIVE
        !           633:                tp->rcindex = findrcline(ngname);
        !           634:                if (tp->rcindex < 0) {
        !           635:                        register FILE *f;
        !           636:                        /* it's not in his .newsrc, maybe it's aliased? */
        !           637:                        f = xfopen(ALIASES,"r");
        !           638:                        while (fscanf(f,"%s %s", afline, bfr) == 2
        !           639:                                && strcmp(ngname, bfr))
        !           640:                                ;
        !           641:                        (void) fclose(f);
        !           642:                        if (strcmp(ngname, bfr) == 0) {
        !           643:                                int j;
        !           644:                                j = findrcline(afline);
        !           645:                                if (j >= 0) {
        !           646:                                        p = rcline[j];
        !           647:                                        while (*p != ':' && *p != '!' && *p)
        !           648:                                                p++;
        !           649:                                        strcat(bfr, p);
        !           650:                                        rcline[j] = realloc(rcline[j], (unsigned)(strlen(bfr)+1));
        !           651:                                        if (rcline[j] == NULL)
        !           652:                                                xerror("Not enough memory");
        !           653:                                        strcpy(rcline[j], bfr);
        !           654:                                        tp++->rcindex = j;
        !           655:                                        continue;
        !           656:                                }
        !           657:                        }
        !           658:                        if (++line > LINES)
        !           659:                                xerror("Too many newsgroups");
        !           660:                        strcat(ngname, ":");
        !           661:                        rcline[line] = malloc((unsigned)(strlen(ngname) + 1));
        !           662:                        if (rcline[line] == NULL)
        !           663:                                xerror("Not enough memory");
        !           664:                        strcpy(rcline[line], ngname);
        !           665:                        tp->rcindex = line;
        !           666:                }
        !           667:                tp++;
        !           668: #endif /* SORTACTIVE */
        !           669:        }
        !           670:        (void) fclose(afp);
        !           671:        BITMAPSIZE =  8 * ((BITMAPSIZE+7) / 8);
        !           672:        bitmap = malloc((unsigned)BITMAPSIZE/8);
        !           673:        if (bitmap == NULL)
        !           674:                xerror("Can't malloc bitmap");
        !           675: 
        !           676: #ifdef SORTACTIVE
        !           677:        /* sort by position in user's .newsrc file (new groups come up last) */
        !           678:        nlines = tp - table;
        !           679:        qsort((char *)table, nlines, sizeof table[0], rcsort);
        !           680: 
        !           681:        tp = table;
        !           682:        lastline = tp->rcindex - 1;
        !           683:        /* copy active to newactive, in the new order */
        !           684:        for (i = 0; i < nlines; i++) {
        !           685:                while (++lastline < tp->rcindex) {
        !           686:                        fprintf(stderr, "Duplicate .newsrc line or bad group %s\n",
        !           687:                                rcline[lastline]);
        !           688:                        lentab[lastline] = 0;
        !           689:                        free(rcline[lastline]);
        !           690:                        rcline[lastline] = NULL;
        !           691:                }
        !           692:                if (rcline[tp->rcindex] == NULL)
        !           693:                        continue;
        !           694:                p = rcline[tp->rcindex];
        !           695:                while (*p != ':' && *p != '!')
        !           696:                        fputc(*p++, nfp);
        !           697:                (void) fprintf(nfp, " %ld %ld %c\n", tp->maxart, tp->minart,
        !           698:                        tp->yn);
        !           699:                tp++;
        !           700:        }
        !           701:        (void) fclose(nfp);
        !           702: #endif /* SORTACTIVE */
        !           703: }
        !           704: 
        !           705: /* ARGSUSED */
        !           706: checkngs(nbuf, f)
        !           707: char *nbuf;
        !           708: FILE *f;
        !           709: {
        !           710:        return 0;
        !           711: }

unix.superglobalmegacorp.com

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