[comp.sources.unix] v22i108: NN Newsreader, release 6.4, Patch4

rsalz@uunet.uu.net (Rich Salz) (06/08/90)

Submitted-by: "Kim F. Storm" <storm@texas.dk>
Posting-number: Volume 22, Issue 108
Archive-name: nn6.4/patch4

	     This is an official patch to nn release 6.4
	     -------------------------------------------

			       PATCH #4

			    Priority: HIGH


These patches fix more bugs in the 6.4 release.  It fixes a nasty bug
causing lines to be dropped from .newsrc if it contained an "aliased"
group (fourth field is =group in Cnews's active file).

All changes are described in the updated RELEASE_NOTES file (read that
for details about this patch).  Thanks to all who reported bugs and
provided fixes.

To apply this patch, use nn's :patch command, or run this command from
the shell in the root of the nn source tree:
	patch -p0 < this-article


++Kim Storm

*** ./LAST/admin.c	Tue May 22 12:53:33 1990
--- admin.c	Mon May 28 23:19:55 1990
***************
*** 776,781 ****
--- 776,782 ----
  group_header *gh;
  {
      char command[FILENAME*2];
+     char *rmprog;
  
      if (!file_exist(news_active, "w")) {
  	printf("Not privileged to run rmgroup\n");
***************
*** 782,788 ****
  	return;
      }
  
!     sprintf(command, "%s/rmgroup %s", news_lib_directory, gh->group_name);
      system(command);
      any_key(0);
      gh->master_flag &= ~M_VALID;		/* just for nnadmin */
--- 783,803 ----
  	return;
      }
  
! #ifdef RMGROUP_PATH
!     rmprog = RMGROUP_PATH;
! #else
!     rmprog = "rmgroup";
! #endif
!     if (*rmprog != '/') rmprog = relative(news_lib_directory, rmprog);
!     if (file_exist(rmprog, "x")) goto rm_ok;
! #ifndef RMGROUP_PATH
!     rmprog = relative(news_lib_directory, "delgroup");
!     if (file_exist(rmprog, "x")) goto rm_ok;
! #endif
!     printf("Program %s not found\n", rmprog);
!     return;
!  rm_ok:
!     sprintf(command, "%s %s", rmprog, gh->group_name);
      system(command);
      any_key(0);
      gh->master_flag &= ~M_VALID;		/* just for nnadmin */
***************
*** 845,851 ****
  	    break;
  
  	 case 'R':
! 	    if (admin_confirm("Recolletion of Group", 0))
  		send_master(SM_RECOLLECT, gh, SP, 0L);
  	    break;
  
--- 860,866 ----
  	    break;
  
  	 case 'R':
! 	    if (admin_confirm("Recollection of Group", 0))
  		send_master(SM_RECOLLECT, gh, SP, 0L);
  	    break;
  
*** ./LAST/answer.c	Tue May 22 12:53:34 1990
--- answer.c	Mon May 28 23:17:29 1990
***************
*** 228,233 ****
--- 228,234 ----
  {
      FILE *param;
      char *args[10], *fn;
+     char route[512], *poster;
      register char **ap = args;
      import int novice;
      import char *pager;
***************
*** 238,244 ****
      param = open_file(relative(nn_directory, ".param"), OPEN_CREATE);
      if (param == NULL) {
  	strcpy(delayed_msg, "cannot create .param file for aux script");
! 	return 0;
      }
  
      if (strcmp(prog, "cancel") == 0) {
--- 239,245 ----
      param = open_file(relative(nn_directory, ".param"), OPEN_CREATE);
      if (param == NULL) {
  	strcpy(delayed_msg, "cannot create .param file for aux script");
! 	return 1;
      }
  
      if (strcmp(prog, "cancel") == 0) {
***************
*** 278,288 ****
  	    aux_param_str(param, "*A", fn != NULL ? fn : "");
  	}
  
! 	/*
! 	aux_param_str(param, "", );
! 	aux_param_bool(param, "", );
! 	aux_param_int(param, "", );
! 	*/
      }
  
      fclose(param);
--- 279,293 ----
  	    aux_param_str(param, "*A", fn != NULL ? fn : "");
  	}
  
! 	poster = NULL;
! 	if (ah != NULL && strcmp(prog, "follow") == 0) {
! 	    poster = news.ng_reply != NULL ? news.ng_reply : news.ng_from;
! 	    if (poster && reroute(route, poster)) 
! 		poster = route;
! 	    else
! 		poster = NULL;
! 	}
! 	aux_param_str(param, "POSTER_ADR", poster);
      }
  
      fclose(param);
***************
*** 327,332 ****
--- 332,338 ----
      int edit_message, append_sig;
      char *str, *script;
      news_header_buffer nhbuf, dhbuf;
+     flag_type st_flag = 0;
  
      first_action = "edit";
      edit_message = 1;
***************
*** 380,386 ****
  	pgm = "reply";
  	append_sig = append_sig_mail;
  
! 	ah->flag |= A_ST_REPLY;
  
  	if (reply_to(t, news.ng_reply) ||
  	    reply_to(t, news.ng_from) ||
--- 386,392 ----
  	pgm = "reply";
  	append_sig = append_sig_mail;
  
! 	st_flag = A_ST_REPLY;
  
  	if (reply_to(t, news.ng_reply) ||
  	    reply_to(t, news.ng_from) ||
***************
*** 426,432 ****
  	script = news_script;
  	append_sig = append_sig_post;
  
! 	ah->flag |= A_ST_FOLLOW;
  
  #ifdef NNTP
  #ifdef NNTP_MINI_INEWS_HEADER
--- 432,438 ----
  	script = news_script;
  	append_sig = append_sig_post;
  
! 	st_flag = A_ST_FOLLOW;
  
  #ifdef NNTP
  #ifdef NNTP_MINI_INEWS_HEADER
***************
*** 562,570 ****
      fclose(t);
      if (art) fclose(art);
  
!     aux_sh(ah, script, pgm, first_action, record_file,
! 	   command == K_FOLLOW_UP ? "Article%s posted" : "Mail%s sent",
! 	   append_sig);
  
      return edit_message;
  
--- 568,577 ----
      fclose(t);
      if (art) fclose(art);
  
!     if (aux_sh(ah, script, pgm, first_action, record_file,
! 	       command == K_FOLLOW_UP ? "Article%s posted" : "Mail%s sent",
! 	       append_sig) == 0)
! 	if (ah) ah->flag |= st_flag;
  
      return edit_message;
  
*** ./LAST/aux.sh	Tue May 22 12:53:35 1990
--- aux.sh	Mon May 28 19:23:53 1990
***************
*** 33,40 ****
  
  # first we handle 'cancel'
  
! if [ "$OPERATION" = "cancel" ] ; then
! 
    $INEWS -h  << EOF > /tmp/nn$$c 2>&1
  Newsgroups: $GROUP
  Subject: cancel $ART_ID
--- 33,40 ----
  
  # first we handle 'cancel'
  
! case "$OPERATION" in
! cancel)
    $INEWS -h  << EOF > /tmp/nn$$c 2>&1
  Newsgroups: $GROUP
  Subject: cancel $ART_ID
***************
*** 50,57 ****
    esac
    rm -f /tmp/nn$$c
    exit $x
! fi
! 
  
  TRACE=${WORK}T
  FINAL=${WORK}F
--- 50,65 ----
    esac
    rm -f /tmp/nn$$c
    exit $x
!   ;;
! post|follow)
!   LOOKFOR="Newsgroups:"
!   SEND="post article"
!   ;;
! *)
!   LOOKFOR="To:"
!   SEND="send letter"
!   ;;
! esac
  
  TRACE=${WORK}T
  FINAL=${WORK}F
***************
*** 66,79 ****
  
  loop=true
  prompt=false
! pr="Action: a)bort e)dit"
! if [ -n "$(SPELL_CHECKER)" ] ; then
!   pr="$pr i)spell"
  fi
! pr="$pr r)eedit s)end v)iew w)rite: "
! if [ -n "${DFLT_ANSW}" ] ; then
!   pr="$pr (${DFLT_ANSW}) "
  fi
  
  while $loop ; do
    if [ -n "${FIRST_ACTION}" ] ; then
--- 74,96 ----
  
  loop=true
  prompt=false
! pr="a)bort"
! if [ -n "${POSTER_ADR}" ] ; then
!   pr="$pr c)c"
  fi
! pr="$pr e)dit"
! if [ -n "${SPELL_CHECKER}" ] ; then
!   pr="$pr i)spell"
  fi
+ pr="$pr m)ail r)eedit s)end v)iew w)rite"
+ case "${DFLT_ANSW}" in
+   p*|s*) pr1=" (${SEND})"
+       ;;
+   "") pr1=""
+       ;;
+   *)  pr1=" (${DFLT_ANSW})"
+       ;;
+ esac
  
  while $loop ; do
    if [ -n "${FIRST_ACTION}" ] ; then
***************
*** 81,87 ****
      FIRST_ACTION=""
    elif $prompt ; then
      echo ''
!     ${AWK} 'END{printf "'"${pr}"'"}' < /dev/null
      read act
      if [ -z "$act" ] ; then
        act="${DFLT_ANSW}"
