[comp.sources.bugs] NN 6.3 - Official patch #2

storm@texas.dk (Kim F. Storm) (06/29/89)

This is patch #2 for nn release 6.3.

nn and patch #1 was posted on comp.sources.unix a few days ago.

Due to the size of the patches, they have been split into two
postings, each containing a SHAR archive which should be unpacked
in turn using the :unshar command into the nn source directory.
It will create the following new files:

	decode.c	-- new uudecode command
	s-dnix5-2.h	-- s- file for dnix system
	s-hpux3-0.h	-- yet another s- file for HP-UX
	PATCH.2		-- patch #2 diff's

Then apply the patches using the command
	patch < PATCH.2   (pipe it though your favourite pager)

Recompile (make all) and reinstall (su ; make install) the package.

You can then remove the PATCH.2 file.

ABOUT PATCH #2

It is of medium-high priority, since it primarily fixes some minor bugs
which have surfaced since I sent the sources to Rick Salz, but also
fixes a few bugs that has been reported on the nn-bugs list this week:

  An NNTP related database corruption bug has been fixed.
  Handling of multiple folders in succession did not work.
  Cross-posted articles in new groups confused the counting of unread articles.
  The FILES entries in the online manual were not formatted properly.
  The :unread command now works as documented + accepts optional group name.
  Two flags were used inconsistently to control the updating of the rc file.
  Patch.Result file now contains all output from the `patch' program.
  Regexp search in articles containing form feeds confused the display code.
  The use of `NEW' in the group sequence now works as documented.
  Cancel command now only redraws the screen if inews complains.
  The 'tab3' mode was turned off by nn (actually terminfo).
  ntohl/htonl are no longer used when NETWORK_BYTE_ORDER is defined.
  nnusage will now report 'no usage statistics' when there are none.
  It is now possible to eliminate #! escapes if necessary (see s-template.h)
  Some groups marked unsubsribed in .newsrc could be seen as new groups by nn.
  The netinet/in.h file is now included correctly in nntp.c

