ftp.nice.ch/pub/next/unix/mail/elm2.4/elm.2.4pl17.s.tar.gz#/src/pattern.c

This is pattern.c in view mode; [Download] [Up]

static char rcsid[] = "@(#)$Id: pattern.c,v 5.2 1992/11/26 00:46:50 syd Exp $";

/*******************************************************************************
 *  The Elm Mail System  -  $Revision: 5.2 $   $State: Exp $
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *******************************************************************************
 * Bug reports, patches, comments, suggestions should be sent to:
 *
 *	Syd Weinstein, Elm Coordinator
 *	elm@DSI.COM			dsinc!elm
 *
 *******************************************************************************
 * $Log: pattern.c,v $
 * Revision 5.2  1992/11/26  00:46:50  syd
 * Fix how errno is used so err is inited and used instead
 * as errno gets overwritten by print system call
 * From: Syd
 *
 * Revision 5.1  1992/10/03  22:58:40  syd
 * Initial checkin as of 2.4 Release at PL0
 *
 *
 ******************************************************************************/

/**    General pattern matching for the ELM mailer.     

**/

#include <errno.h>

#include "headers.h"
#include "s_elm.h"

static char pattern[SLEN] = { "" };
static char alt_pattern[SLEN] = { "" };

extern int errno;

char *error_description(), *shift_lower(), *strcpy();
static char *tag_word = NULL;
static char *tagged_word = NULL;
static char *Tagged_word = NULL;
static char *delete_word = NULL;
static char *mark_delete_word = NULL;
static char *Mark_delete_word = NULL;
static char *undelete_word = NULL;
static char *undeleted_word = NULL;
static char *Undeleted_word = NULL;
static char *enter_pattern = NULL;
static char *match_pattern = NULL;
static char *entire_match_pattern = NULL;
static char *match_anywhere = NULL;

