NN 6.3 -- Official Patch #3

Kim F. Storm storm at texas.dk
Fri Jun 30 20:50:21 AEST 1989


This is patch #3 for nn release 6.3.

Apply it using the :patch command in nn.


ABOUT PATCH #3

This patch fixes a major problem on some systems which is not seen
at all on other systems (including mine):  NN wont find any news.  
A zillion thanks to Aaron Pelton for tracking down this nasty bug.

It also fixes a few portability problems related to cpp (Thanks to
Chip Rosenthal).

It provides a faked siginterrupt for systems that need it. (Thanks to
Chris Smith).

The m-template.h file now describes the possibility to set STRCSPN and
NO_SIGINTERRUPT. 

The stdin, stdout, and stderr are closed by the nnmaster when it is
collecting news. (Thanks to Brad Allen).

The right patchlevel will be shown by nn after compilation.

Two new commands in reading mode:
a {advance-article}
b {back-article}
	These go to the next or previous article (on the menu) even
	when they are not selected.

An addition to the K {kill-select} command:  If the specified name or
subject starts with a /, the rest of the input string is used as a
regular expression.

There is a new variable 'cross-post' to have cross-posted articles shown
in all the addressed groups.

The reading mode prompt line will now show when articles have been
saved or responded to, e.g. -----(Filed)----- 

nnquery has been fixed (it could not locate the active file).

Since the header file data.h has been changed, all files will be
recompiled when you `make all'.


I have received new s- and m- files for the following systems and/or
machines: 
	dynix / symmetry
	A/UX 1.1
	convex
	xenix386
If you need one of these now, mail me.  I will not post them until I
have got a few more.

++Kim Storm


*** /usr/storm/nn6.3.2/patchlevel.h
--- patchlevel.h
**************
*** 10,15
   *
   *	1989-06-06:  Patch 1: rc.c
   *	1989-06-28:  Patch 2: several files
   */
  
  #define PATCHLEVEL 2
--- 10,16 -----
   *
   *	1989-06-06:  Patch 1: rc.c
   *	1989-06-28:  Patch 2: several files
+  *	1989-06-30:  Patch 3: several files
   */
  
  #define PATCHLEVEL 3
**************
*** 12,16
   *	1989-06-28:  Patch 2: several files
   */
  
! #define PATCHLEVEL 2
  
--- 13,17 -----
   *	1989-06-30:  Patch 3: several files
   */
  
! #define PATCHLEVEL 3
  

*** /usr/storm/nn6.3.2/answer.c
--- answer.c
**************
*** 72,77
      
      if (command == K_REPLY) {
  	pgm = "reply";
  	
  	if (reply_to(t, news.ng_reply) ||
  	    reply_to(t, news.ng_from) ||
--- 72,78 -----
      
      if (command == K_REPLY) {
  	pgm = "reply";
+ 	ah->flag |= A_ST_REPLY;
  	
  	if (reply_to(t, news.ng_reply) ||
  	    reply_to(t, news.ng_from) ||
**************
*** 108,113
      if (command == K_FOLLOW_UP) {
  	pgm = "follow";
  	record_file = news_record;
  	
  	ng_line(t);
  
--- 109,115 -----
      if (command == K_FOLLOW_UP) {
  	pgm = "follow";
  	record_file = news_record;
+ 	ah->flag |= A_ST_FOLLOW;
  	
  	ng_line(t);
  

*** /usr/storm/nn6.3.0/collect.c
--- collect.c
**************
*** 103,109
      art_hdr.a_number = art_num;
      art_hdr.hpos = (off_t)0;
      art_hdr.lpos = (off_t)0;
! 
      mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER; 
      if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0)
  	mode |= DIGEST_CHECK;
--- 103,110 -----
      art_hdr.a_number = art_num;
      art_hdr.hpos = (off_t)0;
      art_hdr.lpos = (off_t)0;
!     art_hdr.flag = 0;
!     
      mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER; 
      if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0)
  	mode |= DIGEST_CHECK;

*** /usr/storm/nn6.3.2/data.h
--- data.h
**************
*** 84,90
  
      char		*kill_list;
      char		*save_file; 	/* default save file from init */
! 
      off_t		rc_offset;	/* offset in rc_file */
  } group_header;
  
--- 84,91 -----
  
      char		*kill_list;
      char		*save_file; 	/* default save file from init */
!     char		*enter_macro;
!     
      off_t		rc_offset;	/* offset in rc_file */
  } group_header;
  
**************
*** 119,125
  
      group_header *a_group;	/* if merged article menu	*/
      
!     int	flag;			/* flags: 			*/
  
  #	define AF(n) (1<<(n-1))
  
--- 120,126 -----
  
      group_header *a_group;	/* if merged article menu	*/
      
!     int32	flag;		/* flags: 			*/
  
  #	define AF(n) (1<<(n-1))
  
**************
*** 131,136
  #	define A_FOLDER		AF(6)	/* article file = "folder_path"	*/
  #	define A_CANCEL		AF(7)	/* folder entry cancelled	*/
  #	define A_SEEN		AF(8)	/* article presented on menu	*/
  
  } article_header;
  
--- 132,141 -----
  #	define A_FOLDER		AF(6)	/* article file = "folder_path"	*/
  #	define A_CANCEL		AF(7)	/* folder entry cancelled	*/
  #	define A_SEEN		AF(8)	/* article presented on menu	*/
+ 
+ #	define A_ST_FILED	AF(16)	/* articles is saved		*/
+ #	define A_ST_REPLY	AF(17)	/* sent reply to article	*/
+ #	define A_ST_FOLLOW	AF(18)	/* sent followup to article	*/
  
  } article_header;
  

*** /usr/storm/nn6.3.2/group.c
--- group.c
**************
*** 13,18
  
  export int  dont_split_digests = 0;
  export int  dont_sort_articles = 0;
  
  import int  article_limit, also_read_articles;
  import int  no_update;
--- 13,19 -----
  
  export int  dont_split_digests = 0;
  export int  dont_sort_articles = 0;
+ export int  also_cross_postings = 0;
  
  import int  article_limit, also_read_articles;
  import int  no_update;
**************
*** 390,396
      fl;
  
      access_mode = 0;
!     if (also_read_articles || submask)
  	access_mode |= ALSO_CROSS_POSTINGS;
      if (dont_split_digests)
  	access_mode |= DONT_SPLIT_DIGESTS;
--- 391,397 -----
      fl;
  
      access_mode = 0;
!     if (also_read_articles || submask || also_cross_postings)
  	access_mode |= ALSO_CROSS_POSTINGS;
      if (dont_split_digests)
  	access_mode |= DONT_SPLIT_DIGESTS;
**************
*** 835,841
      free_memory();
  
      access_mode = DONT_SORT_ARTICLES;
!     if (also_read_articles || submask)
  	access_mode |= ALSO_CROSS_POSTINGS;
      if (dont_split_digests)
  	access_mode |= DONT_SPLIT_DIGESTS;
--- 836,842 -----
      free_memory();
  
      access_mode = DONT_SORT_ARTICLES;
!     if (also_read_articles || submask || also_cross_postings)
  	access_mode |= ALSO_CROSS_POSTINGS;
      if (dont_split_digests)
  	access_mode |= DONT_SPLIT_DIGESTS;

*** /usr/storm/nn6.3.2/keymap.c
--- keymap.c
**************
*** 153,160
  /* ^   */		K_FIRST_PAGE, 
  /* _   */	K_UNBOUND, 
  /* `   */	K_UNBOUND, 