--- 98,105 ----
      FIRST_ACTION=""
    elif $prompt ; then
      echo ''
!     echo "${pr}"
!     ${AWK} 'END{printf "Action:'"${pr1}"' "}' < /dev/null
      read act
      if [ -z "$act" ] ; then
        act="${DFLT_ANSW}"
***************
*** 89,95 ****
    fi
    prompt=true
  
!   case $act in
    a*)
      ${AWK} 'END{printf "Confirm abort: (y) "}' < /dev/null
      read act
--- 107,113 ----
    fi
    prompt=true
  
!   case "$act" in
    a*)
      ${AWK} 'END{printf "Confirm abort: (y) "}' < /dev/null
      read act
***************
*** 98,103 ****
--- 116,137 ----
  	     exit 22 ;;
      esac
      ;;
+ 
+   c*)
+     if [ -n "${POSTER_ADR}" ] ; then
+       ${AWK} 'END{printf "CC: '"${POSTER_ADR}"' (y) "}' </dev/null
+       read act
+       case "$act" in
+       ""|"y*")
+ 	echo "Sending copy to poster...."
+ 	CC="${POSTER_ADR}"
+ 	;;
+       esac
+     else
+       echo "Not doing follow-up"
+     fi
+     ;;
+ 
    e*)
      # call editor to enter at line $ED_LINE of work file
  
***************
*** 132,137 ****
--- 166,179 ----
          exit 22
        fi
      fi
+ 
+     if [ -n "${LOOKFOR}" ] ; then
+       if grep "^${LOOKFOR}" $WORK > /dev/null ; then
+ 	:
+       else
+ 	echo "Warning: no $LOOKFOR line in article"
+       fi
+     fi
      ;;
  
    i*)
***************
*** 142,147 ****
--- 184,206 ----
      fi
      ;;
  
+   m*)
+     ${AWK} 'END{printf "To: "}' </dev/null
+     read CC
+     if [ -n "${CC}" ] ; then
+       echo "Sending copy...."
+     fi
+     ;;
+ 
+   n*)
+     act="abort"
+     prompt=false
+     ;;
+ 
+   p*)
+     loop=false
+     ;;
+ 
    r*)
      ${AWK} 'END{printf "Edit original file: (y) "}' < /dev/null
      read act
***************
*** 167,176 ****
--- 226,257 ----
      fi
      ;;
  
+   y*)
+     act="${DFLT_ANSW}"
+     prompt=false
+     ;;
+ 
    ENV)
      set
      ;;
    esac
+ 
+   if [ -n "${CC}" ] ; then
+     echo "To: ${CC}" > $FINAL
+     sed -e "s/^To:/X-To:/" -e "/^Orig-To:/d" $WORK >> $FINAL
+     if ${MAILER_PIPE} ; then
+       $MAILER < $FINAL
+       x=$?
+     else
+       $MAILER $FINAL
+       x=$?
+     fi
+     case $x in
+       0) echo Done ;;
+       *) echo $MAILER failed ;;
+     esac
+     CC=""
+   fi
  done
  
  if [ ${APPEND_SIG} = "true" -a -f $HOME/.signature ] ; then
***************
*** 182,188 ****
    fi
    case $ans in
    ''|y*|Y*)
!     echo "--" >> $WORK
      cat $HOME/.signature >> $WORK
      ;;
    esac
--- 263,269 ----
    fi
    case $ans in
    ''|y*|Y*)
!     echo "-- " >> $WORK
      cat $HOME/.signature >> $WORK
      ;;
    esac
***************
*** 242,252 ****
        ;;
  
      follow|post)
!       $INEWS -h < $FINAL
!       case $? in
! 	0) sleep 60 ;;
! 	*) echo $INEWS failed ;;
!       esac
        ;;
  
      *)
--- 323,335 ----
        ;;
  
      follow|post)
!       {
! 	$INEWS -h < $FINAL
! 	case $? in
! 	  0) sleep 60 ;;
! 	  *) echo $INEWS failed ;;
! 	esac
!       } | fgrep -v "mailing your article to" 
        ;;
  
      *)
*** ./LAST/conf/s-sys5.h	Thu Apr 26 19:56:03 1990
--- conf/s-sys5.h	Fri May 25 23:56:21 1990
***************
*** 62,73 ****
  #define	RESET_SIGNAL_WHEN_CAUGHT	/* */
  
  /*
-  *	Define MICRO_ALARM to timeout in 0.1 seconds if possible
-  */
- 
- #define MICRO_ALARM()	alarm(1)	/* System V */
- 
- /*
   *	Define if your system has BSD like job control (SIGTSTP works)
   */
  
--- 62,67 ----
*** ./LAST/conf/s-template.h	Wed May  2 09:38:37 1990
--- conf/s-template.h	Fri May 25 18:26:11 1990
***************
*** 71,80 ****
  #define	RESET_SIGNAL_WHEN_CAUGHT	/* */
  
  /*
   *	Define MICRO_ALARM to timeout in 0.1 seconds if possible
   */
  
- #define MICRO_ALARM()	alarm(1)	/* System V */
  /*#define MICRO_ALARM()	ualarm(100000,0)	/* BSD 4.3 */
  
  /*
--- 71,91 ----
  #define	RESET_SIGNAL_WHEN_CAUGHT	/* */
  
  /*
+  *	Define FAKE_INTERRUPT if a keyboard interrupt (^C) cannot interrupt
+  *	a read() system call.  This happens on a few BSD based systems
+  *	which don't have SV_INTERRUPT defined in <signal.h> and no
+  *	siginterrupt() call to make systems call interruptable.  
+  *	However, if siginterrupt() is available, but SV_INTERRUPT isn't
+  *	defined, then simply define that instead of FAKE_INTERRUPT!
+  */
+ 
+ /* #define FAKE_INTERRUPT	/* */
+ 
+ /*
   *	Define MICRO_ALARM to timeout in 0.1 seconds if possible
+  *	It is not used on systems with the TERMIO interface (sys V).
   */
  
  /*#define MICRO_ALARM()	ualarm(100000,0)	/* BSD 4.3 */
  
  /*
***************
*** 112,117 ****
--- 123,134 ----
  
  #define	HAVE_MKDIR			/* */
  
+ /*
+  *	Define NO_RENAME if the rename() system call is not available.
+  *	Notice: rename() is only used by the NNTP code.
+  */
+ 
+ /* #define NO_RENAME			/* */
  
  /*
   *	Pick one:
*** ./LAST/config.h-dist	Wed May 16 11:23:35 1990
--- config.h-dist	Mon May 28 19:24:06 1990
***************
*** 194,203 ****
   *	spool directory.  To use this scheme, the OWNER specified above
   *	must have write permission on the news spool directories.
   *
!  *	You should also be careful not to specify a database directory
!  *	if you access news via NNTP - you may not have the proper directories
!  *	on your local system.  However, it is probably ok anyway if nnmaster
!  *	runs on the nntp server.
   *
   *	To change the default behaviour, you can define the following
   *	symbols:
--- 194,204 ----
   *	spool directory.  To use this scheme, the OWNER specified above
   *	must have write permission on the news spool directories.
   *
!  *	If you access news via NNTP, you will probably always have to
!  *	give the database directory explicitly through DB_DIRECTORY
!  *	(and DB_DATA_DIRECTORY), since the normal news spool directories 
!  *	are probably not available on the local system.
!  *	The exception may be if nnmaster runs directly on the nntp server.
   *
   *	To change the default behaviour, you can define the following
   *	symbols:
***************
*** 229,234 ****
--- 230,238 ----
   *
   *	INEWS_PATH		- The location of the inews program.
   *				  Default: NEWS_LIB_DIR/inews
+  *
+  *	RMGROUP_PATH		- The location of the rmgroup program.
+  *				  Default: NEWS_LIB_DIR/{rm,del}group
   */
  
  #define NEWS_DIRECTORY		"/usr/spool/news"	/* */
*** ./LAST/doc/NNTP	Sat May  5 14:11:44 1990
--- doc/NNTP	Mon May 28 23:35:25 1990
***************
*** 132,137 ****
--- 132,147 ----
  	if both are defined.  If neither is defined, it will be
  	installed in /usr/lib/news/inews.
  
+ EXCELAN
+ 	You can define this symbol if your tcp/ip is based on the
+ 	EXCELAN implementation (no netdb.h, no getservbyname(), no
+ 	gethostbyname()).  (This belongs in the s- file!)
+ 
+ NO_BZERO
+ NO_RENAME
+ 	You can define these symbols if your system doesn't provide
+ 	the bzero() and/or rename() functions (these #define:s belong
+ 	in the s- file).
  	
  		
  				TUNING
*** ./LAST/doc/RELEASE_NOTES	Tue May 22 12:53:37 1990
--- doc/RELEASE_NOTES	Mon May 28 23:07:14 1990
***************
*** 547,553 ****
--- 547,690 ----
  	In the command, ":? [space] pwd [return]" which prints the working
  	directory correctly, but then repaints the screen immediately.
  
+ Prog:	nnadmin
+ Title:	"rmgroup" is Bnews specific - Cnews has "delgroup"
+ From:	Uwe Doering <gemini@geminix.mbx.sub.org>
+ Fixed:	Patch #4 [admin.c config.h-dist   -- new RMGROUP_PATH define]
  