int
meta_match(function)
int function;
{
	char	ch;

	/** Perform specific function based on whether an entered string 
	    matches either the From or Subject lines.. 
	    Return TRUE if the current message was matched, else FALSE.
	**/

	register int i, tagged=0, count=0, curtag = 0;
	char		msg[SLEN];
	static char     meta_pattern[SLEN];

	if (delete_word == NULL) {
	     tag_word = catgets(elm_msg_cat, ElmSet, ElmTag, "Tag");
	     tagged_word = catgets(elm_msg_cat, ElmSet, ElmTagged, "tagged");
	     Tagged_word = catgets(elm_msg_cat, ElmSet, ElmCapTagged, "Tagged");
	     delete_word = catgets(elm_msg_cat, ElmSet, ElmDelete, "Delete");
	     mark_delete_word = catgets(elm_msg_cat, ElmSet, ElmMarkDelete, "marked for deletion");
	     Mark_delete_word = catgets(elm_msg_cat, ElmSet, ElmCapMarkDelete, "Marked for deletion");
	     undelete_word = catgets(elm_msg_cat, ElmSet, ElmUndelete, "Undelete");
	     undeleted_word = catgets(elm_msg_cat, ElmSet, ElmUndeleted, "undeleted");
	     Undeleted_word = catgets(elm_msg_cat, ElmSet, ElmCapUndeleted, "Undeleted");
	     enter_pattern = catgets(elm_msg_cat, ElmSet, ElmEnterPattern, "Enter pattern: ");
	}

	PutLine2(LINES-3, strlen(Prompt), catgets(elm_msg_cat, ElmSet, ElmMessagesMatchPattern,
	     "%s %s that match pattern..."), 
	     function==TAGGED?tag_word: function==DELETED?delete_word:undelete_word, items);

	if (function == TAGGED) {	/* are messages already tagged??? */
	  for (i=0; i < message_count; i++)
	    if (ison(ifmain(headers[i]->status,
	                    aliases[i]->status),TAGGED))
	      tagged++;

	  if (tagged) {
	    if (tagged > 1) {
	      PutLine1(LINES-2,0, catgets(elm_msg_cat, ElmSet, ElmSomeMessagesATagged,
		"Some %s are already tagged."), items);
	      MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRemoveTags,
		"Remove Tags? (%c/%c) %c%c"),
		*def_ans_yes, *def_ans_no, *def_ans_yes, BACKSPACE);
	    } else {
	      PutLine1(LINES-2,0, catgets(elm_msg_cat, ElmSet, ElmAMessageATagged,
		"One %s is already tagged."), item);
	      MCsprintf(msg, catgets(elm_msg_cat, ElmSet, ElmRemoveTag,
		"Remove Tag? (%c/%c) %c%c"),
		*def_ans_yes, *def_ans_no, *def_ans_yes, BACKSPACE);
	    }
	
	    Write_to_screen(msg, 0);

	    ch = ReadCh();
	    if (tolower(ch) != *def_ans_no) {	/* remove tags... */
	      Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmYes, "Yes."), 0);
	      for (i=0; i < message_count; i++) {
	        if (inalias)
	          clearit(aliases[i]->status,TAGGED);
	        else
	          clearit(headers[i]->status,TAGGED);
		show_new_status(i);
	      }
	    } else
	      Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmNo, "No."), 0);
	  }
	}
	
	PutLine0(LINES-2,0, enter_pattern);
	CleartoEOLN();

	optionally_enter(meta_pattern, LINES-2, strlen(enter_pattern),
	  FALSE, FALSE);

	if (strlen(meta_pattern) == 0) {
	  ClearLine(LINES-2);
	  return(curtag);
	}

	strcpy(meta_pattern, shift_lower(meta_pattern));   /* lowercase it */

	if (inalias) {
	  for (i = 0; i < message_count; i++) {
	    if (name_matches(i, meta_pattern) ||
	        alias_matches(i, meta_pattern)) {
	      if (! selected || (selected && (aliases[i]->status & VISIBLE))) {
	        if (function == UNDELETE)
	          clearit(aliases[i]->status, DELETED);
	        else
	          if ((function == DELETED) && (aliases[i]->type & SYSTEM)) {
	            if(i == current - 1) curtag--;
	            count--;
	          }
	          else
	            setit(aliases[i]->status, function);
	        show_new_status(i);
	        if(i == current - 1) curtag++;
	        count++;
	      }
	    }
	  }
	}
	else {
	  for (i = 0; i < message_count; i++) {
	    if (from_matches(i, meta_pattern) ||
	        subject_matches(i, meta_pattern)) {
	      if (! selected || (selected && headers[i]->status & VISIBLE)) {
	        if (function == UNDELETE)
	          clearit(headers[i]->status, DELETED);
	        else
	          setit(headers[i]->status, function);
	        show_new_status(i);
	        if(i == current - 1) curtag++;
	        count++;
	      }
	    }
	  }
	}

	ClearLine(LINES-2);	/* remove "pattern: " prompt */
	
	if (count > 1) {
	  error3(catgets(elm_msg_cat, ElmSet, ElmTaggedMessages,
		"%s %d %s."), 
	         function==TAGGED? Tagged_word : 
		   function==DELETED? Mark_delete_word : Undeleted_word,
		 count, items);
	} else if (count == 1) {
	  error2(catgets(elm_msg_cat, ElmSet, ElmTaggedMessage,
		"%s 1 %s."), 
	         function==TAGGED? Tagged_word : 
		   function==DELETED? Mark_delete_word : Undeleted_word, item);
	} else {
	  error2(catgets(elm_msg_cat, ElmSet, ElmNoMatchesNoTags,
		"No matches. No %s %s."), items,
		 function==TAGGED? tagged_word : 
		   function==DELETED? mark_delete_word: undeleted_word);
	}

	return(curtag);
}
	  
