[icus.general] Unofficial patches for rn PL47

gil@limbic.UUCP (Gil Kloepfer Jr.) (08/28/90)

Here are some **UNOFFICIAL** patches for rn, passed-along to me a long
time ago by Todd Day and Andy Tannenbaum.  They used to work with rn PL40,
but they still work with rn PL47 when you hack on them a little.  I've
done it too often, and found it a pain.  So I remade the patches and
put them into one, and am posting it for general consumption.

Please please please keep the patch around so you can back it out when
these patches become official (if they do).  I'm sure there are many
who would benefit from them.

Gil.

-- Cut Here -- -- Cut Here -- -- Cut Here -- -- Cut Here --

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README enh_rn47.patch rnprtf.readme rnvis.HDR rnvis.readme
# Wrapped by gil@limbic on Mon Aug 27 21:05:37 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1258 characters\)
sed "s/^X//" >README <<'END_OF_README'
XMon Aug 27 20:53:25 CDT 1990
X
XThis is a combination of two patches which previously appeared on the net
Xfor rn PL40.  I've done the hacks to make them work all too many times,
Xand upon the recommendation of Lenny, I've put them into one big patch
Xwhich works for PL47.
X
XI've been using the patches as you see them for a while now.  Something
Xmay have gotten lost in the translation from the original files to this
Xshar.  If you notice any problems, please contact me (Gil Kloepfer)
Xat gil%limbic@ames.arc.nasa.gov as soon as possible so I can fix them.
X
XAlso be sure to read all the readme files accompanying this one.  Apply
Xthe patches by sending the enh_rn47.patch to Larry Wall's patch program,
Xas in:
X
X		patch <enh_rn47.patch
X
XWhen you're in the rn source directory.
X
XHere's what you get:
X
X-rw-r-----  1 gil     users     53773 Aug 27 20:49 enh_rn47.patch
X-rw-r-----  1 gil     users      3735 Aug 27 20:50 rnprtf.readme
X-rw-r-----  1 gil     users      1227 Aug 27 20:04 rnvis.HDR
X-rw-r-----  1 gil     users      1737 Aug 27 20:05 rnvis.readme
X
Xrnprtf allows you to modify the "=" listing with printf-type modifiers.
Xrnvis is a patch that gives rn a "visual" feel if desired.  The readme
Xfiles have much more information.  Please read them!
X
XEnjoy!
X
X
END_OF_README
if test 1258 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f enh_rn47.patch -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"enh_rn47.patch\"
else
echo shar: Extracting \"enh_rn47.patch\" \(53773 characters\)
sed "s/^X//" >enh_rn47.patch <<'END_OF_enh_rn47.patch'
X*** Wishlist	Mon Aug 27 20:04:23 1990
X--- ../prn/Wishlist	Mon Aug 27 20:28:37 1990
X***************
X*** 1,5
X  Generalized article set manipulation
X! 	Interface to subject listing.
X  	Recursive newsgroup visitation.
X  Virtual article abstract type to allow the following:
X  	Personalized header munging via % subs.
X
X--- 1,5 -----
X  Generalized article set manipulation
X! 	Interface to subject listing.  <===AHA!  I got that one!!! (-Todd-)
X  	Recursive newsgroup visitation.
X  Virtual article abstract type to allow the following:
X  	Personalized header munging via % subs.
X*** art.c	Mon Aug 27 20:04:33 1990
X--- ../prn/art.c	Mon Aug 27 20:28:40 1990
X***************
X*** 794,799
X      case '1': case '2': case '3': case '4': case '5':
X      case '6': case '7': case '8': case '9':
X      case '=':
X      case '?':
X      case 'c':	case 'C':	
X      case 'f':	case 'F':	
X
X--- 794,800 -----
X      case '1': case '2': case '3': case '4': case '5':
X      case '6': case '7': case '8': case '9':
X      case '=':
X+     case ';': case '%':
X      case '?':
X      case 'c':	case 'C':	
X      case 'f':	case 'F':	
X*** artsrch.c	Mon Aug 27 20:04:42 1990
X--- ../prn/artsrch.c	Mon Aug 27 20:28:41 1990
X***************
X*** 53,59
X  
X  #ifdef ARTSEARCH
X  int
X! art_search(patbuf,patbufsiz,get_cmd)
X  char *patbuf;				/* if patbuf != buf, get_cmd must */
X  int patbufsiz;
X  int get_cmd;				/*   be set to FALSE!!! */
X
X--- 53,59 -----
X  
X  #ifdef ARTSEARCH
X  int
X! art_search(patbuf,patbufsiz,get_cmd,force_doread,print_msg)
X  char *patbuf;				/* if patbuf != buf, get_cmd must */
X  int patbufsiz;
X  int get_cmd;				/*   be set to FALSE!!! */
X***************
X*** 57,62
X  char *patbuf;				/* if patbuf != buf, get_cmd must */
X  int patbufsiz;
X  int get_cmd;				/*   be set to FALSE!!! */
X  {
X      char *pattern;			/* unparsed pattern */
X      register char cmdchr = *patbuf;	/* what kind of search? */
X
X--- 57,64 -----
X  char *patbuf;				/* if patbuf != buf, get_cmd must */
X  int patbufsiz;
X  int get_cmd;				/*   be set to FALSE!!! */
X+ int force_doread;			/* search read arts also */
X+ int print_msg;
X  {
X      char *pattern;			/* unparsed pattern */
X      register char cmdchr = *patbuf;	/* what kind of search? */
X***************
X*** 143,149
X  	    mark_as_read(art);		/* this article has this subject */
X  	    if (!*h) {
X  #ifdef VERBOSE
X! 		IF(verbose)
X  		    fputs("\nCannot delete null subject.\n",stdout) FLUSH;
X  		ELSE
X  #endif
X
X--- 145,151 -----
X  	    mark_as_read(art);		/* this article has this subject */
X  	    if (!*h) {
X  #ifdef VERBOSE
X! 		IF(verbose && print_msg)
X  		    fputs("\nCannot delete null subject.\n",stdout) FLUSH;
X  		ELSE
X  #endif
X***************
X*** 148,154
X  		ELSE
X  #endif
X  #ifdef TERSE
X! 		    fputs("\nNull subject.\n",stdout) FLUSH;
X  #endif
X  		return SRCH_ABORT;
X  	    }
X
X--- 150,157 -----
X  		ELSE
X  #endif
X  #ifdef TERSE
X! 		    if (print_msg)
X! 		        fputs("\nNull subject.\n",stdout) FLUSH;
X  #endif
X  		return SRCH_ABORT;
X  	    }
X***************
X*** 153,159
X  		return SRCH_ABORT;
X  	    }
X  #ifdef VERBOSE
X! 	    else if (verbose)
X  		printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
X  #endif
X  	}
X
X--- 156,162 -----
X  		return SRCH_ABORT;
X  	    }
X  #ifdef VERBOSE
X! 	    else if (verbose && print_msg)
X  		printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
X  #endif
X  	}
X***************
X*** 174,180
X      }
X      if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
X  					/* compile regular expression */
X! 	printf("\n%s\n",s) FLUSH;
X  	return SRCH_ABORT;
X      }
X  #ifdef KILLFILES
X
X--- 177,184 -----
X      }
X      if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
X  					/* compile regular expression */
X! 	if (print_msg)
X! 	    printf("\n%s\n",s) FLUSH;
X  	return SRCH_ABORT;
X      }
X  #ifdef KILLFILES
X***************
X*** 199,205
X  #endif
X      if (cmdlst && index(cmdlst,'='))
X  	normal_return = SRCH_ERROR;	/* listing subjects is an error? */
X!     if (get_cmd) {
X  	fputs("\nSearching...\n",stdout) FLUSH;
X  					/* give them something to read */
X      }
X
X--- 203,209 -----
X  #endif
X      if (cmdlst && index(cmdlst,'='))
X  	normal_return = SRCH_ERROR;	/* listing subjects is an error? */
X!     if (get_cmd && print_msg) {
X  	fputs("\nSearching...\n",stdout) FLUSH;
X  					/* give them something to read */
X      }
X***************
X*** 242,248
X  	    if (wanted(compex,art,howmuch)) {
X  				    /* does the shoe fit? */
X  		if (cmdlst) {
X! 		    if (perform(cmdlst,TRUE)) {
X  			if (cmdlst)
X  			    free(cmdlst);
X  			return SRCH_INTR;
X
X--- 246,252 -----
X  	    if (wanted(compex,art,howmuch)) {
X  				    /* does the shoe fit? */
X  		if (cmdlst) {
X! 		    if (perform(cmdlst,TRUE,print_msg)) {
X  			if (cmdlst)
X  			    free(cmdlst);
X  			return SRCH_INTR;
X***************
X*** 254,260
X  		    return SRCH_FOUND;
X  		}
X  	    }
X! 	    else if (!cmdlst && ! (art%50)) {
X  		printf("...%ld",(long)art);
X  		fflush(stdout);
X  	    }
X
X--- 258,264 -----
X  		    return SRCH_FOUND;
X  		}
X  	    }
X! 	    else if (!cmdlst && !(art%50) && print_msg) {
X  		printf("...%ld",(long)art);
X  		fflush(stdout);
X  	    }
X*** bits.c	Mon Aug 27 20:05:07 1990
X--- ../prn/bits.c	Mon Aug 27 20:28:43 1990
X***************
X*** 196,201
X  	return;
X      }
X  #endif
X      if (!ctl_read(artnum)) {
X  	ctl_set(artnum);
X  	if (toread[ng] > TR_NONE)
X
X--- 196,204 -----
X  	return;
X      }
X  #endif
X+ #ifdef CACHESUBJ
X+     x_clear(artnum);
X+ #endif
X      if (!ctl_read(artnum)) {
X  	ctl_set(artnum);
X  	if (toread[ng] > TR_NONE)
X***************
X*** 504,509
X      ctlsize = (MEM_SIZE)(OFFSET(lastart)/BITSPERBYTE+20);
X  #endif lint
X      ctlarea = safemalloc(ctlsize);	/* allocate control area */
X  
X      /* now modify ctlarea to reflect what has already been read */
X  
X
X--- 507,515 -----
X      ctlsize = (MEM_SIZE)(OFFSET(lastart)/BITSPERBYTE+20);
X  #endif lint
X      ctlarea = safemalloc(ctlsize);	/* allocate control area */
X+ #ifdef CACHESUBJ
X+     xmark = safemalloc(ctlsize);
X+ #endif
X  
X      /* now modify ctlarea to reflect what has already been read */
X  
X***************
X*** 543,548
X      unread = lastart - firstbit + 1;	/* assume this range unread */
X      for (i=OFFSET(firstbit)/BITSPERBYTE; i<ctlsize; i++)
X  	ctlarea[i] = 0;			/* assume unread */
X  #ifdef DEBUGGING
X      if (debug & DEB_CTLAREA_BITMAP) {
X  	printf("\n%s\n",mybuf) FLUSH;
X
X--- 549,559 -----
X      unread = lastart - firstbit + 1;	/* assume this range unread */
X      for (i=OFFSET(firstbit)/BITSPERBYTE; i<ctlsize; i++)
X  	ctlarea[i] = 0;			/* assume unread */
X+ #ifdef CACHESUBJ
X+     for (i=OFFSET(absfirst)/BITSPERBYTE; i<ctlsize; i++)
X+ 	xmark[i] = 0;
X+     xmarked = FALSE;
X+ #endif
X  #ifdef DEBUGGING
X      if (debug & DEB_CTLAREA_BITMAP) {
X  	printf("\n%s\n",mybuf) FLUSH;
X***************
X*** 614,619
X  	if (newsize > ctlsize) {
X  	    newsize += 20;
X  	    ctlarea = saferealloc(ctlarea,newsize);
X  	    ctlsize = newsize;
X  	}
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X
X--- 625,633 -----
X  	if (newsize > ctlsize) {
X  	    newsize += 20;
X  	    ctlarea = saferealloc(ctlarea,newsize);
X+ #ifdef CACHESUBJ
X+ 	    xmark = saferealloc(xmark,newsize);
X+ #endif
X  	    ctlsize = newsize;
X  	}
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X***************
X*** 617,623
X  	    ctlsize = newsize;
X  	}
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X! 	for (i=lastart+1; i<=newlast; i++)
X  	    ctl_clear(i);	/* these articles are unread */
X  #ifdef CACHESUBJ
X  	if (subj_list != Null(char**)) {
X
X--- 631,637 -----
X  	    ctlsize = newsize;
X  	}
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X! 	for (i=lastart+1; i<=newlast; i++) {
X  	    ctl_clear(i);	/* these articles are unread */
X  #ifdef CACHESUBJ
X  	    x_clear(i);		/* these article are unmarked */
X***************
X*** 619,624
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X  	for (i=lastart+1; i<=newlast; i++)
X  	    ctl_clear(i);	/* these articles are unread */
X  #ifdef CACHESUBJ
X  	if (subj_list != Null(char**)) {
X  #ifndef lint
X
X--- 633,642 -----
X  	toread[ng] += (ART_UNREAD)(newlast-lastart);
X  	for (i=lastart+1; i<=newlast; i++) {
X  	    ctl_clear(i);	/* these articles are unread */
X+ #ifdef CACHESUBJ
X+ 	    x_clear(i);		/* these article are unmarked */
X+ #endif
X+ 	}
X  #ifdef CACHESUBJ
X  	if (subj_list != Null(char**)) {
X  #ifndef lint
X*** bits.h	Mon Aug 27 20:05:11 1990
X--- ../prn/bits.h	Mon Aug 27 20:28:44 1990
X***************
X*** 16,21
X  			/* with the following interpretation: */
X  			/*	0 => unread  */
X  			/*	1 => read    */
X  
X  /* if subscripting is faster than shifting on your machine, define this */
X  #undef USESUBSCRIPT
X
X--- 16,28 -----
X  			/* with the following interpretation: */
X  			/*	0 => unread  */
X  			/*	1 => read    */
X+ EXT MEM_SIZE ctlsize;			/* size of bitmap in bytes */
X+ #ifdef CACHESUBJ
X+ EXT char *xmark INIT(Nullch);	/* same here, but */
X+ 				/* 0 => unmarked */
X+ 				/* 1 => marked */
X+ EXT int xmarked INIT(FALSE);	/* any marks done? */
X+ #endif
X  
X  /* if subscripting is faster than shifting on your machine, define this */
X  #undef USESUBSCRIPT
X***************
X*** 36,41
X  #define ctl_set(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] |= pow2((OFFSET(a)) % BITSPERBYTE))
X  #define ctl_clear(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] &= ~pow2((OFFSET(a)) % BITSPERBYTE))
X  #define ctl_read(a) ((ctlarea[(OFFSET(a)) / BITSPERBYTE] & pow2((OFFSET(a)) % BITSPERBYTE)) != 0)
X  
X  #define was_read(a) ((a)<firstbit || ctl_read(a))
X  #endif lint
X
X--- 43,55 -----
X  #define ctl_set(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] |= pow2((OFFSET(a)) % BITSPERBYTE))
X  #define ctl_clear(a) (ctlarea[(OFFSET(a)) / BITSPERBYTE] &= ~pow2((OFFSET(a)) % BITSPERBYTE))
X  #define ctl_read(a) ((ctlarea[(OFFSET(a)) / BITSPERBYTE] & pow2((OFFSET(a)) % BITSPERBYTE)) != 0)
X+ 
X+ #ifdef CACHESUBJ
X+ #define x_set(a) (xmark[(OFFSET(a)) / BITSPERBYTE] |= pow2((OFFSET(a)) % BITSPERBYTE))
X+ #define x_clear(a) (xmark[(OFFSET(a)) / BITSPERBYTE] &= ~pow2((OFFSET(a)) % BITSPERBYTE))
X+ #define x_marked(a) ((xmark[(OFFSET(a)) / BITSPERBYTE] & pow2((OFFSET(a)) % BITSPERBYTE)) != 0)
X+ #endif
X+ 
X  
X  #define was_read(a) ((a)<firstbit || ctl_read(a))
X  #endif lint
X*** common.h	Mon Aug 27 20:05:24 1990
X--- ../prn/common.h	Mon Aug 27 20:32:37 1990
X***************
X*** 203,208
X   *		pattern that had brackets.  %0 matches the last bracket
X   *		matched, in case you had alternatives.
X   *
X   *	Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
X   *	Put _ in the middle to capitalize last component: %_c = net/Jokes
X   *
X
X--- 203,211 -----
X   *		pattern that had brackets.  %0 matches the last bracket
X   *		matched, in case you had alternatives.
X   *
X+  *	(#ifdef PADTRUNC) Put : in the middle for printf-style formatting:
X+  *		-ESUBJLINE="%:-50.50s %:.24t"
X+  *
X   *	Put ^ in the middle to capitalize the first letter: %^C = Net.jokes
X   *	Put _ in the middle to capitalize last component: %_c = net/Jokes
X   *
X***************
X*** 325,330
X  #define KILLFILES	/* automatic article killer files */
X  #define ARTSEARCH	/* pattern searches among articles */
X  			/* /, ?, ^N, ^P, k, K */
X  
X  /* some dependencies among options */
X  
X
X--- 328,334 -----
X  #define KILLFILES	/* automatic article killer files */
X  #define ARTSEARCH	/* pattern searches among articles */
X  			/* /, ?, ^N, ^P, k, K */
X+ #define PADTRUNC	/* printf-style command modifiers */
X  
X  /* some dependencies among options */
X  
X*** help.c	Mon Aug 27 20:05:39 1990
X--- ../prn/help.c	Mon Aug 27 20:28:45 1990
X***************
X*** 75,81
X  Type h at end of article for a description of these commands:\n\
X  ",STANDOUT)) ||
X      (cmd = print_lines("\
X! 	# $ & / = ? c C f F k K ^K m M number r R ^R s S u v w W Y ^ |\n\
X  \n\
X  (To return to the middle of the article after one of these commands, type ^L.)\n\
X  ",NOMARKING)) )
X
X--- 75,81 -----
X  Type h at end of article for a description of these commands:\n\
X  ",STANDOUT)) ||
X      (cmd = print_lines("\
X! 	# $ & / = ; % ? c C f F k K ^K m M number r R ^R s S u v w W Y ^ |\n\
X  \n\
X  (To return to the middle of the article after one of these commands, type ^L.)\n\
X  ",NOMARKING)) )
X***************
X*** 157,162
X  k	Mark current SUBJECT as read.\n\
X  K	Mark current SUBJECT as read, and save command in KILL file.\n\
X  =	List subjects of unread articles.\n\
X  u	Unsubscribe to this newsgroup.\n\
X  ^K	Edit local KILL file (the one for this newsgroup).\n\
X  q	Quit this newsgroup for now.\n\
X
X--- 157,164 -----
X  k	Mark current SUBJECT as read.\n\
X  K	Mark current SUBJECT as read, and save command in KILL file.\n\
X  =	List subjects of unread articles.\n\
X+ ;	Interactive subject list.\n\
X+ %	Same as ';', but include read articles.\n\
X  u	Unsubscribe to this newsgroup.\n\
X  ^K	Edit local KILL file (the one for this newsgroup).\n\
X  q	Quit this newsgroup for now.\n\
X***************
X*** 167,172
X      return 0;
X  }
X  
X  int
X  help_ng()
X  {
X
X--- 169,175 -----
X      return 0;
X  }
X  
X+ #ifdef CACHESUBJ
X  int
X  help_sub_scan()
X  {
X***************
X*** 168,173
X  }
X  
X  int
X  help_ng()
X  {
X      int cmd;
X
X--- 171,228 -----
X  
X  #ifdef CACHESUBJ
X  int
X+ help_sub_scan()
X+ {
X+     int cmd;
X+ 
X+     page_init();
X+     if ((cmd = print_lines("\
X+ Subject Scan/Display commands:\n\
X+ ",STANDOUT)) ||
X+     (cmd = print_lines("\n\
X+ SP,CR,r	Display article, and follow its thread in the Article\n\
X+ 	Selection Level.  Once in the Article Selection Level,\n\
X+ 	you may use any of its commands.  You may return via\n\
X+ 	';' or '%'.\n\
X+ j	Move down to next subject.\n\
X+ k	Move up to previous subject.\n\
X+ n	Display next page of subjects.\n\
X+ ",NOMARKING)) ||
X+     (cmd = print_lines("\
X+ p	Display previous page of subjects.\n\
X+ N,>	Go to next unread newsgroup.\n\
X+ P,<	Go to previous unread newsgroup.\n\
X+ t	Move to top of current page.\n\
X+ b	Move to bottom of current page.\n\
X+ T	Move to top of all subjects.\n\
X+ B	Move to bottom of all subjects.\n\
X+ d	Mark all articles with same subject as read.  Same\n\
X+ 	as 'k' at the Article Selection Level.\n\
X+ f	Toggle thread following mode.\n\
X+ x	Mark or unmark article.  After return from Article\n\
X+ 	Selection level, the next marked article will be read.\n\
X+ c	Clear all marked articles.\n\
X+ ",NOMARKING)) ||
X+     (cmd = print_lines("\
X+ /pattern\n\
X+ 	Search for next subject and, if found, put at top of\n\
X+ 	page.  Usage same as pattern searches at Article\n\
X+ 	Selection Level, including 'header' and 'all' searches.\n\
X+ ?pattern\n\
X+ 	Same as /pattern above, except search for previous subject.\n\
X+ ^L	Redraw screen.\n\
X+ ;	Show only unread subjects.  May force you to next unread\n\
X+ 	newsgroup if all subjects are read.\n\
X+ %	Show all subjects.\n\
X+ q	Quit this level.\n\
X+ ",NOMARKING)) )
X+ 	return cmd;
X+     get_anything();
X+     return 0;
X+ }
X+ #endif
X+ 
X+ int
X  help_ng()
X  {
X      int cmd;
X***************
X*** 185,190
X  y,SP	Do this newsgroup now.\n\
X  .cmd	Do this newsgroup, executing cmd as first command.\n\
X  =	Equivalent to .=<carriage return>.\n\
X  u	Unsubscribe from this newsgroup.\n\
X  c	Catch up (mark this newsgroup all read).\n\
X  ",NOMARKING) )
X
X--- 240,247 -----
X  y,SP	Do this newsgroup now.\n\
X  .cmd	Do this newsgroup, executing cmd as first command.\n\
X  =	Equivalent to .=<carriage return>.\n\
X+ ;	Interactive subject list.\n\
X+ %	Same as ';', but include read articles.\n\
X  u	Unsubscribe from this newsgroup.\n\
X  c	Catch up (mark this newsgroup all read).\n\
X  ",NOMARKING) )
X*** intrp.c	Mon Aug 27 20:05:50 1990
X--- ../prn/intrp.c	Mon Aug 27 20:32:39 1990
X***************
X*** 409,414
X      bool upper = FALSE;
X      bool lastcomp = FALSE;
X      int metabit = 0;
X  
X      while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X  #ifdef DEBUGGING
X
X--- 409,418 -----
X      bool upper = FALSE;
X      bool lastcomp = FALSE;
X      int metabit = 0;
X+ #ifdef PADTRUNC
X+     int wid;
X+     int prec;
X+ #endif
X  
X      while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X  #ifdef DEBUGGING
X***************
X*** 418,423
X  	if (*pattern == '%' && pattern[1]) {
X  	    upper = FALSE;
X  	    lastcomp = FALSE;
X  	    for (s=Nullch; !s; ) {
X  		switch (*++pattern) {
X  		case '^':
X
X--- 422,431 -----
X  	if (*pattern == '%' && pattern[1]) {
X  	    upper = FALSE;
X  	    lastcomp = FALSE;
X+ #ifdef PADTRUNC
X+ 	    wid = 0;
X+ 	    prec = 1000;
X+ #endif
X  	    for (s=Nullch; !s; ) {
X  		switch (*++pattern) {
X  #ifdef PADTRUNC
X***************
X*** 420,425
X  	    lastcomp = FALSE;
X  	    for (s=Nullch; !s; ) {
X  		switch (*++pattern) {
X  		case '^':
X  		    upper = TRUE;
X  		    break;
X
X--- 428,448 -----
X  #endif
X  	    for (s=Nullch; !s; ) {
X  		switch (*++pattern) {
X+ #ifdef PADTRUNC
X+ 		case ':':
X+ 		    if (isdigit(*++pattern) || *pattern == '-') {
X+ 			wid = atol(pattern);
X+ 		        while (isdigit(*++pattern) || *pattern == '-')
X+ 			    ;
X+ 		    }
X+ 		    if (*pattern == '.') {
X+ 			prec = atol(++pattern);
X+ 		    	while (isdigit(*pattern))
X+ 			    pattern++;
X+ 		    }
X+ 		    pattern--;
X+ 		    break;
X+ #endif
X  		case '^':
X  		    upper = TRUE;
X  		    break;
X***************
X*** 852,857
X  		if (islower(*t))
X  		    *t = toupper(*t);
X  	    }
X  	    i = metabit;		/* maybe get into register */
X  	    if (s == dest) {
X  		while (*dest) {
X
X--- 875,888 -----
X  		if (islower(*t))
X  		    *t = toupper(*t);
X  	    }
X+ #ifdef PADTRUNC
X+ 	    if (s != scrbuf) {
X+ 		safecpy(scrbuf,s,(sizeof scrbuf));
X+ 		s = scrbuf;
X+ 	    }
X+ 	    sprintf(dest, "%*.*s", wid, prec, s);
X+ 	    s = dest;
X+ #endif
X  	    i = metabit;		/* maybe get into register */
X  	    if (s == dest) {
X  		while (*dest) {
X*** kfile.c	Mon Aug 27 20:05:54 1990
X--- ../prn/kfile.c	Mon Aug 27 20:31:09 1990
X***************
X*** 114,120
X  	else if (*buf == '/' && firstart <= lastart) {
X  	    mention(buf);
X  	    kill_mentioned = TRUE;
X! 	    switch (art_search(buf, (sizeof buf), FALSE)) {
X  	    case SRCH_ABORT:
X  		continue;
X  	    case SRCH_INTR:
X
X--- 114,120 -----
X  	else if (*buf == '/' && firstart <= lastart) {
X  	    mention(buf);
X  	    kill_mentioned = TRUE;
X! 	    switch (art_search(buf, (sizeof buf), FALSE, FALSE, TRUE)) {
X  	    case SRCH_ABORT:
X  		continue;
X  	    case SRCH_INTR:
X***************
X*** 182,188
X  	putchar('\n') FLUSH;
X  	if (entering && kill_mentioned)
X  #ifdef VERBOSE
X! 	    IF(verbose)
X  		get_anything();
X  	    ELSE
X  #endif
X
X--- 182,188 -----
X  	putchar('\n') FLUSH;
X  	if (entering && kill_mentioned)
X  #ifdef VERBOSE
X! 	    IF(verbose && !sub_scan_mode)
X  		get_anything();
X  	    ELSE
X  #endif
X*** ng.c	Mon Aug 27 20:06:37 1990
X--- ../prn/ng.c	Mon Aug 27 20:36:24 1990
X***************
X*** 157,162
X  #endif
X      
X      mode = 'a';
X      recent_art = curr_art = 0;
X      exit_code = NG_NORM;
X  
X
X--- 157,163 -----
X  #endif
X      
X      mode = 'a';
X+     cur_art_ptr = percent_prev = percent_art = 0;
X      recent_art = curr_art = 0;
X      exit_code = NG_NORM;
X  
X***************
X*** 470,476
X  #ifdef MAILCALL
X  	setmail();
X  #endif
X! 	setdfltcmd();
X  #ifdef CLEAREOL
X  	if (erase_screen && can_home_clear)
X  	    clear_rest();
X
X--- 471,478 -----
X  #ifdef MAILCALL
X  	setmail();
X  #endif
X! 	if (!sub_scan_mode)
X! 	    setdfltcmd();
X  #ifdef CLEAREOL
X  	if (erase_screen && can_home_clear)
X  	    clear_rest();
X***************
X*** 559,564
X      }
X  #endif
X      mode = oldmode;
X      return exit_code;
X  }					/* Whew! */
X  
X
X--- 561,568 -----
X      }
X  #endif
X      mode = oldmode;
X+     if (exit_code != 'n' && exit_code != 'p')	/* just to make sure */
X+ 	sub_scan_mode = 0;
X      return exit_code;
X  }					/* Whew! */
X  
X***************
X*** 619,624
X  	    return AS_NORM;
X  	}
X  	else {
X  	    exit_code = NG_MINUS;
X  	    return AS_CLEAN;
X  	}
X
X--- 623,630 -----
X  	    return AS_NORM;
X  	}
X  	else {
X+ 	    if (sub_scan_mode)
X+ 		goto SubScan;
X  	    exit_code = NG_MINUS;
X  	    return AS_CLEAN;
X  	}
X***************
X*** 624,630
X  	}
X      case 'n':		/* find next unread article? */
X  	if (art > lastart) {
X! 	    if (toread[ng])
X  		art = firstart;
X  	    else
X  		return AS_CLEAN;
X
X--- 630,638 -----
X  	}
X      case 'n':		/* find next unread article? */
X  	if (art > lastart) {
X! 	    if (sub_scan_mode)
X! 		goto SubScan;
X! 	    else if (toread[ng])
X  		art = firstart;
X  	    else
X  		return AS_CLEAN;
X***************
X*** 635,641
X  	    goto normal_search;
X  	}
X  #endif
X! 	else
X  	    art++;
X  #ifdef ARTSEARCH
X  	srchahead = 0;
X
X--- 643,649 -----
X  	    goto normal_search;
X  	}
X  #endif
X! 	else {
X  	    art++;
X  	    if (sub_scan_mode)
X  		goto SubScan;
X***************
X*** 637,642
X  #endif
X  	else
X  	    art++;
X  #ifdef ARTSEARCH
X  	srchahead = 0;
X  #endif
X
X--- 645,653 -----
X  #endif
X  	else {
X  	    art++;
X+ 	    if (sub_scan_mode)
X+ 		goto SubScan;
X+ 	}
X  #ifdef ARTSEARCH
X  	srchahead = 0;
X  #endif
X***************
X*** 698,704
X  	char cmd = *buf;
X  	
X  	reread = TRUE;		/* assume this */
X! 	switch (art_search(buf, (sizeof buf), TRUE)) {
X  	case SRCH_ERROR:
X  	    return AS_ASK;
X  	case SRCH_ABORT:
X
X--- 709,715 -----
X  	char cmd = *buf;
X  	
X  	reread = TRUE;		/* assume this */
X! 	switch (art_search(buf,(sizeof buf),TRUE,sub_scan_mode=='%',TRUE)) {
X  	case SRCH_ERROR:
X  	    return AS_ASK;
X  	case SRCH_ABORT:
X***************
X*** 729,734
X  	    fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH;
X  	    pad(just_a_sec/3);	/* 1/3 second */
X  #endif
X  	    art = firstart;
X  	    reread = FALSE;
X  	    return AS_NORM;
X
X--- 740,747 -----
X  	    fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH;
X  	    pad(just_a_sec/3);	/* 1/3 second */
X  #endif
X+ 	    if (sub_scan_mode)		/* return to SubScan */
X+ 		goto SubScan;
X  	    art = firstart;
X  	    reread = FALSE;
X  	    return AS_NORM;
X***************
X*** 749,754
X      return AS_ASK;
X  #endif
X      case 'u':			/* unsubscribe from this newsgroup? */
X  	rcchar[ng] = NEGCHAR;
X  	return AS_CLEAN;
X      case 'M':
X
X--- 762,768 -----
X      return AS_ASK;
X  #endif
X      case 'u':			/* unsubscribe from this newsgroup? */
X+ 	sub_scan_mode = 0;
X  	rcchar[ng] = NEGCHAR;
X  	return AS_CLEAN;
X      case 'M':
X***************
X*** 818,823
X  	    yankback();
X  #endif
X  	if (*buf == 'u') {
X  	    rcchar[ng] = NEGCHAR;
X  	    return AS_CLEAN;
X  	}
X
X--- 832,838 -----
X  	    yankback();
X  #endif
X  	if (*buf == 'u') {
X+ 	    sub_scan_mode = 0;
X  	    rcchar[ng] = NEGCHAR;
X  	    return AS_CLEAN;
X  	}
X***************
X*** 828,833
X  	exit_code = NG_ASK;
X  	/* FALL THROUGH */
X      case 'q':			/* go back up to newsgroup level? */
X  	return AS_CLEAN;
X      case 'j':
X  	putchar('\n') FLUSH;
X
X--- 843,850 -----
X  	exit_code = NG_ASK;
X  	/* FALL THROUGH */
X      case 'q':			/* go back up to newsgroup level? */
X+ 	if (sub_scan_mode)
X+ 	    goto SubScan;
X  	return AS_CLEAN;
X      case 'j':
X  	putchar('\n') FLUSH;
X***************
X*** 909,914
X  	art = oldart;
X  	return AS_ASK;
X      }
X      case '^':
X  	art = firstart;
X  #ifdef ARTSEARCH
X
X--- 926,1305 -----
X  	art = oldart;
X  	return AS_ASK;
X      }
X+ #ifdef CACHESUBJ
X+ 					/* SubScan			     */
X+ 					/* MODIFICATION BELOW BY TODD DAY    */
X+ 					/* based on concepts by Steve Lemke  */
X+ 					/* and Paul Traina.
X+ 					/* ';' will now bring up full screen */
X+ 					/* interface for easily selecting    */
X+ 					/* articles to read and delete.      */
X+ 					/* '%' does same, but to read        */
X+ 					/* articles, also.		     */
X+     case '%':
X+     case ';':
X+ 	sub_scan_mode = 0;		/* entry from menu */
X+ SubScan:
X+ 	{
X+ 	char tmpbuf[256];		/* max 256 col terminal */
X+ 	static ART_NUM oldfirstart, oldart;
X+ 	int cap, hi_ptr, not_clear, tmp;
X+ 	static ART_NUM arts[256];	/* max 256 line terminal */
X+ 	char buf_cmd, cmd, *subjline = getval("SUBJLINE",Nullch);
X+ 
X+ 	if (!smart_term) {		/* die if term is dumb */
X+ 	    printf("\nSorry, terminal not powerful enough.\n");
X+ 	    return AS_ASK;
X+ 	}
X+ 
X+ 	if (sub_scan_mode)		/* recover cmd */
X+ 	    buf_cmd = sub_scan_mode;
X+ 	else {
X+ 	    buf_cmd = *buf;
X+ 	    oldfirstart = firstart;
X+ 	    oldart = art;
X+ 	}
X+ 					/* search for more threads to read */
X+ 	if (sub_scan_mode && xmarked && *buf != ';' && *buf != '%') {
X+ 	    for (tmp = xmarked; tmp <= lastart; tmp++) {
X+ 		if ( (buf_cmd == '%' || !was_read(tmp)) && x_marked(tmp) ) {
X+ 		    xmarked = art = tmp;
X+ 		    goto Read;
X+ 		}
X+ 		    
X+ 	    }
X+ 	    xmarked = FALSE;
X+ 	}
X+ 	sub_scan_mode = 0;		/* turn off thread return mode */
X+ 	
X+ 	if (!subj_list)
X+ 	    fetchsubj(art,TRUE,FALSE);
X+ 
X+ Swap:	if (buf_cmd == '%') {
X+ 	    oldfirstart = firstart;	/* save first unread article */
X+ 	    firstart = absfirst;	/* set to real first article */
X+ 	}
X+ 	else
X+ 	    firstart = oldfirstart;	/* set to first unread article */
X+ Top:	hi_ptr = 0;
X+ 	cmd = ' ';
X+ 	if (percent_art < firstart)
X+ 	    percent_art = firstart;
X+ 
X+ 	for (i=percent_art; i<=lastart; i++) {
X+ 					/* fill page */
X+ 	    not_clear = TRUE;		/* screen not clear */
X+ 	    cap = 0;
X+ 	    percent_art = i;		/* update last top article */
X+ 	    do {
X+ ClrEOS:		if ( (buf_cmd == '%' || !was_read(i)) &&
X+ 		  (subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE))
X+ 		  && *subj_list[OFFSET(i)]) {
X+ 					/* save article number */
X+ 		    arts[cap++] = i;
X+ 					/* print article subject */	
X+ 		    sprintf(tmpbuf,"  %c%5ld ", x_marked(i)?'*':' ',i);
X+ 		    safecpy(tmpbuf + 9, subj_list[OFFSET(i)], COLS - 10);
X+ 		    if (not_clear) {	/* screen need clearing? */
X+ 			clear();
X+ 			not_clear = FALSE;
X+ 		    }
X+ 		    printf("%s\n", tmpbuf) FLUSH;
X+ 		}
X+ 		i++;
X+ 					/* stop if end of screen */
X+ 	    } while (cap < LINES-1 && i <= lastart);
X+ 	    i--;
X+ 
X+ 	    if (hi_ptr == -3)		/* last command was 'd' (del) */
X+ 		hi_ptr = cap - 1;
X+ 	    else if (hi_ptr == -2) {	/* last command was (prev) */
X+ 		if (cap <= 0) {		/* nothing on screen */
X+ 		    clear();
X+ 		    sub_scan_mode = buf_cmd;
X+ 		    exit_code = 'n';	/* goto next news group */
X+ 		    return AS_CLEAN;
X+ 		}
X+ 	    	hi_ptr = cap - 1;
X+ 		if (cmd == 'k' || cmd == 'd')
X+ 		    cur_art_ptr = hi_ptr;
X+ 	    }
X+ 	    else {			/* last command was (next) */
X+ 		hi_ptr = cap - 1;
X+ 		if (cmd == 'j')
X+ 		    cur_art_ptr = 0;
X+ 	    }
X+ 
X+ 	    if (cap <= 0) {		/* oh oh! no articles on screen */
X+ 		if (cmd == 'j' || cmd == 'n') {
X+ 		    cur_art_ptr = hi_ptr = LINES-2;
X+ 		    i = arts[cur_art_ptr];/* bottom of screen */
X+ 		    goto Skip;
X+ 		}
X+ 		else
X+ 		    goto Prev;		/* back up one page if current empty */
X+ 	    }
X+ 
X+ 	    if (cur_art_ptr > hi_ptr)
X+ 		cur_art_ptr = hi_ptr;
X+ 
X+ RedoBt:	    standout();
X+ 	    printf("%s", ngname);
X+ 	    un_standout();
X+ 	    printf(" %s", buf_cmd=='%' ? "all" : "unread");
X+ #ifdef VERBOSE
X+ 	    if (verbose)
X+ 		printf(" articles");
X+ #endif
X+ 	    if (dfltcmd[0] == '^' || srchahead || scanon) {
X+ 		dfltcmd = "^Nnpq";
X+ 		srchahead = -1;
X+ 		printf(", follow threads");
X+ 	    }
X+ 	    else {
X+ 		dfltcmd = "npq";
X+ 		srchahead = 0;
X+ 	    }
X+ Place:					/* place cursor */
X+ 	    home_cursor();
X+ 	    for (tmp = 0; tmp < cur_art_ptr; tmp++)
X+ 		tputs(DO, 1, putchr);
X+ 	    printf(">");
X+ 
X+ Skip:	    fflush(stdout);
X+ 	    eat_typeahead();
X+ 					/* scan keyboard, do cmds */
X+ 	    do {
X+ 		collect_subjects();	/* get more subjs in background */
X+ 		getcmd(tmpbuf);
X+ 		cmd = tmpbuf[0];
X+      		switch(cmd) {
X+ 		    case 'f':
X+ 			if (dfltcmd[0] == '^')
X+ 			    dfltcmd = "npq";
X+ 			else
X+ 			    dfltcmd = "^Nnpq";
X+ 			home_cursor();
X+ 			for (tmp = 0; tmp <= hi_ptr; tmp++)
X+ 			    tputs(DO, 1, putchr);
X+ 			printf("                                                                             \r");
X+ 			goto RedoBt;
X+ 		    case '>':
X+ 			cmd = 'N';
X+ 		    case '<':
X+ 			if (cmd == '<')
X+ 			    cmd = 'P';
X+ 		    case 'N':
X+ 		    case 'P':
X+ 			clear();
X+ 			sub_scan_mode = buf_cmd;
X+ 			exit_code = tolower(cmd);
X+ 			return AS_CLEAN;
X+ 		    case 'c':
X+ 			for (tmp = OFFSET(firstart)/BITSPERBYTE; tmp<ctlsize;
X+ 			  tmp++)
X+ 			    xmark[tmp] = 0;
X+ 			xmarked = FALSE;
X+ 			goto Top;
X+ 		    case 'x':
X+ 			art = arts[cur_art_ptr];
X+ 			if (x_marked(art)) {	/* already marked? */
X+ 			    x_clear(art);
X+ 			    printf("  \r>");
X+ 			}
X+ 			else {			/* not marked yet */
X+ 			    x_set(art);
X+ 			    printf(" *\r>");
X+ 			    xmarked = TRUE;	/* we have marked something */
X+ 			}
X+ 			fflush(stdout);
X+ 			continue;
X+ 		    case '%':
X+ 		    case ';':
X+ 			if (buf_cmd == cmd)
X+ 			    continue;	/* we are in this mode already */
X+ 			buf_cmd = cmd;	/* swap modes */
X+ 			goto Swap;
X+ 		    case 'h': 		/* help */
X+ 			clear();
X+ 			if ((tmp = help_sub_scan()) > 0)
X+ 			    pushchar(tmp);
X+ 		    case '\014':		/* redraw screen */
X+ 			goto Top;
X+ 		    case '/':		/* do search */
X+ 		    case '?':
X+ 			buf[0] = cmd;
X+ 			buf[1] = FINISHCMD;
X+ 			buf[2] = '\0';
X+ 			art = arts[cur_art_ptr];
X+ 			home_cursor();
X+ 			for (tmp = 0; tmp <= hi_ptr; tmp++)
X+ 			    tputs(DO, 1, putchr);
X+ 			printf("                                                                             \r");
X+ 			if (art_search(buf, (sizeof buf), TRUE, buf_cmd == '%',
X+ 			  FALSE) == SRCH_FOUND) {
X+ 			    i = art - 1;
X+ 					/* best guess at prev page */
X+ 			    for (tmp = 0, percent_prev = art;
X+ 			      percent_prev > firstart && tmp < LINES;
X+ 				percent_prev--) {
X+ 				if (buf_cmd == '%' || !was_read(percent_prev) )
X+ 				    tmp++;
X+ 			    }
X+ 			    cur_art_ptr = 0;
X+ 			    hi_ptr = -1;
X+ 			    break;
X+ 			}
X+ 			else {
X+ 			    printf("\r");
X+ 			    goto RedoBt;
X+ 			}
X+ 		    case 'T':		/* top of subjects */
X+ 			i = firstart - 1;
X+ 			cur_art_ptr = 0;
X+ 			hi_ptr = -1;
X+ 			break;
X+ 		    case 'B':		/* bottom of subjects */
X+ 					/* find end page */
X+ 			for (tmp = 0, percent_art = lastart;
X+ 			  percent_art > firstart && tmp < LINES-2;
X+ 			  percent_art--) {
X+ 			    if (buf_cmd == '%' || !was_read(percent_art) )
X+ 				tmp++;
X+ 			}
X+ 					/* best guess at prev page */
X+ 			for (tmp = 0, percent_prev = percent_art;
X+ 			  percent_prev > firstart && tmp < LINES-1;
X+ 			  percent_prev--) {
X+ 			    if (buf_cmd == '%' || !was_read(percent_prev) )
X+ 				tmp++;
X+ 			}
X+ 			cur_art_ptr = LINES;
X+ 			goto Top;
X+ 		    case 't':		/* top of page */
X+ 			cur_art_ptr = 0;
X+ 			rubout();
X+ 			goto Place;	/* move cursor */
X+ 		    case 'b':		/* bottom of directory */
X+ 			cur_art_ptr = hi_ptr;
X+ 			rubout();
X+ 			goto Place;	/* move cursor */
X+ 		    case 'd':		/* mark arts as read */
X+ 			if (buf_cmd == '%')
X+ 			    continue;	/* disable for % mode */
X+ 			tmpbuf[0] = 'k';/* kill */
X+ 			tmpbuf[1] = '\0';
X+ 			printf("\r");	/* clear to end of screen */
X+ 			tputs(CD, 1, putchr);
X+ 			printf("Marking subject as read...");
X+ 			art = arts[cur_art_ptr];
X+ 			i = art;	/* redraw page at current pos */
X+ 			cap = cur_art_ptr;
X+ 			fflush(stdout);
X+ 			art_search(tmpbuf, sizeof(tmpbuf), FALSE, FALSE, FALSE);
X+ 			hi_ptr = -3;
X+ 			printf("\r");
X+ 			tputs(CD, 1, putchr);
X+ 			goto ClrEOS;
X+ 		    case 'j':		/* go down */
X+ 			if (cur_art_ptr < hi_ptr) {
X+ 			    cur_art_ptr++;
X+ 			    rubout();
X+ 			    tputs(DO, 1, putchr);
X+ 			    printf(">");
X+ 			}
X+ 			else
X+ 			    goto Next;
X+ 			break;
X+ 		    case 'k':		/* go up */
X+ 			if (cur_art_ptr > 0) {
X+ 			    cur_art_ptr--;
X+ 			    rubout();
X+ 			    tputs(UP, 1, putchr);
X+ 			    printf(">");
X+ 			}
X+ 			else
X+ 			    goto Prev;
X+ 			break;
X+ 		    case 'n':
X+ Next:			if (i >= lastart && cap){/* if at end, ignore request */
X+ 			    home_cursor();
X+ 			    for (tmp = 0; tmp <= hi_ptr; tmp++)
X+ 				tputs(DO, 1, putchr);
X+ 			    printf("                                                                             \r");
X+ 			    standout();
X+ 			    printf("\007End of Subjects");
X+ 			    un_standout();
X+ 			    goto Place;
X+ 			}
X+ 					/* save top of page */
X+ 			percent_prev = percent_art;
X+ 			hi_ptr = -1;	/* quit do loop */
X+ 			break;
X+ 		    case 'p':
X+ Prev:			if (percent_art <= firstart && cap) {
X+ 			    home_cursor();
X+ 			    for (tmp = 0; tmp <= hi_ptr; tmp++)
X+ 				tputs(DO, 1, putchr);
X+ 			    printf("                                                                             \r");
X+ 			    standout();
X+ 			    printf("\007Beginning of Subjects");
X+ 			    un_standout();
X+ 			    goto Place;
X+ 			}
X+ 			i = percent_prev - 1;
X+ 			if (i < firstart)
X+ 			    i = firstart - 1;
X+ 					/* best guess at prev page */
X+ 			for (tmp = 0;
X+ 			  percent_prev > firstart && tmp < LINES-1;
X+ 			  percent_prev--) {
X+ 			    if (buf_cmd == '%' || !was_read(percent_prev) )
X+ 				tmp++;
X+ 			}
X+ 			hi_ptr = -2;	/* quit do loop */
X+ 			break;
X+ 		    case 'r':		/* read article */
X+ 		    case '\n':
X+ 		    case '\r':
X+ 		    case ' ':
X+ 			art = arts[cur_art_ptr];
X+ 			if (xmarked) {
X+ 			    x_set(art);
X+ 			    xmarked = FALSE;
X+ 	    		    for (tmp = firstart; tmp <= lastart; tmp++) {
X+ 				if ( (buf_cmd == '%' || !was_read(tmp))
X+ 				  && x_marked(tmp) ) {
X+ 				    xmarked = art = tmp;
X+ 				    break;
X+ 				}
X+ 	    		    }
X+ 			}
X+ Read:			reread = TRUE;
X+ 			if (xmarked)
X+ 			    xmarked++;
X+ 			sub_scan_mode = buf_cmd;/* return from threads */
X+ 			return AS_NORM;	/* print art */
X+ 		    case 'q':		/* quit do and for loop */
X+ 			hi_ptr = -4;
X+ 			break;
X+ 		}
X+ 		fflush(stdout);
X+ 	    } while (hi_ptr >= 0);
X+ 					/* exit huge for-loop on quit */
X+ 	    if (hi_ptr == -4)
X+ 		break;
X+ 	}
X+ 	clear();
X+ 	int_count = sub_scan_mode = 0;
X+ 	art = oldart;
X+ 	firstart = oldfirstart;
X+ 	printf("\nEnd of subject scan.\n") FLUSH;
X+ 	return AS_CLEAN;
X+     }
X+ #endif
X+ 
X+ 
X      case '^':
X  	art = firstart;
X  #ifdef ARTSEARCH
X*** ng.h	Mon Aug 27 20:06:39 1990
X--- ../prn/ng.h	Mon Aug 27 20:28:51 1990
X***************
X*** 8,13
X  
X  EXT ART_NUM art INIT(0);	/* current or prospective article # */
X  
X  EXT int checkcount INIT(0);	/* how many articles have we read */
X  			/*   in the current newsgroup since */
X  			/*   the last checkpoint? */
X
X--- 8,18 -----
X  
X  EXT ART_NUM art INIT(0);	/* current or prospective article # */
X  
X+ EXT ART_NUM percent_art INIT(0); /* last top article displayed by '%' & ';' */
X+ EXT ART_NUM percent_prev INIT(0);/* prev top article displayed by '%' & ';' */
X+ EXT ART_NUM cur_art_ptr INIT(0); /* current (or last) pointed article */
X+ EXT int sub_scan_mode INIT(0);	 /* check for return from threads */
X+ 
X  EXT int checkcount INIT(0);	/* how many articles have we read */
X  			/*   in the current newsgroup since */
X  			/*   the last checkpoint? */
X*** ngstuff.c	Mon Aug 27 20:06:54 1990
X--- ../prn/ngstuff.c	Mon Aug 27 20:33:59 1990
X***************
X*** 196,202
X  	}
X  	check_first(min);
X  	for (art=min; art<=max; art++) {
X! 	    if (perform(cmdlst,TRUE)) {
X  #ifdef VERBOSE
X  		IF(verbose)
X  		    printf("\n(Interrupted at article %ld)\n",(long)art)
X
X--- 196,202 -----
X  	}
X  	check_first(min);
X  	for (art=min; art<=max; art++) {
X! 	    if (perform(cmdlst,TRUE,TRUE)) {
X  #ifdef VERBOSE
X  		IF(verbose)
X  		    printf("\n(Interrupted at article %ld)\n",(long)art)
X***************
X*** 219,225
X  }
X  
X  int
X! perform(cmdlst,toplevel)
X  register char *cmdlst;
X  int toplevel;
X  {
X
X--- 219,225 -----
X  }
X  
X  int
X! perform(cmdlst,toplevel,print_msg)
X  register char *cmdlst;
X  int toplevel;
X  int print_msg;
X***************
X*** 222,227
X  perform(cmdlst,toplevel)
X  register char *cmdlst;
X  int toplevel;
X  {
X      register int ch;
X      
X
X--- 222,228 -----
X  perform(cmdlst,toplevel,print_msg)
X  register char *cmdlst;
X  int toplevel;
X+ int print_msg;
X  {
X      register int ch;
X      
X***************
X*** 225,232
X  {
X      register int ch;
X      
X!     if (toplevel) {
X! 	printf("%-6ld",art);
X  	fflush(stdout);
X      }
X      for (; ch = *cmdlst; cmdlst++) {
X
X--- 226,237 -----
X  {
X      register int ch;
X      
X!     if (toplevel && print_msg) {
X! #ifdef PADTRUNC
X!  	printf("%5ld ",art);
X! #else
X!   	printf("%-6ld",art);
X! #endif
X  	fflush(stdout);
X      }
X      for (; ch = *cmdlst; cmdlst++) {
X***************
X*** 236,242
X  	    if (!was_read(art)) {
X  		mark_as_read(art);
X  #ifdef VERBOSE
X! 		IF(verbose)
X  		    fputs("\tJunked",stdout);
X  #endif
X  	    }
X
X--- 241,247 -----
X  	    if (!was_read(art)) {
X  		mark_as_read(art);
X  #ifdef VERBOSE
X! 		IF(verbose && print_msg)
X  		    fputs("\tJunked",stdout);
X  #endif
X  	    }
X***************
X*** 245,251
X  	    if (was_read(art)) {
X  		unmark_as_read(art);
X  #ifdef VERBOSE
X! 		IF(verbose)
X  		    fputs("\tMarked unread",stdout);
X  #endif
X  	    }
X
X--- 250,256 -----
X  	    if (was_read(art)) {
X  		unmark_as_read(art);
X  #ifdef VERBOSE
X! 		IF(verbose && print_msg)
X  		    fputs("\tMarked unread",stdout);
X  #endif
X  	    }
X***************
X*** 254,260
X  #ifdef DELAYMARK
X  	    delay_unmark(art);
X  #ifdef VERBOSE
X! 		IF(verbose)
X  		    fputs("\tWill return",stdout);
X  #endif
X  #else
X
X--- 259,265 -----
X  #ifdef DELAYMARK
X  	    delay_unmark(art);
X  #ifdef VERBOSE
X! 		IF(verbose && print_msg)
X  		    fputs("\tWill return",stdout);
X  #endif
X  #else
X***************
X*** 263,268
X  #endif
X  	}
X  	else if (ch == '=') {
X  	    printf("\t%s",fetchsubj(art,FALSE,FALSE));
X  #ifdef VERBOSE
X  	    IF(verbose)
X
X--- 268,284 -----
X  #endif
X  	}
X  	else if (ch == '=') {
X+ #ifdef PADTRUNC
X+ 	    char tmpbuf[256];
X+ 	    char *subjline = getval("SUBJLINE",Nullch);
X+ 
X+ 	    if (subjline) {	/* probably fetches it again! */
X+ 		/* art = i; */
X+ 		interp(tmpbuf, (sizeof tmpbuf), subjline);
X+ 		printf(tmpbuf);
X+ 	    } else
X+ 		printf(fetchsubj(art,FALSE,FALSE));
X+ #else
X  	    printf("\t%s",fetchsubj(art,FALSE,FALSE));
X  #endif
X  #ifdef VERBOSE
X***************
X*** 264,269
X  	}
X  	else if (ch == '=') {
X  	    printf("\t%s",fetchsubj(art,FALSE,FALSE));
X  #ifdef VERBOSE
X  	    IF(verbose)
X  		;
X
X--- 280,286 -----
X  		printf(fetchsubj(art,FALSE,FALSE));
X  #else
X  	    printf("\t%s",fetchsubj(art,FALSE,FALSE));
X+ #endif
X  #ifdef VERBOSE
X  	    IF(verbose)
X  		;
X***************
X*** 269,275
X  		;
X  	    ELSE
X  #endif
X! 		putchar('\n') FLUSH;		/* ghad! */
X  	}
X  	else if (ch == 'C') {
X  #ifdef ASYNC_PARSE
X
X--- 286,293 -----
X  		;
X  	    ELSE
X  #endif
X! 		if (print_msg)
X! 		    putchar('\n') FLUSH;	/* ghad! */
X  	}
X  	else if (ch == 'C') {
X  #ifdef ASYNC_PARSE
X***************
X*** 286,292
X  	    cmdlst = dointerp(tmpbuf, (sizeof tmpbuf), cmdlst,":");
X  	    if (*cmdlst != ':')
X  		--cmdlst;
X! 	    if (perform(tmpbuf,FALSE))
X  		return -1;
X  #else
X  	    notincl("%");
X
X--- 304,310 -----
X  	    cmdlst = dointerp(tmpbuf, (sizeof tmpbuf), cmdlst,":");
X  	    if (*cmdlst != ':')
X  		--cmdlst;
X! 	    if (perform(tmpbuf,FALSE,TRUE))
X  		return -1;
X  #else
X  	    notincl("%");
X***************
X*** 323,329
X  	fflush(stdout);
X  #endif
X      }
X!     if (toplevel) {
X  #ifdef VERBOSE
X  	IF(verbose)
X  	    putchar('\n') FLUSH;
X
X--- 341,347 -----
X  	fflush(stdout);
X  #endif
X      }
X!     if (toplevel && print_msg) {
X  #ifdef VERBOSE
X  	IF(verbose)
X  	    putchar('\n') FLUSH;
X*** rn.1	Mon Aug 27 20:07:40 1990
X--- ../prn/rn.1	Mon Aug 27 20:32:45 1990
X***************
X*** 104,111
X  level.
X  .PP
X  .I Rn
X! operates on three levels: the newsgroup selection level, the article
X! selection level, and the paging level.
X  Each level has its own set of commands, and its own help menu.
X  At the paging level (the bottom level),
X  .I rn
X
X--- 104,111 -----
X  level.
X  .PP
X  .I Rn
X! operates on four levels: the newsgroup selection level, the article
X! selection level, the subject scan level, and the paging level.
X  Each level has its own set of commands, and its own help menu.
X  At the paging level (the bottom level),
X  .I rn
X***************
X*** 115,120
X  At the article selection level, you may specify which article you want
X  next, or read them in the default order, which is either in order of
X  arrival on your system, or by subject threads.
X  At the newsgroup selection level (the top level), you may specify which
X  newsgroup you want next, or read them in the default order, which is the
X  order that the newsgroups occur in your
X
X--- 115,125 -----
X  At the article selection level, you may specify which article you want
X  next, or read them in the default order, which is either in order of
X  arrival on your system, or by subject threads.
X+ At the subject scan level, a list of subjects is displayed and you can
X+ use a screen oriented marker to select what subjects you want to read.
X+ You will follow a thread in the article selection level until it ends,
X+ and at that point, you will
X+ automatically be returned to the subject scan level.
X  At the newsgroup selection level (the top level), you may specify which
X  newsgroup you want next, or read them in the default order, which is the
X  order that the newsgroups occur in your
X***************
X*** 199,204
X  The command will be interpreted as if given on the article selection level.
X  .Ip = 8
X  Do this newsgroup now, but list subjects before displaying articles.
X  .Ip n 8
X  Go to the next newsgroup with unread news.
X  .Ip N 8
X
X--- 204,213 -----
X  The command will be interpreted as if given on the article selection level.
X  .Ip = 8
X  Do this newsgroup now, but list subjects before displaying articles.
X+ .Ip ; 8
X+ Do this newsgroup now, but startup subject display/scan mode of unread articles.
X+ .Ip % 8
X+ Same as ;, but include read articles as well.
X  .Ip n 8
X  Go to the next newsgroup with unread news.
X  .Ip N 8
X***************
X*** 647,652
X  from a range or search command.
X  .Ip = 8
X  List subjects of unread articles.
X  .Ip # 8
X  Print last article number.
X  .Sh "Pager Level"
X
X--- 656,665 -----
X  from a range or search command.
X  .Ip = 8
X  List subjects of unread articles.
X+ .Ip ; 8
X+ Start subject display/scan mode on unread articles.
X+ .Ip % 8
X+ Same as ; but include read articles as well.
X  .Ip # 8
X  Print last article number.
X  .Sp
X***************
X*** 649,654
X  List subjects of unread articles.
X  .Ip # 8
X  Print last article number.
X  .Sh "Pager Level"
X  At the pager level (within an article), the prompt looks like this:
X  .Sp
X
X--- 662,734 -----
X  Same as ; but include read articles as well.
X  .Ip # 8
X  Print last article number.
X+ .Sp
X+ .Sh "Subject Display/Scan Mode"
X+ If your site supports the '-S' option and your terminal is sufficiently
X+ smart, you can take advantage of this mode.  You do not have to have the '-S'
X+ option enabled to use this mode, though it greatly speeds things up.
X+ This mode is invoked by either ';' or '%'.  ';' will use only unread
X+ articles, while '%' will use read articles also.
X+ .PP
X+ After entering this mode, the screen will be cleared and a list of
X+ subjects will be displayed.  The prompt '>' will indicate which subject
X+ you are currently acting on.
X+ .PP
X+ The commands in this section differ greatly from that of the other three
X+ sections.  This is because this section is screen oriented (like 'vi')
X+ and the 'j' and 'k' keys are used for cursor movement.  A detailed description
X+ of the keys is given below:
X+ .Sp
X+ .Ip SP,CR,r 8
X+ Display article, and follow its thread in the Article Selection Level.
X+ Once in the Article Selection Level, you may use any of its commands.
X+ You may return via ';' or '%'.
X+ .Ip f 8
X+ Toggle thread follow mode.
X+ .Ip j 8
X+ Move down to next subject.
X+ .Ip k 8
X+ Move up to previous subject.
X+ .Ip n 8
X+ Display next page of subjects.
X+ .Ip p 8
X+ Display previous page of subjects.
X+ .Ip N,> 8
X+ Go to next unread newsgroup.
X+ .Ip P,< 8
X+ Go to previous unread newsgroup.
X+ .Ip t 8
X+ Move to top of current page.
X+ .Ip b 8
X+ Move to bottom of current page.
X+ .Ip T 8
X+ Move to top of all subjects.
X+ .Ip B 8
X+ Move to bottom of all subjects.
X+ .Ip d 8
X+ Mark all articles with same subject as read.  Same as 'k' at the
X+ Article Selection Level.
X+ .Ip x 8
X+ Mark article for reading.  After returning from a thread read, the
X+ next marked article will be read.
X+ .Ip c 8
X+ Clear all marks (see x).
X+ .Ip /pattern 8
X+ Search for next subject and, if found, put at top of page.  Usage same as
X+ pattern searches at Article Selection Level, including 'header' and 'all'
X+ searches.
X+ .Ip ?pattern 8
X+ Same as /pattern above, except search for previous subject.
X+ .Ip ^L 8
X+ Redraw screen.
X+ .Ip ; 8
X+ Show only unread subjects.  May force you to next unread newsgroup if
X+ all subjects are read.
X+ .Ip % 8
X+ Show all subjects.
X+ .Ip q 8
X+ Quit this level.
X+ .Sp
X  .Sh "Pager Level"
X  At the pager level (within an article), the prompt looks like this:
X  .Sp
X***************
X*** 708,714
X  as if typed to the \*(L"What next?\*(R" prompt at the end of the article.
X  See the documentation at the article selection level for these commands.
X  .Sp	
X!     # $ & / = ? c C f F k K ^K m M r R ^R u v Y ^
X  .br
X      number
X  .br
X
X--- 788,794 -----
X  as if typed to the \*(L"What next?\*(R" prompt at the end of the article.
X  See the documentation at the article selection level for these commands.
X  .Sp	
X!     # $ & / = ; % ? c C f F k K ^K m M r R ^R u v Y ^
X  .br
X      number
X  .br
X***************
X*** 1266,1271
X  \*(L"%^C\*(R" produces something like \*(L"Net.jokes\*(R".
X  Inserting \*(L'_\*(R' causes the first letter following the last
X  \&\*(L'/\*(R' to be capitalized: \*(L"%_c\*(R" produces \*(L"net/Jokes\*(R".
X  .SH ENVIRONMENT
X  The following environment variables are paid attention to by
X  .IR rn .
X
X--- 1346,1359 -----
X  \*(L"%^C\*(R" produces something like \*(L"Net.jokes\*(R".
X  Inserting \*(L'_\*(R' causes the first letter following the last
X  \&\*(L'/\*(R' to be capitalized: \*(L"%_c\*(R" produces \*(L"net/Jokes\*(R".
X+ Inserting \*(L':\*(R' causes the substitution value to be printed with
X+ printf-style formatting.  If you want your indices to have up to 50
X+ characters of subject followed by 24 characters of author,
X+ you can define the following environment variable with \-E:
X+ .Sp
X+ .nf
X+ SUBJLINE=\*(L%:"\-50.50s %:.24t\*(R".
X+ .fi
X  .SH ENVIRONMENT
X  The following environment variables are paid attention to by
X  .IR rn .
X*** rn.c	Mon Aug 27 20:07:46 1990
X--- ../prn/rn.c	Mon Aug 27 20:29:01 1990
X***************
X*** 99,104
X  					/*   with no unread news? */
X  	bool retry;			/* cycle back to top of list? */
X  	NG_NUM recent_ng = 0;
X  	
X  	current_ng = 0;
X  	do {
X
X--- 99,105 -----
X  					/*   with no unread news? */
X  	bool retry;			/* cycle back to top of list? */
X  	NG_NUM recent_ng = 0;
X+ 	sub_scan_mode = 0;
X  	
X  	current_ng = 0;
X  	do {
X***************
X*** 189,194
X  		    }
X      reprompt_newsgroup:
X  		    dfltcmd = "ynq";
X  #ifdef VERBOSE
X  		    IF(verbose)
X  			sprintf(promptbuf,
X
X--- 190,201 -----
X  		    }
X      reprompt_newsgroup:
X  		    dfltcmd = "ynq";
X+ 		    if (sub_scan_mode) {
X+ 			buf[0] = sub_scan_mode;
X+ 			buf[1] = '\0';
X+ 			sub_scan_mode = 0;
X+ 			goto SubGrp;
X+ 		    }
X  #ifdef VERBOSE
X  		    IF(verbose)
X  			sprintf(promptbuf,
X***************
X*** 225,231
X  #ifdef VERIFY
X  		printcmd();
X  #endif
X! 		switch (*buf) {
X  		case 'p':		/* find previous unread newsgroup */
X  		    do {
X  			if (ng <= 0)
X
X--- 232,238 -----
X  #ifdef VERIFY
X  		printcmd();
X  #endif
X! SubGrp:		switch (*buf) {
X  		case 'p':		/* find previous unread newsgroup */
X  		    do {
X  			if (ng <= 0)
X***************
X*** 467,473
X  		    crmode();
X  		    goto reask_newsgroup;
X  		}
X! 		case '.': case '=':
X  		case 'y': case 'Y': /* do normal thing */
X  		    if (ng >= nextrcline) {
X  			fputs("\nNot on a newsgroup.",stdout) FLUSH;
X
X--- 474,480 -----
X  		    crmode();
X  		    goto reask_newsgroup;
X  		}
X! 		case '.': case '=': case ';': case '%':
X  		case 'y': case 'Y': /* do normal thing */
X  		    if (ng >= nextrcline) {
X  			fputs("\nNot on a newsgroup.",stdout) FLUSH;
X***************
X*** 475,480
X  		    }
X  		    if (*buf == '=')
X  			s = savestr("=");
X  		    else if (*buf == '.') {	/* start command? */
X  			if (!finish_command(FALSE)) /* get rest of command */
X  			    goto reinp_newsgroup;
X
X--- 482,491 -----
X  		    }
X  		    if (*buf == '=')
X  			s = savestr("=");
X+ 		    else if (*buf == ';')
X+ 			s = savestr(";");
X+ 		    else if (*buf == '%')
X+ 			s = savestr("%");
X  		    else if (*buf == '.') {	/* start command? */
X  			if (!finish_command(FALSE)) /* get rest of command */
X  			    goto reinp_newsgroup;
X***************
X*** 486,491
X  		    if (toread[ng])
X  			retry = TRUE;
X  		    switch (do_newsgroup(s)) {
X  		    case NG_ERROR:
X  		    case NG_NORM:
X  			ng++;
X
X--- 497,510 -----
X  		    if (toread[ng])
X  			retry = TRUE;
X  		    switch (do_newsgroup(s)) {
X+ 		    case 'p':
X+ 			buf[0] = 'p';
X+ 			buf[1] = '\0';
X+ 			goto SubGrp;
X+ 		    case 'n':
X+ 			buf[0] = 'n';
X+ 			buf[1] = '\0';
X+ 			goto SubGrp;
X  		    case NG_ERROR:
X  		    case NG_NORM:
X  			ng++;
X*** term.c	Mon Aug 27 20:08:15 1990
X--- ../prn/term.c	Mon Aug 27 20:32:11 1990
X***************
X*** 191,196
X  	    BC = Tgetstr("le");
X      } else
X  	BC = "\b";			/* make a backspace handy */
X      UP = Tgetstr("up");			/* move up a line */
X      if (!*UP)				/* no UP string? */
X  	marking = 0;			/* disable any marking */
X
X--- 191,197 -----
X  	    BC = Tgetstr("le");
X      } else
X  	BC = "\b";			/* make a backspace handy */
X+     DO = Tgetstr("do");			/* move down a line */
X      UP = Tgetstr("up");			/* move up a line */
X      if (!*UP)				/* no UP string? */
X  	marking = 0;			/* disable any marking */
X***************
X*** 199,204
X      else
X  	CL = Tgetstr("cl");		/* get clear string */
X      CE = Tgetstr("ce");			/* clear to end of line string */
X  #ifdef CLEAREOL
X      CM = Tgetstr("cm");			/* cursor motion */
X      HO = Tgetstr("ho");			/* home cursor if no CM */
X
X--- 200,207 -----
X      else
X  	CL = Tgetstr("cl");		/* get clear string */
X      CE = Tgetstr("ce");			/* clear to end of line string */
X+     CD = Tgetstr("cd");			/* clear to end of display - PWP */
X+     smart_term = *DO && *UP && *CD;	/* necessary for sub disp/scan */
X  #ifdef CLEAREOL
X      CM = Tgetstr("cm");			/* cursor motion */
X      HO = Tgetstr("ho");			/* home cursor if no CM */
X***************
X*** 202,208
X  #ifdef CLEAREOL
X      CM = Tgetstr("cm");			/* cursor motion */
X      HO = Tgetstr("ho");			/* home cursor if no CM */
X-     CD = Tgetstr("cd");			/* clear to end of display */
X      if (!*CE || !*CD || (!*CM && !*HO))	/* can we CE, CD, and home? */
X  	can_home_clear = FALSE;		/*  no, so disable use of clear eol */
X  #endif CLEAREOL
X
X--- 205,210 -----
X  #ifdef CLEAREOL
X      CM = Tgetstr("cm");			/* cursor motion */
X      HO = Tgetstr("ho");			/* home cursor if no CM */
X      if (!*CE || !*CD || (!*CM && !*HO))	/* can we CE, CD, and home? */
X  	can_home_clear = FALSE;		/*  no, so disable use of clear eol */
X  #endif CLEAREOL
X*** term.h	Mon Aug 27 20:08:20 1990
X--- ../prn/term.h	Mon Aug 27 20:29:05 1990
X***************
X*** 151,156
X   */
X  
X  #ifdef HAVETERMLIB
X  EXT char *BC INIT(Nullch);		/* backspace character */
X  EXT char *UP INIT(Nullch);		/* move cursor up one line */
X  EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
X
X--- 151,157 -----
X   */
X  
X  #ifdef HAVETERMLIB
X+ EXT int smart_term INIT(FALSE);		/* do we have smart_terminal? */
X  EXT char *BC INIT(Nullch);		/* backspace character */
X  EXT char *DO INIT(Nullch);		/* move cursor down one line */
X  EXT char *UP INIT(Nullch);		/* move cursor up one line */
X***************
X*** 152,157
X  
X  #ifdef HAVETERMLIB
X  EXT char *BC INIT(Nullch);		/* backspace character */
X  EXT char *UP INIT(Nullch);		/* move cursor up one line */
X  EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
X  EXT char *VB INIT(Nullch);		/* visible bell */
X
X--- 153,159 -----
X  #ifdef HAVETERMLIB
X  EXT int smart_term INIT(FALSE);		/* do we have smart_terminal? */
X  EXT char *BC INIT(Nullch);		/* backspace character */
X+ EXT char *DO INIT(Nullch);		/* move cursor down one line */
X  EXT char *UP INIT(Nullch);		/* move cursor up one line */
X  EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
X  EXT char *VB INIT(Nullch);		/* visible bell */
X***************
X*** 156,164
X  EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
X  EXT char *VB INIT(Nullch);		/* visible bell */
X  EXT char *CL INIT(Nullch);		/* home and clear screen */
X- EXT char *CE INIT(Nullch);		/* clear to end of line */
X- #ifdef CLEAREOL
X- EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X  #endif CLEAREOL
X
X--- 158,163 -----
X  EXT char *CR INIT(Nullch);		/* get to left margin, somehow */
X  EXT char *VB INIT(Nullch);		/* visible bell */
X  EXT char *CL INIT(Nullch);		/* home and clear screen */
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X  EXT char *CE INIT(Nullch);		/* clear to end of line */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X***************
X*** 160,165
X  #ifdef CLEAREOL
X  EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X  #endif CLEAREOL
X  EXT char *SO INIT(Nullch);		/* begin standout mode */
X
X--- 159,165 -----
X  EXT char *VB INIT(Nullch);		/* visible bell */
X  EXT char *CL INIT(Nullch);		/* home and clear screen */
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X+ EXT char *CE INIT(Nullch);		/* clear to end of line */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X  EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
X  EXT char *SO INIT(Nullch);		/* begin standout mode */
X***************
X*** 161,167
X  EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X! #endif CLEAREOL
X  EXT char *SO INIT(Nullch);		/* begin standout mode */
X  EXT char *SE INIT(Nullch);		/* end standout mode */
X  EXT int SG INIT(0);		/* blanks left by SO and SE */
X
X--- 161,167 -----
X  EXT char *HO INIT(Nullch);		/* home cursor -- PWP */
X  EXT char *CE INIT(Nullch);		/* clear to end of line */
X  EXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
X! EXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
X  EXT char *SO INIT(Nullch);		/* begin standout mode */
X  EXT char *SE INIT(Nullch);		/* end standout mode */
X  EXT int SG INIT(0);		/* blanks left by SO and SE */
END_OF_enh_rn47.patch
if test 53773 -ne `wc -c <enh_rn47.patch`; then
    echo shar: \"enh_rn47.patch\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rnprtf.readme -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rnprtf.readme\"
else
echo shar: Extracting \"rnprtf.readme\" \(3735 characters\)
sed "s/^X//" >rnprtf.readme <<'END_OF_rnprtf.readme'
XFrom mtune!mtunx!whuts!homxb!att-ih!pacbell!ames!necntc!ima!haddock!trb Sun Mar 20 01:48:47 EST 1988
XArticle 160 of news.admin:
XPath: icus!mtune!mtunx!whuts!homxb!att-ih!pacbell!ames!necntc!ima!haddock!trb
X>From: trb@haddock.ISC.COM (Andrew Tannenbaum)
XNewsgroups: news.admin,comp.sources.bugs,news.software.b
XSubject: enhancement to rn = index command
XMessage-ID: <3063@haddock.ISC.COM>
XDate: 18 Mar 88 20:08:52 GMT
XReply-To: trb@haddock.isc.com (Andrew Tannenbaum)
XOrganization: Interactive Systems, Boston
XLines: 212
XXref: icus news.admin:160 comp.sources.bugs:639 news.software.b:74
X
XSystem: rn version 4.3
XPriority: LOW
XSubject: enhancement to rn = index command
X>From: trb@ima.isc.com (Andrew Tannenbaum)
X
XDescription:
X	This patch lets you use printf-style formatting in rn strings,
X	most usefully, the SUBJLINE variable.
X
X	This is a patch to rn patch level 40.  I sent it to Larry Wall
X	back in Dec 1987, and he said to post it myself.  I didn't add
X	new RCS IDs, as I figured it could cause confusion since I don't
X	control rn.  I've been running the code for four months on two
X	different types of UNIX systems, without incident.
X
X	A sample of the output is just below.  The format used is
X	-ESUBJLINE="%:-50.50s %:.24t"
X
X	This work was done by me and Karl Heuer.  Karl points out that
X	%+ has special meaning to printf, and %: is used by terminfo to
X	disambiguate %wid.prec in a similar manner (see terminfo(4):
X	Parameterized strings).  This hack only distinguished + and -
X	for justification, it doesn't do %# or fancy %+.  It's all
X	#ifdef PADTRUNC.
X
X	I also fixed the /foo/= bug (it wasn't checking SUBJLINE).  I
X	notice that the %s fields have all the Re's stripped off, which
X	isn't quite right, but I haven't dealt with that.  (That's an
X	existing bug, or at least the doc for = says that it uses %s by
X	default).
X
XFix:	To fix rn, install the following patches and recompile.
X
X	From rn, say "| patch -d DIR", where DIR is your rn source directory.
X	Outside of rn, say "cd DIR; patch <thisarticle".  If you don't have
X	the patch program, apply the following by hand, or get patch.
X
X	Andrew Tannenbaum   Interactive   Boston, MA   +1 617 247 1155
X<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
XSample output: 
X
XWhat next? [^Nnpq] =
X...
X 5584 Ultrix uucp problems - Help!                  steph@alberta.UUCP
X 5585 Ksh question.                                 lenny@quincy.UUCP
X 5586 POSIX execlfd and execvfd proposal            karl@tut.cis.ohio-state.
X 5588 suggest solutions for "rm *"                  jsb@dasys1.UUCP
X 5589 3b5 inode problem with news                   KEN%ORION.BITNET@CUNYVM.
X 5590 The whole prompt string thing (was: PS1 and t marcos@caus-dp.UUCP
X 5592 setpgrp() bug?                                chapman@sco.COM
X 5593 more rm insanity                              chris@mimsy.UUCP
X 5595 //host vs "mount point"                       matt@oddjob.UChicago.EDU
X...
XWhat next? [^Nnpq]
XType h for help.
XWhat next? [^Nnpq] /gwyn/h=
XSearching...
X 5576 The whole prompt string thing (was: PS1 and t gwyn@brl.arpa
X 5578 Bug in Ultrix2.0?                             gwyn@brl.arpa
X 5611 The whole prompt string thing (was: PS1 and t gwyn@brl.arpa
X 5612 globbing in the shell (Was Re: more rm insani gwyn@brl.arpa
X 5659 Help! How 2 get info from C to Unix script    gwyn@brl.arpa
X 5662 globbing in the shell                         gwyn@brl.arpa
X 5676 shell globbing universal ?????                gwyn@brl.arpa
X 5690 more rm insanity                              gwyn@brl.arpa
X 5692 globbing in the shell (Was Re: more rm insani gwyn@brl.arpa
X 5695 ACCESS TO SHARED TAPEDRIVES                   gwyn@brl.arpa
XWhat next? [^Nnpq]
X<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
END_OF_rnprtf.readme
if test 3735 -ne `wc -c <rnprtf.readme`; then
    echo shar: \"rnprtf.readme\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rnvis.HDR -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rnvis.HDR\"
else
echo shar: Extracting \"rnvis.HDR\" \(1227 characters\)
sed "s/^X//" >rnvis.HDR <<'END_OF_rnvis.HDR'
XFrom rayssd!uunet!anise!ivucsb!todd Mon Jul 10 20:33:04 EDT 1989
XArticle 818 of alt.sources:
XPath: icus!rayssd!uunet!anise!ivucsb!todd
X>From: todd@ivucsb.sba.ca.us (Todd Day)
XNewsgroups: alt.sources
XSubject: Todd's hacks to rn (the diffs for patchlevel 40)
XMessage-ID: <1989Jul9.182246.28380@ivucsb.sba.ca.us>
XDate: 9 Jul 89 18:22:46 GMT
XReply-To: todd@ivucsb.sba.ca.us (Todd Day)
XOrganization: Disillusioned Graduate Hackers, Santa Barbara, CA
XLines: 1904
X
XThose of you who have requested the diffs to my hacks, well, here
Xthey are.
X
XI have included a file called 1READ_FIRST, so please do.
X
XAlso, to those of you who have already grabbed the source off anise,
Xmake sure you got rn40todd.Z and not rn.todd.tar.Z.  The later is
Xpatchlevel39 and the former is patchlevel40.  (anise is anise.acc.com
X[129.192.64.22])  These diffs are also available on anise (rn40todd.dif.Z).
X
XTo those of you who don't know what I am talking about, my hacks to
Xrn present you with a visual interface to the subjects when you type
X';' or '%'.  A user who never types these two characters will never
Xknow about my hacks (i.e., this doesn't interrupt normal rn).  All
Xmy changes are in the documentation and in the help section of rn.
X
XGood Luck!
X
END_OF_rnvis.HDR
if test 1227 -ne `wc -c <rnvis.HDR`; then
    echo shar: \"rnvis.HDR\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rnvis.readme -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rnvis.readme\"
else
echo shar: Extracting \"rnvis.readme\" \(1737 characters\)
sed "s/^X//" >rnvis.readme <<'END_OF_rnvis.readme'
X
X						July 7, 1989
XHello!
X
X	This is Todd's attempt at making rn act a bit more like vn (and
Xnow nn).  I have incorporated it first into rn:patchlevel39, then I
Xapplied level40 patches to it.  In other words, it should be at level 40.
X
X	Please note that my changes are kinda kludgey, in keeping with
Xthe programming style of lwall :-)
X
X	All of my changes have been documented in the documentation
Xplus the help files.
X
X	You enter my special mode by typing ';' anywhere.  As far
Xas I know, unless you type ';' or '%' at any prompt, you
Xwill not even know that rn has been modified.  In other words, users
Xthat don't want to use my changes don't have to.
X
X	If you find any bugs, please send them to me (plus fixes,
Xif you gottem).
X
X	Please be patient with me about this software.  I am now
Xusing nn (and suggest that you use it, also), but I will try to
Xupdate this software (in keeping with being a nice net.citizen).
X
X	Good luck... hope you like this stuff.  It cut my reading
Xtime down in half.  Most of the time, I would start reading the
Xarticle (since it all was displayed).  Now, with this program,
XI was able to delete stuff I really shouldn't have been reading.
X
X	Oh, I almost forgot.  You MUST have CACHESUBJ set in
Xcommon.h.  This is true for most people.  It is only false for
Xpdp11s.  Also, you must have a sorta smart terminal (I don't make
Xtoo much use of termcap stuff).  By sorta smart terminal, I mean
Xmust have do, cd, and up entry in termcap file.  Just about every
Xterminal I know of has this. [see term.c]
X
X	You can find most of my changes in ng.c.  Just search for
XSubScan(tm).
X
X	Have fun!
X
X
XTodd Day | todd@ivucsb.sba.ca.us | ivucsb!todd@anise.acc.com
X"Santa Barbara - so many babes... so few who will talk to me."
END_OF_rnvis.readme
if test 1737 -ne `wc -c <rnvis.readme`; then
    echo shar: \"rnvis.readme\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0


-- 
Gil Kloepfer, Jr.  ...!ames!limbic!gil  |  gil%limbic@ames.arc.nasa.gov
Southwest Systems Development Labs (Div of ICUS)   Houston, Texas