Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10 5/3/83; site stolaf.UUCP
Path: utzoo!linus!wivax!decvax!harpo!floyd!vax135!ariel!houti!hogpc!houxm!ihnp4!stolaf!borman
From: borman@stolaf.UUCP
Newsgroups: net.news.b
Subject: Fixes for bugs in 2.10 readnews
Message-ID: <1014@stolaf.UUCP>
Date: Sun, 5-Jun-83 22:14:27 EDT
Article-I.D.: stolaf.1014
Posted: Sun Jun  5 22:14:27 1983
Date-Received: Tue, 7-Jun-83 01:07:51 EDT
Organization: St. Olaf College, Northfield MN
Lines: 252


This article deals with a bug in readnews that clobbers your .newsrc,
and a speedup to readnews to avoid lots of unneccessary calls to access(2).

The bug is one that was in 2.9, and which I reported last summer,
but I guess they must have overlooked it in the 2.10 distro...
It has to do with getting your .newsrc clobbered, leaving only your
options line. The problem is that when readnews is reading in your
.newsrc, it checks after each line to see if it has been interrupted.
If it has, it just stops reading your .newsrc and effectively throws
away the rest of it.  The fix is to remove the check until after you
have read in the entire .newsrc file, and then take the appropriate
action.  It is fairly straight forward, the diffs to readnews.c are
listed below.

The second modification is to speed up readnews when you first start
reading a group for the first time. On sites that expire articles,
you eventually get lots of articles that don't exist. (like on our
system, fa.info-cpm has at least the first 1000 articles expired)
You start reading news for the first time, and you get to fa.info-cpm,
and readnews says "Oh, an new group! Let's see, is article 1 there?
nope. Is article 2 there? nope. Is article 3 there? nope..." and
so on and so on, so it does over 1000 calls to access(2), which is
really a waste.  My modifications solve this.  When readnews finds
5 consecutive articles that don't exist, it hauls off and opens up
the directory, and reads it in and finds the next article to show.
I use 5 because that seems to be a reasonable number.  It is possible
to have holes of a couple of articles, so you don't want to do this
every time you can't access an article. This modification should work
on systems that are not running 4.2 directories. (We are running V7)
Below are the changes, relative to the distributed versions of
readnews.c and readr.c.

			-Dave Borman, St. Olaf College
			{ihnp4, harpo}!stolaf!borman


	**** CHANGES TO KEEP YOUR .NEWSRC FROM GETTING CLOBBERED ****