int
pattern_match()
{
	/** Get a pattern from the user and try to match it with the
	    from/subject lines being displayed.  If matched (ignoring
	    case), move current message pointer to that message, if
	    not, error and return ZERO **/

	register int i;

	char buffer[SLEN];
	int anywhere = FALSE;
	int matched;

	if (match_pattern == NULL) {
	  match_pattern = catgets(elm_msg_cat, ElmSet, ElmMatchPattern,
		"Match pattern:");
	  entire_match_pattern = catgets(elm_msg_cat, ElmSet,
		ElmMatchPatternInEntire, "Match pattern (in entire %s):");
	  match_anywhere = catgets(elm_msg_cat, ElmSet, ElmMatchAnywhere,
		"/ = Match anywhere in %s.");
	}

	MCsprintf(buffer, entire_match_pattern, item);

	PutLine1(LINES-3,40, match_anywhere, items);
	
	PutLine0(LINES-1,0, match_pattern);

	if (pattern_enter(pattern, alt_pattern, LINES-1,
		strlen(match_pattern)+1, buffer)) {
	  if (strlen(alt_pattern) == 0) {
	    return(1);
	  }
	  anywhere = TRUE;
	  strcpy(pattern, shift_lower(alt_pattern));
	}
	else if (strlen(pattern) == 0) {
	  return(0);
	}
	else {
	  strcpy(pattern, shift_lower(pattern));
	}

	if (inalias) {
	  for (i = current; i < message_count; i++) {
	    matched = name_matches(i, pattern) || alias_matches(i, pattern);
	    if (! matched && anywhere) {	/* Look only if no match yet */
	      matched = comment_matches(i, pattern) ||
			address_matches(i, pattern);
	    }
	    if (matched) {
	      if (!selected || (selected && aliases[i]->status & VISIBLE)) {
	        current = ++i;
	        return(1);
	      }
	    }
	  }
	}
	else {
	  if (anywhere) {
	      return(match_in_message(pattern));
	  }
	  else {
	    for (i = current; i < message_count; i++) {
	      if (from_matches(i, pattern) || subject_matches(i, pattern)) {
	        if (!selected || (selected && headers[i]->status & VISIBLE)) {
	          current = ++i;
	          return(1);
	        }
	      }
	    }
	  }
	}

	return(0);
}

int
from_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the from line of the indicated message **/

	return( in_string(shift_lower(headers[message_number]->from), 
		pat) );
}

int
subject_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the subject line of the indicated message **/

	return( in_string(shift_lower(headers[message_number]->subject), 
		pat) );
}

int
name_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the proper name of the indicated alias **/

	return( in_string(shift_lower(aliases[message_number]->name),
		pat) );
}

int
alias_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the alias name of the indicated alias **/

	return( in_string(shift_lower(aliases[message_number]->alias),
		pat) );
}

int
comment_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the comment field of the indicated alias **/

	return( in_string(shift_lower(aliases[message_number]->comment),
		pat) );
}

int
address_matches(message_number, pat)
int message_number;
char *pat;
{
	/** Returns true iff the pattern occurs in it's entirety
	    in the fully expanded address of the indicated alias **/

	return( in_string(shift_lower(
		get_alias_address(aliases[message_number]->alias, TRUE)),
		pat) );
}

match_in_message(pat)
char *pat;
{
	/** Match a string INSIDE a message...starting at the current 
	    message read each line and try to find the pattern.  As
	    soon as we do, set current and leave! 
	    Returns 1 if found, 0 if not
	**/

	char buffer[LONG_STRING];
	int  message_number, lines, line, line_len, err;

	message_number = current-1;

	error(catgets(elm_msg_cat, ElmSet, ElmSearchingFolderPattern,
		"Searching folder for pattern..."));

	while (message_number < message_count) {

	  if (fseek(mailfile, headers[message_number]->offset, 0L) == -1) {

	    err = errno;
	    dprint(1, (debugfile,
		"Error: seek %ld bytes into file failed. errno %d (%s)\n",
		headers[message_number]->offset, err, 
		"match_in_message"));
	    error2(catgets(elm_msg_cat, ElmSet, ElmMatchSeekFailed,
		   "ELM [match] failed looking %ld bytes into file (%s)."),
		   headers[message_number]->offset, error_description(err));
	    return(1);	/* fake it out to avoid replacing error message */
	  }

	  line = 0;
	  lines = headers[message_number]->lines;

	  while ((line_len = mail_gets(buffer, LONG_STRING, mailfile)) && line < lines) {
	
	    if(buffer[line_len - 1] == '\n') line++;

	    if (in_string(shift_lower(buffer), pat)) {
	      current = message_number+1; 
	      clear_error();
	      return(1);
	    }
	  }

	  /** now we've passed the end of THIS message...increment and 
	      continue the search with the next message! **/

	  message_number++;
	}

	return(0);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.