+ 	Cnews has no `rmgroup' but instead a `delgroup' in its `newsbin'
+ 	directory. The entire path including the program name should be
+ 	configurable (in config.h).
+ 
+ Prog:	nnmaster - manual
+ Title:	nnmaster is in man8, but identifies itself as nnmaster(1M)
+ From:	Uwe Doering <gemini@geminix.mbx.sub.org>
+ Fixed:	Patch #4 [nnmaster.8]
+ 
+ Prog:	nnmaster
+ Title:	Files created by nnmaster are not in group GROUP
+ From:	Uwe Doering <gemini@geminix.mbx.sub.org>
+ Fixed:	Patch #4 [inst.sh -- nnmaster also runs setgid GROUP]
+ 
+ Prog:	nnadmin
+ Title:	Typo in "Recolle(c)tion ..." prompt
+ From:	Jim Clausing <jac@brahms.tinton.ccur.com> + fix
+ Fixed:	Patch #4 [admin.c]
+ 
+ Prog:	nn
+ Title:	Missing external declaration of nntp_get_filename in group.c
+ From:	hans@duttnph.tudelft.nl (Hans Buurman)
+ Fixed:	Patch #4 [group.c]
+ 
+ Prog:	nn
+ Title:	Interpretation of "marked-by-read-skip" is reversed
+ From:	dean%coplex@relay.EU.net (Dean Brooks) + fix
+ Fixed:	Patch #4 [menu.c]
+ 
+ Prog:	nn
+ Title:	re-layout 2 shows "base" articles as "0>".
+ From:	syd@dsinc.dsi.com (Syd Weinstein)
+ Fixed:	Patch #4 [menu.c]
+ 
+ Prog:	nn
+ Title:	.newsrc corruption -- lines are lost
+ From:	jeremy@cs.swarthmore.edu (Jeremy Brest)
+ From:	fitz@wang.com (Tom Fitzgerald) + explanation!
+ Fixed:	Patch #4 [newsrc.c]
+ 
+ 	Groups aliased in the active file and appearing in .newsrc would
+ 	cause parts of it to be lost!
+ 
+ Prog:	nn, nnacct
+ Title:	nn does not compile if only AUTHORIZE is defined.
+ From:	eps@toaster.SFSU.EDU (Eric P. Scott)
+ Fixed:	Patch #4 [nn.c]
+ 
+ Prog:	nn
+ Title:	SP/CR/X/.... cannot skip to next group when "nn -x" is used.
+ From:	jbayer@ispi.UUCP (Jonathan Bayer)
+ Fixed:	Patch #4 [menu.c]
+ 
+ Prog:	inst
+ Title:	It is not checked that nnmaster is actually killed by ./inst m
+ From:	Jaap Vermeulen <jaap%sequent@relay.EU.net> + fix
+ 	deborah@Sun.COM (Deborah Bennett)
+ Fixed:	Patch #4 [inst.sh]
+ 
+ Prog:	various
+ Title:	Not all y/n prompts are flushed
+ From:	Jaap Vermeulen <jaap%sequent@relay.EU.net>
+ Fixed:	Patch #4 [term.c]
+ 
+ Prog:	nntp support
+ Title:	nntp module uses rename() which is not generally available.
+ From:	Tim Oldham <tjo@its.bt.co.uk>
+ Fixed:	Patch #4 [nntp.c s-template.h  -- #define NO_RENAME in s- file]
+ 
+ Prog:	nn / nnpost
+ Title:	Should check that a Newsgroups: line exists before posting
+ From:	olson%anchor.esd@sgi.com (Dave Olson)
+ Fixed:	Patch #4 [aux.sh]
+ 
+ 	If one accidentally deletes the newsgroup line from a followup, and
+ 	then posts the article, it gets posted anyway.  In our case, it got
+ 	posted to 'general', which is the only group with no '.' in it.
+ 
+ Prog:	nnmaster
+ Title:	nnmaster doesn't complete installation if duplicates in active.
+ From:	Ric Steinberger <RIC@RML2.SRI.COM>
+ Fixed:	Patch #4 [master.c]
+ 
+ 	No error is reported, and no instructions are given if initialization
+ 	is stopped by confirming to fix duplicated entries in active file.
+ 
+ Prog:	nn -g
+ Title:	Error message shown if unknown group is entered is cleared instantly.
+ From:	Uwe Doering <gemini@geminix.mbx.sub.org>
+ 	Nick Holloway <alfie@cs.warwick.ac.uk>
+ Fixed:	Patch #4 [nn.c -- added 2s delay]
+ 
+ Prog:	nn
+ Title:	nncheck does not respect "newsrc" setting in init file.
+ From:	cjsa!jeff (Jeffery Small)
+ Fixed:	Patch #4 [nn.c]
+ 
+ Prog:	nn
+ Title:	The X command in reading mode doesn't mark selected articles read.
+ From:	dannie%coplex@relay.EU.net (Dannie Gregoire)
+ Fixed:	Patch #4 [menu.c]
+ 	
+ Prog:	nnmaster
+ Title:	nnmaster says "master already running" but this is not true....
+ From:	Bob Halloran <rkh@mtune.dptg.att.com>
+ 	Dean Brooks <dean@coplex.UUCP> [$MASTER is write protected!]
+ Fixed:	Patch #4 [proto.c -- will halt with fatal error]
+ 
+ Prog:	nn
+ Title:	The --(Filed,Re,Follow)-- labels are set even if the action fails.
+ From:	leo@aai.com
+ Fixed:	Patch #4 [answer.c save.c]
+ 
+ Prog:	nn
+ Title:	confirm-append does not work with $N
+ From:	leo@aai.com
+ 	
+ Prog:	nn
+ Title:	previous (group) command doesn't include read articles on the menu.
+ From:	netmgr@VENUS.CSC.FI
+ 
+ 	The current behaviour isn't logical, and it is difficult to get into
+ 	a state where articles marked read by mistake can be unmarked.
+ 
+ Prog:	nn
+ Title:	L and J commands should barf when used in no-update mode.
+ From:	netmgr@VENUS.CSC.FI
+ 
+ Prog:	nn
+ Title:	L and J commands should work *at least* when menu contains all art.
+ From:	netmgr@VENUS.CSC.FI
+ 
+ 
  New features since initial 6.4.0 release
  ----------------------------------------
  
***************
*** 596,598 ****
--- 733,760 ----
  Title:	New folder-save-file variable for saving from folders.
  From:	KFS (to fix problem with default-save-file)
  Fixed:	Patch #3 [save.c group.c variable.c nn.1]
+ 
+ Prog:	nn
+ Title:	New ignore-xon-xoff variable can be unset to make ^S/^Q useful
+ From:	KFS
+ Added:	Patch #4 [term.c variable.c nn.1]
+ 
+ Prog:	aux
+ Title:	New "c)c" command when posting followup to send copy to poster.
+ From:	KFS
+ Added:	Patch #4 [aux.sh answer.c nn.1]
+ 
+ Prog:	nn
+ Title:	New variable: show-purpose-mode
+ From:	KFS (on request from Rasmus Lerdorf)
+ Added:	Patch #4 [menu.c variable.c nn.1]
+ 
+ Prog:	nntp
+ Title:	Added support for EXCELAN
+ From:	fleming%nvuxk@bellcore.bellcore.com
+ Added:	Patch #4 [nntp.c NNTP]
+ 
+ Prog:	nn
+ Title:	New variable: read-return-next-page
+ From:	Jeffrey (J.D.) Sparkes <JSPARKES@BNR.CA>
+ Added:	Patch #4 [menu.c variable.c nn.1]
*** ./LAST/folder.c	Tue May 22 12:53:38 1990
--- folder.c	Mon May 28 23:35:24 1990
***************
*** 14,19 ****
--- 14,22 ----
  export int  dont_sort_folders = 0;
  export char *folder_directory  = NULL;
  
+ import int fmt_linenum;
+ import char *header_lines;
+ 
  /*
   * 	file name completion and expansion
   *
***************
*** 241,248 ****
      return 1;	/* number of header lines */
  }
  
! folder_menu(path)
  char *path;
  {
      FILE 			*folder;
      register article_header	*ah;
--- 244,259 ----
      return 1;	/* number of header lines */
  }
  
! /*
!  *	mode values:
!  *		0: normal folder or digest
!  *		1: online manual
!  *		2: mailbox
!  */
! 
! folder_menu(path, mode)
  char *path;