! /* a   */	K_UNBOUND, 
! /* b   */	K_UNBOUND, 
  /* c   */		K_COMPRESS, 
  /* d   */		K_NEXT_HALF_PAGE, 
  /* e   */	K_UNBOUND, 
--- 153,160 -----
  /* ^   */		K_FIRST_PAGE, 
  /* _   */	K_UNBOUND, 
  /* `   */	K_UNBOUND, 
! /* a   */		K_FORW_ARTICLE, 
! /* b   */		K_BACK_ARTICLE, 
  /* c   */		K_COMPRESS, 
  /* d   */		K_NEXT_HALF_PAGE, 
  /* e   */	K_UNBOUND, 
**************
*** 409,414
      int	  	cmd_restriction;
  } command_name_map[] = {
      
      "advance-group",		K_ADVANCE_GROUP,	0,
  
      "back-group",		K_BACK_GROUP,		0,
--- 409,415 -----
      int	  	cmd_restriction;
  } command_name_map[] = {
      
+     "advance-article",		K_FORW_ARTICLE,		K_ONLY_MORE,
      "advance-group",		K_ADVANCE_GROUP,	0,
  
      "back-article",		K_BACK_ARTICLE,		K_ONLY_MORE,
**************
*** 411,416
      
      "advance-group",		K_ADVANCE_GROUP,	0,
  
      "back-group",		K_BACK_GROUP,		0,
  
      "cancel",			K_CANCEL,		0,
--- 412,418 -----
      "advance-article",		K_FORW_ARTICLE,		K_ONLY_MORE,
      "advance-group",		K_ADVANCE_GROUP,	0,
  
+     "back-article",		K_BACK_ARTICLE,		K_ONLY_MORE,
      "back-group",		K_BACK_GROUP,		0,
  
      "cancel",			K_CANCEL,		0,

*** /usr/storm/nn6.3.2/keymap.h
--- keymap.h
**************
*** 71,76
  #define K_ROT13			0x0037 /* do rot13 			*/
  #define K_COMPRESS		0x0038 /* compress spaces		*/
  #define K_BACK_TO_MENU		0x0039 /* return to menu */
  
      /* menu() SPECIFIC COMMANDS	 */
  
--- 71,78 -----
  #define K_ROT13			0x0037 /* do rot13 			*/
  #define K_COMPRESS		0x0038 /* compress spaces		*/
  #define K_BACK_TO_MENU		0x0039 /* return to menu */
+ #define	K_BACK_ARTICLE		0x003a /* back one article		*/
+ #define	K_FORW_ARTICLE		0x003b /* forward one article		*/
  
      /* menu() SPECIFIC COMMANDS	 */
  

*** /usr/storm/nn6.3.0/kill.c
--- kill.c
**************
*** 1,5
  #include "config.h"
  #include "term.h"
  
  /*
   * kill file handling
--- 1,6 -----
  #include "config.h"
  #include "term.h"
+ #include "regexp.h"
  
  /*
   * kill file handling
**************
*** 22,27
  #define	ON_SENDER	0x00	/* pseudo flag */
  
  #define	KILL_MUST_MATCH	0x10
  
  /*
   * external flag representation
--- 23,29 -----
  #define	ON_SENDER	0x00	/* pseudo flag */
  
  #define	KILL_MUST_MATCH	0x10
+ #define KILL_ON_REGEXP	0x20
  
  /*
   * external flag representation
**************
*** 32,37
  #define EXT_ON_SUBJECT		's'
  #define	EXT_ON_SENDER		'n'
  #define	EXT_KILL_MUST_MATCH	'='
  
  /*
   * period = nnn DAYS
--- 34,40 -----
  #define EXT_ON_SUBJECT		's'
  #define	EXT_ON_SENDER		'n'
  #define	EXT_KILL_MUST_MATCH	'='
+ #define EXT_KILL_ON_REGEXP	'/'
  
  /*
   * period = nnn DAYS
**************
*** 79,85
  	    if (strcmp(kl->kill_pattern, string))
  		continue;
  	} else
! 	    if (quick_match(string, kl->kill_pattern) == NULL)
  		continue;
  	
  	if (kl->kill_flag & AUTO_KILL)
--- 82,89 -----
  	    if (strcmp(kl->kill_pattern, string))
  		continue;
  	} else
! 	if (kl->kill_flag & KILL_ON_REGEXP) {
! 	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
  		continue;
  	} else
  	    if (quick_match(string, kl->kill_pattern) == NULL)
**************
*** 81,86
  	} else
  	    if (quick_match(string, kl->kill_pattern) == NULL)
  		continue;
  	
  	if (kl->kill_flag & AUTO_KILL)
  	    return 1;
--- 85,93 -----
  	if (kl->kill_flag & KILL_ON_REGEXP) {
  	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
  		continue;
+ 	} else
+ 	    if (quick_match(string, kl->kill_pattern) == NULL)
+ 		continue;
  	
  	if (kl->kill_flag & AUTO_KILL)
  	    return 1;
**************
*** 116,122
  	    if (strcmp(kl->kill_pattern, string))
  		continue;
  	} else
! 	    if (quick_match(string, kl->kill_pattern) == NULL)
  		continue;
  	return 1;
      }
--- 123,130 -----
  	    if (strcmp(kl->kill_pattern, string))
  		continue;
  	} else
! 	if (kl->kill_flag & KILL_ON_REGEXP) {
! 	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
  		continue;
  	} else
  	    if (quick_match(string, kl->kill_pattern) == NULL)
**************
*** 118,123
  	} else
  	    if (quick_match(string, kl->kill_pattern) == NULL)
  		continue;
  	return 1;
      }
      
--- 126,134 -----
  	if (kl->kill_flag & KILL_ON_REGEXP) {
  	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
  		continue;
+ 	} else
+ 	    if (quick_match(string, kl->kill_pattern) == NULL)
+ 		continue;
  	return 1;
      }
      
**************
*** 139,144
      register kill_list_entry *kl;
      char *str;
      
      killf = open_file(relative(nn_directory, "kill"), OPEN_APPEND);
      if (killf == NULL) {
  	msg("cannot create kill file");
--- 150,168 -----
      register kill_list_entry *kl;
      char *str;
      
+     if (flag & KILL_ON_REGEXP) {
+ 	str = (char *)regcomp(pattern);
+ 	if (str == NULL) return;
+     } else {
+ 	str = malloc(strlen(pattern) + 1);
+ 	mem_check(str, 1, "string");
+ 	
+ 	strcpy(str, pattern);
+ 	
+ 	if ((flag & KILL_MUST_MATCH) == 0)
+ 	    init_quick_match(str);
+     }
+     
      killf = open_file(relative(nn_directory, "kill"), OPEN_APPEND);
      if (killf == NULL) {
  	msg("cannot create kill file");
**************
*** 157,162
      fputc(flag & AUTO_KILL ? EXT_AUTO_KILL : EXT_AUTO_SELECT, killf);
      fputc(flag & ON_SUBJECT ? EXT_ON_SUBJECT : EXT_ON_SENDER, killf);
      if (flag & KILL_MUST_MATCH) fputc(EXT_KILL_MUST_MATCH, killf);
      fputc(':', killf);
  
      fputs(pattern, killf);
--- 181,187 -----
      fputc(flag & AUTO_KILL ? EXT_AUTO_KILL : EXT_AUTO_SELECT, killf);
      fputc(flag & ON_SUBJECT ? EXT_ON_SUBJECT : EXT_ON_SENDER, killf);
      if (flag & KILL_MUST_MATCH) fputc(EXT_KILL_MUST_MATCH, killf);
+     if (flag & KILL_ON_REGEXP) fputc(EXT_KILL_ON_REGEXP, killf);
      fputc(':', killf);
  
      fputs(pattern, killf);
**************
*** 165,178
      fclose(killf);
      rm_kill_file();
      
-     str = malloc(strlen(pattern) + 1);
-     mem_check(str, 1, "string");
-     
-     strcpy(str, pattern);
-     
-     if ((flag & KILL_MUST_MATCH) == 0)
- 	init_quick_match(str);
-     
      kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry));
      mem_check(kl, 1, "kill list entry");
      
--- 190,195 -----
      fclose(killf);
      rm_kill_file();
      
      kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry));
      mem_check(kl, 1, "kill list entry");
      
**************
*** 269,275
  
      prompt("\1%s %s:\1", mode1, mode2);
      
!     pattern = get_s(dflt, NONE, "%=", NO_COMPLETION);
      if (pattern == NULL) return;
      if (*pattern == NUL || *pattern == '%' || *pattern == '=') {
  	if (dflt && *dflt)
--- 286,292 -----
  
      prompt("\1%s %s:\1", mode1, mode2);
      
!     pattern = get_s(dflt, NONE, "%=/", NO_COMPLETION);
      if (pattern == NULL) return;
      if (*pattern == NUL || *pattern == '%' || *pattern == '=') {
  	if (dflt && *dflt)
**************
*** 279,285
  	    pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender;
  	}
  	flag |= KILL_MUST_MATCH;
!     }
      
      strcpy(buffer, pattern);
      pattern = buffer;
--- 296,304 -----
  	    pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender;
  	}
  	flag |= KILL_MUST_MATCH;
!     } else
! 	if (*pattern == '/') {
! 	    prompt("\1%s %s\1 (regexp): ", mode1, mode2);
      
  	    pattern = get_s(NONE, NONE, NONE, NO_COMPLETION);
  	    if (pattern == NULL || *pattern == NUL) return;
**************
*** 281,286
  	flag |= KILL_MUST_MATCH;
      }
      
      strcpy(buffer, pattern);
      pattern = buffer;
      
--- 300,310 -----
  	if (*pattern == '/') {
  	    prompt("\1%s %s\1 (regexp): ", mode1, mode2);
      
+ 	    pattern = get_s(NONE, NONE, NONE, NO_COMPLETION);
+ 	    if (pattern == NULL || *pattern == NUL) return;
+ 	    flag |= KILL_ON_REGEXP;
+ 	}
+     
      strcpy(buffer, pattern);
      pattern = buffer;
      
**************
*** 323,329
  
      prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ",
  	   mode1, mode2, days_str, 
! 	   (flag & KILL_MUST_MATCH) ? " exact" : "",
  	   pattern, strlen(pattern) > 35 ? "..." : "");
      if (yes(0) <= 0) return;
      
--- 347,354 -----
  
      prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ",
  	   mode1, mode2, days_str, 
! 	   (flag & KILL_MUST_MATCH) ? " exact" : 
! 	   (flag & KILL_ON_REGEXP) ? " regexp" : "",
  	   pattern, strlen(pattern) > 35 ? "..." : "");
      if (yes(0) <= 0) return;
      
**************
*** 372,377
  	
  	kl->kill_pattern = patterns + entry.ck_pattern_index;
  	kl->kill_flag = entry.ck_flag;
  	
  	if (entry.ck_group >= 0) {
  	    gh = active_groups + entry.ck_group;
--- 397,405 -----
  	
  	kl->kill_pattern = patterns + entry.ck_pattern_index;
  	kl->kill_flag = entry.ck_flag;
+ 
+ 	if (kl->kill_flag & KILL_ON_REGEXP) 
+ 	    kl->kill_pattern = (char *)regcomp(kl->kill_pattern);
  	
  	if (entry.ck_group >= 0) {
  	    gh = active_groups + entry.ck_group;
**************
*** 500,505
  	     case EXT_KILL_MUST_MATCH:
  		flag |= KILL_MUST_MATCH;
  		continue;
  	     case ':':
  		break;
  	     case NL:
--- 528,536 -----
  	     case EXT_KILL_MUST_MATCH:
  		flag |= KILL_MUST_MATCH;
  		continue;
+ 	     case EXT_KILL_ON_REGEXP:
+ 		flag |= KILL_ON_REGEXP;
+ 		continue;
  	     case ':':
  		break;
  	     case NL:
**************
*** 517,523
  	if ((np = strchr(cp, NL)) == NULL) goto bad_entry;
  	
  	*np++ = NUL;
! 	if ((flag & KILL_MUST_MATCH) == 0)
  	    init_quick_match(cp);
  	
  	entry.ck_pattern_index = ftell(patternf);
--- 548,554 -----
  	if ((np = strchr(cp, NL)) == NULL) goto bad_entry;
  	
  	*np++ = NUL;
! 	if ((flag & (KILL_MUST_MATCH | KILL_ON_REGEXP)) == 0)
  	    init_quick_match(cp);
  	
  	entry.ck_pattern_index = ftell(patternf);
**************
*** 638,644
      printf("\r%s ON %s '%.35s'%s\n",
  	   kl->kill_flag & AUTO_KILL ? "KILL" : "SELECT",
  	   kl->kill_flag & ON_SUBJECT ? "SUBJECT" : "NAME",
! 	   kl->kill_pattern,
  	   kl->kill_flag & KILL_MUST_MATCH ? " (exact)" : "");
  
      return 0;
--- 669,675 -----
      printf("\r%s ON %s '%.35s'%s\n",
  	   kl->kill_flag & AUTO_KILL ? "KILL" : "SELECT",
  	   kl->kill_flag & ON_SUBJECT ? "SUBJECT" : "NAME",
! 	   kl->kill_flag & KILL_ON_REGEXP ? "*regexp*" : kl->kill_pattern,
  	   kl->kill_flag & KILL_MUST_MATCH ? " (exact)" : "");
  
      return 0;

*** /usr/storm/nn6.3.0/m-template.h
--- m-template.h
**************
*** 27,32
  
  /* #define NO_VARARGS */
  
  
  
  #ifdef NETWORK_DATABASE
--- 27,45 -----
  
  /* #define NO_VARARGS */
  
+ /*
+  *	Define STRCSPN if the strcspn() function is not available.
+  */
+ 
+ /* #define STRCSPN 	/* */
+ 
+ /*
+  *	Define NO_SIGINTERRUPT on BSD based systems which don't have
+  *	a siginterrupt() function, but provides an SV_INTERRUPT flag
+  *	in <signal.h>.
+  */
+ 
+ /* #define NO_SIGINTERRUPT	/* */
  
  
  #ifdef NETWORK_DATABASE

*** /usr/storm/nn6.3.0/master.c
--- master.c
**************
*** 115,120
  	nn_exit(0);
      }
  
      if (repeat_delay && !debug_mode) {
  	while ((temp = fork()) < 0) sleep(1);
  	if (temp) nn_exit(0);
--- 115,126 -----
  	nn_exit(0);
      }
  
