[net.news.b] fix for garbaged vnews display

mp@whuxle.UUCP (Mark Plotnick) (05/09/84)

vnews will occasionally have a garbaged display (missing and rearranged
lines) if you're running it on 4.1bsd and you have a terminal with an
odd number of columns (e.g. a BLIT).  The problem is very transient,
but it seems to happen when you have a blank line at the bottom of the
screen and you either type a space or a ^N.

The real problem is that it keeps a temp file whose byte count is a
multiple of the number of columns on the terminal.  At some point, the
program reads from the file (using fread), seeks from an even address to an odd
address, and then writes to the file (using putc).  After the first putc,
the I/O pointer gets some random value and subsequent putc's write
over the wrong part of the temp file.  I dimly remember a bug in the
stdio library that had to do with files opened for rw coupled with odd
fseeks, and I think this may be the same bug.

The fix for visual.c follows; perhaps someone who has the 4.1bsd stdio
fix can post it to the net.
	Mark Plotnick

*** visual.c	Wed May  9 15:48:10 1984
--- visual.c.new	Wed May  9 15:52:43 1984
***************
*** 51,56
  #include "db.h"
  #endif
  
  
  #define ARTWLEN	(ROWS-2)/* number of lines used to display article */
  #ifdef STATTOP

--- 51,57 -----
  #include "db.h"
  #endif
  
+ #define even(cols) ((cols&1) ? cols+1 : cols)
  
  #define ARTWLEN	(ROWS-2)/* number of lines used to display article */
  #ifdef STATTOP
***************
*** 1569,1575
  	register FILE *rtfp;		/* try to make it a litte faster */
  	register int i;
  
! 	p = line, i = COLS;
  	tfseek(linno, 1);
  	rtfp = tfp;
  	while (--i >= 0) {

--- 1570,1576 -----
  	register FILE *rtfp;		/* try to make it a litte faster */
  	register int i;
  
! 	p = line, i = even(COLS);
  	tfseek(linno, 1);
  	rtfp = tfp;
  	while (--i >= 0) {
***************
*** 1586,1592
  	char *line;
  	{
  	tfseek(linno, 0);
! 	fread(line, COLS, 1, tfp);
  	line[COLS] = '\0';
  	tflinno++;
  }

--- 1587,1593 -----
  	char *line;
  	{
  	tfseek(linno, 0);
! 	fread(line, even(COLS), 1, tfp);
  	line[COLS] = '\0';
  	tflinno++;
  }
***************
*** 1596,1602
  	static int last = 1;
  
  	if (linno != tflinno || wrflag != last) {
! 		fseek(tfp, (long)linno * COLS, 0);
  		tflinno = linno;
  		last = wrflag;
  	}

--- 1597,1603 -----
  	static int last = 1;
  
  	if (linno != tflinno || wrflag != last) {
! 		fseek(tfp, (long)linno * even(COLS), 0);
  		tflinno = linno;
  		last = wrflag;
  	}