diff -c ../vanilla/src/readnews.c readnews.c
*** ../vanilla/src/readnews.c	Wed May 25 12:58:16 1983
--- readnews.c	Fri Jun  3 02:05:59 1983
***************
*** 223,228
  		xxit(0);
  	}
  	if (!xflag && (rcfp = xfopen(newsrc, "r"))) {
  		while (!sigtrap && fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  			if (!nstrip(rcbuf))
  				xerror(".newsrc line too long");

--- 223,231 -----
  		xxit(0);
  	}
  	if (!xflag && (rcfp = xfopen(newsrc, "r"))) {
+ #ifdef FIX_SIGNALS
+ 		while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
+ #else
  		while (!sigtrap && fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  #endif FIX_SIGNALS
  			if (!nstrip(rcbuf))
***************
*** 224,229
  	}
  	if (!xflag && (rcfp = xfopen(newsrc, "r"))) {
  		while (!sigtrap && fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  			if (!nstrip(rcbuf))
  				xerror(".newsrc line too long");
  			if (++line >= LINES)

--- 227,233 -----
  		while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  #else
  		while (!sigtrap && fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
+ #endif FIX_SIGNALS
  			if (!nstrip(rcbuf))
  				xerror(".newsrc line too long");
  			if (++line >= LINES)
***************
*** 234,239
  		}
  		fclose(rcfp);
  	}
  	actfp = xfopen(ACTIVE, "r");
  
  #ifdef DEBUG

--- 238,255 -----
  		}
  		fclose(rcfp);
  	}
+ #ifdef FIX_SIGNALS
+ 	if (sigtrap) {
+ 		if (sigtrap == SIGHUP || !rcreadok)
+ 			xxit(0);
+ 		fprintf(stdout, "Abort (n)?  ");
+ 		fflush(stdout);
+ 		gets(bfr);
+ 		if (*bfr == 'y' || *bfr == 'Y')
+ 			xxit(0);
+ 		sigtrap = FALSE;
+ 	}
+ #endif FIX_SIGNALS
  	actfp = xfopen(ACTIVE, "r");
  
  #ifdef DEBUG
*** END OF DIFF ***


**** CHANGES TO ELIMINATE UNNECCESSARY CALLS TO ACCESS(2) ****

diff -c ../vanilla/src/readr.c readr.c
*** ../vanilla/src/readr.c	Wed May 25 12:58:29 1983
--- readr.c	Sun Jun  5 18:19:14 1983
***************
*** 968,973
  getnextart(minus)
  int minus;
  {
  	if (minus)
  		goto nextart2;	/* Kludge for "-" command. */
  

--- 1031,1044 -----
  getnextart(minus)
  int minus;
  {
+ #ifdef	FAST
+ 	int noaccess = 0;
+ #include 
+ 	struct direct dir;
+ 	long nextnum, tnum;
+ 	long atol();
+ #endif	FAST
+ 
  	if (minus)
  		goto nextart2;	/* Kludge for "-" command. */
  
***************
*** 1034,1039
  	fprintf(stderr, "filename = '%s'\n", filename);
  #endif
  	/* Decide if we want to show this article. */
  	if (ignorenews
  	|| access(filename, 4)
  	|| ((fp = fopen(filename, "r")) == NULL)

--- 1105,1155 -----
  	fprintf(stderr, "filename = '%s'\n", filename);
  #endif
  	/* Decide if we want to show this article. */
+ #ifdef	FAST
+ 	if (access(filename, 4)) {
+ 		/* 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;
+ 		fp = fopen(dirname(groupdir), "r");
+ 		if (fp == NULL) {
+ #ifdef	DEBUG
+ 	fprintf(stderr, "can't open groupdir (%s)\n", dirname(groupdir));
+ #endif
+ 			noaccess = 0;
+ 			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;
+ #ifdef	DEBUG
+ 	fprintf(stderr, "bit %d nextnum %ld\n", bit, nextnum);
+ #endif	DEBUG
+ 	} else
+ 		noaccess = 0;
+ #endif	FAST
  	if (ignorenews
  #ifndef	FAST
  	|| access(filename, 4)
***************
*** 1035,1040
  #endif
  	/* Decide if we want to show this article. */
  	if (ignorenews
  	|| access(filename, 4)
  	|| ((fp = fopen(filename, "r")) == NULL)
  	|| (hread(&h, fp, TRUE) == NULL)

--- 1151,1157 -----
  		noaccess = 0;
  #endif	FAST
  	if (ignorenews
+ #ifndef	FAST
  	|| access(filename, 4)
  #endif	FAST
  	|| ((fp = fopen(filename, "r")) == NULL)
***************
*** 1036,1041
  	/* Decide if we want to show this article. */
  	if (ignorenews
  	|| access(filename, 4)
  	|| ((fp = fopen(filename, "r")) == NULL)
  	|| (hread(&h, fp, TRUE) == NULL)
  	|| (!rfq && !select(&h, abs))) {

--- 1153,1159 -----
  	if (ignorenews
  #ifndef	FAST
  	|| access(filename, 4)
+ #endif	FAST
  	|| ((fp = fopen(filename, "r")) == NULL)
  	|| (hread(&h, fp, TRUE) == NULL)
  	|| (!rfq && !select(&h, abs))) {
***************
*** 1039,1044
  	|| ((fp = fopen(filename, "r")) == NULL)
  	|| (hread(&h, fp, TRUE) == NULL)
  	|| (!rfq && !select(&h, abs))) {
  #ifdef DEBUG
  		fprintf(stderr, "Bad article '%s'\n", filename);
  #endif

--- 1157,1165 -----
  	|| ((fp = fopen(filename, "r")) == NULL)
  	|| (hread(&h, fp, TRUE) == NULL)
  	|| (!rfq && !select(&h, abs))) {
+ #ifdef	FAST
+ 	badart:
+ #endif	FAST
  #ifdef DEBUG
  		fprintf(stderr, "Bad article '%s'\n", filename);
  #endif