+     if (!debug_mode) {
+ 	close(0);
+ 	close(1);
+ 	close(2);
+     }
+     
      if (repeat_delay && !debug_mode) {
  	while ((temp = fork()) < 0) sleep(1);
  	if (temp) nn_exit(0);

*** /usr/storm/nn6.3.2/menu.c
--- menu.c
**************
*** 1016,1022
  	 show:
  	    mode = 0;
  	    if (prev >= 0) mode |= MM_PREVIOUS;
! 	    if (next == n_articles) mode |= MM_LAST_ARTICLE;
  	    
  	    cmd = more(articles[cur], mode, 0);
  	    
--- 1016,1024 -----
  	 show:
  	    mode = 0;
  	    if (prev >= 0) mode |= MM_PREVIOUS;
! 	    if (next == n_articles) mode |= MM_LAST_SELECTED;
! 	    if ((cur + 1) >= n_articles) mode |= MM_LAST_ARTICLE;
! 	    if (cur == 0) mode |= MM_FIRST_ARTICLE;
  	    
  	    cmd = more(articles[cur], mode, 0);
  	    
**************
*** 1061,1066
  	     case MC_NEXT:
  		if (articles[cur]->flag & A_SELECT) again++;
  		break;
  		
  	     case MC_NEXTGROUP:
  		return SH_NEXT;
--- 1063,1075 -----
  	     case MC_NEXT:
  		if (articles[cur]->flag & A_SELECT) again++;
  		break;
+ 
+ 	     case MC_BACK_ART:
+ 		if (cur > 0) {
+ 		    next = cur - 1;
+ 		    break;
+ 		}
+ 		goto show;
  		
  	     case MC_FORW_ART:
  		next = cur + 1;
**************
*** 1062,1067
  		if (articles[cur]->flag & A_SELECT) again++;
  		break;
  		
  	     case MC_NEXTGROUP:
  		return SH_NEXT;
  		
--- 1071,1080 -----
  		}
  		goto show;
  		
