NN 6.3 -- Official Patch #4 (part 01/03)

Kim F. Storm storm at texas.dk
Tue Jul 11 00:35:31 AEST 1989


This is patch #4 for nn 6.3 (part 1 of 3).

Once more the size of the patches has grown out of hands, and I have
been forced to split the patches into a three-part shell archive.
To apply the patches, you must unpack the three archives in turn
into the nn sources directory using :unshar, and then run
	patch < PATCH.4
to apply the patches.

Besides the PATCH.4 file, the following m- and s- files are also included:

			s-aux1-1.h 
	m-convex.h 
			s-fortune.h 
	m-i80286.h 	s-uport2-2.h 	
	m-sgi4D.h 	s-sgi4D.h 
	m-symmetry.h 	s-dynix3-0.h 
	m-xenix386.h	s-xenix386.h  


ABOUT PATCH #4
--------------

The rc file could be more or less zeroed out if nn was invoked while
the nnmaster was rebuilding the database after `nnadmin I' had been run.
This should no longer happen, so it will be safe to invoke nn while the
nnmaster is rebuilding the database (but it is still not recommended
practice!)

Obeying the wishes from non-nn users (and RFC 1036), the Re^n:
prefixes on response Subject: lines are not used anymore.  nn still
filters out multiple Re: prefixes, and puts just one in the Subject
line.  (Thanks to all those who voted yes to keep this nn-ism).

The article id can be included in the "In article ... ... writes:"
line by setting the `include-art-id' variable.

The variable `flow-control' can be `unset' to avoid the switching
between raw and cooked mode.  This will also avoid the flush of
type-ahead, and unfortunately also make it impossible to stop certain
actions with ^C (because tty signals are not enabled in raw mode).
Most significantly, nnadmin's V)alidate cannot be interrupted.
  It is my hope that unsetting `flow-control' will clear the problems
with nn not displaying the middle part of the screen in some cases.

The auto-kill/auto-selections made with the K command will now have an
instant effect on the current menu - killed articles will disappear
and selected articles will be high-lighted.

The 'l' leave-article command now behaves more intelligently.  It will
not mark articles as selected instantly - instead it completes the
current selection in the group, and then it will auto-select the
left-over articles and start reading mode on those.  Left-over
articles will be marked with a '+' after the article id on the menu.

The interrim 'left-over' status is also saved between invokations of nn.

The '~' command will not deselect left-over articles.  To do this,
the '~' command must be executed twice in succession.

Furthermore, if ONLY auto-selections have been performed in a group,
the selections will not be saved for the next invokation (which will
just redo the auto-selections itself).

There is a new option to nnmaster (-y) which will cause nnmaster
to perform several attempts to open a news article before regarding
it as missing (expired/cancelled).  This may happen in some flaky
network systems, i.e. when the master is accessing news via NFS or
perhaps even NNTP.

The new -f option to nnmaster will prevent nnmaster started in daemon
mode (-r) from going into background operation, i.e. -fr will not
fork/exit.

It is now possible to clear global group flags from nnadmin (Thanks to
Bernd-Gunter Nitzler).

Using `?' when prompted for a group by `nn -g' no longer messes up the screen.

The `CR' {line+1} and `d' {page+1/2} commands now work properly.

Quite a number of type conversions have been added in the hope that
nn will work on 16 bit machines (Thanks to Wietse Z. Venema and Miek
Grenier).

The Summary: line can now be included in header-lines (code Y).

There are new mail-header and news-header variables which may contain
additional customized headers to be included in the mail and news you send,
e.g.
	set mail-header Slyrf: Heck yes!;Heck: Slyrf No!
to include the lines
	Slyrf: Heck yes!
	Heck: Slyrf No!
in (all) your mail headers.

There is a new variable default-distribution which can be set to
give the default distribution for articles posted using the :post 
command.  If set it will be suggested instead of the default main group
such as `comp' when posting to comp.unix.questions.  This may be
useful to set in the global init file, e.g.
	set default-distribution local

nncheck caused big problems if a user invoked it before having run nn
at least once (to create the rc file etc.) - this is now prohibited.

The `find' command can now be used in menu mode also (bound to =).
It prompts for a regular expression, and will select all articles
ON THE MENU whose subject matches the expression.

The '*' on selected articles is now placed correctly on dumb terminals
without stand-out mode.

The dependencies in xmakefile have been updated.

