[net.sources.bugs] Rn bug patch #22

jonab@sdcrdcf.UUCP (Jonathan Biggar) (11/17/84)

System: rn version 4.1
Bug #: 22
Priority: LOW
Subject: unread article count can get off when articles expire
Index: bits.c
Prereq: 4.1
From: uddeborg@chalmers.UUCP (G|ran Uddeborg)

Description:
	Rn makes a faulty assumption about the read/unread status of
	certain expired articles when entering a newsgroup, with the
	result that the number of articles reported as remaining to be read
	will be low, and possibly even negative.  This doesn't hurt anything
	in particular, but it is somewhat disconcerting.

Repeat-By:
	Find a newsgroup in which the first existing article is followed
	by a range of expired articles.  If for instance, you have a newsgroup
	in which article 100 exists, as well as articles 200-300, edit your
	.newsrc to read:

	net.blurfl: 1-100,110-190,200-299

	If you then enter this newsgroup with rn, in trying to process
	expired articles 101-199 it will forget that you have read 110-190,
	and count them twice when it marks 101-199 as read.  In this example
	you would end up with rn saying there are about -80 unread articles.

Fix:	From rn, say "| patch -d DIR", where DIR is your rn source directory.
	Outside of rn, say "cd DIR; patch <thisarticle".  If you don't have
	the patch program, apply the following by hand, or get patch.

*** /tmp/,RCSt1015166	Wed Oct 31 12:01:42 1984
--- /tmp/,RCSt2015166	Wed Oct 31 12:01:45 1984
***************
*** 1,4
! /* $Header: bits.c,v 4.1 84/09/24 11:43:17 lwall Exp $
   *
   * $Log:	bits.c,v $
   * Revision 4.1  84/09/24  11:43:17  lwall

--- 1,4 -----
! /* $Header: bits.c,v 4.1.1.2 84/10/31 11:58:50 lwall Exp $
   *
   * $Log:	bits.c,v $
   * Revision 4.1.1.2  84/10/31  11:58:50  lwall
***************
*** 1,6
  /* $Header: bits.c,v 4.1 84/09/24 11:43:17 lwall Exp $
   *
   * $Log:	bits.c,v $
   * Revision 4.1  84/09/24  11:43:17  lwall
   * Real baseline.
   * 

--- 1,14 -----
  /* $Header: bits.c,v 4.1.1.2 84/10/31 11:58:50 lwall Exp $
   *
   * $Log:	bits.c,v $
+  * Revision 4.1.1.2  84/10/31  11:58:50  lwall
+  * initctl() wrongly assumed that expired articles were unread when trying
+  * to adjust firstart, and misadjusted toread[ng].  toread[ng] is now
+  * recomputed from scratch.
+  * 
+  * Revision 4.1.1.1  84/09/25  13:20:31  lwall
+  * Branch for sdcrdcf changes.
+  * 
   * Revision 4.1  84/09/24  11:43:17  lwall
   * Real baseline.
   * 
***************
*** 370,375
      char *mybuf = buf;			/* place to decode rc line */
      register char *s, *c, *h;
      register long i;
      
  #ifdef DELAYMARK
      dmcount = 0;

--- 378,384 -----
      char *mybuf = buf;			/* place to decode rc line */
      register char *s, *c, *h;
      register long i;
+     register ART_NUM unread;
      
  #ifdef DELAYMARK
      dmcount = 0;
***************
*** 403,409
      else
  	firstart = 1;			/* all the bits are valid for now */
      if (absfirst > firstart) {		/* do we know already? */
- 	toread[ng] -= (ART_UNREAD)(absfirst - firstart);
  	firstart = absfirst;		/* no point calling getngmin again */
      }
      else if (artopen(firstart) == Nullfp) {

--- 412,417 -----
      else
  	firstart = 1;			/* all the bits are valid for now */
      if (absfirst > firstart) {		/* do we know already? */
  	firstart = absfirst;		/* no point calling getngmin again */
      }
      else if (artopen(firstart) == Nullfp) {
***************
*** 410,416
  					/* first unread article missing? */
  	i = getngmin(".",firstart);	/* see if expire has been busy */
  	if (i) {			/* avoid a bunch of extra opens */
- 	    toread[ng] -= (ART_UNREAD)(i - firstart);
  	    firstart = i;
  	}
      }

--- 418,423 -----
  					/* first unread article missing? */
  	i = getngmin(".",firstart);	/* see if expire has been busy */
  	if (i) {			/* avoid a bunch of extra opens */
  	    firstart = i;
  	}
      }
***************
*** 419,424
  	subj_to_get = firstart;
  #   endif
  #endif
      for (i=OFFSET(firstart)/BITSPERBYTE; i<ctlsize; i++)
  	ctlarea[i] = 0;			/* assume unread */
  #ifdef DEBUGGING

--- 426,432 -----
  	subj_to_get = firstart;
  #   endif
  #endif
+     unread = lastart - firstart + 1;	/* assume this range unread */
      for (i=OFFSET(firstart)/BITSPERBYTE; i<ctlsize; i++)
  	ctlarea[i] = 0;			/* assume unread */
  #ifdef DEBUGGING
***************
*** 442,447
  		min = firstart;
  	    if (max > lastart)
  		max = lastart;
  	    for (i=min; i<=max; i++)	/* for all articles in range */
  		/*NOSTRICT*/
  		ctl_set(i);		/* mark them read */

--- 450,457 -----
  		min = firstart;
  	    if (max > lastart)
  		max = lastart;
+ 	    if (min <= max)		/* non-null range? */
+ 		unread -= max - min + 1;/* adjust unread count */
  	    for (i=min; i<=max; i++)	/* for all articles in range */
  		/*NOSTRICT*/
  		ctl_set(i);		/* mark them read */
***************
*** 446,452
  		/*NOSTRICT*/
  		ctl_set(i);		/* mark them read */
  	}
! 	else if ((i = atol(s)) >= firstart && i <= lastart)
  					/* is single number reasonable? */
  	    /*NOSTRICT*/
  	    ctl_set(i);			/* mark it read */

--- 456,462 -----
  		/*NOSTRICT*/
  		ctl_set(i);		/* mark them read */
  	}
! 	else if ((i = atol(s)) >= firstart && i <= lastart) {
  					/* is single number reasonable? */
  	    /*NOSTRICT*/
  	    ctl_set(i);			/* mark it read */
***************
*** 450,455
  					/* is single number reasonable? */
  	    /*NOSTRICT*/
  	    ctl_set(i);			/* mark it read */
  #ifdef DEBUGGING
  	if (debug & DEB_CTLAREA_BITMAP) {
  	    printf("\n%s\n",s);

--- 460,467 -----
  					/* is single number reasonable? */
  	    /*NOSTRICT*/
  	    ctl_set(i);			/* mark it read */
+ 	    unread--;			/* decrement articles to read */
+ 	}
  #ifdef DEBUGGING
  	if (debug & DEB_CTLAREA_BITMAP) {
  	    printf("\n%s\n",s);
***************
*** 468,473
  #endif
      if (mybuf != buf)
  	free(mybuf);
      return 0;
  }
  

--- 480,486 -----
  #endif
      if (mybuf != buf)
  	free(mybuf);
+     toread[ng] = unread;
      return 0;
  }