+ int mode;
  {
      FILE 			*folder;
      register article_header	*ah;
***************
*** 253,260 ****
--- 264,276 ----
      group_header 		fake_group;
      int				cc_save;
      char folder_name[FILENAME], folder_file[FILENAME];
+     int orig_layout;
+     char *orig_hdr_lines;
      extern time_stamp pack_date();
  
+     orig_layout = fmt_linenum;
+     orig_hdr_lines = header_lines;
+     
      strcpy(folder_name, path);
      fake_group.group_name = folder_name;
      if (!expand_file_name(folder_file, folder_name, 1)) return ME_NO_REDRAW;
***************
*** 303,308 ****
--- 319,325 ----
  	    ah->sender = alloc_str(length);
  	    strcpy(ah->sender, buffer);
  	    ah->name_length = length;
+ 	    if (mode == 1) fold_string(ah->sender);
  	} else {
  	    ah->sender = "";
  	    ah->name_length = 0;
***************
*** 314,319 ****
--- 331,337 ----
  	    ah->subject = alloc_str(length);
  	    strcpy(ah->subject, buffer);
  	    ah->subj_length = length;
+ 	    if (mode == 1 && length > 1) fold_string(ah->subject + 1);
  	} else {
  	    ah->replies = 0;
  	    ah->subject = "";
***************
*** 340,355 ****
  	if (n_articles > 1) {
  	    clrdisp();
  	    prompt_line = 2;
! 	    if (!dont_sort_folders) sort_articles(-1);
  	}
  
  	cc_save = cancel_count;
  	cancel_count = 0;
  
       reenter_menu:
  	menu_cmd = menu(folder_header);
  
! 	if (cancel_count) {
  	    clrdisp();
  	    printf("Folder: %s\nFile:   %s\n\n", folder_name, folder_file);
  	    if (cancel_count == n_articles)
--- 358,377 ----
  	if (n_articles > 1) {
  	    clrdisp();
  	    prompt_line = 2;
! 	    if (mode == 0 && !dont_sort_folders) sort_articles(-1);
  	}
  
  	cc_save = cancel_count;
  	cancel_count = 0;
+ 	if (mode == 1) {
+ 	    fmt_linenum = -1;
+ 	    header_lines = "*";
+ 	}
  
       reenter_menu:
  	menu_cmd = menu(folder_header);
  
! 	if (mode == 0 && cancel_count) {
  	    clrdisp();
  	    printf("Folder: %s\nFile:   %s\n\n", folder_name, folder_file);
  	    if (cancel_count == n_articles)
***************
*** 380,385 ****
--- 402,411 ----
      }
  
      release_memory(&mem_marker);
+     if (fmt_linenum == -1) {
+ 	fmt_linenum = orig_layout;
+ 	header_lines = orig_hdr_lines;
+     }
  
      return menu_cmd;
  }
*** ./LAST/global.c	Tue May 22 12:53:38 1990
--- global.c	Tue May 22 16:06:42 1990
***************
*** 75,80 ****
--- 75,83 ----
  export int s_keyboard		= 0;	/* keyboard interrupt */
  export int s_pipe		= 0;	/* broken pipe */
  export int s_redraw		= 0;	/* redraw signal (if job control) */
+ #ifdef RESIZING
+ export int s_resized		= 0;	/* screen resized */
+ #endif
  
  #ifdef FAKE_INTERRUPT
  #include <setjmp.h>
***************
*** 81,86 ****
--- 84,90 ----
  
  export jmp_buf fake_keyb_sig;
  export int arm_fake_keyb_sig = 0;
+ export char fake_keyb_siglist[NSIG];
  #endif
  
  sig_type catch_hangup(n)
***************
*** 88,93 ****
--- 92,101 ----
      signal(n, SIG_IGN);
  
      s_hangup++;
+ #ifdef FAKE_INTERRUPT
+     if (fake_keyb_siglist[n] && arm_fake_keyb_sig)
+         longjmp(fake_keyb_sig, 1);
+ #endif
  }
  
  static sig_type catch_keyboard(n)
***************
*** 96,102 ****
      signal(n, catch_keyboard);
  #endif
  #ifdef FAKE_INTERRUPT
!     if (arm_fake_keyb_sig)
  	longjmp(fake_keyb_sig, 1);
  #endif
      s_keyboard++;
--- 104,110 ----
      signal(n, catch_keyboard);
  #endif
  #ifdef FAKE_INTERRUPT
!     if (fake_keyb_siglist[n] && arm_fake_keyb_sig)
  	longjmp(fake_keyb_sig, 1);
  #endif
      s_keyboard++;
***************
*** 109,114 ****
--- 117,126 ----
  #ifdef RESET_SIGNAL_WHEN_CAUGHT
      signal(n, catch_pipe);
  #endif
+ #ifdef FAKE_INTERRUPT
+     if (fake_keyb_siglist[n] && arm_fake_keyb_sig)
+         longjmp(fake_keyb_sig, 1);
+ #endif
  }
  
  #ifdef HAVE_JOBCONTROL
***************
*** 121,126 ****
--- 133,147 ----
  #endif
  
      suspend_nn();
+ 
+ #ifdef FAKE_INTERRUPT
+     if (fake_keyb_siglist[n] && arm_fake_keyb_sig) {
+ #ifdef RESIZING
+ 	s_resized++;
+ #endif
+ 	longjmp(fake_keyb_sig, 1);
+     }
+ #endif
  }
  #endif
  
***************
*** 130,135 ****
--- 151,161 ----
      unsigned short getuid(), getgid();
      int getpid();
      int suspend_nn();
+     int i;
+ 
+ #ifdef FAKE_INTERRUPT
+     for (i = 0; i < NSIG; i++) fake_keyb_siglist[i] = i == 2 ? 1 : 0;
+ #endif
  
      if (who_am_i != I_AM_NN) {
  	signal(SIGINT,  SIG_IGN);
*** ./LAST/group.c	Tue May 22 12:53:39 1990
--- group.c	Fri May 25 12:20:36 1990
***************
*** 498,503 ****
--- 498,504 ----
  	    if ((ah->flag & A_DIGEST) == 0) {
  #ifdef NNTP
  		if (use_nntp) {
+ 		    extern char *nntp_get_filename();
  		    answer = nntp_get_filename(ah->a_number, current_group);
  		    goto get_folder;
  		}
***************
*** 705,711 ****
      if (strcmp(answer, "+") == 0)
  	answer = (gh && gh->save_file != NULL) ? gh->save_file : 
  	    (gh->group_flag & G_FOLDER) ? folder_save_file : default_save_file;
!     menu_cmd = folder_menu(answer);
      gh = NULL;
      goto goto_exit;
  
--- 706,712 ----
      if (strcmp(answer, "+") == 0)
  	answer = (gh && gh->save_file != NULL) ? gh->save_file : 
  	    (gh->group_flag & G_FOLDER) ? folder_save_file : default_save_file;
!     menu_cmd = folder_menu(answer, 0);
      gh = NULL;
      goto goto_exit;
  
*** ./LAST/init.c	Tue May 22 12:53:41 1990
--- init.c	Fri May 25 12:20:35 1990
***************
*** 978,985 ****
  	CASE( "man" ) {
  	    char *manual;
  	    group_header *orig_group;
- 	    int orig_layout, orig_fsort;
- 	    import int fmt_linenum, dont_sort_folders;
  
  	    manual = relative(help_directory, "Manual");
  	    if (!file_exist(manual, "fr")) {
--- 978,983 ----
***************
*** 990,1005 ****
  		}
  	    }
  	    orig_group = current_group;
! 	    orig_layout = fmt_linenum;
! 	    orig_fsort = dont_sort_folders;
! 
! 	    fmt_linenum = -1;
! 	    dont_sort_folders = 1;
! 
! 	    folder_menu(manual);
! 
! 	    fmt_linenum = orig_layout;
! 	    dont_sort_folders = orig_fsort;
  	    init_group(orig_group);
  
  	    return AC_REDRAW;
--- 988,994 ----
  		}
  	    }
  	    orig_group = current_group;
! 	    folder_menu(manual, 1);
  	    init_group(orig_group);
  
  	    return AC_REDRAW;
***************
*** 1105,1111 ****
  	    }
  
  	    orig_group = current_group;
! 	    folder_menu(mail_box);
  	    init_group(orig_group);
  
  	    return AC_REDRAW;
--- 1094,1100 ----
  	    }
  
  	    orig_group = current_group;
! 	    folder_menu(mail_box, 2);
  	    init_group(orig_group);
  
  	    return AC_REDRAW;
*** ./LAST/inst.sh	Wed May 16 11:23:38 1990
--- inst.sh	Sun May 27 17:34:53 1990
***************
*** 14,21 ****
  			exit 1
  		fi
  		chmod $3 $2
! 		chgrp $GROUP $2
! 		chown $OWNER $2
  		echo Created directory $2
  	fi
  	exit 0
--- 14,23 ----
  			exit 1
  		fi
  		chmod $3 $2
! 		if ./usercheck 0 ; then
! 			chgrp $GROUP $2
! 			chown $OWNER $2
! 		fi
  		echo Created directory $2
  	fi
  	exit 0
***************
*** 23,37 ****
  copy)
  	cp $4 $3
  	chmod $2 $3/$4
! 	chgrp $GROUP $3/$4
! 	chown $OWNER $3/$4
  	echo "$4 -> $3/$4"
  	exit 0
  	;;
  chmod)
  	chmod $2 $3
! 	chgrp $GROUP $3
! 	chown $OWNER $3
  	exit 0
  	;;
  
--- 25,43 ----
  copy)
  	cp $4 $3
  	chmod $2 $3/$4
! 	if ./usercheck 0 ; then
! 		chgrp $GROUP $3/$4
! 		chown $OWNER $3/$4
! 	fi
  	echo "$4 -> $3/$4"
  	exit 0
  	;;
  chmod)
  	chmod $2 $3