The `:show kill' command now shows the original regular expressing
rather than just *regexp*.

++Kim Storm

#!/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.4
#	  s-aux1-1.h
#	  s-dynix3-0.h
#	  s-fortune.h
#	  s-sgi4D.h
#	  s-uport2-2.h
#	  s-xenix386.h
#	  m-convex.h
#	  m-i80286.h
#	  m-sgi4D.h
#	  m-symmetry.h
#	  m-xenix386.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.4 (Text)"
sed 's/^X//' << 'NN_IS_BETTER' > PATCH.4 &&
X*** /usr/storm/nn6.3.3/patchlevel.h	Fri Jun 30 11:30:40 1989
X--- patchlevel.h	Mon Jul 10 12:40:46 1989
X***************
X*** 11,17 ****
X   *	1989-06-06:  Patch 1: rc.c
X   *	1989-06-28:  Patch 2: several files
X   *	1989-06-30:  Patch 3: several files
X   */
X  
X! #define PATCHLEVEL 3
X  
X--- 11,18 ----
X   *	1989-06-06:  Patch 1: rc.c
X   *	1989-06-28:  Patch 2: several files
X   *	1989-06-30:  Patch 3: several files
X+  *	1989-07-10:  Patch 4: several files
X   */
X  
X! #define PATCHLEVEL 4
X  
X
X*** /usr/storm/nn6.3.0/admin.c	Thu Jun  1 11:10:41 1989
X--- admin.c	Wed Jul  5 14:54:49 1989
X***************
X*** 34,40 ****
X          raw();
X  	c = get_c();
X  	no_raw();
X! 	printf("%c\n\n\r", c);
X      }
X      
X      if (islower(c)) 
X--- 34,43 ----
X          raw();
X  	c = get_c();
X  	no_raw();
X! 	if (c == K_interrupt)
X! 	    s_keyboard++;
X! 	else
X! 	    printf("%c\n\n\r", c);
X      }
X      
X      if (islower(c)) 
X***************
X*** 49,55 ****
X  long min_val, max_val;
X  {
X      char buf[100];
X!     int val;
X      
X   loop:
X      
X--- 52,58 ----
X  long min_val, max_val;
X  {
X      char buf[100];
X!     long val;
X      
X   loop:
X      
X***************
X*** 56,63 ****
X      printf("%s %ld..%ld (or all): ", prompt_str, min_val, max_val);
X      fl;
X      gets(buf);
X!     if (buf[0] == 'a')
X! 	return -1;
X  
X      val =  atol(buf);
X      if (val < min_val || val > max_val) goto loop;
X--- 59,66 ----
X      printf("%s %ld..%ld (or all): ", prompt_str, min_val, max_val);
X      fl;
X      gets(buf);
X!     if (buf[0] == 'a' || buf[0] == NUL)
X! 	return -1L;
X  
X      val =  atol(buf);
X      if (val < min_val || val > max_val) goto loop;
X***************
X*** 181,187 ****
X  static master_admin()
X  {
X      register char c;
X!     int cur_group, value;
X      register group_header *gh;
X  
X      for (;;) {
X--- 184,191 ----
X  static master_admin()
X  {
X      register char c;
X!     int cur_group;
X!     long value;
X      register group_header *gh;
X  
X      for (;;) {
X***************
X*** 190,196 ****
X  "MASTER")) {
X  
X  	 case 'G':
X! 	    cur_group = get_entry("Group number",
X  				  0L, (long)(master.number_of_groups - 1));
X  	    if (cur_group >= 0)
X  		dump_m_entry(&active_groups[cur_group]);
X--- 194,200 ----
X  "MASTER")) {
X  
X  	 case 'G':
X! 	    cur_group = (int)get_entry("Group number",
X  				  0L, (long)(master.number_of_groups - 1));
X  	    if (cur_group >= 0)
X  		dump_m_entry(&active_groups[cur_group]);
X***************
X*** 219,227 ****
X  	 case 'O':
X  	    c = get_cmd("r)epeat_delay  e)xpire_level", "OPTION");
X  	    if (c != 'r' && c != 'e') break;
X! 	    value = get_entry("Option value", 1, 10000);
X  	    if (value < 0) break;
X! 	    send_master(c, (long)value, 0L);
X  	    break;
X  	    
X  	 case 'S':
X--- 223,231 ----
X  	 case 'O':
X  	    c = get_cmd("r)epeat_delay  e)xpire_level", "OPTION");
X  	    if (c != 'r' && c != 'e') break;
X! 	    value = get_entry("Option value", 1L, 10000L);
X  	    if (value < 0) break;
X! 	    send_master(c, value, 0L);
X  	    break;
X  	    
X  	 case 'S':
X***************
X*** 586,596 ****
X      article_number		first_article, next_article, this_art;
X      int				n, was_digest;
X      char			buffer[512];
X-     
X-     if (init_group(gh) <= 0)
X- 	printf("cannot access group %s\n", gh->group_name);
X  
X!     update_group(gh);
X      
X      if (validate)
X  	first_article = gh->first_l_article;
X--- 590,602 ----
X      article_number		first_article, next_article, this_art;
X      int				n, was_digest;
X      char			buffer[512];
X  
X!     if (!validate) {
X! 	if (init_group(gh) <= 0)
X! 	    printf("cannot access group %s\n", gh->group_name);
X! 
X! 	update_group(gh);
X!     }
X      
X      if (validate)
X  	first_article = gh->first_l_article;
X***************
X*** 600,606 ****
X  			      (long)gh->last_l_article);
X  
X      if (first_article < 0) first_article = gh->first_l_article;
X! 
X      ix = open_data_file(gh, 'x', OPEN_READ);
X      if (ix == NULL) {
X  	if (verbose) printf("NO INDEX FILE\n");
X--- 606,613 ----
X  			      (long)gh->last_l_article);
X  
X      if (first_article < 0) first_article = gh->first_l_article;
X!     if (first_article <= 0) first_article = 1;
X!     
X      ix = open_data_file(gh, 'x', OPEN_READ);
X      if (ix == NULL) {
X  	if (verbose) printf("NO INDEX FILE\n");
X***************
X*** 906,911 ****
X--- 913,919 ----
X  	if (init_group(gh) <= 0) continue; /* no directory */
X  
X  	if (verbose) { printf("\r%s: ", gh->group_name); clrline(); }
X+ 	update_group(gh);
X  	
X  	if (gh->group_flag & G_BLOCKED) {
X  	    if (verbose) printf("BLOCKED\n");
X
X*** /usr/storm/nn6.3.3/answer.c	Fri Jun 30 11:30:41 1989
X--- answer.c	Wed Jul  5 17:16:05 1989
X***************
X*** 5,13 ****
X  
X  extern char *temp_file;
X  
X! char *news_record	= NULL;
X! char *mail_record	= NULL;
X  
X  
X  #define INCL_MARK_SIZE	10
X  
X--- 5,18 ----
X  
X  extern char *temp_file;
X  
X! export char *default_distribution = NULL;
X! export char *extra_mail_headers	= NULL;
X! export char *extra_news_headers	= NULL;
X! export char *mail_record	= NULL;
X! export char *news_record	= NULL;
X  
X+ export int nn_re_style		= 0;	/* use Re^n: in replies */
X+ export int include_art_id	= 0;
X  
X  #define INCL_MARK_SIZE	10
X  
X***************
X*** 97,104 ****
X  	
X  	ng_line(t);
X  	ref_line(t);
X! 
X! 	end_header(t);
X  
X  	if (incl) {
X  	    fprintf(t, "In %s you write:\n", current_group->group_name);
X--- 102,109 ----
X  	
X  	ng_line(t);
X  	ref_line(t);
X!     
X! 	end_header(t, extra_mail_headers);
X  
X  	if (incl) {
X  	    fprintf(t, "In %s you write:\n", current_group->group_name);
X***************
X*** 135,145 ****
X  	}
X  
X  	ref_line(t);
X! 
X! 	end_header(t);
X  
X  	if (incl) {
X  	    if (news.ng_from) {
X  		fprintf(t, "%s writes:\n", news.ng_from);
X  		ed_line++;
X  	    } else
X--- 140,154 ----
X  	}
X  
X  	ref_line(t);
X!     
X! 	end_header(t, extra_news_headers);
X  
X  	if (incl) {
X  	    if (news.ng_from) {
X+ 		if (include_art_id && news.ng_ident)
X+ 		    fprintf(t, "In %s %s ", 
X+ 			    ah->flag & A_DIGEST ? "digest" : "article",
X+ 			    news.ng_ident);
X  		fprintf(t, "%s writes:\n", news.ng_from);
X  		ed_line++;
X  	    } else
X***************
X*** 179,185 ****
X  
X  	subj_line(t, -1, str, (char *)NULL);
X  
X! 	end_header(t);
X     
X  	if (incl) {
X  	    prompt("\1Edit\1 forwarded message? ");
X--- 188,194 ----
X  
X  	subj_line(t, -1, str, (char *)NULL);
X  
X! 	end_header(t, extra_mail_headers);
X     
X  	if (incl) {
X  	    prompt("\1Edit\1 forwarded message? ");
X***************
X*** 325,332 ****
X      if (str == NULL) return 0;
X      strcpy(keywords, str);
X      
X!     strcpy(distribution, group_name);
X!     if (str = strchr(distribution, '.')) *str = NUL;
X      
X      prompt("\1Distribution\1 (default '%s') ", distribution);
X      str = get_s(NONE, NONE, NONE, NO_COMPLETION);
X--- 334,345 ----
X      if (str == NULL) return 0;
X      strcpy(keywords, str);
X      
X!     if (default_distribution != NULL)
X! 	strcpy(distribution, default_distribution);
X!     else {
X! 	strcpy(distribution, group_name);
X! 	if (str = strchr(distribution, '.')) *str = NUL;
X!     }
X      
X      prompt("\1Distribution\1 (default '%s') ", distribution);
X      str = get_s(NONE, NONE, NONE, NO_COMPLETION);
X***************
X*** 348,354 ****
X  	fprintf(t, "Keywords: %s\n", keywords);
X  	ed_line++;
X      }
X!     fputc(NL, t);
X      fputc(NL, t);
X  
X      fclose(t);
X--- 361,368 ----
X  	fprintf(t, "Keywords: %s\n", keywords);
X  	ed_line++;
X      }
X! 
X!     end_header(t, extra_news_headers);
X      fputc(NL, t);
X  
X      fclose(t);
X***************
X*** 367,373 ****
X      
X      fputs("Subject: ", t);
X  
X!     if (re == 0) 
X  	fputs("Re: ", t);
X      else if (re > 0)
X  	fprintf(t, "Re^%d: ", re + 1);
X--- 381,387 ----
X      
X      fputs("Subject: ", t);
X  
X!     if (re == 0 || !nn_re_style) 
X  	fputs("Re: ", t);
X      else if (re > 0)
X  	fprintf(t, "Re^%d: ", re + 1);
X***************
X*** 427,435 ****
X      ed_line++;
X  }
X  
X! static end_header(t)
X  FILE *t;
X  {
X      fputc(NL, t);
X      ed_line++;
X  }
X--- 441,463 ----
X      ed_line++;
X  }
X  
X! static end_header(t, extra_headers)
X  FILE *t;
X+ register char *extra_headers;
X  {
X+     if (extra_headers != NULL && *extra_headers != NUL) {
X+ 	while (*extra_headers != NUL) {
X+ 	    if (*extra_headers == ';') {
X+ 		if (*++extra_headers == NUL) break;
X+ 		fputc(NL, t);
X+ 		ed_line++;
X+ 	    } else
X+ 		fputc(*extra_headers++, t);
X+ 	}
X+ 	fputc(NL, t);
X+ 	ed_line++;
X+     }
X+     
X      fputc(NL, t);
X      ed_line++;
X  }
X
X*** /usr/storm/nn6.3.0/articles.c	Thu Jun  1 11:10:41 1989
X--- articles.c	Sat Jul  8 17:10:23 1989
X***************
X*** 29,39 ****
X  static thunk *current_str_t = &dummy_str_t;
X  static thunk *first_art_t = &dummy_art_t;
X  static thunk *current_art_t = &dummy_art_t;
X! static int   cur_str_size = 0, cur_art_size = 0;
X  static char *next_str;
X  static article_header *next_art, **art_array;
X  
X! static unsigned max_articles = 0, mem_offset = 0;
X  
X  /*
X   * allocate one article header
X--- 29,39 ----
X  static thunk *current_str_t = &dummy_str_t;
X  static thunk *first_art_t = &dummy_art_t;
X  static thunk *current_art_t = &dummy_art_t;
X! static long  cur_str_size = 0, cur_art_size = 0;
X  static char *next_str;
X  static article_header *next_art, **art_array;
X  
X! static article_number max_articles = 0, mem_offset = 0;
X  
X  /*
X   * allocate one article header
X***************
X*** 54,60 ****
X      mem_check(ptr, (int)size, chk_msg);
X      
X      new = (thunk *)calloc(1, sizeof(thunk));
X!     mem_check(new, sizeof(thunk), "memory thunk");
X      
X      new->next_thunk = t->next_thunk;
X      t->next_thunk = new;
X--- 54,60 ----
X      mem_check(ptr, (int)size, chk_msg);
X      
X      new = (thunk *)calloc(1, sizeof(thunk));
X!     mem_check((char *)new, sizeof(thunk), "memory thunk");
X      
X      new->next_thunk = t->next_thunk;
X      t->next_thunk = new;
X***************
X*** 99,105 ****
X  	if (current_str_t->next_thunk == NULL)
X  	    new_thunk(current_str_t, 
X  		      malloc(STR_THUNK_SIZE),
X! 		      STR_THUNK_SIZE,
X  		      "string bytes");
X  
X  	current_str_t = current_str_t->next_thunk;
X--- 99,105 ----
X  	if (current_str_t->next_thunk == NULL)
X  	    new_thunk(current_str_t, 
X  		      malloc(STR_THUNK_SIZE),
X! 		      (long)STR_THUNK_SIZE,
X  		      "string bytes");
X  
X  	current_str_t = current_str_t->next_thunk;
X***************
X*** 226,232 ****
X  	}
X  	art_array = (article_header **)
X  	    calloc(max_articles, sizeof(article_header **));
X! 	mem_check(art_array, (int)max_articles, "article headers");
X  	while (--n >= 0) art_array[n] = *--articles;
X  	articles = art_array + mem_offset;
X      }
X--- 226,232 ----
X  	}
X  	art_array = (article_header **)
X  	    calloc(max_articles, sizeof(article_header **));
X! 	mem_check((char *)art_array, (int)max_articles, "article headers");
X  	while (--n >= 0) art_array[n] = *--articles;
X  	articles = art_array + mem_offset;
X      }
X***************
X*** 322,328 ****
X      
X      if (n_articles <= 1) return;
X  
X!     qsort(articles, n_articles, sizeof(article_header *), article_comp);
X  	
X      for (n = n_articles - 1, app = articles + 1; --n >= 0; app++)
X  	if (article_equal(app, app - 1)) (**app).flag |= A_SAME;
X--- 322,328 ----
X      
X      if (n_articles <= 1) return;
X  
X!     qsort((char *)articles, (int)n_articles, sizeof(article_header *), article_comp);
X  	
X      for (n = n_articles - 1, app = articles + 1; --n >= 0; app++)
X  	if (article_equal(app, app - 1)) (**app).flag |= A_SAME;
X***************
X*** 332,343 ****
X  static offset_cmp(a, b)
X  article_header **a, **b;
X  {
X!     register i;
X      
X!     if (i = (int)((*a)->a_number - (*b)->a_number))
X! 	return i;
X!     
X!     return (int)((*a)->fpos - (*b)->fpos);
X  }
X  
X  static age_cmp(ah1, ah2)
X--- 332,343 ----
X  static offset_cmp(a, b)
X  article_header **a, **b;
X  {
X!     register long i;
X      
X!     if ((i = (int)((*a)->a_number - (*b)->a_number)) == 0)
X! 	i = (*a)->fpos - (*b)->fpos;
X! 
X!     return (i > 0) ? 1 : (i < 0) ? -1 : 0;
X  }
X  
X  static age_cmp(ah1, ah2)
X***************
X*** 351,363 ****
X  
X  unsort_articles(arrival)
X  {
X!     register int i;
X      
X      for (i = n_articles; --i >= 0;)
X  	articles[i]->flag &= ~A_SAME;
X      
X      if (n_articles <= 1) return;
X!     qsort(articles, n_articles, sizeof(article_header *), 
X  	  arrival ? offset_cmp : age_cmp);
X  }
X  
X--- 351,412 ----
X  
X  unsort_articles(arrival)
X  {
X!     register article_number i;
X      
X      for (i = n_articles; --i >= 0;)
X  	articles[i]->flag &= ~A_SAME;
X      
X      if (n_articles <= 1) return;
X!     qsort((char *)articles, (int)n_articles, sizeof(article_header *), 
X  	  arrival ? offset_cmp : age_cmp);
X  }
X  
X+ /*
X+  * Eliminate articles with the A_KILL flag set preserving the present ordering.
X+  * This will only release the last entries in the articles array.
X+  * Neither strings nor articles headers are released.
X+  */
X+ 
X+ elim_articles(list, list_lgt)
X+ register article_number *list;
X+ int list_lgt;
X+ {
X+     register article_header **srca, **desta;
X+     register article_number n, count;
X+     int changed, llen;
X+     
X+     count = 0;
X+     changed = 0, llen = 0;
X+     for (n = 0, srca = desta = articles; n < n_articles; n++, srca++) {
X+ 	if ((*srca)->flag & A_KILL) {
X+ 	    if (list_lgt > 0) {
X+ 		if (n < *list) {
X+ 		    if (llen) changed = 1;
X+ 		} else
X+ 		if (n == *list) {
X+ 		    if (llen) {
X+ 			llen++;
X+ 			list_lgt--;
X+ 			*list++ = -1;
X+ 		    } else
X+ 			++(*list);
X+ 		    changed = 1;
X+ 		}
X+ 	    }
X+ 	    continue;
X+ 	}
X+ 	if (list_lgt > 0 && n == *list) {
X+ 	    *list++ = count;
X+ 	    list_lgt--;
X+ 	    llen++;
X+ 	}
X+ 	count++;
X+ 	*desta++ = *srca;
X+     }
X+     if (list_lgt > 0) {
X+ 	if (!llen) *list = 0;
X+ 	changed = 1;
X+     }
X+     n_articles = count;
X+     return changed;
X+ }
X
X*** /usr/storm/nn6.3.3/collect.c	Fri Jun 30 11:30:42 1989
X--- collect.c	Tue Jul  4 18:21:16 1989
X***************
X*** 13,22 ****
X   *	On entry, init_group has been called to setup the proper environment
X   */
X  
X! collect_group(gh)
X  register group_header *gh;
X  {
X!     int article_count, temp;
X      article_number start_collect;
X      
X      if (gh->last_l_article == 0) {
X--- 13,22 ----
X   *	On entry, init_group has been called to setup the proper environment
X   */
X  
X! long collect_group(gh)
X  register group_header *gh;
X  {
X!     long article_count, temp;
X      article_number start_collect;
X      
X      if (gh->last_l_article == 0) {
X
X*** /usr/storm/nn6.3.3/data.h	Fri Jun 30 11:30:43 1989
X--- data.h	Sat Jul  8 16:21:38 1989
X***************
X*** 36,43 ****
X  
X      int32		group_flag;
X  
X! #	define MF(n)	(1<<(n-1))
X! #	define CF(n)	(1<<(n+15))
X  
X  #	define G_MASTER_FLAGS	(MF(17)-1) /* flags that are saved on file */
X  
X--- 36,43 ----
X  
X      int32		group_flag;
X  
X! #	define MF(n)	(((int32)1)<<(n-1))
X! #	define CF(n)	(((int32)1)<<(n+15))
X  
X  #	define G_MASTER_FLAGS	(MF(17)-1) /* flags that are saved on file */
X  
X***************
X*** 122,128 ****
X      
X      int32	flag;		/* flags: 			*/
X  
X! #	define AF(n) (1<<(n-1))
X  
X  #	define A_SELECT   	AF(1)	/* article has been selected	*/
X  #	define A_SAME	    	AF(2)	/* same subject as prev. article */
X--- 122,128 ----
X      
X      int32	flag;		/* flags: 			*/
X  
X! #	define AF(n) (((int32)1)<<(n-1))
X  
X  #	define A_SELECT   	AF(1)	/* article has been selected	*/
X  #	define A_SAME	    	AF(2)	/* same subject as prev. article */
X***************
X*** 132,137 ****
X--- 132,142 ----
X  #	define A_FOLDER		AF(6)	/* article file = "folder_path"	*/
X  #	define A_CANCEL		AF(7)	/* folder entry cancelled	*/
X  #	define A_SEEN		AF(8)	/* article presented on menu	*/
X+ #	define A_KILL		AF(9)	/* eliminate article		*/
X+ #	define A_AUTO		AF(10)	/* article was auto selected	*/
X+ #	define A_READ		AF(11)	/* article has been read	*/
X+ #	define A_LEAVE		AF(12)	/* marked for later activity	*/
X+ #	define A_LEAVE_NEXT	AF(13)	/* marked for next invokation	*/
X  
X  #	define A_ST_FILED	AF(16)	/* articles is saved		*/
X  #	define A_ST_REPLY	AF(17)	/* sent reply to article	*/
X
X*** /usr/storm/nn6.3.0/db.c	Thu Jun  1 11:10:42 1989
X--- db.c	Wed Jul  5 15:36:56 1989
X***************
X*** 29,36 ****
X      
X      current_group = gh;
X  
X-     if (gh->group_flag & G_NO_DIRECTORY) return 0;
X- 
X      if (gh->group_flag & G_FOLDER) {
X  	group_position = NULL;
X  	group_file_name = NULL;
X--- 29,34 ----
X***************
X*** 47,52 ****
X--- 45,51 ----
X  	if (is_master) 
X  	    group_position = group_path_name;
X  	else {
X+ 	    if (gh->group_flag & G_NO_DIRECTORY) return 0;
X  	    strcpy(group_path_name, news_directory);
X  	    group_position = group_path_name + strlen(group_path_name);
X  	    *group_position++ = '/';
X***************
X*** 109,115 ****
X  open_master(mode)
X  {
X      FILE 			*g;
X!     int 			entries, n, cur_group;
X      char 			*strings;
X      register group_header 	*gh;
X      static int 			first_open = 1;
X--- 108,115 ----
X  open_master(mode)
X  {
X      FILE 			*g;
X!     int 			n, cur_group;
X!     unsigned			entries;
X      char 			*strings;
X      register group_header 	*gh;
X      static int 			first_open = 1;
X***************
X*** 133,141 ****
X  	
X      sorted_groups = (group_header **) 
X  	calloc(entries, sizeof(group_header *));
X!     mem_check(sorted_groups, entries, "sorted group header pointers");
X  
X!     strings = malloc((int)master.next_group_write_offset);
X      mem_check(strings, (int)master.next_group_write_offset, 
X  	      "bytes for group names");
X  
X--- 133,141 ----
X  	
X      sorted_groups = (group_header **) 
X  	calloc(entries, sizeof(group_header *));
X!     mem_check((char *)sorted_groups, entries, "sorted group header pointers");
X  
X!     strings = malloc((unsigned)master.next_group_write_offset);
X      mem_check(strings, (int)master.next_group_write_offset, 
X  	      "bytes for group names");
X  
X***************
X*** 177,183 ****
X  update_group(gh)
X  group_header *gh;
X  {
X!     int flag;
X  
X      flag = gh->group_flag & ~G_MASTER_FLAGS;
X  
X--- 177,183 ----
X  update_group(gh)
X  group_header *gh;
X  {
X!     int32 flag;
X  
X      flag = gh->group_flag & ~G_MASTER_FLAGS;
X  
X***************
X*** 200,206 ****
X  
X  sort_groups()
X  {
X!     qsort(sorted_groups, master.number_of_groups,
X  	  sizeof(group_header *), group_name_cmp);
X  }
X  
X--- 200,206 ----
X  
X  sort_groups()
X  {
X!     qsort((char *)sorted_groups, (unsigned)master.number_of_groups,
X  	  sizeof(group_header *), group_name_cmp);
X  }
X  
X***************
X*** 331,337 ****
X      if (fwrite(buf, sizeof(net_long), MASTER_FIELDS, f) != MASTER_FIELDS) return 0;
X  #else
X  
X!     if (fwrite(masterp, sizeof(master_header), 1, f) != 1) return 0;
X  #endif
X      return 1;
X  }
X--- 331,337 ----
X      if (fwrite(buf, sizeof(net_long), MASTER_FIELDS, f) != MASTER_FIELDS) return 0;
X  #else
X  
X!     if (fwrite((char *)masterp, sizeof(master_header), 1, f) != 1) return 0;
X  #endif
X      return 1;
X  }
X***************
X*** 397,403 ****
X      if (n >= 0)
X  	fseek(f, (off_t)(sizeof(master_header) + SAVED_GROUP_HEADER_SIZE(*gh) * n), 0);
X  
X!     if (fwrite(gh, SAVED_GROUP_HEADER_SIZE(*gh), 1, f) != 1)
X  	return 0;
X  #endif
X  
X--- 397,403 ----
X      if (n >= 0)
X  	fseek(f, (off_t)(sizeof(master_header) + SAVED_GROUP_HEADER_SIZE(*gh) * n), 0);
X  
X!     if (fwrite((char *)gh, SAVED_GROUP_HEADER_SIZE(*gh), 1, f) != 1)
X  	return 0;
X  #endif
X  
X***************
X*** 432,438 ****
X      if (offset) *offset += ARTICLE_FIELDS * sizeof(net_long);
X  #else
X      
X!     if (fread(dh, sizeof(data_header), 1, f) != 1) return 0;
X      if (offset) *offset += sizeof(data_header);
X  #endif
X      return 1;
X--- 432,438 ----
X      if (offset) *offset += ARTICLE_FIELDS * sizeof(net_long);
X  #else
X      
X!     if (fread((char *)dh, sizeof(data_header), 1, f) != 1) return 0;
X      if (offset) *offset += sizeof(data_header);
X  #endif
X      return 1;
X***************
X*** 462,468 ****
X  	return 0;
X  #else
X      
X!     if (fwrite(dh, sizeof(data_header), 1, f) != 1) return 0;
X  
X  #endif
X  
X--- 462,468 ----
X  	return 0;
X  #else
X      
X!     if (fwrite((char *)dh, sizeof(data_header), 1, f) != 1) return 0;
X  
X  #endif
X  
X
X*** /usr/storm/nn6.3.0/execute.c	Thu Jun  1 11:10:42 1989
X--- execute.c	Wed Jul  5 16:52:17 1989
X***************
X*** 18,24 ****
X      sig_type  (*quit)(), (*intr)(), (*cont)();
X      extern int errno;
X      
X!     was_raw = no_raw();
X      
X      while ((pid = fork()) == -1) sleep(1);
X      
X--- 18,24 ----
X      sig_type  (*quit)(), (*intr)(), (*cont)();
X      extern int errno;
X      
X!     was_raw = unset_raw();
X      
X      while ((pid = fork()) == -1) sleep(1);
X      
X***************
X*** 121,127 ****
X  {
X      int was_raw;
X      
X!     was_raw = no_raw();
X      gotoxy(0, Lines-1);
X      clrline();
X  
X--- 121,127 ----
X  {
X      int was_raw;
X      
X!     was_raw = unset_raw();
X      gotoxy(0, Lines-1);
X      clrline();
X  
X
X*** /usr/storm/nn6.3.0/expire.c	Thu Jun  1 11:10:42 1989
X--- expire.c	Tue Jul  4 18:21:15 1989
X***************
X*** 15,21 ****
X      goto error_handler; \
X  }
X  
X! expire_group(gh)
X  register group_header *gh;
X  {
X      FILE *old_x, *old_d;
X--- 15,21 ----
X      goto error_handler; \
X  }
X  
X! long expire_group(gh)
X  register group_header *gh;
X  {
X      FILE *old_x, *old_d;
X
X*** /usr/storm/nn6.3.2/folder.c	Wed Jun 28 20:07:46 1989
X--- folder.c	Tue Jul  4 18:11:08 1989
X***************
X*** 320,326 ****
X      }
X      closedir(dirp);
X      *comp = (char *)0;
X!     qsort((char *)completions, comp - completions, sizeof(char *), sort_directory);
X      comp_iterator = completions;
X      comp_help = completions;
X      
X--- 320,326 ----
X      }
X      closedir(dirp);
X      *comp = (char *)0;
X!     qsort((char *)completions, (unsigned)(comp - completions), sizeof(char *), sort_directory);
X      comp_iterator = completions;
X      comp_help = completions;
X      
X***************
X*** 527,533 ****
X      register int c;
X      register long cnt;
X      register article_header *ah, **ahp;
X!     register int n;
X      
X      if ((src = fopen(group_path_name, "r")) == NULL) {
X  	msg("Cannot open %s", group_path_name);
X--- 527,533 ----
X      register int c;
X      register long cnt;
X      register article_header *ah, **ahp;
X!     register article_number n;
X      
X      if ((src = fopen(group_path_name, "r")) == NULL) {
X  	msg("Cannot open %s", group_path_name);
X
X*** /usr/storm/nn6.3.0/global.c	Thu Jun  1 11:10:43 1989
X--- global.c	Tue Jul  4 21:02:28 1989
X***************
X*** 58,63 ****
X--- 58,70 ----
X  }
X  #endif
X  
X+ /*
X+  * who:
X+  *	0	nn
X+  *	1	nnmaster
X+  *	2	nnadmin
X+  *	3	nncheck
X+  */
X  
X  init_global(who)
X  int who;
X***************
X*** 84,90 ****
X      if (is_master) {
X  	signal(SIGINT,  catch_hangup);
X  	signal(SIGQUIT, catch_hangup);
X! 	return;
X      }
X      
X      signal(SIGINT,  catch_keyboard);
X--- 91,97 ----
X      if (is_master) {
X  	signal(SIGINT,  catch_hangup);
X  	signal(SIGQUIT, catch_hangup);
X! 	return 0;
X      }
X      
X      signal(SIGINT,  catch_keyboard);
X***************
X*** 98,109 ****
X  
X      nn_directory = mk_file_name(home_directory, ".nn");
X      
X!     if (!file_exist(nn_directory, "drwx"))
X  	mkdir(nn_directory, 0755);	/* should check here */
X! 
X      if ((env = getenv("TMPDIR")) == NULL) env = TMP_DIRECTORY;
X      temp_file = mk_file_name(env, "nn.XXXXXX");	/* dies in ANSI C! */
X      mktemp(temp_file);
X  }
X  
X  /*
X--- 105,119 ----
X  
X      nn_directory = mk_file_name(home_directory, ".nn");
X      
X!     if (who != 2 && !file_exist(nn_directory, "drwx")) {
X! 	if (who == 3) return -1;
X  	mkdir(nn_directory, 0755);	/* should check here */
X!     }
X!     
X      if ((env = getenv("TMPDIR")) == NULL) env = TMP_DIRECTORY;
X      temp_file = mk_file_name(env, "nn.XXXXXX");	/* dies in ANSI C! */
X      mktemp(temp_file);
X+     return 0;
X  }
X  
X  /*
X***************
X*** 369,381 ****
X  log_entry(va_alist)
X  va_dcl
X  {
X!     int type;
X      va_list ap;
X  
X      va_start(ap);
X      type = va_arg1(int);
X!     enter_log(type, va_args2toN);
X      va_end(ap);
X  }
X  
X  #ifdef HAVE_SYSLOG
X--- 379,392 ----
X  log_entry(va_alist)
X  va_dcl
X  {
X!     int type, rval;
X      va_list ap;
X  
X      va_start(ap);
X      type = va_arg1(int);
X!     rval = enter_log(type, va_args2toN);
X      va_end(ap);
X+     return rval;
X  }
X  
X  #ifdef HAVE_SYSLOG
X
X*** /usr/storm/nn6.3.3/group.c	Fri Jun 30 11:30:44 1989
X--- group.c	Sat Jul  8 15:05:35 1989
X***************
X*** 9,15 ****
X  #include "menu.h"
X  #include "keymap.h"
X  #include "regexp.h"
X! 
X  
X  export int  dont_split_digests = 0;
X  export int  dont_sort_articles = 0;
X--- 9,17 ----
X  #include "menu.h"
X  #include "keymap.h"
X  #include "regexp.h"
X! #ifdef HAVE_SYSLOG
X! #include <syslog.h>
X! #endif
X  
X  export int  dont_split_digests = 0;
X  export int  dont_sort_articles = 0;
X***************
X*** 150,156 ****
X  	submask++;
X  	if (subpattern != NULL) {
X  	    if (strncmp(submask, subptext, 80) != 0) {
X! 		free(subpattern);
X  		subpattern = NULL;
X  	    }
X  	}
X--- 152,158 ----
X  	submask++;
X  	if (subpattern != NULL) {
X  	    if (strncmp(submask, subptext, 80) != 0) {
X! 		free((char *)subpattern);
X  		subpattern = NULL;
X  	    }
X  	}
X***************
X*** 162,168 ****
X  	submask = NULL;
X      } else
X  	if (subpattern != NULL) {
X! 	    free(subpattern);
X  	    subpattern = NULL;
X  	}
X      
X--- 164,170 ----
X  	submask = NULL;
X      } else
X  	if (subpattern != NULL) {
X! 	    free((char *)subpattern);
X  	    subpattern = NULL;
X  	}
X      
X***************
X*** 287,293 ****
X      if ((flags & DONT_SORT_ARTICLES) == 0)
X  	sort_articles();
X      
X!     return n_articles;
X  }
X  
X  static article_number current_first_article;
X--- 289,295 ----
X      if ((flags & DONT_SORT_ARTICLES) == 0)
X  	sort_articles();
X      
X!     return n_articles > 0 ? 1 : 0;
X  }
X  
X  static article_number current_first_article;
X***************
X*** 402,408 ****
X  	if (submask == NULL && !also_read_articles) {
X  	    if (has_selection(gh, &current_first_article, &last_article)) {
X  		status = access_group(gh, current_first_article, last_article,
X! 				      DONT_SORT_ARTICLES, (char *)NULL, do_kill);
X  		do_selections(status >= 0 && n_articles);
X  		if (status < 0) goto access_exception;
X  		if (n_articles) {
X--- 404,410 ----
X  	if (submask == NULL && !also_read_articles) {
X  	    if (has_selection(gh, &current_first_article, &last_article)) {
X  		status = access_group(gh, current_first_article, last_article,
X! 				      DONT_SORT_ARTICLES, (char *)NULL, 0);
X  		do_selections(status >= 0 && n_articles);
X  		if (status < 0) goto access_exception;
X  		if (n_articles) {
X***************
X*** 433,443 ****
X   access_exception:
X  
X      if (status < 0) {
X! 	if (status == -1)
X  	    msg("DATABASE CORRUPTED FOR GROUP %s", gh->group_name);
X! /*	else
X! 	    msg("Group %s is blocked - try again later", gh->group_name);
X! */
X  	menu_return( ME_NEXT );
X      }
X      
X--- 435,451 ----
X   access_exception:
X  
X      if (status < 0) {
X! 	if (status == -1) {
X! 	    clrdisp();
X  	    msg("DATABASE CORRUPTED FOR GROUP %s", gh->group_name);
X! #ifdef HAVE_SYSLOG
X! 	    openlog("nn", LOG_CONS, LOG_DAEMON);
X! 	    syslog(LOG_ALERT, "database corrupted for newsgroup %s.",
X! 		   gh->group_name);
X! 	    closelog();
X! #endif
X! 	    user_delay(5);
X! 	}
X  	menu_return( ME_NEXT );
X      }
X      
X***************
X*** 452,462 ****
X  
X      if (menu_cmd == ME_QUIT || menu_cmd == ME_NEXT || menu_cmd == ME_PREV)
X  	if (submask == NULL && !no_update) 
X! 	    save_selection(gh, current_first_article, gh->last_l_article);
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--- 460,470 ----
X  
X      if (menu_cmd == ME_QUIT || menu_cmd == ME_NEXT || menu_cmd == ME_PREV)
X  	if (submask == NULL && !no_update) 
X! 	    save_selection(gh, current_first_article, gh->last_l_article, 0);
X  
X      if (menu_cmd == ME_READ || menu_cmd == ME_NO_ARTICLES) {
X  	if (did_selection) {
X! 	    int32 was_read = gh->group_flag & G_READ;
X  
X  	    prev_last = gh->last_l_article;
X  	    gh->last_l_article = last_article;
X***************
X*** 855,861 ****
X  	
X  	printf("\r%s", cur->group_name); clrline();
X  	
X! 	access_group(cur, -1, cur->last_l_article, access_mode, submask, do_kill);
X      }
X      merge_memory();
X      if (n_articles == 0) return;
X--- 863,869 ----
X  	
X  	printf("\r%s", cur->group_name); clrline();
X  	
X! 	access_group(cur, (article_number)(-1), cur->last_l_article, access_mode, submask, do_kill);
X      }
X      merge_memory();
X      if (n_articles == 0) return;
X
X*** /usr/storm/nn6.3.0/help.more	Thu Jun  1 11:10:43 1989
X--- help.more	Fri Jul  7 11:06:17 1989
X***************
X*** 7,14 ****
X  						c       compress spaces
X  ;:AGOTO ANOTHER ARTICLE;:A
X  SP      next (at end of current article)	;:ACANCEL, SUBSCRIBE, KILL;:A
X! n       next                            	C       cancel article
X! p       previous article                	U       (un)subscribe to group
X  k       kill subject (not permanently)  	K       kill/select handling
X  *       select subject                  
X        	                                  	;:AQUIT / ESCAPE;:A
X--- 7,14 ----
X  						c       compress spaces
X  ;:AGOTO ANOTHER ARTICLE;:A
X  SP      next (at end of current article)	;:ACANCEL, SUBSCRIBE, KILL;:A
X! n, p    next/previous article           	C       cancel article
X! l       mark article for later action   	U       (un)subscribe to group
X  k       kill subject (not permanently)  	K       kill/select handling
X  *       select subject                  
X        	                                  	;:AQUIT / ESCAPE;:A
X
X*** /usr/storm/nn6.3.2/init.c	Wed Jun 28 20:07:51 1989
X--- init.c	Sat Jul  8 00:04:11 1989
X***************
X*** 581,586 ****
X--- 581,587 ----
X  	    
X  	    clrdisp();
X  	    rm_kill_file();
X+ 	    free_kill_entries();
X  	    do_kill_handling = init_kill() && do_kill_handling;
X  	    return AC_REDRAW;
X  	}
X***************
X*** 646,652 ****
X  	}
X  	
X  	CASE( "coredump" ) {
X! 	    no_raw();
X  	    abort();
X  	}
X  
X--- 647,653 ----
X  	}
X  	
X  	CASE( "coredump" ) {
X! 	    unset_raw();
X  	    abort();
X  	}
X  
X
X*** /usr/storm/nn6.3.3/keymap.c	Fri Jun 30 11:30:46 1989
X--- keymap.c	Tue Jul  4 19:58:05 1989
X***************
X*** 317,323 ****
X  /* :   */		K_EXTENDED_CMD,
X  /* ;   */	K_UNBOUND, 
X  /* <   */		K_PREV_PAGE,
X! /* =   */	K_UNBOUND, 
X  /* >   */		K_NEXT_PAGE,
X  /* ?   */		K_HELP,
X  /* @   */		K_SELECT_INVERT,
X--- 317,323 ----
X  /* :   */		K_EXTENDED_CMD,
X  /* ;   */	K_UNBOUND, 
X  /* <   */		K_PREV_PAGE,
X! /* =   */		K_GOTO_MATCH, 
X  /* >   */		K_NEXT_PAGE,
X  /* ?   */		K_HELP,
X  /* @   */		K_SELECT_INVERT,
X***************
X*** 422,428 ****
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      "full-digest",		K_FULL_DIGEST,		K_ONLY_MORE,
X--- 422,428 ----
X  
X      "decode",			K_UUDECODE,		0,
X  
X!     "find",			K_GOTO_MATCH,		0,
X      "find-next",		K_NEXT_MATCH,		K_ONLY_MORE,
X      "follow",			K_FOLLOW_UP,		0,
X      "full-digest",		K_FULL_DIGEST,		K_ONLY_MORE,
X
X*** /usr/storm/nn6.3.3/keymap.h	Fri Jun 30 11:30:47 1989
X--- keymap.h	Thu Jul  6 15:04:13 1989
X***************
X*** 97,115 ****
X  #define	K_MACRO			0x0100 /* call macro			*/
X  #define	K_ARTICLE_ID		0x0200 /* article id in lower part	*/
X  
X- /* special keys returned by get_c() */
X- 
X- #define	K_interrupt	CTRL('G')
X- 
X- #define	K_up_arrow	0x0081
X- #define	K_down_arrow	0x0082
X- #define K_left_arrow	0x0083
X- #define K_right_arrow	0x0084
X- 
X- #define	K_function(n)	(0x0085 + n)
X- 
X- 
X- #define	GETC_COMMAND	0x4000	/* bit set by get_c to return a command */
X  
X  /*
X   * KEY MAP SIZE is:
X--- 97,102 ----
X
X*** /usr/storm/nn6.3.3/kill.c	Fri Jun 30 11:30:48 1989
X--- kill.c	Sat Jul  8 00:56:04 1989
X***************
X*** 11,22 ****
X  
X  extern char *quick_match();
X  
X! #define COMP_KILL_MAGIC	0x4b694c6c	/* KiLl */
X  
X  /*
X   * kill flags
X   */
X  
X  #define	AUTO_KILL	0x01
X  #define AUTO_SELECT	0x00	/* pseudo flag */
X  #define ON_SUBJECT	0x02
X--- 11,24 ----
X  
X  extern char *quick_match();
X  
X! #define COMP_KILL_MAGIC	0x4b694c6d	/* KiLm */
X  
X  /*
X   * kill flags
X   */
X  
X+ #define COMP_KILL_ENTRY	0x80
X+ 
X  #define	AUTO_KILL	0x01
X  #define AUTO_SELECT	0x00	/* pseudo flag */
X  #define ON_SUBJECT	0x02
X***************
X*** 52,67 ****
X  typedef struct kill_list_entry {
X      int kill_flag;
X      char *kill_pattern;
X      struct kill_list_entry *next_kill;
X  } kill_list_entry;
X  
X  
X  static kill_list_entry dummy_kill = {
X!     0, (char *)NULL, (kill_list_entry *)NULL 
X  };
X  static kill_list_entry *global_kill_list = &dummy_kill;
X  static kill_list_entry *end_kill_list = &dummy_kill;
X! 
X  
X  kill_article(ah)
X  article_header *ah;
X--- 54,72 ----
X  typedef struct kill_list_entry {
X      int kill_flag;
X      char *kill_pattern;
X+     regexp *kill_regexp;
X      struct kill_list_entry *next_kill;
X  } kill_list_entry;
X  
X+ static kill_list_entry *kill_tab;
X+ static char *kill_patterns;
X  
X  static kill_list_entry dummy_kill = {
X!     0, (char *)NULL, (regexp *)NULL, (kill_list_entry *)NULL 
X  };
X  static kill_list_entry *global_kill_list = &dummy_kill;
X  static kill_list_entry *end_kill_list = &dummy_kill;
X! static kill_list_entry latest_kl_entry;
X  
X  kill_article(ah)
X  article_header *ah;
X***************
X*** 83,89 ****
X  		continue;
X  	} else
X  	if (kl->kill_flag & KILL_ON_REGEXP) {
X! 	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
X  		continue;
X  	} else
X  	    if (quick_match(string, kl->kill_pattern) == NULL)
X--- 88,94 ----
X  		continue;
X  	} else
X  	if (kl->kill_flag & KILL_ON_REGEXP) {
X! 	    if (regexec(kl->kill_regexp, string) == 0)
X  		continue;
X  	} else
X  	    if (quick_match(string, kl->kill_pattern) == NULL)
X***************
X*** 91,98 ****
X  	
X  	if (kl->kill_flag & AUTO_KILL)
X  	    return 1;
X! 	
X! 	ah->flag |= A_SELECT;
X  	break;
X      }
X      
X--- 96,103 ----
X  	
X  	if (kl->kill_flag & AUTO_KILL)
X  	    return 1;
X! 
X! 	ah->flag |= A_SELECT | A_AUTO;
X  	break;
X      }
X      
X***************
X*** 100,119 ****
X  }
X  
X  
X! auto_select_article(ah)
X  article_header *ah;
X  {
X      register kill_list_entry *kl;
X      char *string;
X!     
X!     end_kill_list->next_kill = ah->a_group ?
X! 	(kill_list_entry *)(ah->a_group->kill_list) :
X! 	(kill_list_entry *)(current_group->kill_list);
X      
X-     kl = global_kill_list;
X      while (kl = kl->next_kill) {
X! 	if (kl->kill_flag & AUTO_KILL) continue;
X! 	
X  	if (kl->kill_flag & ON_SUBJECT)
X  	    string = ah->subject;
X  	else
X--- 105,135 ----
X  }
X  
X  
X! auto_select_article(ah, do_select)
X  article_header *ah;
X+ int do_select;
X  {
X      register kill_list_entry *kl;
X+     kill_list_entry kl_head;
X      char *string;
X! 
X!     if (do_select == 2) {
X! 	kl = &kl_head;
X! 	kl->next_kill = &latest_kl_entry;
X!     } else {
X! 	end_kill_list->next_kill = ah->a_group ?
X! 	    (kill_list_entry *)(ah->a_group->kill_list) :
X! 		(kill_list_entry *)(current_group->kill_list);
X! 	kl = global_kill_list;
X!     }
X      
X      while (kl = kl->next_kill) {
X! 	if (do_select) {
X! 	    if (kl->kill_flag & AUTO_KILL) continue;
X! 	} else {
X! 	    if ((kl->kill_flag & AUTO_KILL) == 0) continue;
X! 	}
X!      check_one:	
X  	if (kl->kill_flag & ON_SUBJECT)
X  	    string = ah->subject;
X  	else
X***************
X*** 124,130 ****
X  		continue;
X  	} else
X  	if (kl->kill_flag & KILL_ON_REGEXP) {
X! 	    if (regexec((regexp *)(kl->kill_pattern), string) == 0)
X  		continue;
X  	} else
X  	    if (quick_match(string, kl->kill_pattern) == NULL)
X--- 140,146 ----
X  		continue;
X  	} else
X  	if (kl->kill_flag & KILL_ON_REGEXP) {
X! 	    if (regexec(kl->kill_regexp, string) == 0)
X  		continue;
X  	} else
X  	    if (quick_match(string, kl->kill_pattern) == NULL)
X***************
X*** 148,164 ****
X      time_t now;
X      FILE *killf;
X      register kill_list_entry *kl;
X      char *str;
X      
X      if (flag & KILL_ON_REGEXP) {
X! 	str = (char *)regcomp(pattern);
X! 	if (str == NULL) return;
X      } else {
X! 	str = malloc(strlen(pattern) + 1);
X! 	mem_check(str, 1, "string");
X! 	
X! 	strcpy(str, pattern);
X! 	
X  	if ((flag & KILL_MUST_MATCH) == 0)
X  	    init_quick_match(str);
X      }
X--- 164,179 ----
X      time_t now;
X      FILE *killf;
X      register kill_list_entry *kl;
X+     regexp *re;
X      char *str;
X      
X+     str = copy_str(pattern);
X+ 	
X      if (flag & KILL_ON_REGEXP) {
X! 	re = regcomp(pattern);
X! 	if (re == NULL) return;
X      } else {
X! 	re = NULL;
X  	if ((flag & KILL_MUST_MATCH) == 0)
X  	    init_quick_match(str);
X      }
X***************
X*** 191,200 ****
X      rm_kill_file();
X      
X      kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry));
X!     mem_check(kl, 1, "kill list entry");
X      
X!     kl->kill_pattern = str;
X!     kl->kill_flag = flag;
X      
X      if (gh) {
X  	kl->next_kill = (kill_list_entry *)(gh->kill_list);
X--- 206,217 ----
X      rm_kill_file();
X      
X      kl = (kill_list_entry *)calloc(1, sizeof(kill_list_entry));
X!     mem_check((char *)kl, 1, "kill list entry");
X      
X!     latest_kl_entry.kill_pattern = kl->kill_pattern = str;
X!     latest_kl_entry.kill_regexp = kl->kill_regexp = re;
X!     latest_kl_entry.kill_flag = kl->kill_flag = flag;
X!     latest_kl_entry.next_kill = NULL;
X      
X      if (gh) {
X  	kl->next_kill = (kill_list_entry *)(gh->kill_list);
X***************
X*** 236,242 ****
X       case NL:
X  	if (ah == NULL) {
X  	    ah = get_menu_article();
X! 	    if (ah == NULL) return;
X  	}
X  	
X  	strcpy(buffer, ah->subject);
X--- 253,259 ----
X       case NL:
X  	if (ah == NULL) {
X  	    ah = get_menu_article();
X! 	    if (ah == NULL) return -1;
X  	}
X  	
X  	strcpy(buffer, ah->subject);
X***************
X*** 243,249 ****
X  	enter_kill_file(current_group, buffer, 
X  			AUTO_KILL | ON_SUBJECT | KILL_MUST_MATCH, 30);
X  	msg("DONE");
X! 	return;
X  	
X       case 'k':
X       case 'K':
X--- 260,266 ----
X  	enter_kill_file(current_group, buffer, 
X  			AUTO_KILL | ON_SUBJECT | KILL_MUST_MATCH, 30);
X  	msg("DONE");
X! 	return 1;
X  	
X       case 'k':
X       case 'K':
X***************
X*** 258,264 ****
X  	mode1 = "SELECT";
X  	break;
X       default:
X! 	return;
X      }
X      
X      prompt("\1AUTO %s\1 on (S)ubject or (N)ame ?", mode1);
X--- 275,281 ----
X  	mode1 = "SELECT";
X  	break;
X       default:
X! 	return -1;
X      }
X      
X      prompt("\1AUTO %s\1 on (S)ubject or (N)ame ?", mode1);
X***************
X*** 281,298 ****
X  	mode2 = "Subject";
X  	break;
X       default:
X! 	return;
X      }
X  
X      prompt("\1%s %s:\1", mode1, mode2);
X      
X      pattern = get_s(dflt, NONE, "%=/", NO_COMPLETION);
X!     if (pattern == NULL) return;
X      if (*pattern == NUL || *pattern == '%' || *pattern == '=') {
X  	if (dflt && *dflt)
X  	    pattern = dflt;
X  	else {
X! 	    if ((ah = get_menu_article()) == NULL) return;
X  	    pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender;
X  	}
X  	flag |= KILL_MUST_MATCH;
X--- 298,315 ----
X  	mode2 = "Subject";
X  	break;
X       default:
X! 	return -1;
X      }
X  
X      prompt("\1%s %s:\1", mode1, mode2);
X      
X      pattern = get_s(dflt, NONE, "%=/", NO_COMPLETION);
X!     if (pattern == NULL) return -1;
X      if (*pattern == NUL || *pattern == '%' || *pattern == '=') {
X  	if (dflt && *dflt)
X  	    pattern = dflt;
X  	else {
X! 	    if ((ah = get_menu_article()) == NULL) return -1;
X  	    pattern = (flag & ON_SUBJECT) ? ah->subject : ah->sender;
X  	}
X  	flag |= KILL_MUST_MATCH;
X***************
X*** 301,307 ****
X  	    prompt("\1%s %s\1 (regexp): ", mode1, mode2);
X      
X  	    pattern = get_s(NONE, NONE, NONE, NO_COMPLETION);
X! 	    if (pattern == NULL || *pattern == NUL) return;
X  	    flag |= KILL_ON_REGEXP;
X  	}
X      
X--- 318,324 ----
X  	    prompt("\1%s %s\1 (regexp): ", mode1, mode2);
X      
X  	    pattern = get_s(NONE, NONE, NONE, NO_COMPLETION);
X! 	    if (pattern == NULL || *pattern == NUL) return -1;
X  	    flag |= KILL_ON_REGEXP;
X  	}
X      
X***************
X*** 324,335 ****
X  	 gh = NULL;
X  	 break;
X        default:
X! 	 return;
X       }
X  
X      prompt("\1Lifetime of entry in days\1 (P)ermanent ");
X      days_str = get_s(" 30 days", NONE, "pP", NO_COMPLETION);
X!     if (days_str == NULL) return;
X  
X      if (*days_str == NUL) {
X      	days_str = "30 days";
X--- 341,352 ----
X  	 gh = NULL;
X  	 break;
X        default:
X! 	 return -1;
X       }
X  
X      prompt("\1Lifetime of entry in days\1 (P)ermanent ");
X      days_str = get_s(" 30 days", NONE, "pP", NO_COMPLETION);
X!     if (days_str == NULL) return -1;
X  
X      if (*days_str == NUL) {
X      	days_str = "30 days";
X***************
X*** 342,348 ****
X  	sprintf(days_str, "%d days", days);
X      } else {
X  	ding();
X! 	return;
X      }
X  
X      prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ",
X--- 359,365 ----
X  	sprintf(days_str, "%d days", days);
X      } else {
X  	ding();
X! 	return -1;
X      }
X  
X      prompt("\1CONFIRM\1 %s %s %s%s: %-.35s%s ",
X***************
X*** 350,358 ****
X  	   (flag & KILL_MUST_MATCH) ? " exact" : 
X  	   (flag & KILL_ON_REGEXP) ? " regexp" : "",
X  	   pattern, strlen(pattern) > 35 ? "..." : "");
X!     if (yes(0) <= 0) return;
X      
X      enter_kill_file(gh, pattern, flag, days);
X  }
X  
X  
X--- 367,377 ----
X  	   (flag & KILL_MUST_MATCH) ? " exact" : 
X  	   (flag & KILL_ON_REGEXP) ? " regexp" : "",
X  	   pattern, strlen(pattern) > 35 ? "..." : "");
X!     if (yes(0) <= 0) return -1;
X      
X      enter_kill_file(gh, pattern, flag, days);
X+ 
X+     return (flag & AUTO_KILL) ? 1 : 0;
X  }
X  
X  
X***************
X*** 363,374 ****
X      FILE *killf;
X      comp_kill_header header;
X      comp_kill_entry  entry;
X-     kill_list_entry *kill_tab;
X      register group_header *gh;
X      register kill_list_entry *kl;
X-     char *patterns;
X      time_t kill_age, comp_age;
X!     register n;
X      
X      Loop_Groups_Header(gh)
X  	gh->kill_list = NULL;
X--- 382,393 ----
X      FILE *killf;
X      comp_kill_header header;
X      comp_kill_entry  entry;
X      register group_header *gh;
X      register kill_list_entry *kl;
X      time_t kill_age, comp_age;
X!     register long n;
X!     int first_try = 1;
X!     import char *delayed_msg;
X      
X      Loop_Groups_Header(gh)
X  	gh->kill_list = NULL;
X***************
X*** 377,405 ****
X      if (kill_age == 0) return 0;
X      
X      comp_age = file_exist(relative(nn_directory, COMPILED_KILL), "fr");
X      if (comp_age < kill_age && !compile_kill_file()) return 0;
X! 	
X      killf = open_file(relative(nn_directory, COMPILED_KILL), OPEN_READ);
X      if (killf == NULL) return 0;
X  
X!     if (fread(&header, sizeof(header), 1, killf) != 1) goto err;
X      if (header.ckh_magic != COMP_KILL_MAGIC) goto err;
X  
X!     patterns = malloc(header.ckh_pattern_size);
X!     mem_check(patterns, header.ckh_pattern_size, "kill bytes");
X      
X      kill_tab = (kill_list_entry *)
X! 	calloc(header.ckh_entries, sizeof(kill_list_entry));
X!     mem_check(kill_tab, header.ckh_entries, "kill entries");
X!     
X      for (n = header.ckh_entries, kl = kill_tab; --n >= 0; kl++) {
X! 	if (fread(&entry, sizeof(entry), 1, killf) != 1) goto err;
X  	
X! 	kl->kill_pattern = patterns + entry.ck_pattern_index;
X  	kl->kill_flag = entry.ck_flag;
X  
X! 	if (kl->kill_flag & KILL_ON_REGEXP) 
X! 	    kl->kill_pattern = (char *)regcomp(kl->kill_pattern);
X  	
X  	if (entry.ck_group >= 0) {
X  	    gh = active_groups + entry.ck_group;
X--- 396,437 ----
X      if (kill_age == 0) return 0;
X      
X      comp_age = file_exist(relative(nn_directory, COMPILED_KILL), "fr");
X+  again:
X      if (comp_age < kill_age && !compile_kill_file()) return 0;
X! 
X!     kill_tab = NULL;
X!     kill_patterns = NULL;
X!     
X      killf = open_file(relative(nn_directory, COMPILED_KILL), OPEN_READ);
X      if (killf == NULL) return 0;
X  
X!     if (fread((char *)&header, sizeof(header), 1, killf) != 1) goto err;
X      if (header.ckh_magic != COMP_KILL_MAGIC) goto err;
X  
X!     kill_patterns = malloc((unsigned)header.ckh_pattern_size);
X!     mem_check(kill_patterns, (int)header.ckh_pattern_size, "kill bytes");
X      
X      kill_tab = (kill_list_entry *)
X! 	calloc((unsigned)header.ckh_entries, sizeof(kill_list_entry));
X!     mem_check((char *)kill_tab, (int)header.ckh_entries, "kill entries");
X! 
X!     fseek(killf, (off_t)(header.ckh_entries * sizeof(entry)), 1);
X!     if (fread(kill_patterns, sizeof(char), (int)header.ckh_pattern_size, killf)
X! 	!=  header.ckh_pattern_size) goto err;
X! 
X!     fseek(killf, (off_t)sizeof(header), 0);
X      for (n = header.ckh_entries, kl = kill_tab; --n >= 0; kl++) {
X! 	if (fread((char *)&entry, sizeof(entry), 1, killf) != 1) goto err;
X! 	if (header.ckh_pattern_size <= entry.ck_pattern_index ||
X! 	    entry.ck_pattern_index < 0) goto err;
X  	
X! 	kl->kill_pattern = kill_patterns + entry.ck_pattern_index;
X  	kl->kill_flag = entry.ck_flag;
X  
X! 	if (kl->kill_flag & KILL_ON_REGEXP)
X! 	    kl->kill_regexp = regcomp(kl->kill_pattern);
X! 	else
X! 	    kl->kill_regexp = NULL;
X  	
X  	if (entry.ck_group >= 0) {
X  	    gh = active_groups + entry.ck_group;
X***************
X*** 412,428 ****
X  	}
X      }
X  	      
X-     if (fread(patterns, sizeof(char), header.ckh_pattern_size, killf)
X- 	!=  header.ckh_pattern_size) goto err;
X- 
X      fclose(killf);
X      
X      return 1;
X      
X   err:
X      fclose(killf);
X-     msg("Error in compiled kill file");
X      rm_kill_file();
X  
X      Loop_Groups_Header(gh)
X  	gh->kill_list = NULL;
X--- 444,466 ----
X  	}
X      }
X  	      
X      fclose(killf);
X      
X      return 1;
X      
X   err:
X+     if (kill_patterns != NULL) free(kill_patterns);
X+     if (kill_tab != NULL) free(kill_tab);
X+     
X      fclose(killf);
X      rm_kill_file();
X+     if (first_try) {
X+ 	first_try = 0;
X+ 	comp_age = 0;
X+ 	goto again;
X+     }
X+     
X+     delayed_msg = "Error in compiled kill file (ignored)";
X  
X      Loop_Groups_Header(gh)
X  	gh->kill_list = NULL;
X***************
X*** 509,515 ****
X  	/* flags */
X  
X  	cp = np;
X! 	flag = 0;
X  	
X  	for (;;) {
X  	    switch (*cp++) {
X--- 547,553 ----
X  	/* flags */
X  
X  	cp = np;
X! 	flag = COMP_KILL_ENTRY;
X  	
X  	for (;;) {
X  	    switch (*cp++) {
X***************
X*** 579,585 ****
X  
X      header.ckh_magic = COMP_KILL_MAGIC;
X  
X!     if (fwrite(&header, sizeof(header), 1, compf) != 1)
X  	goto err2;
X      
X      fclose(compf);
X--- 617,623 ----
X  
X      header.ckh_magic = COMP_KILL_MAGIC;
X  
X!     if (fwrite((char *)&header, sizeof(header), 1, compf) != 1)
X  	goto err2;
X      
X      fclose(compf);
X***************
X*** 629,634 ****
X--- 667,706 ----
X  }
X  
X  
X+ free_kill_entries()
X+ {
X+     register group_header *gh;
X+ 
X+     Loop_Groups_Header(gh)
X+ 	if (gh->kill_list) {
X+ 	    free_kill_list((kill_list_entry *)(gh->kill_list));
X+ 	    gh->kill_list = NULL;
X+ 	}
X+     
X+     end_kill_list->next_kill = NULL;
X+     free_kill_list(global_kill_list->next_kill);
X+ 
X+     end_kill_list = global_kill_list = &dummy_kill;
X+ 
X+     if (kill_patterns != NULL) free(kill_patterns);
X+     if (kill_tab != NULL) free(kill_tab);
X+ }
X+ 
X+ static free_kill_list(kl)
X+ register kill_list_entry *kl;
X+ {
X+     register kill_list_entry *nxt;
X+     while (kl) {
X+ 	nxt = kl->next_kill;
X+ 	if (kl->kill_regexp != NULL) free(kl->kill_regexp);
X+ 	if ((kl->kill_flag & COMP_KILL_ENTRY) == 0) {
X+ 	    if (kl->kill_pattern != NULL) free(kl->kill_pattern);
NN_IS_BETTER
echo "End of part 1"
echo "File PATCH.4 is continued in part 2"
echo "2" > s2_seq_.tmp
exit 0

-- 
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