diff options
author | Jeffrey Stedfast <fejj@helixcode.com> | 2000-10-26 05:29:11 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2000-10-26 05:29:11 +0800 |
commit | 1c81f56fdefa6412bd1f3ae5f36ad3f872e25ce7 (patch) | |
tree | 9e18282eeb2fe230db745f3404b1e02afc68bf6f /filter/filter-message-search.c | |
parent | e2ebe055b611bd040558bffd990a5b6dafa1b334 (diff) | |
download | gsoc2013-evolution-1c81f56fdefa6412bd1f3ae5f36ad3f872e25ce7.tar.gz gsoc2013-evolution-1c81f56fdefa6412bd1f3ae5f36ad3f872e25ce7.tar.zst gsoc2013-evolution-1c81f56fdefa6412bd1f3ae5f36ad3f872e25ce7.zip |
Added option menu items to allow searching based on regular expressions.
2000-10-25 Jeffrey Stedfast <fejj@helixcode.com>
* filtertypes.xml: Added option menu items to allow searching
based on regular expressions.
* filter-message-search.c (body_regex): New callback to match text
in the body using regex.
(body_contains): Modified to only match using strstr.
(header_regex): New callback to match headers using regex.
(header_contains): Modified to only match using strstr.
svn path=/trunk/; revision=6177
Diffstat (limited to 'filter/filter-message-search.c')
-rw-r--r-- | filter/filter-message-search.c | 122 |
1 files changed, 97 insertions, 25 deletions
diff --git a/filter/filter-message-search.c b/filter/filter-message-search.c index 8b90e273e6..a227af41c0 100644 --- a/filter/filter-message-search.c +++ b/filter/filter-message-search.c @@ -23,6 +23,7 @@ #include "filter-message-search.h" #include <e-util/e-sexp.h> #include <regex.h> +#include <string.h> typedef struct { CamelMimeMessage *message; @@ -33,8 +34,10 @@ typedef struct { /* ESExp callbacks */ static ESExpResult *header_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); +static ESExpResult *header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *match_all (struct _ESExp *f, int argc, struct _ESExpTerm **argv, FilterMessageSearch *fms); static ESExpResult *body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); +static ESExpResult *body_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *user_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *user_tag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *get_sent_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); @@ -52,7 +55,9 @@ static struct { } symbols[] = { { "match-all", (ESExpFunc *) match_all, 0 }, { "body-contains", (ESExpFunc *) body_contains, 0 }, + { "body-regex", (ESExpFunc *) body_regex, 0 }, { "header-contains", (ESExpFunc *) header_contains, 0 }, + { "header-regex", (ESExpFunc *) header_regex, 0 }, { "user-tag", (ESExpFunc *) user_tag, 0 }, { "user-flag", (ESExpFunc *) user_flag, 0 }, { "get-sent-date", (ESExpFunc *) get_sent_date, 0 }, @@ -71,6 +76,31 @@ header_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterM if (argc == 2) { char *header = (argv[0])->value.string; char *match = (argv[1])->value.string; + const char *contents; + + contents = camel_medium_get_header (CAMEL_MEDIUM (fms->message), header); + + if (contents) { + if (strstr (contents, match)) + matched = TRUE; + } + } + + r = e_sexp_result_new (ESEXP_RES_BOOL); + r->value.bool = matched; + + return r; +} + +static ESExpResult * +header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + gboolean matched = FALSE; + ESExpResult *r; + + if (argc == 2) { + char *header = (argv[0])->value.string; + char *match = (argv[1])->value.string; regex_t regexpat; /* regex patern */ regmatch_t *fltmatch; gint regerr = 0; @@ -127,7 +157,7 @@ match_all (struct _ESExp *f, int argc, struct _ESExpTerm **argv, FilterMessageSe } static gboolean -mime_part_matches (CamelMimePart *mime_part, const char *match, CamelException *ex) +mime_part_matches (CamelMimePart *mime_part, const char *match, gboolean regex, CamelException *ex) { CamelStream *stream; GByteArray *array; @@ -142,38 +172,46 @@ mime_part_matches (CamelMimePart *mime_part, const char *match, CamelException * array = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (array); camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (mime_part), stream); - camel_stream_reset (stream); + camel_object_unref (CAMEL_OBJECT (stream)); + g_byte_array_append (array, "", 1); text = array->data; - regerr = regcomp (®expat, match, REG_EXTENDED | REG_NEWLINE | REG_ICASE); - if (regerr) { - /* regerror gets called twice to get the full error string - length to do proper posix error reporting */ - reglen = regerror (regerr, ®expat, 0, 0); - regmsg = g_malloc0 (reglen + 1); - regerror (regerr, ®expat, regmsg, reglen); - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Failed to perform regex search on message body: %s", - regmsg); - g_free (regmsg); - regfree (®expat); + if (regex) { + regerr = regcomp (®expat, match, REG_EXTENDED | REG_NEWLINE | REG_ICASE); + if (regerr) { + /* regerror gets called twice to get the full error string + length to do proper posix error reporting */ + reglen = regerror (regerr, ®expat, 0, 0); + regmsg = g_malloc0 (reglen + 1); + regerror (regerr, ®expat, regmsg, reglen); + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Failed to perform regex search on message body: %s", + regmsg); + g_free (regmsg); + regfree (®expat); + } else { + fltmatch = g_new0 (regmatch_t, regexpat.re_nsub); + + if (!regexec (®expat, text, regexpat.re_nsub, fltmatch, 0)) + matched = TRUE; + + g_free (fltmatch); + regfree (®expat); + } } else { - fltmatch = g_new0 (regmatch_t, regexpat.re_nsub); - - if (!regexec (®expat, text, regexpat.re_nsub, fltmatch, 0)) + if (strstr (text, match)) matched = TRUE; - - g_free (fltmatch); - regfree (®expat); } + g_byte_array_free (array, TRUE); + return matched; } static gboolean -handle_multipart (CamelMultipart *multipart, const char *match, CamelException *ex) +handle_multipart (CamelMultipart *multipart, const char *match, gboolean regex, CamelException *ex) { gboolean matched = FALSE; int i, nparts; @@ -189,7 +227,7 @@ handle_multipart (CamelMultipart *multipart, const char *match, CamelException * if (gmime_content_field_is_type (content, "text", "*")) { /* we only want to match text parts */ - matched = mime_part_matches (mime_part, match, ex); + matched = mime_part_matches (mime_part, match, regex, ex); if (camel_exception_is_set (ex)) break; @@ -200,7 +238,7 @@ handle_multipart (CamelMultipart *multipart, const char *match, CamelException * wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); mpart = CAMEL_MULTIPART (wrapper); - matched = handle_multipart (mpart, match, ex); + matched = handle_multipart (mpart, match, regex, ex); if (camel_exception_is_set (ex)) break; @@ -231,10 +269,44 @@ body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMes wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (fms->message))); multipart = CAMEL_MULTIPART (wrapper); - matched = handle_multipart (multipart, match, fms->ex); + matched = handle_multipart (multipart, match, FALSE, fms->ex); + } else { + /* single-part message so just search the entire message */ + matched = mime_part_matches (CAMEL_MIME_PART (fms->message), match, FALSE, fms->ex); + } + } + + r = e_sexp_result_new (ESEXP_RES_BOOL); + r->value.bool = matched; + + return r; +} + +static ESExpResult * +body_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + gboolean matched = FALSE; + ESExpResult *r; + + if (argc > 0) { + GMimeContentField *content; + char *match; + + match = (*argv)->value.string; + + content = camel_mime_part_get_content_type (CAMEL_MIME_PART (fms->message)); + + if (gmime_content_field_is_type (content, "multipart", "*")) { + CamelDataWrapper *wrapper; + CamelMultipart *multipart; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (CAMEL_MIME_PART (fms->message))); + multipart = CAMEL_MULTIPART (wrapper); + + matched = handle_multipart (multipart, match, TRUE, fms->ex); } else { /* single-part message so just search the entire message */ - matched = mime_part_matches (CAMEL_MIME_PART (fms->message), match, fms->ex); + matched = mime_part_matches (CAMEL_MIME_PART (fms->message), match, TRUE, fms->ex); } } |