! 	if ./usercheck 0 ; then
! 		chgrp $GROUP $3
! 		chown $OWNER $3
! 	fi
  	exit 0
  	;;
  
***************
*** 101,125 ****
  else
  	PAUSE=true
  
! echo
! echo
! echo "INSTALLATION"
! echo ""
! echo "1) Master programs (machine dependent)"
! echo "2) User programs (machince dependent, shareable)"
! echo "3) Help files and auxiliary programs (shareable)"
! echo "4) Documentation (shareable)"
! echo "5) Online manual (shareable with 3)"
! echo ""
! echo "INIT) Initialize database"
! echo ""
! echo "s) Server installation:  1 + 2 + 3 + 4 + 5"
! echo "n) Network installation:     2 + 3 + 4 + 5"
! echo "m) Master installation:  1"
! echo "c) Client installation:      2"
! echo "u) Update after patch"
! echo "q) Quit"
! echo ""
  if ./usercheck 0 ; then
  	:
  else
--- 107,135 ----
  else
  	PAUSE=true
  
! cat <<'EOF'
! 
! 
! INSTALLATION
! 
! 1) Master programs (machine dependent)
! 2) User programs (machince dependent, shareable)
! 3) auxiliary programs (configuration dependent, shareable)
! 4) Documentation (shareable)
! 5) Help files (shareable)
! 6) Online manual (shareable with 5)
! 
! INIT) Initialize database
! 
! s) Server installation:  1 + 2 + 3 + 4 + 5 + 6
! n) Network installation:     2 + 3 + 4 + 5 + 6
! h) Shared installation:      2 + 3
! m) Master installation:  1
! c) Client installation:      2
! u) Update after patch
! q) Quit
! 
! EOF
  if ./usercheck 0 ; then
  	:
  else
***************
*** 151,156 ****
--- 161,170 ----
  	then
  		OPT="$OPT aux help"
  	fi
+ 	if [ -d "$HELP" ]
+ 	then
+ 		OPT="$OPT help"
+ 	fi
  	if [ -f "$DMAN_DIR/nnmaster.$DMAN_SECT" ]
  	then
  		OPT="$OPT man"
***************
*** 169,187 ****
  2|c)
  	OPT=bin
  	;;
- 3)
- 	OPT="aux help"
- 	;;
- x)
- 	OPT=aux
- 	;;
  h)
! 	OPT=help
  	;;
  4)
  	OPT="man"
  	;;
  5)
  	OPT="online"
  	;;
  INIT)
--- 183,201 ----
  2|c)
  	OPT=bin
  	;;
  h)
! 	OPT="bin aux"
! 	;;
! 3)
! 	OPT="aux"
  	;;
  4)
  	OPT="man"
  	;;
  5)
+ 	OPT="help"
+ 	;;
+ 6)
  	OPT="online"
  	;;
  INIT)
***************
*** 209,225 ****
  
  	if [ -f $MASTER/nnmaster ]
  	then
! 	    (
! 		cd $MASTER
! 		if [ -f MPID ]
  		then
  			echo "Stopping running master..."
! 			kill -1 `cat MPID`
! 			sleep 5
! 			rm -f MPID
  		fi
! 		mv nnmaster nnmaster.old
! 	   )
  	fi
  
  	echo Installing master in $MASTER
--- 223,238 ----
  
  	if [ -f $MASTER/nnmaster ]
  	then
! 		if [ -f $MASTER/MPID ]
  		then
  			echo "Stopping running master..."
! 			if ./nnmaster -k ; then
! 				echo "Stopped."
! 			else
! 				exit 1
! 			fi
  		fi
! 		mv $MASTER/nnmaster $MASTER/nnmaster.old
  	fi
  
  	echo Installing master in $MASTER
***************
*** 229,235 ****
  		./inst copy 755 $MASTER $prog
  	done
  
! 	chmod 4750 $MASTER/nnmaster
  	;;
  
  bin)
--- 242,248 ----
  		./inst copy 755 $MASTER $prog
  	done
  
! 	chmod 6750 $MASTER/nnmaster
  	;;
  
  bin)
*** ./LAST/man/nn.1.B	Tue May 22 12:53:46 1990
--- man/nn.1.B	Tue May 29 13:06:43 1990
***************
*** 194,200 ****
  just \fBreturn\fP to take the default action):
  .br
  .sp 0.5v
! 	Action: a)bort e)dit i)spell r)eedit s)end v)iew w)rite  (send)
  .sp 0.5v
  .br
  You now have the opportunity to perform one of the following actions:
--- 194,202 ----
  just \fBreturn\fP to take the default action):
  .br
  .sp 0.5v
! 	a)bort c)c e)dit i)spell m)ail r)eedit s)end v)iew w)rite
! .br
! 	Action: (post article)
  .sp 0.5v
  .br
  You now have the opportunity to perform one of the following actions:
***************
*** 204,213 ****
--- 206,223 ----
  .\"ta 4 9
  \fBa\fP	throw the response away (will ask for confirmation),
  .br
+ \fBc\fP	mail a copy of a \fIfollow-up\fP to the poster of the article,
+ .br
  \fBe\fP	edit the file again,
  .br
  \fBi\fP	run an (interactive) \fBspell-checker\fP on the text,
  .br
+ \fBm\fP	mail a (blind) copy to a specified recipient,
+ .br
+ \fBn\fP	same as \fBa\fPbort (\fIno\fP don't post)
+ .br
+ \fBp\fP	post article (same as \fBs\fPend)
+ .br
  \fBr\fP	throw away the edited text and edit the original text,
  .br
  \fBs\fP	send the article or letter,
***************
*** 215,220 ****
--- 225,232 ----
  \fBv\fP	view the article (through the \fBpager\fP), or
  .br
  \fBw\fP	append it to a file (before you send it).
+ .br
+ \fBy\fP	confirm \fIdefault answer\fP (e.g. \fIyes\fP post it)
  .in -2m
  .DT
  .LP
*** ./LAST/man/nn.1.C	Tue May 22 12:53:47 1990
--- man/nn.1.C	Tue May 29 13:06:43 1990
***************
*** 447,452 ****
--- 447,457 ----
  completions for the next component
  when \fInn\fP is prompting for a string, e.g. a file name.
  .TP
+ \fBignore-xon-xoff\fP		(boolean, default false)
+ Normally, \fInn\fP will ignore ^S and ^Q in the input from the
+ terminal (if they are not handled in the tty driver).  Setting this
+ variable will treat these characters as normal input.
+ .TP
  \fBinclude-art-id\fP		(boolean, default false)
  The first line in a response with included material normally reads
  \&"...somebody... writes:" without a reference to the specific article
***************
*** 763,768 ****
--- 768,777 ----
  	3:  A single Re: is shown.
  .fi
  .TP
+ \fBread-return-next-page\fP	(boolean, default false)
+ When set, the \fBZ\fP {\fBread-return\fP} command will return to the
+ \fInext\fP menu page rather than the current menu page.
+ .TP
  \fBrecord\fP \fIfile\fP	(string, no default)
  Setting this
  .I pseudo
***************
*** 841,846 ****
--- 850,866 ----
  When set (in the init file), \fInn\fP will not allow the user to
  invoke the shell in any way, including saving on pipes.  It also
  prevents the user from changing certain variables containing commands.
+ .TP
+ \fBshow-purpose-mode\fP \fIN\fP		(integer, default 1)
+ Normally, \fInn\fP will show the purpose of a group the first time it
+ is read, provided a purpose is known.  Setting this variable, this
+ behaviour can be changed as follows:
+ .br
+ .nf
+ 	0:  Never show the purpose.
+ 	1:  Show the purpose for new groups only.
+ 	2:  Show the purpose for all groups.
+ .fi
  .TP
  \fBsilent\fP		(boolean, default false)
  When set, \fInn\fP wont print the logo or "No News" if there are no
*** ./LAST/man/nnmaster.8	Wed May 16 11:23:52 1990
--- man/nnmaster.8	Tue May 22 12:15:45 1990
***************
*** 1,4 ****
! .TH NNMASTER 1M "Release 6.4"
  .\" (c) Copyright 1988, 1990, Kim F. Storm.  All rights reserved.
  .UC 4
  .SH NAME
--- 1,4 ----
! .TH NNMASTER 8 "Release 6.4"
  .\" (c) Copyright 1988, 1990, Kim F. Storm.  All rights reserved.
  .UC 4
  .SH NAME
*** ./LAST/master.c	Tue May 22 12:53:51 1990
--- master.c	Mon May 28 23:35:24 1990
***************
*** 365,372 ****
  	printf("Do you want to repair this file before continuing ? (y)");
  	gets(command);
  	if (s_hangup ||
! 	    command[0] == NUL || command[0] == 'y' || command[0] == 'Y')
  	    nn_exit(0);
      }
  
      /* if a "GROUPS" file exist offer to use that, else */
--- 365,375 ----
  	printf("Do you want to repair this file before continuing ? (y)");
  	gets(command);
  	if (s_hangup ||
! 	    command[0] == NUL || command[0] == 'y' || command[0] == 'Y') {
! 	    printf("Initialization stopped.\n");
! 	    printf("Redo ./inst INIT after repairing active file\n");
  	    nn_exit(0);
+ 	}
      }
  
      /* if a "GROUPS" file exist offer to use that, else */