It also adds two new `features of the month':

  A :decode command to concatenate & decode UUENCODED articles automagically!

  The C {cancel} command now uses the same dialog as the {save} commands,
  so cancelling more than one article is much faster now (C* also works).

++Kim Storm

---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
#	Run the following text with /bin/sh to create:
#	  PATCH.2
#	  decode.c
#	  s-dnix5-2.h
#	  s-hpux3-0.h
#
if test -r s2_seq_.tmp
then echo "Must unpack archives in sequence!"
     next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
     exit 1; fi
echo "x - extracting PATCH.2 (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > PATCH.2 &&
X*** /usr/storm/nn6.3.1/patchlevel.h
X--- patchlevel.h
X**************
X*** 9,14
X   *	1989-05-30:  Distributed release 6.3	(World)
X   *
X   *	1989-06-06:  Patch 1: rc.c
X   */
X  
X  #define PATCHLEVEL 1
X--- 9,15 -----
X   *	1989-05-30:  Distributed release 6.3	(World)
X   *
X   *	1989-06-06:  Patch 1: rc.c
X+  *	1989-06-28:  Patch 2: several files
X   */
X  
X  #define PATCHLEVEL 2
X**************
X*** 11,15
X   *	1989-06-06:  Patch 1: rc.c
X   */
X  
X! #define PATCHLEVEL 1
X  
X--- 12,16 -----
X   *	1989-06-28:  Patch 2: several files
X   */
X  
X! #define PATCHLEVEL 2
X  
X
X*** /usr/storm/nn6.3.0/answer.c
X--- answer.c
X**************
X*** 256,263
X  	    return 2;
X  	}
X      } else {
X! 	fputs("\rConfirm cancel: ", stdout); clrline();
X! 	if (yes(1) <= 0) return 0;
X      }
X      
X      f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
X--- 256,263 -----
X  	    return 2;
X  	}
X      } else {
X! 	prompt("Confirm cancel: '%.50s'", ah->subject ? ah->subject : ""); 
X! 	if (yes(1) <= 0) return 1;
X      }
X      
X      f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
X**************
X*** 262,268
X      
X      f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
X      if (f == NULL) {
X! 	msg("Can't find original article");
X  	return 2;
X      }
X      fclose(f);
X--- 262,268 -----
X      
X      f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
X      if (f == NULL) {
X! 	msg("Article not found");
X  	return 2;
X      }
X      fclose(f);
X**************
X*** 275,281
X      
X      if (aux_sh("cancel", 
X  	       news.ng_ident, current_group->group_name, "Not canceled"))
X! 	return 3;
X          
X      return 1;
X  }
X--- 275,281 -----
X      
X      if (aux_sh("cancel", 
X  	       news.ng_ident, current_group->group_name, "Not canceled"))
X! 	return -1;
X          
X      return 0;
X  }
X**************
X*** 277,283
X  	       news.ng_ident, current_group->group_name, "Not canceled"))
X  	return 3;
X          
X!     return 1;
X  }
X  
X  
X--- 277,283 -----
X  	       news.ng_ident, current_group->group_name, "Not canceled"))
X  	return -1;
X          
X!     return 0;
X  }
X  
X  
X
X*** /usr/storm/nn6.3.0/data.h
X--- data.h
X**************
X*** 56,62
X  
X  #	define G_SUBSCRIPTION	CF(1)	/* from .rc */
X  #	define G_READ		CF(2)	/* group has been read	*/
X- #	define G_RC_UPDATED	CF(3)	/* .rc is updated */
X  #	define G_DONE		CF(4)	/* finished with this group */
X  #	define G_NEW		CF(5)	/* new group */
X  #	define G_FOLDER		CF(6)	/* "group" is a folder file */
X--- 56,61 -----
X  
X  #	define G_SUBSCRIPTION	CF(1)	/* from .rc */
X  #	define G_READ		CF(2)	/* group has been read	*/
X  #	define G_DONE		CF(4)	/* finished with this group */
X  #	define G_NEW		CF(5)	/* new group */
X  #	define G_FOLDER		CF(6)	/* "group" is a folder file */
X
X*** /usr/storm/nn6.3.0/folder.c
X--- folder.c
X**************
X*** 402,408
X      int				cc_save;
X      
X      fake_group.group_name = path;
X!     fake_group.group_flag = G_RC_UPDATED | G_FOLDER | G_READ;
X      init_group(&fake_group);
X      
X      folder = open_file(group_path_name, OPEN_READ);
X--- 402,409 -----
X      int				cc_save;
X      
X      fake_group.group_name = path;
X!     fake_group.group_flag = G_FOLDER | G_READ;
X!     current_group = NULL;
X      init_group(&fake_group);
X      
X      folder = open_file(group_path_name, OPEN_READ);
X**************
X*** 486,493
X  	if (cancel_count) {
X  	    clrdisp();
X  	    printf("Folder: %s\nFile:   %s\n\n", buffer, group_path_name);
X! 	    printf("Remove %d article%s from folder? ", 
X! 		   cancel_count, cancel_count == 1 ? "" : "s");
X  	    fl;
X  	    
X  	    switch (yes(1)) {
X--- 487,497 -----
X  	if (cancel_count) {
X  	    clrdisp();
X  	    printf("Folder: %s\nFile:   %s\n\n", buffer, group_path_name);
X! 	    if (cancel_count == n_articles)
X! 		printf("Cancel all articles and remove folder? ");
X! 	    else
X! 		printf("Remove %d article%s from folder? ", 
X! 		       cancel_count, cancel_count == 1 ? "" : "s");
X  	    fl;
X  	    
X  	    switch (yes(1)) {
X**************
X*** 493,499
X  	    switch (yes(1)) {
X  	     case 1:
X  		printf("\n\n");
X! 		rewrite_folder();
X  		break;
X  	     case 0:
X  		break;
X--- 497,509 -----
X  	    switch (yes(1)) {
X  	     case 1:
X  		printf("\n\n");
X! 		if (cancel_count == n_articles) {
X! 		    if (unlink(group_path_name) < 0) {
X! 			printf("Could not unlink %s\n", group_path_name);
X! 			sleep(3);
X! 		    }
X! 		} else
X! 		    rewrite_folder();
X  		break;
X  	     case 0:
X  		break;
X**************
X*** 526,533
X      
X      strcpy(oldfile, group_path_name);
X      sp = strrchr(oldfile, '/');
X!     if (!sp) goto move_error;
X!     strcpy(sp+1, "~OLD~FOLDER~");
X  
X      unlink(oldfile);
X      if (link(group_path_name, oldfile) < 0) goto move_error;
X--- 536,542 -----
X      
X      strcpy(oldfile, group_path_name);
X      sp = strrchr(oldfile, '/');
X!     strcpy((sp == NULL ? oldfile : sp+1), "~OLD~FOLDER~");
X  
X      unlink(oldfile);
X      if (link(group_path_name, oldfile) < 0) goto move_error;
X
X*** /usr/storm/nn6.3.0/group.c
X--- group.c
X**************
X*** 376,383
X  	if ((gh->last_article = gh->first_l_article - 1) < 0)
X  	    gh->last_article = 0;
X  	gh->first_article = gh->last_article;
X! 	updflag = gh->group_flag & (G_RC_UPDATED|G_READ);
X! 	gh->group_flag &= ~(G_RC_UPDATED|G_READ);
X  	update_rc(gh);
X  	gh->group_flag &= ~(G_RC_UPDATED|G_READ);
X  	gh->group_flag |= updflag;
X--- 376,383 -----
X  	if ((gh->last_article = gh->first_l_article - 1) < 0)
X  	    gh->last_article = 0;
X  	gh->first_article = gh->last_article;
X! 	updflag = gh->group_flag & G_READ;
X! 	gh->group_flag &= ~G_READ;
X  	update_rc(gh);
X  	gh->group_flag &= ~G_READ;
X  	gh->group_flag |= updflag;
X**************
X*** 379,385
X  	updflag = gh->group_flag & (G_RC_UPDATED|G_READ);
X  	gh->group_flag &= ~(G_RC_UPDATED|G_READ);
X  	update_rc(gh);
X! 	gh->group_flag &= ~(G_RC_UPDATED|G_READ);
X  	gh->group_flag |= updflag;
X      }
X  
X--- 379,385 -----
X  	updflag = gh->group_flag & G_READ;
X  	gh->group_flag &= ~G_READ;
X  	update_rc(gh);
X! 	gh->group_flag &= ~G_READ;
X  	gh->group_flag |= updflag;
X      }
X  
X**************
X*** 455,461
X  
X      if (menu_cmd == ME_READ || menu_cmd == ME_NO_ARTICLES) {
X  	if (did_selection) {
X! 	    int was_read = gh->group_flag & (G_READ|G_RC_UPDATED);
X  
X  	    prev_last = gh->last_l_article;
X  	    gh->last_l_article = last_article;
X--- 455,461 -----
X  
X      if (menu_cmd == ME_READ || menu_cmd == ME_NO_ARTICLES) {
X  	if (did_selection) {
X! 	    int was_read = gh->group_flag & G_READ;
X  
X  	    prev_last = gh->last_l_article;
X  	    gh->last_l_article = last_article;
X**************
X*** 463,469
X  	    gh->last_l_article = prev_last;
X  	    
X  	    if (last_article < gh->last_l_article) {
X! 		gh->group_flag &= ~ (G_READ|G_RC_UPDATED);
X  		gh->group_flag |= was_read;
X  		release_memory(&sel_marker);
X  		goto after_selection;
X--- 463,469 -----
X  	    gh->last_l_article = prev_last;
X  	    
X  	    if (last_article < gh->last_l_article) {
X! 		gh->group_flag &= ~G_READ;
X  		gh->group_flag |= was_read;
X  		release_memory(&sel_marker);
X  		goto after_selection;
X**************
X*** 470,479
X  	    }
X  	} else
X  	    if (submask == NULL && !also_read_articles &&
X! 		(menu_cmd != ME_NO_ARTICLES || 
X! 		 (gh->group_flag & G_NEW) == 0) &&
X! 		(first_art == -1 || 
X! 		 current_first_article == gh->first_article + 1))
X  		update_rc(gh);
X      }
X      
X--- 470,478 -----
X  	    }
X  	} else
X  	    if (submask == NULL && !also_read_articles &&
X! 		(first_art == -1 || current_first_article == gh->first_article + 1)) {
X! 		if (menu_cmd != ME_NO_ARTICLES)
X! 		    gh->group_flag &= ~G_NEW;
X  		update_rc(gh);
X  	    }
X      }
X**************
X*** 475,480
X  		(first_art == -1 || 
X  		 current_first_article == gh->first_article + 1))
X  		update_rc(gh);
X      }
X      
X      current_first_article = o_first_article;
X--- 474,480 -----
X  		if (menu_cmd != ME_NO_ARTICLES)
X  		    gh->group_flag &= ~G_NEW;
X  		update_rc(gh);
X+ 	    }
X      }
X      
X      current_first_article = o_first_article;
X**************
X*** 890,896
X  	if (yes(0) <= 0) return 0;
X  
X  	add_unread(gh, -1);
X! 	gh->group_flag &= ~G_SUBSCRIPTION;
X  	write_rc_entry(gh, 0);
X  	return 1;
X      }
X--- 890,896 -----
X  	if (yes(0) <= 0) return 0;
X  
X  	add_unread(gh, -1);
X! 	gh->group_flag &= ~(G_SUBSCRIPTION | G_NEW);
X  	write_rc_entry(gh, 0);
X  	return 1;
X      }
X
X*** /usr/storm/nn6.3.0/keymap.c
X--- keymap.c
X**************
X*** 418,423
X      "compress",			K_COMPRESS,		K_ONLY_MORE,
X      "continue",			K_CONTINUE,		0,
X  
X      "find",			K_GOTO_MATCH,		K_ONLY_MORE,
X      "find-next",		K_NEXT_MATCH,		K_ONLY_MORE,
X      "follow",			K_FOLLOW_UP,		0,
X--- 418,425 -----
X      "compress",			K_COMPRESS,		K_ONLY_MORE,
X      "continue",			K_CONTINUE,		0,
X  
X+     "decode",			K_UUDECODE,		0,
X+ 
X      "find",			K_GOTO_MATCH,		K_ONLY_MORE,
X      "find-next",		K_NEXT_MATCH,		K_ONLY_MORE,
X      "follow",			K_FOLLOW_UP,		0,
X
X*** /usr/storm/nn6.3.0/keymap.h
X--- keymap.h
X**************
X*** 35,40
X  #define K_UNSUBSCRIBE		0x001b /* (un)subscribe to group 	*/
X  #define K_GROUP_OVERVIEW 	0x001c /* group overview 		*/
X  #define K_PATCH			0x001d /* pipe article to patch         */
X  
X  #define K_GOTO_GROUP		0x0020 /* goto named group/folder	*/
X  
X--- 35,41 -----
X  #define K_UNSUBSCRIBE		0x001b /* (un)subscribe to group 	*/
X  #define K_GROUP_OVERVIEW 	0x001c /* group overview 		*/
X  #define K_PATCH			0x001d /* pipe article to patch         */
X+ #define	K_UUDECODE		0x001e /* uudecode articles		*/
X  
X  #define K_GOTO_GROUP		0x0020 /* goto named group/folder	*/
X  
X
X*** /usr/storm/nn6.3.0/init.c
X--- init.c
X**************
X*** 190,195
X      "cd",			2,	1,
X      "compile",			7,	0,
X      "coredump",			8,	0,
X      "define",			6,	0,
X      "help",			4,	2,
X      "man",			3,	0,
X--- 190,196 -----
X      "cd",			2,	1,
X      "compile",			7,	0,
X      "coredump",			8,	0,
X+     "decode",			6,	0,
X      "define",			6,	0,
X      "help",			4,	2,
X      "man",			3,	0,
X**************
X*** 550,557
X  	}
X  
X  	CASE( "unread" ) {
X! 	    if (restore_rc(current_group, argv(2) ? ARGVAL(2) : 0))
X! 		return AC_HEADER;
X  	    break;
X  	}
X  	
X--- 551,566 -----
X  	}
X  
X  	CASE( "unread" ) {
X! 	    group_header *gh;
X! 	    int ix = 1;
X! 	    
X! 	    if (argv(1) && (gh = lookup(argv(1))) != NULL)
X! 		ix = 2;
X! 	    else
X! 		gh = current_group;
X! 	    
X! 	    if (restore_rc(gh, argv(ix) ? ARGVAL(ix) : 0))
X! 		if (gh == current_group) return AC_HEADER;
X  	    break;
X  	}
X  	
X
X*** /usr/storm/nn6.3.1/install_aux
X--- install_aux
X**************
X*** 26,32
X  
X  	echo "INSTALLATION COMPLETED"
X  
X! 	if [ -n "$2" ]
X  	then
X  		echo
X  		echo "--------------------------------------------------------"
X--- 26,32 -----
X  
X  	echo "INSTALLATION COMPLETED"
X  
X! 	if [ $# -gt 1 ]
X  	then
X  		echo
X  		echo "--------------------------------------------------------"
X
X*** /usr/storm/nn6.3.0/MANIFEST
X--- MANIFEST
X**************
X*** 20,25
X  db.c
X  db.h
X  debug.h
X  digest.c
X  execute.c
X  expire.c
X--- 20,26 -----
X  db.c
X  db.h
X  debug.h
X+ decode.c
X  digest.c
X  execute.c
X  expire.c
X**************
X*** 96,101
X  routes.sample
X  s-bsd4-2.h
X  s-bsd4-3.h
X  s-hpux.h
X  s-hpux2-1.h
X  s-sunos3.h
X--- 97,103 -----
X  routes.sample
X  s-bsd4-2.h
X  s-bsd4-3.h
X+ s-dnix5-2.h
X  s-hpux.h
X  s-hpux2-1.h
X  s-hpux3-0.h
X**************
X*** 98,103
X  s-bsd4-3.h
X  s-hpux.h
X  s-hpux2-1.h
X  s-sunos3.h
X  s-sunos4-0.h
X  s-template.h
X--- 100,106 -----
X  s-dnix5-2.h
X  s-hpux.h
X  s-hpux2-1.h
X+ s-hpux3-0.h
X  s-sunos3.h
X  s-sunos4-0.h
X  s-template.h
X
X*** /usr/storm/nn6.3.0/menu.c
X--- menu.c
X**************
X*** 433,439
X       }
X  
X       last_k_cmd = cur_k_cmd;
X!      cur_k_cmd = k_cmd = get_k_cmd();
X       if (any_message) clrmsg(-1);
X  
X    alt_key:
X--- 433,439 -----
X       }
X  
X       last_k_cmd = cur_k_cmd;
X!      k_cmd = get_k_cmd();
X       if (any_message) clrmsg(-1);
X  
X    alt_key:
X**************
X*** 438,444
X  
X    alt_key:
X  
X!      switch (k_cmd) {
X  
X        case K_UNBOUND:
X  	 ding();
X--- 438,444 -----
X  
X    alt_key:
X  
X!      switch (cur_k_cmd = k_cmd) {
X  
X        case K_UNBOUND:
X  	 ding();
X**************
X*** 494,499
X        case K_QUIT:
X  	 menu_return(ME_QUIT);
X  
X        case K_SAVE_NO_HEADER:
X        case K_SAVE_SHORT_HEADER:
X        case K_SAVE_FULL_HEADER:
X--- 494,504 -----
X        case K_QUIT:
X  	 menu_return(ME_QUIT);
X  
X+       case K_CANCEL:
X+ 	 savemode = "Cancel";
X+ 	 fname = "";
X+ 	 goto cancel1;
X+ 	 
X        case K_SAVE_NO_HEADER:
X        case K_SAVE_SHORT_HEADER:
X        case K_SAVE_FULL_HEADER:
X**************
X*** 500,506
X        case K_PRINT:
X        case K_UNSHAR:
X        case K_PATCH:
X! 
X  	 if (numa < 0) goto nextmenu;
X  
X  	 fname = init_save(k_cmd, &savemode);
X--- 505,512 -----
X        case K_PRINT:
X        case K_UNSHAR:
X        case K_PATCH:
X!       case K_UUDECODE:
X! 	 
X  	 if (numa < 0) goto nextmenu;
X  
X  	 fname = init_save(k_cmd, &savemode);
X**************
X*** 506,511
X  	 fname = init_save(k_cmd, &savemode);
X  	 if (fname == NULL) goto Prompt;
X  
X  	 enable_stop = 0;
X  	 save_selected = 0;
X  	 doing_unshar = k_cmd == K_UNSHAR || k_cmd == K_PATCH;
X--- 512,518 -----
X  	 fname = init_save(k_cmd, &savemode);
X  	 if (fname == NULL) goto Prompt;
X  
X+       cancel1:
X  	 enable_stop = 0;
X  	 save_selected = 0;
X  	 doing_unshar = k_cmd == K_UNSHAR || k_cmd == K_PATCH;
X**************
X*** 542,547
X  		 ah = articles[article_id];
X  		 if (save_selected && (ah->flag & A_SELECT) == 0) continue;
X  
X  		 if (doing_unshar) {
X  		     did_unshar++;
X  		 } else
X--- 549,576 -----
X  		 ah = articles[article_id];
X  		 if (save_selected && (ah->flag & A_SELECT) == 0) continue;
X  
X+ 		 if (cur_k_cmd == K_CANCEL) {
X+ 		     if (current_group->group_flag & G_FOLDER) {
X+ 			 if ((ah->flag & A_CANCEL) == 0) fcancel(ah);
X+ 		     } else
X+ 			 switch (cancel(ah)) {
X+ 			  case -1:
X+ 			     did_unshar = 1;
X+ 			     continue;
X+ 			  case 0:
X+ 			     ah->flag |= A_CANCEL;
X+ 			     break;
X+ 			  default:
X+ 			     continue;
X+ 			 }
X+ 		     
X+ 		     if (!did_unshar) {
X+ 			 how = CANCEL;
X+ 			 mark();
X+ 		     }
X+ 		     continue;
X+ 		 }
X+ 
X  		 if (doing_unshar) {
X  		     did_unshar++;
X  		 } else
X**************
X*** 547,552
X  		 } else
X  		 if (cura >= 0 && cura <= numa)
X  		     prompt("Processing %c...", ident[cura]);
X  		 else
X  		     prompt("Processing entry %d...", article_id);
X  
X--- 576,583 -----
X  		 } else
X  		 if (cura >= 0 && cura <= numa)
X  		     prompt("Processing %c...", ident[cura]);
X+ 		 else if (ah->subject != NULL)
X+ 		     prompt("Processing '%.50s'...", ah->subject);
X  		 else
X  		     prompt("Processing entry %d...", article_id);
X  
X**************
X*** 572,578
X  	 m_endinput();
X  
X  	 enable_stop = 1;
X! 	 end_save();
X  
X  	 if (did_unshar) {
X  	     any_key(0);
X--- 603,610 -----
X  	 m_endinput();
X  
X  	 enable_stop = 1;
X! 	 if (cur_k_cmd != K_CANCEL)
X! 	     end_save();
X  
X  	 if (did_unshar) {
X  	     printf("\r\n");
X**************
X*** 575,580
X  	 end_save();
X  
X  	 if (did_unshar) {
X  	     any_key(0);
X  	     goto redraw;
X  	 }	
X--- 607,613 -----
X  	     end_save();
X  
X  	 if (did_unshar) {
X+ 	     printf("\r\n");
X  	     any_key(0);
X  	     goto redraw;
X  	 }	
X**************
X*** 612,618
X  		 goto redraw;
X  
X  	 goto Prompt;
X! 
X        case K_CANCEL:
X  	 if (numa < 0) goto nextmenu;
X  
X--- 645,651 -----
X  		 goto redraw;
X  
X  	 goto Prompt;
X! /*
X        case K_CANCEL:
X  	 if (numa < 0) goto nextmenu;
X  
X**************
X*** 632,638
X  	 if (get_k_cmd() == K_ARTICLE_ID)
X  	     if (cancel(articles[firsta+article_id]) & 1) goto redraw;
X  	 goto Prompt;
X! 
X        case K_UNSUBSCRIBE:
X  	 if (unsubscribe(current_group)) {
X  	     if (!(current_group->group_flag & G_SUBSCRIPTION))
X--- 665,671 -----
X  	 if (get_k_cmd() == K_ARTICLE_ID)
X  	     if (cancel(articles[firsta+article_id]) & 1) goto redraw;
X  	 goto Prompt;
X! */
X        case K_UNSUBSCRIBE:
X  	 if (unsubscribe(current_group)) {
X  	     if (!(current_group->group_flag & G_SUBSCRIPTION))
X
X*** /usr/storm/nn6.3.0/mk_online_man
X--- mk_online_man
X**************
X*** 6,11
X  	-e '/^\.\\"/d' \
X  	-e '/^\.nf/d' \
X  	-e '/^\.fi/d' \
X  	-e 's/^\.[BI] //' "$@" |
X  awk '
X  BEGIN {
X--- 6,15 -----
X  	-e '/^\.\\"/d' \
X  	-e '/^\.nf/d' \
X  	-e '/^\.fi/d' \
X+ 	-e '/^\.if/d' \
X+ 	-e '/^\.DT/d' \
X+ 	-e '/^\.ta/d' \
X+ 	-e '/^\.nr/d' \
X  	-e 's/^\.[BI] //' "$@" |
X  awk '
X  BEGIN {
X
X*** /usr/storm/nn6.3.0/more.c
X--- more.c
X**************
X*** 58,64
X      register c, col, lno;
X      register FILE *art;
X      int more_cmd, eof, skip_spaces, has_space, window_lines;
X!     int form_feed, ignore_nl;
X      off_t firstl, lastl;
X      off_t linepos[LINEMAX];
X      char linebuf[200], *lp;
X--- 58,64 -----
X      register c, col, lno;
X      register FILE *art;
X      int more_cmd, eof, skip_spaces, has_space, window_lines;
X!     int form_feed, last_ff_line, ignore_nl;
X      off_t firstl, lastl;
X      off_t linepos[LINEMAX];
X      char linebuf[200], *lp;
X**************
X*** 141,147
X      
X      rot13 = 0;
X      compress_space = 0;
X!     goto_line = -1, prev_goto = 1;
X      match_lines = match_redraw = match_expr = 0;
X      underline_line = -1;
X      fake_underline = 0;
X--- 141,147 -----
X      
X      rot13 = 0;
X      compress_space = 0;
X!     last_ff_line = goto_line = -1, prev_goto = 1;
X      match_lines = match_redraw = match_expr = 0;
X      underline_line = -1;
X      fake_underline = 0;
X**************
X*** 398,403
X  	switch (c) {
X  
X  	 case '\f':
X  	    if (lp == linebuf) {
X  		if (goto_line && lno == lno1) goto next_line;
X  		form_feed = 1;
X--- 398,404 -----
X  	switch (c) {
X  
X  	 case '\f':
X+ 	    last_ff_line = linenum;
X  	    if (lp == linebuf) {
X  		if (goto_line > 0 || match_expr || lno == lno1) goto next_line;
X  		form_feed = 1;
X**************
X*** 399,405
X  
X  	 case '\f':
X  	    if (lp == linebuf) {
X! 		if (goto_line && lno == lno1) goto next_line;
X  		form_feed = 1;
X  		goto Prompt;
X  	    }
X--- 400,406 -----
X  	 case '\f':
X  	    last_ff_line = linenum;
X  	    if (lp == linebuf) {
X! 		if (goto_line > 0 || match_expr || lno == lno1) goto next_line;
X  		form_feed = 1;
X  		goto Prompt;
X  	    }
X**************
X*** 475,480
X  	match_lines = 1;
X  	if (linenum > match_botline) {
X  	    match_redraw = 0;
X  	    linenum -= 5;
X  	    goto next_page;
X  	} 
X--- 476,482 -----
X  	match_lines = 1;
X  	if (linenum > match_botline) {
X  	    match_redraw = 0;
X+ 	    if (last_ff_line > linenum) last_ff_line = -1;
X  	    linenum -= 5;
X  	    if (linenum < last_ff_line) linenum = last_ff_line;
X  	    goto next_page;
X**************
X*** 476,481
X  	if (linenum > match_botline) {
X  	    match_redraw = 0;
X  	    linenum -= 5;
X  	    goto next_page;
X  	} 
X  	match_redraw = (stop_line < 0);
X--- 478,484 -----
X  	    match_redraw = 0;
X  	    if (last_ff_line > linenum) last_ff_line = -1;
X  	    linenum -= 5;
X+ 	    if (linenum < last_ff_line) linenum = last_ff_line;
X  	    goto next_page;
X  	} 
X  	match_redraw = (stop_line < 0);
X**************
X*** 665,670
X       case K_PRINT:
X       case K_UNSHAR:
X       case K_PATCH:
X  	
X  	putchar(CR);
X  	if (init_save(c, (char **)NULL) != NULL) {
X--- 668,674 -----
X       case K_PRINT:
X       case K_UNSHAR:
X       case K_PATCH:
X+      case K_UUDECODE:
X  	
X  	putchar(CR);
X  	if (init_save(c, (char **)NULL) != NULL) {
X**************
X*** 695,701
X  	    goto Prompt;
X  	}
X  	
X! 	if (cancel(ah) == 0) goto Prompt;
X  	more_return(MC_NEXT);
X  
X       case K_UNSUBSCRIBE:
X--- 699,705 -----
X  	    goto Prompt;
X  	}
X  	
X! 	if (cancel(ah) > 0) goto Prompt;
X  	more_return(MC_NEXT);
X  
X       case K_UNSUBSCRIBE:
X
X*** /usr/storm/nn6.3.0/nn.1
X--- nn.1
X**************
X*** 768,773
X  article through the patch command. 
X    The output from the patch process will be piped through the pager
X  defined in the \fBpager\fP variable and appear on the screen.
X  .TP
X  \&\fB:unshar\fP	{\fBunshar\fP}
X  Unshar articles.  You will be prompted for the name of a directory in
X--- 768,775 -----
X  article through the patch command. 
X    The output from the patch process will be piped through the pager
X  defined in the \fBpager\fP variable and appear on the screen.
X+   The output is also saved in (or appended to) a file named
X+ \fIPatch.Result\fP in the patch directory. 
X  .TP
X  \&\fB:unshar\fP	{\fBunshar\fP}
X  Unshar articles.  You will be prompted for the name of a directory in
X**************
X*** 777,782
X    During the unpacking, the normal output from the unshar process will
X  appear on the screen, and the menu or article text will be redrawn when
X  the process is finished.
X  .LP
X  In reading mode, the following keys can also be used to invoke the
X  save commands:
X--- 779,802 -----
X    During the unpacking, the normal output from the unshar process will
X  appear on the screen, and the menu or article text will be redrawn when
X  the process is finished.
X+   The output is also saved in (or appended to) a file named
X+ \fIUnshar.Result\fP in the unshar directory. 
X+ .TP
X+ \&\fB:decode\fP	{\fBdecode\fP}
X+ Decode \fIuuencoded\fP articles into binary files.  You will be
X+ prompted for the name of a directory in which you want \fInn\fP to
X+ place the decoded binary files (the file names are taken from the
X+ uuencoded data).
X+   \fInn\fP will combine several articles into single files as needed,
X+ and you can even decode unrelated packages (into the same directory)
X+ with one \fBdecode\fP command.
X+   To be able to decode a binary file which spans several articles,
X+ \fInn\fP may have to \fIignore\fP lines which fail the normal sanity checks 
X+ on uuencoded data instead of treating them as \fItransmission errors\fP.
X+ Consequently, it is strongly recommended to check the resulting
X+ decoded file using the checksum which is normally contained in the
X+ original article.  (Actually, you are also supposed to do this after
X+ decoding with a stand-alone uudecode program).
X  .LP
X  In reading mode, the following keys can also be used to invoke the
X  save commands:
X**************
X*** 1546,1553
X  in the order in which they arrived on the local system (which is a
X  completely arbitrary order).
X  .TP
X! \fB:unread\fP [ \fIarticles\fP ]
X! Mark the current group as unread.  If the argument is omitted, the
X  number of unread articles in the group will be set to the number of
X  unread articles when \fInn\fP was invoked.  Otherwise, the argument
X  specifies the number of unread articles.
X--- 1566,1574 -----
X  in the order in which they arrived on the local system (which is a
X  completely arbitrary order).
X  .TP
X! \fB:unread\fP [ \fIgroup\fP ] [ \fIarticles\fP ]
X! Mark the current (or specified) group as unread.  If the
X! \fIarticles\fP argument is omitted, the
X  number of unread articles in the group will be set to the number of
X  unread articles when \fInn\fP was invoked.  Otherwise, the argument
X  specifies the number of unread articles.
X
X*** /usr/storm/nn6.3.0/nngrep.sh
X--- nngrep.sh
X**************
X*** 8,13
X  if [ "$1" = "-a" ] ; then
X  	grep "$2" .nn/rc
X  else
X! 	grep "^+ .* .*$1" .nn/rc
X  fi |
X  awk '{print $3}'
X--- 8,13 -----
X  if [ "$1" = "-a" ] ; then
X  	grep "$2" .nn/rc
X  else
X! 	grep "^[+=] .* .*$1" .nn/rc
X  fi |
X  awk '{print $3}'
X
X*** /usr/storm/nn6.3.0/nntidy.sh
X--- nntidy.sh
X**************
X*** 35,41
X  	if (act) { 
X  		X[$1] = 1
X  		L[$1] = $2+0 
X! 		if (L[$1] == 0) F[$1] = 0; else F[$1] = $3+0
X  	}
X  	next
X  }
X--- 35,41 -----
X  	if (act) { 
X  		X[$1] = 1
X  		L[$1] = $2+0 
X! 		if (L[$1] == 0 || $3+0 == 0) F[$1] = 0; else F[$1] = $3-1
X  	}
X  	next
X  }
X**************
X*** 43,49
X  	print $0
X  	next
X  }
X! NF == 3 && ($1 == "!" || $1 == "+") {
X  	if (X[$3] != 1) next
X  	S[$3] = $1
X  	if (L[$3] >= $2+0)
X--- 43,49 -----
X  	print $0
X  	next
X  }
X! NF == 3 && ($1 == "!" || $1 == "+" || $1 == "=") {
X  	if (X[$3] != 1) next
X  	S[$3] = $1
X  	if (L[$3] >= $2+0)
X
X*** /usr/storm/nn6.3.0/nntp.c
X--- nntp.c
X**************
X*** 32,38
X  #include <netdb.h>
X  
X  /* This is necessary due to the definitions in m-XXX.h */
X! #ifdef NETWORK_BYTE_ORDER
X  #include <netinet/in.h>
X  #endif
X  
X--- 32,38 -----
X  #include <netdb.h>
X  
X  /* This is necessary due to the definitions in m-XXX.h */
X! #ifndef NETWORK_DATABASE
X  #include <netinet/in.h>
X  #else
X  #ifdef NETWORK_BYTE_ORDER
X**************
X*** 34,39
X  /* This is necessary due to the definitions in m-XXX.h */
X  #ifdef NETWORK_BYTE_ORDER
X  #include <netinet/in.h>
X  #endif
X  
X  export char nntp_server[256];	/* name of nntp server */
X--- 34,42 -----
X  /* This is necessary due to the definitions in m-XXX.h */
X  #ifndef NETWORK_DATABASE
X  #include <netinet/in.h>
X+ #else
X+ #ifdef NETWORK_BYTE_ORDER
X+ #include <netinet/in.h>
X  #endif
X  #endif
X  
X**************
X*** 35,40
X  #ifdef NETWORK_BYTE_ORDER
X  #include <netinet/in.h>
X  #endif
X  
X  export char nntp_server[256];	/* name of nntp server */
X  export int use_nntp = 0;	/* bool: t iff we use nntp */
X--- 38,44 -----
X  #ifdef NETWORK_BYTE_ORDER
X  #include <netinet/in.h>
X  #endif
X+ #endif
X  
X  export char nntp_server[256];	/* name of nntp server */
X  export int use_nntp = 0;	/* bool: t iff we use nntp */
X**************
X*** 150,155
X  	fl;
X      }
X      nntp_failed = 1;
X  
X      sockt_rd = nntp_get_socket();
X      if ((nntp_in = fdopen(sockt_rd, "r")) == NULL)
X--- 154,160 -----
X  	fl;
X      }
X      nntp_failed = 1;
X+     is_connected = 0;
X  
X      sockt_rd = nntp_get_socket();
X      if (sockt_rd < 0)
X**************
X*** 152,158
X      nntp_failed = 1;
X  
X      sockt_rd = nntp_get_socket();
X!     if ((nntp_in = fdopen(sockt_rd, "r")) == NULL)
X          return -1;
X   
X      sockt_wr = dup(sockt_rd);
X--- 157,167 -----
X      is_connected = 0;
X  
X      sockt_rd = nntp_get_socket();
X!     if (sockt_rd < 0)
X!       return -1;
X! 
X!     if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) {
X! 	close(sockt_rd);
X          return -1;
X      }
X      sockt_wr = dup(sockt_rd);
X**************
X*** 154,160
X      sockt_rd = nntp_get_socket();
X      if ((nntp_in = fdopen(sockt_rd, "r")) == NULL)
X          return -1;
X!  
X      sockt_wr = dup(sockt_rd);
X      if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) {
X          nntp_in = NULL;               /* from above */
X--- 163,169 -----
X      if ((nntp_in = fdopen(sockt_rd, "r")) == NULL) {
X  	close(sockt_rd);
X          return -1;
X!     }
X      sockt_wr = dup(sockt_rd);
X      if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) {
X  	close(sockt_wr);
X**************
X*** 157,162
X   
X      sockt_wr = dup(sockt_rd);
X      if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) {
X          nntp_in = NULL;               /* from above */
X          return -1;
X      }
X--- 166,173 -----
X      }
X      sockt_wr = dup(sockt_rd);
X      if ((nntp_out = fdopen(sockt_wr, "w")) == NULL) {
X+ 	close(sockt_wr);
X+ 	fclose(nntp_in);
X          nntp_in = NULL;               /* from above */
X          return -1;
X      }
X**************
X*** 228,233
X  	if (!is_master)
X  	    msg("Connecting to %s: %s", nntp_server, syserr());
X  	(void) close(s);
X      }
X      if (x < 0 && !is_master)
X  	(*errfct)("Giving up on NNTP server %s!\n", nntp_server);
X--- 239,245 -----
X  	if (!is_master)
X  	    msg("Connecting to %s: %s", nntp_server, syserr());
X  	(void) close(s);
X+ 	s = -1;
X      }
X      if (x < 0 && !is_master)
X  	(*errfct)("Giving up on NNTP server %s!\n", nntp_server);
X**************
X*** 240,245
X      if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
X  	if (is_master)
X  	    (*errfct)("Connecting to %s: %s", nntp_server, syserr());
X      }
X      
X  #endif
X--- 252,258 -----
X      if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
X  	if (is_master)
X  	    (*errfct)("Connecting to %s: %s", nntp_server, syserr());
X+ 	s = -1;
X      }
X      
X  #endif
X**************
X*** 261,266
X      fprintf(nntp_out, "%s\r\n", string);
X      if (fflush(nntp_out) == EOF) {
X  	nntp_error();
X      }
X  }
X  
X--- 274,280 -----
X      fprintf(nntp_out, "%s\r\n", string);
X      if (fflush(nntp_out) == EOF) {
X  	nntp_error();
X+ 	return -1;
X      }
X      return 0;
X  }
X**************
X*** 262,267
X      if (fflush(nntp_out) == EOF) {
X  	nntp_error();
X      }
X  }
X  
X  /* 
X--- 276,282 -----
X  	nntp_error();
X  	return -1;
X      }
X+     return 0;
X  }
X  
X  /* 
X**************
X*** 277,283
X  {
X      register char *cp, *nl;
X  
X-     errno = 0;
X      if (fgets(string, size, nntp_in) == NULL) {
X  	nntp_error();
X  	return -1;
X--- 292,297 -----
X  {
X      register char *cp, *nl;
X  
X      if (fgets(string, size, nntp_in) == NULL) {
X  	nntp_error();
X  	return -1;
X**************
X*** 323,329
X      if (!nntp_failed) {			/* avoid infinite recursion */
X  	char line[NNTP_STRLEN];
X  
X! 	nntp_put_server("QUIT");
X  	(void) nntp_get_server(line, sizeof line);
X      }
X  
X--- 337,343 -----
X      if (!nntp_failed) {			/* avoid infinite recursion */
X  	char line[NNTP_STRLEN];
X  
X! 	(void) nntp_put_server("QUIT");
X  	(void) nntp_get_server(line, sizeof line);
X      }
X  
X**************
X*** 344,352
X  char *string;
X  int size;
X  {
X!     (void)nntp_put_server(string);
X! 
X!     if (nntp_get_server(string, size) < 0)
X  	return -1;
X  #ifdef DEBUG
X      msg("<<< %.75s", string);
X--- 358,364 -----
X  char *string;
X  int size;
X  {
X!     if (nntp_put_server(string) < 0 || nntp_get_server(string, size) < 0)
X  	return -1;
X  #ifdef DEBUG
X      msg("<<< %.75s", string);
X**************
X*** 367,374
X  {
X      nntp_failed = 1;
X      if (is_master) {
X! 	log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr());
X! 	if (is_connected)
X  	    nntp_close_server();
X      } else {
X  #ifdef DEBUG
X--- 379,386 -----
X  {
X      nntp_failed = 1;
X      if (is_master) {
X! 	if (is_connected) {
X! 	    log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr());
X  	    nntp_close_server();
X  	}
X      } else {
X**************
X*** 370,375
X  	log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr());
X  	if (is_connected)
X  	    nntp_close_server();
X      } else {
X  #ifdef DEBUG
X  	printf("Can't talk to NNTP server %s: %s", nntp_server, syserr());
X--- 382,388 -----
X  	if (is_connected) {
X  	    log_entry('N', "Lost connection to server %s: %s", nntp_server, syserr());
X  	    nntp_close_server();
X+ 	}
X      } else {
X  #ifdef DEBUG
X  	printf("Can't talk to NNTP server %s: %s", nntp_server, syserr());
X
X*** /usr/storm/nn6.3.0/nnusage.sh
X--- nnusage.sh
X**************
X*** 8,16
X  
X  grep '^U:' $LIB/Log |
X  
X! awk ' 
X! NF == 7 { 
X! 	if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2]
X  }
X  END {
X  	for (n in u) {
X--- 8,16 -----
X  
X  grep '^U:' $LIB/Log |
X  
X! awk '
X! BEGIN {
X! 	any=0
X  }
X  NF == 7 { 
X  	if (split($7, t, ".") == 2) { 
X**************
X*** 12,17
X  NF == 7 { 
X  	if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2]
X  }
X  END {
X  	for (n in u) {
X  		name=substr(n, 2, length(n)-3)
X--- 12,23 -----
X  BEGIN {
X  	any=0
X  }
X+ NF == 7 { 
X+ 	if (split($7, t, ".") == 2) { 
X+ 		u[$5] += t[1] * 60 + t[2]
X+ 		any=1
X+ 	}
X+ }
X  END {
X  	if (!any) {
X  		printf("No usage statistics\n")
X**************
X*** 13,18
X  	if (split($7, t, ".") == 2) u[$5] += t[1] * 60 + t[2]
X  }
X  END {
X  	for (n in u) {
X  		name=substr(n, 2, length(n)-3)
X  		printf("%s%16d.%02d\n", name, u[n]/60, u[n]%60);
X--- 19,28 -----
X  	}
X  }
X  END {
X+ 	if (!any) {
X+ 		printf("No usage statistics\n")
X+ 		exit
X+ 	}
X  	for (n in u) {
X  		name=substr(n, 2, length(n)-3)
X  		printf("%-10.10s%8d.%02d\n", name, u[n]/60, u[n]%60);
X**************
X*** 15,21
X  END {
X  	for (n in u) {
X  		name=substr(n, 2, length(n)-3)
X! 		printf("%s%16d.%02d\n", name, u[n]/60, u[n]%60);
X  	}
X  }' |
X  
X--- 25,31 -----
X  	}
X  	for (n in u) {
X  		name=substr(n, 2, length(n)-3)
X! 		printf("%-10.10s%8d.%02d\n", name, u[n]/60, u[n]%60);
X  	}
X  }' |
X  
X
X*** /usr/storm/nn6.3.0/prefix.sh
X--- prefix.sh
X**************
X*** 5,10
X  #include "update.h"
X  
X  --------CUT PREFIX HERE--------
X  &!/bin/sh
X  
X  & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE
X--- 5,11 -----
X  #include "update.h"
X  
X  --------CUT PREFIX HERE--------
X+ #ifndef AVOID_SHELL_EXEC
X  &!/bin/sh
X  #endif
X  
X**************
X*** 6,11
X  
X  --------CUT PREFIX HERE--------
X  &!/bin/sh
X  
X  & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE
X  
X--- 7,13 -----
X  --------CUT PREFIX HERE--------
X  #ifndef AVOID_SHELL_EXEC
X  &!/bin/sh
X+ #endif
X  
X  & Release RELEASE,VERSION,PATCHLEVEL, No. UPDATE
X  
X
X*** /usr/storm/nn6.3.1/rc.c
X--- rc.c
X**************
X*** 45,51
X   * master file has been read in
X   */
X  
X! #define	G_OLD	G_NEW	/* inverse use during rc reading */
X  #define G_RENUM	G_DONE
X  
X  
X--- 45,51 -----
X   * master file has been read in
X   */
X  
X! #define	G_OLD	G_SELECTION
X  #define G_RENUM	G_DONE
X  
X  
X**************
X*** 166,172
X  	    fputc(NL, bak);
X  	}
X  	
X! 	if (SUBSCR(line) != '+' && SUBSCR(line) != '!') {
X  	    /* unrecognized line */
X  	    continue;
X  	}
X--- 166,172 -----
X  	    fputc(NL, bak);
X  	}
X  	
X! 	if (SUBSCR(line) != '+' && SUBSCR(line) != '!' && SUBSCR(line) != '=') {
X  	    /* unrecognized line */
X  	    continue;
X  	}
X**************
X*** 182,188
X  	gh->group_flag |= G_OLD;
X  	if (SUBSCR(line) == '+')
X  	    gh->group_flag |= G_SUBSCRIPTION;
X! 	
X  	gh->last_article = LASTART(line);
X  	
X  	if (gh->last_article > gh->last_l_article)
X--- 182,190 -----
X  	gh->group_flag |= G_OLD;
X  	if (SUBSCR(line) == '+')
X  	    gh->group_flag |= G_SUBSCRIPTION;
X! 	if (SUBSCR(line) == '=')
X! 	    gh->group_flag |= G_SUBSCRIPTION | G_NEW;
X! 
X  	gh->last_article = LASTART(line);
X  	
X  	if (gh->last_article > gh->last_l_article)
X**************
X*** 207,213
X  	if (gh->group_flag & G_OLD) {
X  	    if (gh->group_flag & G_RENUM) /* group is renumbered */
X  		write_rc_entry(gh, 0);
X! 	    gh->group_flag &= ~(G_NEW | G_RENUM);
X  	} else {
X  	    gh->group_flag |= G_SUBSCRIPTION | G_NEW;
X  	    gh->last_article = gh->first_l_article - 1;
X--- 209,215 -----
X  	if (gh->group_flag & G_OLD) {
X  	    if (gh->group_flag & G_RENUM) /* group is renumbered */
X  		write_rc_entry(gh, 0);
X! 	    gh->group_flag &= ~(G_OLD | G_RENUM);
X  	} else {
X  	    gh->group_flag |= G_SUBSCRIPTION | G_NEW;
X  	    gh->last_article = gh->first_l_article - 1;
X**************
X*** 272,278
X  {
X      add_unread(gh, -1);
X  
X!     if (no_update || gh->group_flag & G_RC_UPDATED) return;
X  
X      gh->last_article = gh->last_l_article;
X  
X--- 274,280 -----
X  {
X      add_unread(gh, -1);
X  
X!     if (no_update || gh->group_flag & G_READ) return;
X  
X      gh->last_article = gh->last_l_article;
X  
X**************
X*** 284,291
X  
X      write_rc_entry(gh, 0);
X      
X-     if (gh->group_flag & G_READ) return;
X-     
X      gh->group_flag |= G_READ;
X  
X      if ((gh->group_flag & G_SUBSCRIPTION) == 0) return;
X--- 286,291 -----
X  
X      write_rc_entry(gh, 0);
X      
X      gh->group_flag |= G_READ;
X  }
X  
X**************
X*** 287,294
X      if (gh->group_flag & G_READ) return;
X      
X      gh->group_flag |= G_READ;
X- 
X-     if ((gh->group_flag & G_SUBSCRIPTION) == 0) return;
X  }
X  
X  
X--- 287,292 -----
X      write_rc_entry(gh, 0);
X      
X      gh->group_flag |= G_READ;
X  }
X  
X  
X**************
X*** 296,302
X  register group_header *gh;
X  long count;
X  {
X!     if (no_update || (count == 0 && (gh->group_flag & G_RC_UPDATED) == 0))
X  	return 0;
X  
X      if (gh->group_flag & G_READ || count > 0) {
X--- 294,300 -----
X  register group_header *gh;
X  long count;
X  {
X!     if (no_update || (count == 0 && (gh->group_flag & G_READ) == 0))
X  	return 0;
X  
X      if (gh->group_flag & G_READ || count > 0) {
X**************
X*** 318,324
X  
X  	write_rc_entry(gh, 0);
X  	
X! 	gh->group_flag &= ~(G_READ|G_RC_UPDATED);
X  	
X  	add_unread(gh, 1);
X  	
X--- 316,322 -----
X  
X  	write_rc_entry(gh, 0);
X  	
X! 	gh->group_flag &= ~G_READ;
X  	
X  	add_unread(gh, 1);
X  	
X**************
X*** 469,474
X      /* update article number */
X  	
X      fprintf(rc, "%c %06ld",	/* MUST CHANGE IF LASTARTZ CHANGES */
X  	    (gh->group_flag & G_SUBSCRIPTION) ? '+' : '!',
X  	    (long)(gh->last_article));
X  
X--- 467,473 -----
X      /* update article number */
X  	
X      fprintf(rc, "%c %06ld",	/* MUST CHANGE IF LASTARTZ CHANGES */
X+ 	    (gh->group_flag & G_NEW) ? '=' :
X  	    (gh->group_flag & G_SUBSCRIPTION) ? '+' : '!',
X  	    (long)(gh->last_article));
X  
X**************
X*** 570,578
X  	    
X  	    /* Notice: unread articles before the last read article are lost */
X  	    
X- 	    if (*sub == NL)	/* new group */
X- 		continue;
X- 	    
X  	    if (subscr) {
X  		last = strrchr(sub, '-');
X  		if (last == NULL) last = strrchr(sub, ',');
X--- 569,574 -----
X  	    
X  	    /* Notice: unread articles before the last read article are lost */
X  	    
X  	    if (subscr) {
X  		if (*sub == NL) continue; /* new group */
X  	    
X**************
X*** 574,579
X  		continue;
X  	    
X  	    if (subscr) {
NO_NEWS_IS_GOOD_NEWS
echo "End of part 1"
echo "File PATCH.2 is continued in part 2"
echo "2" > s2_seq_.tmp
exit 0
-- 
Kim F. Storm        storm@texas.dk        Tel +45 429 174 00
Texas Instruments, Marielundvej 46E, DK-2730 Herlev, Denmark
	  No news is good news, but nn is better!

storm@texas.dk (Kim F. Storm) (06/29/89)

This is the second and last part of patch #2 for nn 6.3.

Unpack with :unshar after unpacking the first part.

++Kim Storm

---- Cut Here and unpack ----
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file PATCH.2 continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file PATCH.2"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' >> PATCH.2
X  		last = strrchr(sub, '-');
X  		if (last == NULL) last = strrchr(sub, ',');
X  		if (last == NULL) last = strrchr(sub, ' ');
X--- 570,577 -----
X  	    /* Notice: unread articles before the last read article are lost */
X  	    
X  	    if (subscr) {
X+ 		if (*sub == NL) continue; /* new group */
X+ 	    
X  		last = strrchr(sub, '-');
X  		if (last == NULL) last = strrchr(sub, ',');
X  		if (last == NULL) last = strrchr(sub, ' ');
X
X*** /usr/storm/nn6.3.0/s-template.h
X--- s-template.h
X**************
X*** 128,133
X  #define SHELL		"/bin/sh"
X  
X  /*
X   *	Specify the default mailer to be invoked by nnmail
X   */
X  
X--- 128,142 -----
X  #define SHELL		"/bin/sh"
X  
X  /*
X+  *	Define AVOID_SHELL_EXEC if the system gets confused by
X+  *		#!/bin/sh
X+  *	lines in shell scripts, e.g. only reads #! and thinks it
X+  *	is a csh script.
X+  */
X+ 
X+ /* #define AVOID_SHELL_EXEC		/* */
X+ 
X+ /*
X   *	Specify the default mailer to be invoked by nnmail
X   */
X  
X
X*** /usr/storm/nn6.3.0/save.c
X--- save.c
X**************
X*** 44,49
X  #define	IS_PIPE		0x1000	/* output is on pipe */
X  #define	DO_UNSHAR	0x2000	/* unshar article (or patch) */
X  #define	DO_PATCH	0x4000	/* patch article */
X  
X  /* open modes for open_news_article for the various HEADER_HANDLINGs */
X  
X--- 44,50 -----
X  #define	IS_PIPE		0x1000	/* output is on pipe */
X  #define	DO_UNSHAR	0x2000	/* unshar article (or patch) */
X  #define	DO_PATCH	0x4000	/* patch article */
X+ #define	DO_DECODE	0x8000	/* uudecode article */
X  
X  /* open modes for open_news_article for the various HEADER_HANDLINGs */
X  
X**************
X*** 144,149
X  	}
X  	break;
X  
X       case K_PATCH:
X  	save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR | DO_PATCH;
X  	mode_text = "Patch";
X--- 145,155 -----
X  	}
X  	break;
X  
X+      case K_UUDECODE:
X+ 	save_mode = NO_HEADER | DO_UNSHAR | DO_DECODE;
X+ 	mode_text = "Decode";
X+ 	goto patch1;
X+ 	
X       case K_PATCH:
X  	save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR | DO_PATCH;
X  	mode_text = "Patch";
X**************
X*** 157,170
X  	
X       patch1:
X  	prompt("\1%s Directory:\1 ", mode_text);
X! 	save_name = get_s(last_dir, NONE, NONE, file_completion);
X! 	if (save_name == NULL) return NULL;
X! 	if (*save_name == NUL) 
X! 	    save_name = NULL;
X! 	else {
X! 	    strcpy(last_dir, save_name);
X! 	}
X! 	
X  	break;
X  	
X       case K_PRINT:
X--- 163,171 -----
X  	
X       patch1:
X  	prompt("\1%s Directory:\1 ", mode_text);
X! 	save_name = get_s(last_dir, current_group->save_file, NONE, file_completion);
X! 	if (save_name == NULL || *save_name == NUL) return NULL;
X! 	strcpy(last_dir, save_name);
X  	break;
X  	
X       case K_PRINT:
X**************
X*** 198,204
X  	
X  	if (!(save_mode & IS_PIPE)) {
X  	    if (file_exist(save_name, (save_mode & DO_UNSHAR) ? "wd" : "wf")) {
X! 		if (conf_append && (save_mode & DO_UNSHAR) == 0) {
X  		    printf("\rAppend to: %s ? ", save_name);
X  		    clrline();
X  		    if (!yes(0)) return NULL;
X--- 199,210 -----
X  	
X  	if (!(save_mode & IS_PIPE)) {
X  	    if (file_exist(save_name, (save_mode & DO_UNSHAR) ? "wd" : "wf")) {
X! 		if (save_mode & DO_UNSHAR) {
X! 		    int len = strlen(save_name);
X! 		    if (save_name[len - 1] != '/')
X! 			strcpy(save_name + len, "/");
X! 		} else
X! 		if (conf_append) {
X  		    printf("\rAppend to: %s ? ", save_name);
X  		    clrline();
X  		    if (!yes(0)) return NULL;
X**************
X*** 210,216
X  		}
X  
X  		if (save_mode & DO_UNSHAR) {
X! 		    strcat(save_name, "/");
X  		}
X  
X  		start = ckdir_path(save_name);
X--- 216,224 -----
X  		}
X  
X  		if (save_mode & DO_UNSHAR) {
X! 		    int len = strlen(save_name);
X! 		    if (save_name[len - 1] != '/')
X! 			strcpy(save_name + len, "/");
X  		}
X  
X  		start = ckdir_path(save_name);
X**************
X*** 244,249
X  
X      save_mode |= FILE_IS_NEW;	/* so save() will open it */
X  
X  #ifdef PAGED_OUTPUT
X      if (save_mode & DO_UNSHAR) {
X  	int was_raw = no_raw();
X--- 252,262 -----
X  
X      save_mode |= FILE_IS_NEW;	/* so save() will open it */
X  
X+     if (save_mode & DO_DECODE) {
X+ 	uud_start(save_name);
X+ 	save_mode &= ~DO_UNSHAR;
X+     }
X+     
X  #ifdef PAGED_OUTPUT
X      if (save_mode & DO_UNSHAR) {
X  	int was_raw = no_raw();
X**************
X*** 258,264
X  	system("fdcheck");
X      }
X  #endif
X!     
X      return save_name;
X  }
X  
X--- 271,277 -----
X  	system("fdcheck");
X      }
X  #endif
X! 
X      return save_name;
X  }
X  
X**************
X*** 284,289
X  	return 0;
X      }
X  
X      if (save_mode & UNIQUE_FILES) {
X  	do {
X  	    uniq_counter++;
X--- 297,309 -----
X  	return 0;
X      }
X  
X+     if (save_mode & DO_DECODE) {
X+ 	save_file = NULL;
X+ 	c = uudecode(ah, art);
X+ 	fclose(art);
X+ 	return (c < 0) ? 0 : 1;
X+     }
X+     
X      if (save_mode & UNIQUE_FILES) {
X  	do {
X  	    uniq_counter++;
X**************
X*** 317,323
X  		sprintf(copybuf, "%s %s", unshar_cmd, pager_redir);
X  #else
X  	    sprintf(copybuf, 
X! 		    "cd %s && %s | tee %s 2>&1 ; cat %s >> %s.Result ; rm %s",
X  		    save_name != NULL ? save_name : ".", unshar_cmd,
X  		    temp_file, temp_file, 
X  		    (save_mode & DO_PATCH) ? "Patch" : "Unshar",
X--- 337,343 -----
X  		sprintf(copybuf, "%s %s", unshar_cmd, pager_redir);
X  #else
X  	    sprintf(copybuf, 
X! 		    "cd %s && { %s 2>&1 ; } | tee %s ; cat %s >> %s.Result ; rm %s",
X  		    save_name != NULL ? save_name : ".", unshar_cmd,
X  		    temp_file, temp_file, 
X  		    (save_mode & DO_PATCH) ? "Patch" : "Unshar",
X**************
X*** 450,455
X  	save_file = NULL;
X      }
X      
X  #ifdef PAGED_OUTPUT
X      if (pager_stream != NULL) {
X  	pclose(pager_stream);
X--- 470,478 -----
X  	save_file = NULL;
X      }
X      
X+     if (save_mode & DO_DECODE) {
X+ 	uud_end();
X+     }
X  #ifdef PAGED_OUTPUT
X      if (pager_stream != NULL) {
X  	pclose(pager_stream);
X
X*** /usr/storm/nn6.3.0/selection.c
X--- selection.c
X**************
X*** 17,22
X  } header;
X  
X  #ifndef NETWORK_DATABASE
X  #undef ntohl
X  #undef htonl
X  #undef NETWORK_BYTE_ORDER
X--- 17,27 -----
X  } header;
X  
X  #ifndef NETWORK_DATABASE
X+ #undef NETWORK_BYTE_ORDER
X+ #define NETWORK_BYTE_ORDER
X+ #endif
X+ 
X+ #ifdef NETWORK_BYTE_ORDER
X  #undef ntohl
X  #undef htonl
X  #define ntohl(x) (x)
X**************
X*** 19,25
X  #ifndef NETWORK_DATABASE
X  #undef ntohl
X  #undef htonl
X- #undef NETWORK_BYTE_ORDER
X  #define ntohl(x) (x)
X  #define htonl(x) (x)
X  #define NETWORK_BYTE_ORDER
X--- 24,29 -----
X  #ifdef NETWORK_BYTE_ORDER
X  #undef ntohl
X  #undef htonl
X  #define ntohl(x) (x)
X  #define htonl(x) (x)
X  #endif
X**************
X*** 22,28
X  #undef NETWORK_BYTE_ORDER
X  #define ntohl(x) (x)
X  #define htonl(x) (x)
X- #define NETWORK_BYTE_ORDER
X  #endif
X  
X  struct sel_art {
X--- 26,31 -----
X  #undef htonl
X  #define ntohl(x) (x)
X  #define htonl(x) (x)
X  #endif
X  
X  struct sel_art {
X
X*** /usr/storm/nn6.3.0/sequence.c
X--- sequence.c
X**************
X*** 175,181
X      if (st.st_size == 0 || st.st_mtime < st.st_atime) return;
X      
X      mail_group.group_name = read_mail;
X!     gh->group_flag = G_FOLDER | G_MAILBOX | G_RC_UPDATED | G_READ;
X  
X      /* "invent" an unread article for read_news */
X      gh->last_article = 1;
X--- 175,181 -----
X      if (st.st_size == 0 || st.st_mtime < st.st_atime) return;
X      
X      mail_group.group_name = read_mail;
X!     gh->group_flag = G_FOLDER | G_MAILBOX | G_READ;
X  
X      /* "invent" an unread article for read_news */
X      gh->last_article = 1;
X**************
X*** 367,373
X      mem_check(gh, 1, "group header");
X      
X      gh->group_name = name;
X!     gh->group_flag = flag | G_RC_UPDATED | G_READ;
X  
X      /* "invent" an unread article for read_news */
X      gh->last_article = 1;
X--- 367,373 -----
X      mem_check(gh, 1, "group header");
X      
X      gh->group_name = name;
X!     gh->group_flag = flag | G_READ;
X  
X      /* "invent" an unread article for read_news */
X      gh->last_article = 1;
X**************
X*** 392,398
X  	
X      if (strcmp(group, "NEW") == 0) {
X  	gs_mode = GS_NEW_GROUP;
X! 	gs_length = 127;
X      } else {
X  	gs_mode = GS_PREFIX;
X  	
X--- 392,398 -----
X  	
X      if (strcmp(group, "NEW") == 0) {
X  	gs_mode = GS_NEW_GROUP;
X! 	gs_length = 0;
X      } else {
X  	gs_mode = GS_PREFIX;
X  	
X
X*** /usr/storm/nn6.3.0/term.c
X--- term.c
X**************
X*** 213,218
X      
X      if ((term_name = getenv("TERM")) == NULL)
X  	user_error("No TERM variable in enviroment");
X      
X  #ifdef USE_TERMINFO
X      setupterm(0,1,0);
X--- 213,224 -----
X      
X      if ((term_name = getenv("TERM")) == NULL)
X  	user_error("No TERM variable in enviroment");
X+ 
X+ #ifdef HAVE_TERMIO
X+     ioctl(0, TCGETA, &norm_tty);
X+ #else	
X+     ioctl(0, TIOCGETP, &norm_tty);
X+ #endif
X      
X  #ifdef USE_TERMINFO
X      setupterm(0,1,0);
X**************
X*** 291,300
X  	cookie_size = two_cookies = 0;
X      
X      
X- #ifdef HAVE_TERMIO
X-     
X-     ioctl(0, TCGETA, &norm_tty);
X-     
X      raw_tty = norm_tty;
X      
X      raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
X--- 297,302 -----
X  	cookie_size = two_cookies = 0;
X      
X      
X      raw_tty = norm_tty;
X      
X  #ifdef HAVE_TERMIO
X**************
X*** 297,302
X      
X      raw_tty = norm_tty;
X      
X      raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
X      raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP;
X      raw_tty.c_oflag &= ~OPOST;
X--- 299,305 -----
X      
X      raw_tty = norm_tty;
X      
X+ #ifdef HAVE_TERMIO
X      raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR);
X      raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP;
X      raw_tty.c_oflag &= ~OPOST;
X**************
X*** 307,315
X      raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2;
X      
X  #else	
X-     
X-     ioctl(0, TIOCGETP, &norm_tty);
X-     
X      ioctl(0, TIOCGETC, &norm_chars);
X      
X  #ifdef TIOCGLTC
X--- 310,315 -----
X      raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2;
X      
X  #else	
X      ioctl(0, TIOCGETC, &norm_chars);
X      
X  #ifdef TIOCGLTC
X**************
X*** 318,325
X      
X      ospeed = norm_tty.sg_ospeed;
X      if (ospeed < B2400) slow_mode++;
X-     
X-     raw_tty = norm_tty;
X      
X      raw_tty.sg_flags |= RAW;
X      raw_tty.sg_flags &= ~(ECHO|CRMOD);
X--- 318,323 -----
X      
X      ospeed = norm_tty.sg_ospeed;
X      if (ospeed < B2400) slow_mode++;
X      
X      raw_tty.sg_flags |= RAW;
X      raw_tty.sg_flags &= ~(ECHO|CRMOD);
X
X*** /usr/storm/nn6.3.0/xmakefile
X--- xmakefile
X**************
X*** 55,61
X  	init.o variable.o term.o keymap.o macro.o regexp.o \
X  	menu.o more.o rc.o group.o folder.o \
X  	articles.o sequence.o selection.o kill.o \
X! 	answer.o reroute.o save.o unshar.o execute.o \
X  	pack_date.o pack_name.o pack_subject.o news.o digest.o match.o 
X  
X  MAIL = nnmail.o reroute.o global.o options.o update.o
X--- 55,61 -----
X  	init.o variable.o term.o keymap.o macro.o regexp.o \
X  	menu.o more.o rc.o group.o folder.o \
X  	articles.o sequence.o selection.o kill.o \
X! 	answer.o reroute.o save.o unshar.o decode.o execute.o \
X  	pack_date.o pack_name.o pack_subject.o news.o digest.o match.o 
X  
X  MAIL = nnmail.o reroute.o global.o options.o update.o
X**************
X*** 195,200
X  date_regexp.o:	config.h global.h data.h
X  
X  db.o:		db.c config.h global.h data.h db.h
X  
X  digest.o:	digest.c config.h global.h data.h news.h match.h
X  
X--- 195,202 -----
X  date_regexp.o:	config.h global.h data.h
X  
X  db.o:		db.c config.h global.h data.h db.h
X+ 
X+ decode.o:	decode.c config.h
X  
X  digest.o:	digest.c config.h global.h data.h news.h match.h
X  
X
NO_NEWS_IS_GOOD_NEWS
echo "File PATCH.2 is complete"
chmod 0644 PATCH.2 || echo "restore of PATCH.2 fails"
set `wc -c PATCH.2`;Sum=$1
if test "$Sum" != "47497"
then echo original size 47497, current size $Sum;fi
echo "x - extracting decode.c (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > decode.c &&
X/*
X * Decode one or more uuencoded article back to binary form.
X *
X * UNIX/NN VERSION 
X *	This version cannot be used as a stand-alone uud!
X * 	This version is made: 16 June 1989.
X *
X * From the Berkeley original, modified by MSD, RDR, JPHD & WLS.
X */
X
X#include "config.h"
X
X#define MAXCHAR 256
X#define LINELEN 256
X#define NORMLEN 60	/* allows for 80 encoded chars per line */
X
X#define SEQMAX 'z'
X#define SEQMIN 'a'
X
Xstatic char seqc;
Xstatic int first, secnd, check, numl;
X
Xstatic FILE *out;
Xstatic char *target;
Xstatic char blank;
Xstatic int chtbl[MAXCHAR], cdlen[NORMLEN + 3];
Xstatic char ofname[FILENAME];
Xstatic int state;
X
X#define	NO_ADVANCE		0x10
X
X#define	FIND_BEGIN		0x01
X#define	FIND_BEGIN_AFTER_ERROR	0x02
X#define	DECODE_TEXT		0x03
X#define	SKIP_TRAILING	       (0x04 | NO_ADVANCE)
X#define	SKIP_LEADING		0x05
X#define	FOUND_END	       (0x06 | NO_ADVANCE)
X#define DECODE_ERROR	       (0x07 | NO_ADVANCE)
X#define OTHER_ERROR	       (0x08 | NO_ADVANCE)
X#define NEW_BEGIN	       (0x09 | NO_ADVANCE)
X
Xuud_start(dir)
Xchar *dir;
X{
X    target = dir;
X    out = NULL;
X    seqc = SEQMAX;
X    check = 1;
X    first = 1;
X    secnd = 0;
X    state = FIND_BEGIN;
X}
X
Xuud_end()
X{
X    if (out != NULL) {
X	fclose(out);
X	msg("%s INCOMPLETE -- removed", ofname);
X	unlink(ofname);
X    }
X}
X
X
Xuudecode(ah, in)
Xregister article_header *ah;
XFILE *in;
X{
X    int mode, onedone, lens;
X    char dest[FILENAME], buf[LINELEN];
X
X    numl = onedone = 0;
X
X    if (state == FIND_BEGIN)
X	inittbls();
X    
X    /*
X     * search for header or translation table line.
X     */
X
X    while ((state & NO_ADVANCE) || 
X	   (ftell(in) < ah->lpos && fgets(buf, sizeof buf, in) != NULL)) {
X	numl++;
X
X	switch (state) {
X
X	 case NEW_BEGIN:
X	    if (out != NULL) {
X		msg("INCOMPLETE FILE: %s -- removed", ofname);
X		user_delay(5);
X		fclose(out);
X		out = NULL;
X		unlink(ofname);
X	    }
X	    /* fall thru */
X
X	 case FIND_BEGIN:
X	 case FIND_BEGIN_AFTER_ERROR:
X	    if (strncmp(buf, "table", 5) == 0) {
X		gettable(in);
X		continue;
X	    }
X
X	    if (strncmp(buf, "begin", 5) == 0) {
X		lens = strlen(buf);
X		buf[--lens] = '\0';
X
X		if(sscanf(buf,"begin%o%s", &mode, dest) != 2)
X		    continue;
X		
X		if (target != NULL)
X		    sprintf(ofname, "%s%s", target, dest);
X		else
X		    strcpy(ofname, dest);
X		    
X		if ((out = open_file(ofname, OPEN_CREATE)) == NULL) {
X		    msg("Cannot create file: %s\n", ofname);
X		    goto err;
X		}
X		chmod(ofname, mode);
X
X		msg("Decoding: %s", ofname);
X		state = DECODE_TEXT;
X	    }
X	    continue;
X	
X	 case SKIP_LEADING:
X	    state = decode_line(buf);
X	    continue;
X
X	 case DECODE_TEXT:
X	    state = decode_line(buf);
X	    onedone = 1;
X	    continue;
X
X	 case FOUND_END:
X	    fclose(out);
X	    out = NULL;
X	    state = FIND_BEGIN;
X	    continue;
X	    
X	 case SKIP_TRAILING:
X	    state = SKIP_LEADING;
X	    return 0;
X
X	 case DECODE_ERROR:
X	    state = SKIP_TRAILING;
X	    continue;
X	    
X	 case OTHER_ERROR:
X	    fclose(out);
X	    out = NULL;
X	    state = FIND_BEGIN_AFTER_ERROR;
X	    goto err;
X	}
X    }
X    
X    if (onedone) {
X	if (state == DECODE_TEXT) state = SKIP_LEADING;
X	return 0;
X    }
X    
X    if (state == FIND_BEGIN_AFTER_ERROR) return -1;
X    msg("No 'begin' line");
X    
X err:
X    user_delay(2);
X    return -1;
X}
X
X/*
X * decode one line, write on out file
X */
X
Xstatic decode_line(buf)
Xchar *buf;
X{
X    char outl[LINELEN];
X    register char *bp, *ut;
X    register int *trtbl = chtbl;
X    register int n; 
X    register int blen;		/* binary length (from decoded file) */
X    register int rlen;		/* calculated input line length */
X    register int len;		/* actual input line length */
X    
X    len = strlen(buf);
X    if (--len < 0) return state;
X
X    buf[len] = '\0';
X
X    /*
X     * Get the binary line length.
X     */
X    if ((blen = trtbl[buf[0]]) < 0) {
X	if (state == SKIP_LEADING) {
X	    if (strncmp(buf, "begin", 5) == 0)
X		return NEW_BEGIN;
X	
X	    return SKIP_LEADING;
X	}	
X	/*
X	 * end of uuencoded file ?
X	 */
X	if (strncmp(buf, "end", 3) == 0) 
X	    return FOUND_END;
X	
X	/*
X	 * end of current file ? : get next one.
X	 */
X	if (strncmp(buf, "include", 7) == 0) {
X	    msg("Cannot handle 'include' lines -- unpack with uud");
X	    return OTHER_ERROR;
X	}
X
X	/*
X	 * trailing garbage
X	 */
X	return SKIP_TRAILING;
X    }
X    
X    rlen = cdlen[blen];
X    if (len != rlen && state == SKIP_LEADING)
X	return SKIP_LEADING;
X    
X    /*
X     * Is it the empty line before the end line ?
X     */
X    if (blen == 0) return state;
X    
X    /*
X     * Pad with blanks.
X     */
X    for (bp = buf + len, n = rlen - len; --n >= 0; ) *bp++ = blank;
X    
X    /*
X     * Verify
X     */
X    for (n = rlen, bp = buf; --n >= 0; bp++) 
X	if (trtbl[*bp] < 0) {
X	    if (state == SKIP_LEADING) return SKIP_LEADING;
X	    return DECODE_ERROR;
X	}
X    
X    /*
X     * Check for uuencodes that append a 'z' to each line....
X     */
X    if (check)
X	if (secnd) {
X	    secnd = 0;
X	    if (buf[rlen] == SEQMAX) check = 0;
X	} else if (first) {
X	    first = 0;
X	    secnd = 1;
X	    if (buf[rlen] != SEQMAX) check = 0;
X	}
X    
X    /*
X     * There we check.
X     */
X    if (check) {
X	if (buf[rlen] != seqc) {
X	    if (state == SKIP_LEADING) return SKIP_LEADING;
X	    return DECODE_ERROR;
X	}
X	
X	if (--seqc < SEQMIN) seqc = SEQMAX;
X    }
X    
X    /*
X     * output a group of 3 bytes (4 input characters).
X     * the input chars are pointed to by p, they are to
X     * be output to file f. blen is used to tell us not to
X     * output all of them at the end of the file.
X     */
X    ut = outl;
X    n = blen;
X    bp = &buf[1];
X    while (--n >= 0) {
X	*(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4;
X	if (n > 0) {
X	    *(ut++) = (trtbl[bp[1]] << 4) | (trtbl[bp[2]] >> 2);
X	    n--;
X	}
X	if (n > 0) {
X	    *(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]];
X	    n--;
X	}
X	bp += 4;
X    }
X    if (fwrite(outl, 1, blen, out) <= 0) {
X	msg("Error on writing decoded file");
X	return OTHER_ERROR;
X    }
X
X    return DECODE_TEXT;
X}
X
X
X
X/*
X * Install the table in memory for later use.
X */
Xstatic inittbls()
X{
X    register int i, j;
X    
X    /*
X     * Set up the default translation table.
X     */
X    for (i = 0; i < ' '; i++) chtbl[i] = -1;
X    for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j;
X    for (i = ' ' + 64; i < MAXCHAR; i++) chtbl[i] = -1;
X    chtbl['`'] = chtbl[' '];	/* common mutation */
X    chtbl['~'] = chtbl['^'];	/* an other common mutation */
X    blank = ' ';
X    /*
X     * set up the line length table, to avoid computing lotsa * and / ...
X     */
X    cdlen[0] = 1;
X    for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)
X	cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));
X}
X
Xstatic gettable(in)
XFILE *in;
X{
X    char buf[LINELEN];
X    register int c, n = 0;
X    register char *cpt;
X    
X    for (c = 0; c <= MAXCHAR; c++) chtbl[c] = -1;
X    
X    for (;;) {
X	
X	if (fgets(buf, sizeof buf, in) == NULL) {
X	    msg("EOF while in translation table.\n");
X	    return -1;
X	}
X	numl++;
X	if (strncmp(buf, "begin", 5) == 0) {
X	    msg("Incomplete translation table.\n");
X	    return -1;
X	}
X	cpt = buf + strlen(buf) - 1;
X	*cpt = ' ';
X	while (*(cpt) == ' ') {
X	    *cpt = 0;
X	    cpt--;
X	}
X	cpt = buf;
X	while (c = *cpt) {
X	    if (chtbl[c] != -1) {
X		msg("Duplicate char in translation table.\n");
X		return -1;
X	    }
X	    if (n == 0) blank = c;
X	    chtbl[c] = n++;
X	    if (n >= 64) return 0;
X	    cpt++;
X	}
X    }
X}
X
NO_NEWS_IS_GOOD_NEWS
chmod 0644 decode.c || echo "restore of decode.c fails"
set `wc -c decode.c`;Sum=$1
if test "$Sum" != "7241"
then echo original size 7241, current size $Sum;fi
echo "x - extracting s-dnix5-2.h (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > s-dnix5-2.h &&
X/*
X *	This version is for dnix version 5.2 on DIAB DS90-10.
X */
X
X
X/*
X *	Include header files containing the following definitions:
X *
X * 		off_t, time_t, struct stat
X */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X
X/*
X *	Define if your system has system V like ioctls
X */
X
X#define	HAVE_TERMIO			/* */
X
X/*
X *	Define to use terminfo database.
X *	Otherwise, termcap is used
X */
X
X#define	USE_TERMINFO			/* */
X
X/*
X *	Specify the library containing the termcap/terminfo access routines.
X *	Notice:  nn does not use curses.
X *	Notice:  You must also specify whether termcap or terminfo is
X *		 used when you edit config.h (see below).
X */
X
X#define	TERMLIB -lcurses
X
X/*
X *	Define HAVE_STRCHR if strchr() and strrchr() are available
X */
X
X#define HAVE_STRCHR			/* */
X
X/*
X *	Define if a signal handler has type void (see signal.h)
X */
X
X/*#define	SIGNAL_HANDLERS_ARE_VOID	/* */
X
X/*
X *	Define if signals must be set again after they are caught
X */
X
X#define	RESET_SIGNAL_WHEN_CAUGHT	/* */
X
X/*
X *	Define MICRO_ALARM to timeout in 0.1 seconds if possible
X */
X
X#define MICRO_ALARM()	alarm(1)	/* System V */
X
X/*
X *	Define if your system has BSD like job control (SIGTSTP works)
X */
X
X/* #define HAVE_JOBCONTROL			/* */
X
X/*
X *	Define if your system provides the "directory(3X)" access routines
X *
X *	If true, include the header file(s) required by the package below
X *	(remember that <sys/types.h> or equivalent is included above)
X *	Also typedef Direntry to the proper struct type.
X */
X
X#define	HAVE_DIRECTORY			/* */
X
X#include <dirent.h>			/* System V */
X
Xtypedef struct dirent Direntry;		/* System V */
X
X/*
X *	Define if your system has a mkdir() library routine
X */
X
X#define	HAVE_MKDIR			/* */
X
X/*
X *	Define HAVE_GETHOSTNAME if your system provides a BSD like 
X *	gethostname routine.
X *	Otherwise, define HAVE_UNAME if uname() is avaiable.
X *	As a final resort, define HOSTNAME to the name of your system.
X */
X
X#define	HAVE_UNAME			/* System V */
X
X/*
X *	Define DETATCH_TERMINAL to be a command sequence which 
X *	will detatch a process from the control terminal
X *	Also include files needed to perform this HERE.
X *	If not possible, just define it (empty)
X */
X
X#define	DETATCH_TERMINAL setpgrp();	/* System V */
X
X/* 
X *	Specify where the Bourne Shell is.
X */
X
X#define SHELL		"/bin/sh"
X
X/*
X *	Define AVOID_SHELL_EXEC if the system gets confused by
X *		#!/bin/sh
X *	lines in shell scripts, e.g. only reads #! and thinks it
X *	is a csh script.
X */
X
X#define AVOID_SHELL_EXEC		/* */
X
X/*
X *	Specify the default mailer to be invoked by nnmail
X */
X
X#define	MAILX		"/usr/bin/mailx"	/* SV */
X
X/*
X *	Specify the default pager & options.
X */
X
X#define	PAGER		"pg -n -s"
X
X/*
X *	Specify the default print command and options.
X */
X
X#define	PRINTER		"lp -s"
X
X
X/*
X *	Define the maximum length of any pathname that may occur
X */
X
X#define	FILENAME 	128
NO_NEWS_IS_GOOD_NEWS
chmod 0644 s-dnix5-2.h || echo "restore of s-dnix5-2.h fails"
set `wc -c s-dnix5-2.h`;Sum=$1
if test "$Sum" != "2819"
then echo original size 2819, current size $Sum;fi
echo "x - extracting s-hpux3-0.h (Text)"
sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > s-hpux3-0.h &&
X/*
X *    This version is for HP-UX 3.0 (on HP9000 Series 800)
X */
X 
X 
X/*
X *    Include header files containing the following definitions:
X *
X *         off_t, time_t, struct stat
X */
X 
X#include <sys/types.h>
X#include <sys/stat.h>
X 
X 
X/*
X *    Define if your system has system V like ioctls
X */
X 
X#define    HAVE_TERMIO            /* */
X 
X/*
X *    Define to use terminfo database.
X *    Otherwise, termcap is used
X */
X 
X#define    USE_TERMINFO            /* */
X 
X/*
X *    Specify the library (or libraries) containing the termcap/terminfo
X *    routines.
X *
X *    Notice:  nn only uses the low-level terminal access routines
X *    (i.e. it does not use curses).
X */
X 
X#define TERMLIB    -lcurses
X 
X/*
X *    Define HAVE_STRCHR if strchr() and strrchr() are available
X */
X 
X#define HAVE_STRCHR            /* */
X 
X/*
X *    Define if a signal handler has type void (see signal.h)
X */
X 
X#define    SIGNAL_HANDLERS_ARE_VOID    /* */
X 
X/*
X *    Define if signals must be set again after they are caught
X */
X 
X#define    RESET_SIGNAL_WHEN_CAUGHT    /* */
X 
X/*
X *    Define MICRO_ALARM to timeout in 0.1 seconds if possible
X */
X 
X#define MICRO_ALARM()    not_needed(0.1)  /* only used #ifndef HAVE_TERMIO */
X 
X/*
X *    Define if your system has BSD like job control (SIGTSTP works)
X */
X 
X#define HAVE_JOBCONTROL            /* */
X 
X 
X/*
X *    Define if your system has a 4.3BSD like syslog library.
X */
X 
X#define HAVE_SYSLOG
X 
X/*
X *    Define if your system provides the "directory(3X)" access routines
X *
X *    If true, include the header file(s) required by the package below
X *    (remember that <sys/types.h> or equivalent is included above)
X *    Also typedef Direntry to the proper struct type.
X */
X 
X#define    HAVE_DIRECTORY            /* */
X 
X#include <ndir.h>
X 
Xtypedef struct direct Direntry;
X 
X/*
X *    Define if your system has a mkdir() library routine
X */
X 
X#define    HAVE_MKDIR            /* */
X 
X 
X/*
X *    Define HAVE_GETHOSTNAME if your system provides a BSD like
X *    gethostname routine.
X *    Otherwise, define HAVE_UNAME if uname() is avaiable.
X *    As a final resort, define HOSTNAME to the name of your system
X *    (in config.h).
X */
X 
X#define    HAVE_GETHOSTNAME
X 
X/*
X *    Define DETATCH_TERMINAL to be a command sequence which
X *    will detatch a process from the control terminal
X *    Also include system files needed to perform this HERE.
X *    If not possible, just define it (empty)
X */
X 
X/* #include "...." */
X 
X#define    DETATCH_TERMINAL setpgrp();
X 
X 
X/*
X *    Specify where the Bourne Shell is.
X */
X 
X#define SHELL        "/bin/sh"
X 
X/*
X *    Specify the default mailer to be invoked by nnmail
X */
X 
X#define    MAILX        "/usr/bin/mailx"    /* SV */
X 
X 
X/*
X *    Specify the default pager & options.
X */
X 
X#define    PAGER        "/usr/local/bin/less"
X 
X/*
X *    Specify the default print command and options.
X */
X 
X#define    PRINTER        "/usr/bin/lp -s"
X 
X 
X/*
X *    Define the maximum length of any pathname that may occur
X */
X 
X#define    FILENAME     1024
X 
X 
X/*
X *    Define standard compiler flags here:
X */
X 
X#define COMPILER_FLAGS -O -z
X
NO_NEWS_IS_GOOD_NEWS
chmod 0644 s-hpux3-0.h || echo "restore of s-hpux3-0.h fails"
set `wc -c s-hpux3-0.h`;Sum=$1
if test "$Sum" != "3085"
then echo original size 3085, current size $Sum;fi
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0

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