+ 	     case MC_FORW_ART:
+ 		next = cur + 1;
+ 		break;
+ 		
  	     case MC_NEXTGROUP:
  		return SH_NEXT;
  		
**************
*** 1178,1184
  alt_command()
  {
      int ok_val, macro_cmd;
!     char *cmd;
      extern char erase_key;
      extern int get_from_macro;
      extern int alt_completion();
--- 1191,1197 -----
  alt_command()
  {
      int ok_val, macro_cmd;
!     char *cmd, brkchars[10];
      extern char erase_key;
      extern int get_from_macro;
      extern int alt_completion();
**************
*** 1188,1195
      
   again:
      
!     cmd = "?? ";
!     cmd[1] = erase_key;
      
      cmd = get_s(NONE, NONE, cmd, alt_completion);
      if (cmd == NULL ||
--- 1201,1207 -----
      
   again:
      
!     sprintf(brkchars, "?%c ", erase_key);
      
      cmd = get_s(NONE, NONE, brkchars, alt_completion);
      if (cmd == NULL ||
**************
*** 1191,1197
      cmd = "?? ";
      cmd[1] = erase_key;
      
!     cmd = get_s(NONE, NONE, cmd, alt_completion);
      if (cmd == NULL ||
  	*cmd == NUL || *cmd == SP || *cmd == erase_key)
  	return ok_val;
--- 1203,1209 -----
      
      sprintf(brkchars, "?%c ", erase_key);
      
!     cmd = get_s(NONE, NONE, brkchars, alt_completion);
      if (cmd == NULL ||
  	*cmd == NUL || *cmd == SP || *cmd == erase_key)
  	return ok_val;

*** /usr/storm/nn6.3.0/menu.h
--- menu.h
**************
*** 31,36
  #define MC_PREVIEW_OTHER 9	/* preview another article */
  #define MC_REDRAW	10	/* redraw screen after return */
  #define MC_NO_REDRAW	11	/* screen is not corrupted */
  
  /* more modes */
  
--- 31,38 -----
  #define MC_PREVIEW_OTHER 9	/* preview another article */
  #define MC_REDRAW	10	/* redraw screen after return */
  #define MC_NO_REDRAW	11	/* screen is not corrupted */
+ #define	MC_BACK_ART	12	/* back one article (don't deselect cur) */
+ #define MC_FORW_ART	13	/* forward one article (deselect cur) */
  
  /* more modes */
  
**************
*** 34,45
  
  /* more modes */
  
! #define	MM_NORMAL	0	/* show article */
! #define MM_DIGEST	1	/* show full digest */
! #define MM_PREVIOUS	0x10	/* previous article exists */
! #define MM_LAST_ARTICLE	0x20	/* last article in group */
! #define MM_LAST_GROUP	0x40	/* last group */
! #define MM_PREVIEW	0x80	/* preview mode flag */
  
  /* alt_command return values */
  
--- 36,49 -----
  
  /* more modes */
  
! #define	MM_NORMAL		0x0000	/* show article */
! #define MM_DIGEST		0x0001	/* show full digest */
! #define MM_PREVIOUS		0x0010	/* previous article exists */
! #define MM_LAST_SELECTED	0x0020	/* last selected article in group */
! #define MM_LAST_GROUP		0x0040	/* last group */
! #define MM_PREVIEW		0x0080	/* preview mode flag */
! #define MM_FIRST_ARTICLE 	0x0100	/* first article in group */
! #define MM_LAST_ARTICLE		0x0200	/* last article in group */
  
  /* alt_command return values */
  

*** /usr/storm/nn6.3.2/more.c
--- more.c
**************
*** 50,55
      0
  };
  
  
  more(ah, mode, screen_offset)
  article_header *ah;
--- 50,97 -----
      0
  };
  
+ static char *a_st_flags(flag)
+ int32 flag;
+ {
+     static char buf[40];
+     register char *cp, *sp;
+     static int32 prevflag = 0;
+     
+     flag &= A_ST_FILED | A_ST_REPLY | A_ST_FOLLOW;
+     if (flag == 0) {
+ 	prevflag = 0;
+ 	return "";
+     }
+     
+     if (flag == prevflag) return buf;
+     prevflag = flag;
+     
+     cp = buf;
+     *cp++ = '(';
+     if (flag & A_ST_FILED) {
+ 	*cp++ = 'F';
+ 	*cp++ = 'i';
+ 	*cp++ = 'l';
+ 	*cp++ = 'e';
+ 	*cp++ = 'd';
+     }
+     
+     if (flag & A_ST_REPLY) {
+ 	if (cp[-1] != '(') *cp++ = SP;
+ 	*cp++ = 'R';
+ 	*cp++ = 'e';
+     }
+     
+     if (flag & A_ST_FOLLOW) {
+ 	if (cp[-1] != '(') *cp++ = SP;
+ 	*cp++ = 'F';
+ 	*cp++ = 'o';
+ 	*cp++ = 'l';
+     }
+     
+     strcpy(cp, ")------");
+     return buf;
+ }
  
  more(ah, mode, screen_offset)
  article_header *ah;
**************
*** 149,155
      stop_line = first_page_lines ? first_page_lines : -1;
  
      sprintf(pr_fmt,
! 	   "\1\2-- %s%s %s-----%%s-----\1",
  	   (mode & MM_PREVIEW) ? "PREVIEW " : "",
  	   (mode & MM_DIGEST) ? "FULL DIGEST" :
  	   (mode & MM_LAST_ARTICLE) ? "LAST ARTICLE" : "ARTICLE",
--- 191,197 -----
      stop_line = first_page_lines ? first_page_lines : -1;
  
      sprintf(pr_fmt,
! 	   "\1\2-- %s%s %s-----%%s-----%%s\1",
  	   (mode & MM_PREVIEW) ? "PREVIEW " : "",
  	   (mode & MM_DIGEST) ? "FULL DIGEST" :
  	   (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE",
**************
*** 152,158
  	   "\1\2-- %s%s %s-----%%s-----\1",
  	   (mode & MM_PREVIEW) ? "PREVIEW " : "",
  	   (mode & MM_DIGEST) ? "FULL DIGEST" :
! 	   (mode & MM_LAST_ARTICLE) ? "LAST ARTICLE" : "ARTICLE",
  	   novice ? "-- help:? " : "");
  
      if (screen_offset) goto safe_redraw;
--- 194,200 -----
  	   "\1\2-- %s%s %s-----%%s-----%%s\1",
  	   (mode & MM_PREVIEW) ? "PREVIEW " : "",
  	   (mode & MM_DIGEST) ? "FULL DIGEST" :
! 	   (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE",
  	   novice ? "-- help:? " : "");
  
      if (screen_offset) goto safe_redraw;
**************
*** 576,582
  
      prompt(pr_fmt,
  	   pct((long)(ah->fpos), (long)(ah->lpos), 
! 	       (long)(linepos[topline]), (long)ftell(art)));
  
      if (delayed_msg != NULL) {
  	msg(delayed_msg);
--- 618,625 -----
  
      prompt(pr_fmt,
  	   pct((long)(ah->fpos), (long)(ah->lpos), 
! 	       (long)(linepos[topline]), (long)ftell(art)),
! 	   a_st_flags(ah->flag));
  
      if (delayed_msg != NULL) {
  	msg(delayed_msg);
**************
*** 905,910
  	if ((mode & MM_PREVIEW) == 0) break;
  	more_return(MC_PREVIEW_NEXT);
  
       case K_NEXT_SUBJECT:
  	more_return(MC_NEXTSUBJ);
  	
--- 948,967 -----
  	if ((mode & MM_PREVIEW) == 0) break;
  	more_return(MC_PREVIEW_NEXT);
  
+      case K_BACK_ARTICLE:
+ 	if (mode & MM_FIRST_ARTICLE) {
+ 	    msg("First article is displayed");
+ 	    goto same_prompt;
+ 	}
+ 	more_return(MC_BACK_ART);
+ 	
+      case K_FORW_ARTICLE:
+ 	if (mode & MM_LAST_ARTICLE) {
+ 	    msg("Last article is displayed");
+ 	    goto same_prompt;
+ 	}
+ 	more_return(MC_FORW_ART);
+ 	
       case K_NEXT_SUBJECT:
  	more_return(MC_NEXTSUBJ);
  	

*** /usr/storm/nn6.3.2/nn.1
--- nn.1
**************
*** 552,558
  The following commands are used to move among the selected articles.
  .TP
  \&\fBn\fP	{\fBnext-article\fP}
! Goto next article.  This command skips the rest of the current article
  and jumps directly to the first page of the next article (or to the
  next group if it is the last article).
  .TP
--- 552,558 -----
  The following commands are used to move among the selected articles.
  .TP
  \&\fBn\fP	{\fBnext-article\fP}
! Goto next selected article.  This command skips the rest of the current article
  and jumps directly to the first page of the next article (or to the
  next group if it is the last article).
  .TP
**************
*** 583,588
  select only the first article on a subject in selection mode, and then
  select all follow-ups in reading mode if you find the article
  interesting.
  .LP
  The following commands perform an 
  immediate return from reading mode to selection mode in
--- 583,598 -----
  select only the first article on a subject in selection mode, and then
  select all follow-ups in reading mode if you find the article
  interesting.
+ .TP
+ \&\fBa\fP	{\fBadvance-article\fP}
+ Goto the following article on the menu even if it is not selected.
+ This command skips the rest of the current article 
+ and jumps directly to the first page of the next article (it will not skip
+ to the next group if it is the last article).
+ .TP
+ \&\fBb\fP	{\fBback-article\fP}
+ Goto the article before current article on the menu even if it is not
+ selected.
  .LP
  The following commands perform an 
  immediate return from reading mode to selection mode in
**************
*** 1267,1272
  name or subject matches the original name or subject exactly including
  case.
  .sp 0.5v
  Otherwise, \fInn\fP will select or kill articles which 
  .I contain
  the specified name or subject (or part thereof) anywhere in the name
--- 1277,1286 -----
  name or subject matches the original name or subject exactly including
  case.
  .sp 0.5v
+ If the first character typed at the prompt is a slash `/', the rest of
+ the line is used as a \fIregular expression\fP which is used to match
+ the name or subject.
+ .sp 0.5v
  Otherwise, \fInn\fP will select or kill articles which 
  .I contain
  the specified name or subject (or part thereof) anywhere in the name
**************
*** 1330,1336
  specifying whether the entry applies to the
  name or to the subject of an article.
  .br
! \- The optional third character is an 
  .B =
  sign which
  specify that the match against the name or subject must be an
--- 1344,1350 -----
  specifying whether the entry applies to the
  name or to the subject of an article.
  .br
! \- The optional third character can be an 
  .B =
  sign which
  specify that the match against the name or subject must be an
**************
*** 1334,1340
  .B =
  sign which
  specify that the match against the name or subject must be an
! exact match (including case).
  .LP
  The 
  .I string
--- 1348,1355 -----
  .B =
  sign which
  specify that the match against the name or subject must be an
! exact match (including case), or it can be a slash `/' specifying that
! the name or subject is matched against a regular expression.
  .LP
  The 
  .I string
**************
*** 1338,1344
  .LP
  The 
  .I string
! field in the entry is the name or subject that will be
  matched against the name or subject of each article in the group (or
  all groups).  Notice, that unless an exact match is specified, the
  specified name or subject may occur
--- 1353,1359 -----
  .LP
  The 
  .I string
! field in the entry is the name, subject or regular expression that will be
  matched against the name or subject of each article in the group (or
  all groups).  Notice, that unless an exact match or a regular
  expression match is specified, the
**************
*** 1340,1346
  .I string
  field in the entry is the name or subject that will be
  matched against the name or subject of each article in the group (or
! all groups).  Notice, that unless an exact match is specified, the
  specified name or subject may occur
  .I anywhere
  in a name or a subject, and that case is ignored.
--- 1355,1362 -----
  .I string
  field in the entry is the name, subject or regular expression that will be
  matched against the name or subject of each article in the group (or
! all groups).  Notice, that unless an exact match or a regular
! expression match is specified, the
  specified name or subject may occur
  .I anywhere
  in a name or a subject, and that case is ignored.
**************
*** 1702,1707
  is set, you will also be asked for confirmation before appending an
  article to an existing file.
  .TP
  \fBdate\fP		(boolean, default true)
  If set \fInn\fP will show the article posting date when articles are
  read.
--- 1718,1730 -----
  is set, you will also be asked for confirmation before appending an
  article to an existing file.
  .TP
+ \fBcross-post\fP		(boolean, default false) 
+ Normally, \fInn\fP will only show cross-posted articles in the first
+ subscribed group on the Newsgroups: line.  When
+ .B cross-post
+ is set, \fInn\fP will show cross-posted articles in all subscribed
+ groups to which they are posted.
+ .TP
  \fBdate\fP		(boolean, default true)
  If set \fInn\fP will show the article posting date when articles are
  read.
**************
*** 2265,2270
  .br
  \fIFunction	Selection mode	Reading mode
  .br
  \fBadvance-group\fP	A 	A 
  .br
  \fBback-group\fP	B 	B 
--- 2288,2295 -----
  .br
  \fIFunction	Selection mode	Reading mode
  .br
+ \fBadvance-article\fP	\fBnix\fP 	a 
+ .br
  \fBadvance-group\fP	A 	A 
  .br
  \fBback-article\fP	\fBnix\fP 	b 
**************
*** 2266,2271
  \fIFunction	Selection mode	Reading mode
  .br
  \fBadvance-group\fP	A 	A 
  .br
  \fBback-group\fP	B 	B 
  .br
--- 2291,2298 -----
  \fBadvance-article\fP	\fBnix\fP 	a 
  .br
  \fBadvance-group\fP	A 	A 
+ .br
+ \fBback-article\fP	\fBnix\fP 	b 
  .br
  \fBback-group\fP	B 	B 
  .br

*** /usr/storm/nn6.3.0/nnquery.sh
--- nnquery.sh
**************
*** 1,6
  # CONFIG file is insert above this line by make
  
! if [ -f ${ACTIVE} ] ; then
  	echo "Cannot locate active file ${ACTIVE}"
  	exit 3
  fi
--- 1,6 -----
  # CONFIG file is insert above this line by make
  
! if [ ! -f ${ACTIVE} ] ; then
  	echo "Cannot locate active file ${ACTIVE}"
  	exit 3
  fi

*** /usr/storm/nn6.3.2/prefix.sh
--- prefix.sh
**************
*** 1,4
! WARNING: DON'T CHANGE THE ORDER OR CONTENTS OF THE FOLLOWING LINES
  
  #include "config.h"
  #include "patchlevel.h"
--- 1,4 -----
! WARNING: DO NOT CHANGE THE ORDER OR CONTENTS OF THE FOLLOWING LINES
  
  #include "config.h"
  #include "patchlevel.h"
**************
*** 5,11
  #include "update.h"
  
  --------CUT PREFIX HERE--------
! #ifndef AVOID_SHELL_EXEC
  &!/bin/sh
  #endif
  
--- 5,13 -----
  #include "update.h"
  
  --------CUT PREFIX HERE--------
! #ifdef AVOID_SHELL_EXEC
! :
! #else
  &!/bin/sh
  #endif
  

*** /usr/storm/nn6.3.2/save.c
--- save.c
**************
*** 456,461
  #endif    
      if (was_raw) raw();    
  
      return !s_pipe || (save_mode & SEPARATE_FILES);
  }
  
--- 456,463 -----
  #endif    
      if (was_raw) raw();    
  
+     ah->flag |= A_ST_FILED;
+     
      return !s_pipe || (save_mode & SEPARATE_FILES);
  }
  

*** /usr/storm/nn6.3.2/term.c
--- term.c
**************
*** 204,209
  }
  #endif /* RESIZING */
  
  
  init_term()
  {
--- 204,221 -----
  }
  #endif /* RESIZING */
  
+ #ifdef SV_INTERRUPT
+ #ifdef NO_SIGINTERRUPT
+ static siginterrupt(signo, on)
+ {
+   struct sigvec sv;
+   sv.sv_handler = signal (signo, SIG_DFL);
+   sv.sv_mask = 0;
+   sv.sv_flags = on ? SV_INTERRUPT : 0;
+   sigvec (signo, &sv, 0);
+ }
+ #endif
+ #endif
  
  init_term()
  {

*** /usr/storm/nn6.3.0/variable.c
--- variable.c
**************
*** 23,28
      *save_counter_format;
  
  import int			/* boolean variables */
      conf_append,
      conf_dont_sleep,
      delay_redraw,
--- 23,29 -----
      *save_counter_format;
  
  import int			/* boolean variables */
+     also_cross_postings,
      conf_append,
      conf_dont_sleep,
      delay_redraw,
**************
*** 81,86
      "comp2_key",	V_KEY,		0,	(char **)&comp2_key,
      "confirm",		V_BOOLEAN,	0,	(char **)&conf_dont_sleep,
      "confirm-append",	V_BOOLEAN,	0,	(char **)&conf_append,
      "date",		V_BOOLEAN,	0,	(char **)&show_article_date,
      "debug",		V_INTEGER,	0,	(char **)&Debug,
      "default-save-file",V_STRING,	0,	(char **)&default_save_file,
--- 82,88 -----
      "comp2_key",	V_KEY,		0,	(char **)&comp2_key,
      "confirm",		V_BOOLEAN,	0,	(char **)&conf_dont_sleep,
      "confirm-append",	V_BOOLEAN,	0,	(char **)&conf_append,
+     "cross-post",	V_BOOLEAN,	0,	(char **)&also_cross_postings,
      "date",		V_BOOLEAN,	0,	(char **)&show_article_date,
      "debug",		V_INTEGER,	0,	(char **)&Debug,
      "default-save-file",V_STRING,	0,	(char **)&default_save_file,

*** /usr/storm/nn6.3.2/xmakefile
--- xmakefile
**************
*** 123,129
  * Compilation counter updating
  *
  
! update.o:	update.h update.c
  	-$(CC) -c $(CFLAGS) update.c
  
  *
--- 123,129 -----
  * Compilation counter updating
  *
  
! update.o:	update.h update.c patchlevel.h
  	-$(CC) -c $(CFLAGS) update.c
  
  *
**************
*** 259,265
  nn1:	$(NN) 
  	$(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1
  
! * this is probably non-portable so it is ifdef'ed
  
  #ifdef WITH_LINT
  lint:
--- 259,265 -----
  nn1:	$(NN) 
  	$(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1
  
! * this is probably non-portable so it is ifdef-ed
  
  #ifdef WITH_LINT
  lint:

-- 
Kim F. Storm        storm at texas.dk        Tel +45 429 174 00
Texas Instruments, Marielundvej 46E, DK-2730 Herlev, Denmark
	  No news is good news, but nn is better!



More information about the Comp.sources.bugs mailing list