***************
*** 577,584 ****
      }
  
      if (kill_running) {
! 	for (temp = 10; --temp >= 0; sleep(3))
! 	    if (proto_lock(I_AM_MASTER, PL_TERMINATE) < 0) break;
  
  	if (temp < 0) {
  	    printf("The running master will not die....!\n");
--- 580,590 ----
      }
  
      if (kill_running) {
! 	if (proto_lock(I_AM_MASTER, PL_TERMINATE) < 0)
! 	    temp = 0;
! 	else
! 	    for (temp = 10; --temp >= 0; sleep(3))
! 		if (proto_lock(I_AM_MASTER, PL_CHECK) < 0) break;
  
  	if (temp < 0) {
  	    printf("The running master will not die....!\n");
*** ./LAST/menu.c	Tue May 22 12:53:52 1990
--- menu.c	Mon May 28 23:55:29 1990
***************
*** 27,32 ****
--- 27,34 ----
  export int  mark_read_skip = 4; /* effect of X command */
  export int  mark_read_return = 0; /* effect of Z command */
  export int  mark_next_group = 0; /* effect of N command */
+ export int  show_purpose_mode = 1; /* 0: never, 1: new, 2: always */
+ export int  read_ret_next_page = 0; /* Z returns to next page */
  
  export int  auto_preview_mode = 0; /* preview rather than select */
  export int  preview_continuation = 12; /* what to do after preview */
***************
*** 76,83 ****
  	so_printf(">");
  	return 1;
       case 2:
! 	so_printf("%d>", level);
! 	return level < 10 ? 2 : 3;
       case 3:
  	so_printf("Re: ");
  	return 4;
--- 78,93 ----
  	so_printf(">");
  	return 1;
       case 2:
! 	switch (level) {
! 	 case 0:
! 	    return 0;
! 	 case 1:
! 	    so_printf(">");
! 	    return 1;
! 	 default:
! 	    so_printf("%d>", level);
! 	    return level < 10 ? 2 : 3;
! 	}
       case 3:
  	so_printf("Re: ");
  	return 4;
***************
*** 422,427 ****
--- 432,442 ----
  		return cmd;
  
  	     case MC_READGROUP:
+ 		for (cur = 0; cur < n_articles; cur++) {
+ 		    ah = articles[cur];
+ 		    if (ah->attr == 0 || (ah->attr & A_SELECT))
+ 			ah->attr = A_READ;
+ 		}
  		return cmd;
  	    }
  
***************
*** 632,639 ****
  	      menu_level);
  
      purpose[0] = NUL;
!     if (!merged_menu && current_group->group_flag & G_NEW)
! 	get_purpose(purpose);
  
      firsta = 0;
      while (firsta < n_articles && articles[firsta]->attr == A_SEEN)
--- 647,658 ----
  	      menu_level);
  
      purpose[0] = NUL;
!     if (!merged_menu)
! 	switch (show_purpose_mode) {
! 	 case 0: break;
! 	 case 1: if ((current_group->group_flag & G_NEW) == 0) break;
! 	 case 2: get_purpose(purpose);
! 	}
  
      firsta = 0;
      while (firsta < n_articles && articles[firsta]->attr == A_SEEN)
***************
*** 1046,1052 ****
  	 menu_return(ME_NEXT);
  
        case K_READ_GROUP_UPDATE:
! 	 if (temp = mark_read_skip) break;
        do_marked_by:
  	 temp1 = 0; temp2 = n_articles;
  	 switch (temp) {
--- 1065,1071 ----
  	 menu_return(ME_NEXT);
  
        case K_READ_GROUP_UPDATE:
! 	 if ((temp = mark_read_skip) == 0) break;
        do_marked_by:
  	 temp1 = 0; temp2 = n_articles;
  	 switch (temp) {
***************
*** 1519,1525 ****
  	goto redraw;
  
       case MC_READGROUP:
! 	if (k_cmd == K_READ_GROUP_THEN_SAME || also_read_articles) goto redraw;
       case MC_NEXTGROUP:
  	menu_cmd = ME_NEXT;
  	break;
--- 1538,1549 ----
  	goto redraw;
  
       case MC_READGROUP:
! 	if (k_cmd == K_READ_GROUP_THEN_SAME) {
! 	    if (read_ret_next_page && nexta < n_articles)
! 		firsta = nexta;
! 	    goto redraw;
! 	}
! 	
       case MC_NEXTGROUP:
  	menu_cmd = ME_NEXT;
  	break;
*** ./LAST/news.c	Wed May 16 11:22:46 1990
--- news.c	Fri May 25 13:55:15 1990
***************
*** 55,60 ****
--- 55,75 ----
  		while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
  		*fptr = bp;
  	    }
+ #ifdef NO_HEADER_SEPARATION_HACK
+ 	    else {
+ 		for (cp = bp; *cp && *cp != ':'; cp++) {
+ 		    if (!isascii(*cp)) break;
+ 		    if (*cp == '_' || *cp == '-') continue;
+ 		    if (isalnum(*cp)) continue;
+ 		    break;
+ 		}
+ 		if (*cp != ':') {
+ 		    *bp = NL;
+ 		    pos--;
+ 		    continue;
+ 		}
+ 	    }
+ #endif
  
  	while (*bp && *bp != NL) bp++;
  
*** ./LAST/newsrc.c	Tue May 22 12:53:55 1990
--- newsrc.c	Mon May 28 23:33:28 1990
***************
*** 276,281 ****
--- 276,282 ----
      char bak[FILENAME];
      time_t last_new_group = 0, rc_age, newsrc_age;
      group_header *last_new_gh = NULL;
+     extern group_header *lookup_no_alias();
  
      if (newsrc_file == NULL)
  	newsrc_file = home_relative(".newsrc");
***************
*** 337,347 ****
  	    if (c == RC_UNSUBSCR || c == RC_SUBSCR) {
  		subscr = (c == RC_SUBSCR);
  		*bp = NUL;
! 		gh = lookup(rcbuf);
! 		if (gh == NULL) {
! 		    gh = newobj(group_header, 1);
! 		    gh->group_name = copy_str(rcbuf); /* invalid group! */
! 		}
  		*bp = c;
  		break;
  	    }
--- 338,344 ----
  	    if (c == RC_UNSUBSCR || c == RC_SUBSCR) {
  		subscr = (c == RC_SUBSCR);
  		*bp = NUL;
! 		gh = lookup_no_alias(rcbuf);
  		*bp = c;
  		break;
  	    }
***************
*** 353,358 ****
--- 350,357 ----
  	    gh->master_flag |= M_VALID;
  	}
  
