Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10 Apollo; site apollo.uucp
Path: utzoo!watmath!clyde!floyd!harpo!decvax!wivax!apollo!rees
From: rees@apollo.uucp (Jim Rees)
Newsgroups: net.news
Subject: Re: readnews questions
Message-ID: <272@apollo.uucp>
Date: Mon, 19-Mar-84 11:36:24 EST
Article-I.D.: apollo.272
Posted: Mon Mar 19 11:36:24 1984
Date-Received: Tue, 20-Mar-84 02:04:37 EST
References: <2212@watcgl.UUCP>
Organization: Apollo Computer, Chelmsford, Mass.
Lines: 173

Here is the version of getnextart(), in readr.c, for news 2.10 or
later, to read the directory instead of trying to open each article.
This will make readnews faster for new users.  I don't remember now
who wrote this originally.  It had a bug or two having to do with
newsgroups with 0 articles in them, which I have fixed.

/*
 * Find the next article we want to consider, if we're done with
 * the last one, and show the header.
 */
getnextart(minus)
int minus;
{
	int noaccess = 0;
	struct direct dir;
	long nextnum, tnum;
	long atol();

	if (minus)
		goto nextart2;	/* Kludge for "-" command. */

	if (bit == obit)	/* Return if still on same article as last time */
		return 0;

	sigtrap = FALSE;

nextart:
	dgest = 0;
	if (bit < 1 && !rflag)
		bit = 1;

	/* If done with this newsgroup, find the next one. */
	while (ngsize <= 0 || ((long) bit > ngsize) || (rflag && bit < 1)) {
		int i;
		if (i=nextng()) {
			if (actdirect == BACKWARD) {
				fprintf(ofp, "Can't back up.\n");
				actdirect = FORWARD;
				continue;
			} 
			else if (rfq++ || pflag || cflag)
				return 1;
		}
		if (rflag)
			bit = ngsize + 1L;
		else
			bit = -1;
		if (uflag) {
			long now;
			time(&now);
			if (now - timelastsaved > 5*60 /* 5 minutes */) {
				printf("[Saving .newsrc]\n");
				fflush(stdout);
				writeoutrc();
				timelastsaved = now;
			}
		}
	}

nextart2:
#ifdef DEBUG
	fprintf(stderr, "article: %s/%d\n", groupdir, bit);
#endif
	if (rcreadok)
		rcreadok = 2;	/* have seen >= 1 article */
	sprintf(filename, "%s/%d", dirname(groupdir), bit);
	if (rfq && goodone[0])
		strcpy(filename, goodone);
	if (sigtrap) {
		if (sigtrap == SIGHUP)
			return 1;
		if (!rcreadok)
			xxit(0);
		fprintf(ofp, "Abort (n)?  ");
		fflush(ofp);
		gets(bfr);
		if (*bfr == 'y' || *bfr == 'Y')
			xxit(0);
		sigtrap = FALSE;
	}
#ifdef DEBUG
	fprintf(stderr, "filename = '%s'\n", filename);
#endif
	/* Decide if we want to show this article. */
	if (bit <= 0 || access(filename, 4)) {
#ifdef apollo
		/* Make sure we can still get at the spool directory */
		struct stat stbuf;

		if (stat(SPOOL, &stbuf) < 0) {
			fprintf(ofp, "Net failure has made news temporarily unavailable.\n");
			fprintf(ofp, "Do you want to quit (q) or try again ()? ");
			fflush(ofp);
			gets(bfr);
			if (*bfr == 'q' || *bfr == 'Q') {
				writeoutrc();
				xxit(0);
			} else
				goto nextart2;
		}
#endif
		/* since there can be holes in legal article numbers, */
		/* we wait till we hit 5 consecutive bad articles */
		/* before we haul off and scan the directory */
		if (++noaccess < 5)
			goto badart;
		noaccess = 0;
		fp = fopen(dirname(groupdir), "r");
		if (fp == NULL) {
#ifdef	DEBUG
	fprintf(stderr, "can't open groupdir (%s)\n", dirname(groupdir));
#endif
			goto badart;
		}
		nextnum = rflag ? 0 : ngsize;
		while (fread(&dir, sizeof(dir), 1, fp) == 1) {
			if (!dir.d_ino)
				continue;
			tnum = atol(dir.d_name);
#ifdef	DEBUG
	fprintf(stderr, "art %s (%ld) next %ld\n", dir.d_name, tnum, nextnum);
#endif	DEBUG
			if (tnum <= 0)
				continue;
			if (rflag ? (tnum > nextnum && tnum < bit)
				  : (tnum < nextnum && tnum > bit))
				nextnum = tnum;
		}
		if (rflag ? (nextnum >= bit) : (nextnum <= bit))
			goto badart;
		do {
			clear(bit);
			nextbit();
		} while (rflag ? (nextnum < bit) : (nextnum > bit));
		obit = -1;
		abs = FALSE;
		fclose(fp);
		goto nextart;
	} else
		noaccess = 0;
	if (ignorenews
	|| ((fp = fopen(filename, "r")) == NULL)
	|| (hread(&h, fp, TRUE) == NULL)
	|| (!rfq && !select(&h, abs))) {
	badart:
#ifdef DEBUG
		fprintf(stderr, "Bad article '%s'\n", filename);
#endif
		if (fp != NULL) {
			fclose(fp);
			fp = NULL;
		}
		clear(bit);
		obit = -1;
		nextbit();
		abs = FALSE;
		goto nextart;
	}
	abs = FALSE;
	actdirect = FORWARD;
	news = TRUE;
	hdr();
	if ((cflag && !lflag && !eflag) || pflag)
		tprint(fp, ofp, FALSE);
	if (cflag || lflag || eflag || pflag) {
		itsbeenseen(h.ident);
		sigtrap = FALSE;
		fclose(fp);
		fp = NULL;
	}
	obit = bit;
	return 0;
}