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.