+ 	if (gh->master_flag & M_ALIASED) continue;
+ 
  	if (rc_seq_tail == NULL)
  	    rc_sequence = rc_seq_tail = gh;
  	else {
***************
*** 470,477 ****
  
  	if (c == NUL) continue;
  	*bp = NUL;
! 	gh = lookup(selbuf);
! 	if (gh == NULL) continue;
  	*bp = c;
  	if (c == SEL_NEW) gh->group_flag |= G_NEW;
  	gh->select_orig = gh->select_line = copy_str(selbuf);
--- 469,476 ----
  
  	if (c == NUL) continue;
  	*bp = NUL;
! 	gh = lookup_no_alias(selbuf);
! 	if (gh == NULL || gh->master_flag & M_ALIASED) continue;
  	*bp = c;
  	if (c == SEL_NEW) gh->group_flag |= G_NEW;
  	gh->select_orig = gh->select_line = copy_str(selbuf);
*** ./LAST/nn.c	Wed May 16 11:23:56 1990
--- nn.c	Mon May 28 23:34:22 1990
***************
*** 208,214 ****
  	free_memory();
  
  	if (gh->group_flag & G_FOLDER) {
! 	    menu_cmd = folder_menu(gh->group_name);
  	    if (menu_cmd == ME_NO_REDRAW) {
  		menu_cmd = ME_NO_ARTICLES;
  		gh->last_db_article = 0;
--- 208,214 ----
  	free_memory();
  
  	if (gh->group_flag & G_FOLDER) {
! 	    menu_cmd = folder_menu(gh->group_name, 0);
  	    if (menu_cmd == ME_NO_REDRAW) {
  		menu_cmd = ME_NO_ARTICLES;
  		gh->last_db_article = 0;
***************
*** 473,479 ****
--- 473,483 ----
      ap = args;
      *ap++ = "nnacct";
      if (report) *ap++ = "-r";
+ #ifdef STATISTICS
      sprintf(buf1, "-%c%ld", option, (long)usage_time/60);
+ #else
+     sprintf(buf1, "-%c0", option);
+ #endif
      *ap++ = buf1;
      sprintf(buf2, "-W%d", who_am_i);
      *ap++ = buf2;
***************
*** 688,694 ****
  	nn_exit(0);
  
       case I_AM_CHECK:
! 	visit_init_file(1, (char *)NULL);
  	group_name_args =
  	    parse_options(argc, argv, (char *)NULL, check_options,
  			  " [group]...");
--- 692,698 ----
  	nn_exit(0);
  
       case I_AM_CHECK:
! 	visit_init_file(0, (char *)NULL);
  	group_name_args =
  	    parse_options(argc, argv, (char *)NULL, check_options,
  			  " [group]...");
***************
*** 699,705 ****
  	break;
  
       case I_AM_TIDY:
! 	visit_init_file(1, (char *)NULL);
  	group_name_args = opt_nntidy(argc, argv);
  	break;
  
--- 703,709 ----
  	break;
  
       case I_AM_TIDY:
! 	visit_init_file(0, (char *)NULL);
  	group_name_args = opt_nntidy(argc, argv);
  	break;
  
***************
*** 708,714 ****
  	break;
  
       case I_AM_GREP:
! 	visit_init_file(1, (char *)NULL);
  	opt_nngrep(argc, argv);
  	silent = 1;
  	break;
--- 712,718 ----
  	break;
  
       case I_AM_GREP:
! 	visit_init_file(0, (char *)NULL);
  	opt_nngrep(argc, argv);
  	silent = 1;
  	break;
***************
*** 802,807 ****
--- 806,812 ----
  		prompt_line = 2;
  		cmd = goto_group(K_GOTO_GROUP, (article_header *)NULL, setup_access());
  		
+ 		if (cmd == ME_NO_REDRAW) sleep(2);
  	    } while (repeat_group_query && cmd != ME_QUIT && cmd != ME_NO_REDRAW);
  	    clrdisp();
  	    unset_raw();
*** ./LAST/nntp.c	Wed May 16 11:23:57 1990
--- nntp.c	Mon May 28 23:14:56 1990
***************
*** 28,34 ****
--- 28,37 ----
  #include <stdio.h>
  #include "nntp.h"
  #include <sys/socket.h>
+ #ifndef EXCELAN
  #include <netdb.h>
+ #endif
+ #include <errno.h>
  
  /* This is necessary due to the definitions in m-XXX.h */
  #if !defined(NETWORK_DATABASE) || defined(NETWORK_BYTE_ORDER)
***************
*** 35,40 ****
--- 38,47 ----
  #include <netinet/in.h>
  #endif
  
+ #ifdef EXCELAN
+ #define	IPPORT_NNTP	119
+ #endif
+ 
  import char *db_directory, *tmp_directory, *news_active;
  
  export char nntp_server[256];	/* name of nntp server */
***************
*** 50,56 ****
  
  import int silent, no_update;
  
! import int errno, sys_nerr;
  import char *sys_errlist[];
  extern int user_error();
  extern int sys_error();
--- 57,63 ----
  
  import int silent, no_update;
  
! import int sys_nerr;
  import char *sys_errlist[];
  extern int user_error();
  extern int sys_error();
***************
*** 70,75 ****
--- 77,103 ----
  
  #define ERR_TIMEOUT	503		/* Response code for timeout */
  
+ 
+ #ifdef NO_BZERO
+ static bzero(p, l)
+ register char *p;
+ register int l;
+ {  
+     while (l-- > 0)
+ 	*p++ = 0;
+ }
+ #endif
+ 
+ #ifdef NO_RENAME
+ static rename(old, new)
+ char *old, *new;
+ {
+     if (unlink(new) < 0 && errno != ENOENT) return -1;
+     if (link(old, new) < 0) return -1;
+     return unlink(old);
+ }
+ #endif
+ 
  /*
   * debug_msg: print a debug message.
   *
***************
*** 236,243 ****
--- 264,273 ----
  {
      int s;
      struct sockaddr_in sin;
+ #ifndef EXCELAN
      struct servent *getservbyname(), *sp;
      struct hostent *gethostbyname(), *hp;
+ 
  #ifdef h_addr
      int     x = 0;
      register char **cp;
***************
*** 253,258 ****
--- 283,296 ----
      sin.sin_family = hp->h_addrtype;
      sin.sin_port = sp->s_port;
  
+ #else /* EXCELAN */
+     char *machine;
+ 
+     bzero((char*) &sin, sizeof(sin));
+     sin.sin_family = AF_INET;
+     sin.sin_port = htons(0);
+ #endif  /* EXCELAN */
+ 
  #ifdef h_addr
      /* get a socket and initiate connection -- use multiple addresses */
  
***************
*** 273,278 ****
--- 311,333 ----
      if (x < 0 && who_am_i != I_AM_MASTER)
  	user_error("Giving up on NNTP server %s!\n", nntp_server);
  #else					/* no name server */
+ #ifdef EXCELAN
+     if ((s = socket(SOCK_STREAM, NULL, &sin, SO_KEEPALIVE)) < 0)
+ 	sys_error("Can't get NNTP socket: %s", syserr());
+ 
+     sin.sin_port = htons(IPPORT_NNTP);
+     machine = nntp_server;
+     if ((sin.sin_addr.s_addr = rhost(&machine)) < 0)
+         sys_error("%s:  Unknown host.", nntp_server);
+ 
+     /* And then connect */
+     if (connect(s, &sin) < 0) {
+ 	if (who_am_i == I_AM_MASTER)
+ 	    sys_error("Connecting to %s: %s", nntp_server, syserr());
+         (void) close(s);
+ 	s = -1;
+     }
+ #else /* not EXCELAN */
      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  	sys_error("Can't get NNTP socket: %s\n", syserr());
  
***************
*** 283,288 ****
--- 338,344 ----
  	    sys_error("Connecting to %s failed: %s", nntp_server, syserr());
  	s = -1;
      }
+ #endif  /* EXCELAN */
  #endif
      return s;
  }
*** ./LAST/patchlevel.h	Tue May 22 12:53:56 1990
--- patchlevel.h	Mon May 28 23:15:19 1990
***************
*** 14,20 ****
   *	1990-05-10: Patch #1 (6.4.1) - HIGH
   *	1990-05-15: Patch #2 (6.4.2) - HIGH
   *	1990-05-21: Patch #3 (6.4.3) - HIGH
   */
  
! #define PATCHLEVEL 3
  
--- 14,21 ----
   *	1990-05-10: Patch #1 (6.4.1) - HIGH
   *	1990-05-15: Patch #2 (6.4.2) - HIGH
   *	1990-05-21: Patch #3 (6.4.3) - HIGH
+  *	1990-05-29: Patch #4 (6.4.4) - HIGH
   */
  
! #define PATCHLEVEL 4
  
*** ./LAST/proto.c	Thu Apr 26 16:52:26 1990
--- proto.c	Mon May 28 20:26:04 1990
***************
*** 119,125 ****
  	return -1;
  
      m_pid = open_file(lock, OPEN_CREATE);
!     if (m_pid == NULL) return 1;	/* failed to lock (permission?) */
      fprintf(m_pid, "%d\n", process_id);
      fclose(m_pid);
  
--- 119,126 ----
  	return -1;
  
      m_pid = open_file(lock, OPEN_CREATE);
!     if (m_pid == NULL)
! 	sys_error("Cannot create lock file: %s", lock);
      fprintf(m_pid, "%d\n", process_id);
      fclose(m_pid);
  
*** ./LAST/save.c	Tue May 22 12:53:57 1990
--- save.c	Mon May 28 23:04:10 1990
***************
*** 383,388 ****
--- 383,389 ----
      news_header_buffer hdrbuf;
      int was_raw = 0, set_visual = 0;
      char copybuf[FILENAME * 4], uniqbuf[FILENAME];
+     flag_type st_flag = A_ST_FILED;
  
      if (ah->a_group) init_group(ah->a_group);
  
***************
*** 524,531 ****
      fclose(art);
  
      if (save_mode & DO_UNSHAR) {
! 	if ((c = pclose(save_file)) != 0)
  	    sprintf(delayed_msg, "Save command failed; exit = %d", c);
  	save_file = NULL;
      } else {
  	if (s_pipe)
--- 525,534 ----
      fclose(art);
  
      if (save_mode & DO_UNSHAR) {
! 	if ((c = pclose(save_file)) != 0) {
  	    sprintf(delayed_msg, "Save command failed; exit = %d", c);
+ 	    st_flag = 0;
+ 	}
  	save_file = NULL;
      } else {
  	if (s_pipe)
***************
*** 537,543 ****
  		"%s: %d lines appended", save_name, lcount);
  
  	if (s_pipe || (save_mode & SEPARATE_FILES)) {
! 	    if (end_save() == 0) return 0;
  	} else
  	    save_mode &= ~FILE_IS_NEW;
      }
--- 540,546 ----
  		"%s: %d lines appended", save_name, lcount);
  
  	if (s_pipe || (save_mode & SEPARATE_FILES)) {
! 	    if (end_save() == 0) goto err;
  	} else
  	    save_mode &= ~FILE_IS_NEW;
      }
***************
*** 551,564 ****
      if (set_visual) visual_on();
      if (was_raw) raw();
  
!     ah->flag |= A_ST_FILED;
  
      return !s_pipe || (save_mode & SEPARATE_FILES);
  
   fatal:
      if (set_visual) visual_on();
      if (was_raw) raw();
-     fclose(art);
      return 0;
  }
  
--- 554,568 ----
      if (set_visual) visual_on();
      if (was_raw) raw();
  
!     ah->flag |= st_flag;
  
      return !s_pipe || (save_mode & SEPARATE_FILES);
  
   fatal:
+     fclose(art);
+  err:
      if (set_visual) visual_on();
      if (was_raw) raw();
      return 0;
  }
  
***************
*** 578,584 ****
  		return 0;
  	    }
  	} else
! 	    fclose(sf);
      }
  
      if (save_mode & DO_DECODE) {
--- 582,591 ----
  		return 0;
  	    }
  	} else
! 	    if (fclose(sf) == EOF) {
! 		sprintf(delayed_msg, "Save failed (disk full?)");
! 		return 0;
! 	    }
      }
  
      if (save_mode & DO_DECODE) {
*** ./LAST/term.c	Tue May 22 12:53:59 1990
--- term.c	Mon May 28 20:14:19 1990
***************
*** 17,23 ****
  #include <sys/ptem.h>
  #endif
  
! int s_resized;
  #endif
  
  export char *term_name = NULL;
--- 17,23 ----
  #include <sys/ptem.h>
  #endif
  
! extern int s_resized;
  #endif
  
  export char *term_name = NULL;
***************
*** 29,34 ****
--- 29,35 ----
  export int  any_message = 0;
  export int  flow_control = 1;
  export int  use_visible_bell = 1; /* if supported by terminal */
+ export int  ignore_xon_xoff = 1;
  
  export key_type help_key = '?';
  export key_type comp1_key = SP;
***************
*** 112,117 ****
--- 113,119 ----
  
  extern jmp_buf fake_keyb_sig;
  extern int arm_fake_keyb_sig;
+ extern char fake_keyb_siglist[];
  #endif
  
  #include <sgtty.h>
***************
*** 216,222 ****
  
  #ifdef RESIZING
  
! sig_type catch_winch()
  {
      struct winsize winsize;
  
--- 218,224 ----
  
  #ifdef RESIZING
  
! sig_type catch_winch(n)
  {
      struct winsize winsize;
  
***************
*** 228,233 ****
--- 230,239 ----
  	s_redraw = 1;
  	s_resized = 1;
      }
+ #ifdef FAKE_INTERRUPT
+     if (fake_keyb_siglist[n] && arm_fake_keyb_sig)
+ 	longjmp(fake_keyb_sig, 1);
+ #endif
  }
  #endif /* RESIZING */
  
***************
*** 244,249 ****
--- 250,263 ----
  #endif
  #endif
  
+ #ifdef FAKE_INTERRUPT
+ #define SV_INTERRUPT
+ static siginterrupt (signo, on)
+ {
+     fake_keyb_siglist[signo] = on;
+ }
+ #endif
+ 
  static unsigned sp_table[] = {
      B9600, 960,
  #ifdef B19200
***************
*** 326,352 ****
      get_cap("ce", clr_eol);
      opt_cap("cd", clr_eos);
  
! #ifdef RESIZING
!     {
! 	struct winsize winsize;
! 
! 	if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
! 	    && winsize.ws_row != 0 && winsize.ws_col != 0) {
! 	    Lines = winsize.ws_row;
! 	    Columns = winsize.ws_col;
! 	    (void) signal(SIGWINCH, catch_winch);
! #ifdef SV_INTERRUPT
! 	    siginterrupt(SIGWINCH, 1);	/* make read from tty interruptable */
! #endif /* SV_INTERRUPT */
! 	}
!     }
!     if (Lines == 0 || Columns == 0) {
! #endif /* RESIZING */
! 	Lines = tgetnum("li");
! 	Columns = tgetnum("co");
! #ifdef RESIZING
!     }
! #endif /* RESIZING */
  
      opt_cap("so", enter_standout_mode);
      opt_cap("se", exit_standout_mode);
--- 340,347 ----
      get_cap("ce", clr_eol);
      opt_cap("cd", clr_eos);
  
!     Lines = tgetnum("li");
!     Columns = tgetnum("co");
  
      opt_cap("so", enter_standout_mode);
      opt_cap("se", exit_standout_mode);
***************
*** 372,377 ****
--- 367,388 ----
  
  #endif /* !USE_TERMINFO */
  
+ #ifdef RESIZING
+     {
+ 	struct winsize winsize;
+ 
+ 	if (ioctl(0, TIOCGWINSZ, &winsize) >= 0
+ 	    && winsize.ws_row != 0 && winsize.ws_col != 0) {
+ 	    Lines = winsize.ws_row;
+ 	    Columns = winsize.ws_col;
+ 	    (void) signal(SIGWINCH, catch_winch);
+ #ifdef SV_INTERRUPT
+ 	    siginterrupt(SIGWINCH, 1);	/* make read from tty interruptable */
+ #endif /* SV_INTERRUPT */
+ 	}
+     }
+ #endif /* RESIZING */
+ 
      STANDOUT = HAS_CAP(enter_standout_mode);
      if (STANDOUT) {
  	if (cookie_size < 0) cookie_size = 0;
***************
*** 746,754 ****
  
  static int alarm_on = 0;
  
! static mk_timeout()
  {
      alarm_on = 0;
  }
  
  #endif
--- 757,770 ----
  
  static int alarm_on = 0;
  
! static mk_timeout(n)
  {
      alarm_on = 0;
+ 
+ #ifdef FAKE_INTERRUPT
+     if (fake_keyb_siglist[n] && arm_fake_keyb_sig)
+ 	longjmp(fake_keyb_sig, 1);
+ #endif
  }
  
  #endif
***************
*** 821,827 ****
  	c &= 0177;	/* done by ISTRIP on USG systems */
  #endif
  
! 	if (c == CONTROL_('Q') || c == CONTROL_('S'))
  	    continue;
  
  	any_multi = 0;
--- 837,843 ----
  	c &= 0177;	/* done by ISTRIP on USG systems */
  #endif
  
! 	if (ignore_xon_xoff && (c == CONTROL_('Q') || c == CONTROL_('S')))
  	    continue;
  
  	any_multi = 0;
***************
*** 861,866 ****
--- 877,885 ----
  	goto next_key;
      }
  
+ #ifdef FAKE_INTERRUPT
+     arm_fake_keyb_sig = 0;
+ #endif
  #ifdef CBREAK
      if (s_redraw) {
  	s_redraw = 0;
***************
*** 869,877 ****
  #endif
  
  #ifndef KEY_BURST
- #ifdef FAKE_INTERRUPT
-     arm_fake_keyb_sig = 0;
- #endif
      if (n < 0) {
  	if (errno != EINTR) s_hangup++;
  	return K_interrupt;
--- 888,893 ----
***************
*** 891,896 ****
--- 907,915 ----
  #endif
  
  got_char:
+ #ifdef FAKE_INTERRUPT
+     arm_fake_keyb_sig = 0;
+ #endif
  
  #ifndef KEY_BURST
      if (alarm_on) {
***************
*** 1198,1203 ****
--- 1217,1223 ----
      	in_macro++;
  	break;
      }
+     fl;
  
      for (;;) {
  	if (!is_raw) {
*** ./LAST/variable.c	Tue May 22 12:54:00 1990
--- variable.c	Mon May 28 19:24:01 1990
***************
*** 70,75 ****
--- 70,76 ----
      flow_control,
      flush_typeahead,
      fmt_rptsubj,
+     ignore_xon_xoff,
      include_art_id,
      include_full_header,
      keep_rc_backup,
***************
*** 86,91 ****
--- 87,93 ----
      query_signature,
      quick_save,
      quick_unread_count,
+     read_ret_next_page,
      repeat_group_query,
      report_cost_on_exit,
      retain_seen_status,
***************
*** 135,140 ****
--- 137,143 ----
      response_check_pause,
      retry_on_error,
      save_counter_offset,
+     show_purpose_mode,
      slow_speed,
      sort_mode,
      subject_match_limit,
***************
*** 237,242 ****
--- 240,246 ----
      "fsort",			BOOL 2,		(char **)&dont_sort_folders,
      "header-lines",		STR 0,		(char **)&header_lines,
      "help-key",			KEY 0,		(char **)&help_key,
+     "ignore-xon-xoff",		BOOL 0,		(char **)&ignore_xon_xoff,
      "include-art-id",		BOOL 0,		(char **)&include_art_id,
      "include-full-header",	BOOL 0,		(char **)&include_full_header,
      "included-mark",		STR 1,		(char **)included_mark,
***************
*** 285,290 ****
--- 289,295 ----
      "quick-count",		BOOL 0,		(char **)&quick_unread_count,
      "quick-save",		BOOL 0,		(char **)&quick_save,
      "re-layout",		INT 0,		(char **)&re_layout,
+     "read-return-next-page",	BOOL 0,		(char **)&read_ret_next_page,
      "record",			SPEC 1,		(char **)NULL,
      "repeat",			BOOL 0,		(char **)&fmt_rptsubj,
      "repeat-group-query",	BOOL 0,		(char **)&repeat_group_query,
***************
*** 301,306 ****
--- 306,312 ----
      "select-on-sender",		BOOL 0,		(char **)&select_on_sender,
      "shell",			STR SAFE 0,	(char **)&user_shell,
      "shell-restrictions", 	BOOL INIT 0,	(char **)&shell_restrictions,
+     "show-purpose-mode",	INT 0,		(char **)&show_purpose_mode,
      "silent",			BOOL 0,		(char **)&silent,
      "slow-mode",		BOOL 0,		(char **)&slow_mode,
      "slow-speed",		INT 0,		(char **)&slow_speed,


exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.