2011-01-25 [colin] 3.7.8cvs47
authorColin Leroy <colin@colino.net>
Tue, 25 Jan 2011 17:05:50 +0000 (17:05 +0000)
committerColin Leroy <colin@colino.net>
Tue, 25 Jan 2011 17:05:50 +0000 (17:05 +0000)
* src/matcher.c
Fix matcher body parsing: decode mails with our
MIME parser. This speeds up body search a bit as
binary attachments are not searched anymore, slows
down a bit full message searches, but not awfully.
* src/summary_search.c
Use matcher API to search, in all cases (advanced search or
not). Also, fix little logic bugs related to combos history
* src/common/utils.c
* src/common/utils.h
* src/procmime.c
* src/procmime.h
Remove dead code, export functions needed by matcher.c

ChangeLog
PATCHSETS
configure.ac
src/common/utils.c
src/common/utils.h
src/matcher.c
src/procmime.c
src/procmime.h
src/summary_search.c

index 2a232cc..872123a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-01-25 [colin]     3.7.8cvs47
+
+       * src/matcher.c
+               Fix matcher body parsing: decode mails with our
+               MIME parser. This speeds up body search a bit as
+               binary attachments are not searched anymore, slows
+               down a bit full message searches, but not awfully.
+       * src/summary_search.c
+               Use matcher API to search, in all cases (advanced search or
+               not). Also, fix little logic bugs related to combos history
+       * src/common/utils.c
+       * src/common/utils.h
+       * src/procmime.c
+       * src/procmime.h
+               Remove dead code, export functions needed by matcher.c
+
 2011-01-25 [colin]     3.7.8cvs46
 
        * src/compose.c
index 1e4fe43..8afdcfc 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.16 -r 1.1.2.17 manual/es/advanced.xml;  ) > 3.7.8cvs44.patchset
 ( cvs diff -u -r 1.56.2.66 -r 1.56.2.67 src/pop.c;  ) > 3.7.8cvs45.patchset
 ( cvs diff -u -r 1.382.2.566 -r 1.382.2.567 src/compose.c;  cvs diff -u -r 1.204.2.199 -r 1.204.2.200 src/prefs_common.c;  cvs diff -u -r 1.2.2.9 -r 1.2.2.10 src/common/md5.c;  cvs diff -u -r 1.4.2.36 -r 1.4.2.37 src/common/ssl_certificate.c;  ) > 3.7.8cvs46.patchset
+( cvs diff -u -r 1.75.2.67 -r 1.75.2.68 src/matcher.c;  cvs diff -u -r 1.49.2.137 -r 1.49.2.138 src/procmime.c;  cvs diff -u -r 1.17.2.24 -r 1.17.2.25 src/procmime.h;  cvs diff -u -r 1.15.2.59 -r 1.15.2.60 src/summary_search.c;  cvs diff -u -r 1.36.2.189 -r 1.36.2.190 src/common/utils.c;  cvs diff -u -r 1.20.2.74 -r 1.20.2.75 src/common/utils.h;  ) > 3.7.8cvs47.patchset
index 2a166fd..3efd323 100644 (file)
@@ -12,7 +12,7 @@ MINOR_VERSION=7
 MICRO_VERSION=8
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=46
+EXTRA_VERSION=47
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 70cf95c..826724b 100644 (file)
@@ -301,16 +301,6 @@ void ptr_array_free_strings(GPtrArray *array)
        }
 }
 
-gboolean str_find(const gchar *haystack, const gchar *needle)
-{
-       return strstr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
-gboolean str_case_find(const gchar *haystack, const gchar *needle)
-{
-       return strcasestr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
 gint to_number(const gchar *nstr)
 {
        register const gchar *p;
index 2bdc1fc..50f8afb 100644 (file)
@@ -287,13 +287,6 @@ guint str_case_hash                (gconstpointer   key);
 
 void ptr_array_free_strings    (GPtrArray      *array);
 
-typedef gboolean (*StrFindFunc) (const gchar   *haystack,
-                                const gchar    *needle);
-
-gboolean str_find              (const gchar    *haystack,
-                                const gchar    *needle);
-gboolean str_case_find         (const gchar    *haystack,
-                                const gchar    *needle);
 /* number-string conversion */
 gint to_number                 (const gchar *nstr);
 gchar *itos_buf                        (gchar       *nstr,
index 5626e3d..4e64420 100644 (file)
@@ -599,48 +599,19 @@ const gchar *debug_context)
        return FALSE;
 }
 
-/* FIXME body search is a hack. */
-static gboolean matcherprop_string_decode_match(MatcherProp *prop, const gchar *str,
-                                                                                               const gchar *debug_context)
+static gboolean matcherprop_header_line_match(MatcherProp *prop, const gchar *hdr,
+                                             const gchar *str, const gchar *debug_context)
 {
-       gchar *utf = NULL;
-       gchar tmp[BUFFSIZE];
+       gchar *line = NULL;
        gboolean res = FALSE;
 
-       if (str == NULL)
+       if (hdr == NULL || str == NULL)
                return FALSE;
 
-       /* we try to decode QP first, because it's faster than base64 */
-       qp_decode_const(tmp, BUFFSIZE-1, str);
-       if (!g_utf8_validate(tmp, -1, NULL)) {
-               utf = conv_codeset_strdup
-                       (tmp, conv_get_locale_charset_str_no_utf8(),
-                        CS_INTERNAL);
-               res = matcherprop_string_match(prop, utf, debug_context);
-               g_free(utf);
-       } else {
-               res = matcherprop_string_match(prop, tmp, debug_context);
-       }
-       
-       if (res == FALSE && (strchr(prop->expr, '=') || strchr(prop->expr, '_')
-                           || strchr(str, '=') || strchr(str, '_'))) {
-               /* if searching for something with an equal char, maybe 
-                * we should try to match the non-decoded string. 
-                * In case it was not qp-encoded. */
-               if (!g_utf8_validate(str, -1, NULL)) {
-                       utf = conv_codeset_strdup
-                               (str, conv_get_locale_charset_str_no_utf8(),
-                                CS_INTERNAL);
-                       res = matcherprop_string_match(prop, utf, debug_context);
-                       g_free(utf);
-               } else {
-                       res = matcherprop_string_match(prop, str, debug_context);
-               }
-       }
-
-       /* FIXME base64 decoding is too slow, especially since text can 
-        * easily be handled as base64. Don't even try now. */
-
+       line = g_strdup_printf("%s %s", hdr, str);
+       res = matcherprop_string_match(prop, line, debug_context);
+       g_free(line);
+       
        return res;
 }
 
@@ -1281,13 +1252,23 @@ static gboolean matcherprop_match_one_header(MatcherProp *matcher,
                }
                break;
        case MATCHCRITERIA_HEADERS_PART:
-               return matcherprop_string_match(matcher, buf, _("header line"));
-       case MATCHCRITERIA_NOT_HEADERS_PART:
-               return !matcherprop_string_match(matcher, buf, _("headers line"));
        case MATCHCRITERIA_MESSAGE:
-               return matcherprop_string_decode_match(matcher, buf, _("message line"));
+               header = procheader_parse_header(buf);
+               if (!header)
+                       return FALSE;
+               result = matcherprop_header_line_match(matcher, 
+                              header->name, header->body, _("header line"));
+               procheader_header_free(header);
+               return result;
+       case MATCHCRITERIA_NOT_HEADERS_PART:
        case MATCHCRITERIA_NOT_MESSAGE:
-               return !matcherprop_string_decode_match(matcher, buf, _("message line"));
+               header = procheader_parse_header(buf);
+               if (!header)
+                       return FALSE;
+               result = !matcherprop_header_line_match(matcher, 
+                              header->name, header->body, _("header line"));
+               procheader_header_free(header);
+               return result;
        case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK:
        case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK:
                {
@@ -1491,28 +1472,6 @@ static gboolean matcherprop_criteria_body(const MatcherProp *matcher)
        }
 }
 
-/*!
- *\brief       Check if a (line) string matches the criteria
- *             described by a matcher structure
- *
- *\param       matcher Matcher structure
- *\param       line String
- *
- *\return      gboolean TRUE if string matches criteria
- */
-static gboolean matcherprop_match_line(MatcherProp *matcher, const gchar *line)
-{
-       switch (matcher->criteria) {
-       case MATCHCRITERIA_BODY_PART:
-       case MATCHCRITERIA_MESSAGE:
-               return matcherprop_string_decode_match(matcher, line, _("body line"));
-       case MATCHCRITERIA_NOT_BODY_PART:
-       case MATCHCRITERIA_NOT_MESSAGE:
-               return !matcherprop_string_decode_match(matcher, line, _("body line"));
-       }
-       return FALSE;
-}
-
 /*!
  *\brief       Check if a line in a message file's body matches
  *             the criteria
@@ -1522,45 +1481,94 @@ static gboolean matcherprop_match_line(MatcherProp *matcher, const gchar *line)
  *
  *\return      gboolean TRUE if succesful match
  */
-static gboolean matcherlist_match_body(MatcherList *matchers, FILE *fp)
+static gboolean matcherlist_match_body(MatcherList *matchers, gboolean body_only, MsgInfo *info)
 {
        GSList *l;
+       MimeInfo *mimeinfo = NULL;
+       MimeInfo *partinfo = NULL;
        gchar buf[BUFFSIZE];
-       
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               for (l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
-                       MatcherProp *matcher = (MatcherProp *) l->data;
-                       
-                       if (matcher->done) 
-                               continue;
+       gboolean first_text_found = FALSE;
+       FILE *outfp = NULL;
 
-                       /* if the criteria is ~body_part or ~message, ZERO lines
-                        * must NOT match for the rule to match. */
-                       if (matcher->criteria == MATCHCRITERIA_NOT_BODY_PART ||
-                           matcher->criteria == MATCHCRITERIA_NOT_MESSAGE) {
-                               if (matcherprop_match_line(matcher, buf)) {
-                                       matcher->result = TRUE;
-                               } else {
-                                       matcher->result = FALSE;
-                                       matcher->done = TRUE;
-                               }
-                       /* else, just one line has to match */
-                       } else if (matcherprop_criteria_body(matcher) ||
-                                  matcherprop_criteria_message(matcher)) {
-                               if (matcherprop_match_line(matcher, buf)) {
-                                       matcher->result = TRUE;
-                                       matcher->done = TRUE;
+       cm_return_val_if_fail(info != NULL, FALSE);
+
+       mimeinfo = procmime_scan_message(info);
+
+       /* Skip headers */
+       partinfo = procmime_mimeinfo_next(mimeinfo);
+
+       for (; partinfo != NULL; partinfo = procmime_mimeinfo_next(partinfo)) {
+
+               if (partinfo->type != MIMETYPE_TEXT && body_only)
+                       continue;
+
+               if (partinfo->type == MIMETYPE_TEXT) {
+                       first_text_found = TRUE;
+                       outfp = procmime_get_text_content(partinfo);
+               } else
+                       outfp = procmime_get_binary_content(partinfo);
+
+               if (!outfp) {
+                       procmime_mimeinfo_free_all(mimeinfo);
+                       return FALSE;
+               }
+
+               while (fgets(buf, sizeof(buf), outfp) != NULL) {
+                       strretchomp(buf);
+
+                       for (l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
+                               MatcherProp *matcher = (MatcherProp *) l->data;
+
+                               if (matcher->done) 
+                                       continue;
+
+                               /* Don't scan non-text parts when looking in body, only
+                                * when looking in whole message
+                                */
+                               if (partinfo && partinfo->type != MIMETYPE_TEXT &&
+                               (matcher->criteria == MATCHCRITERIA_NOT_BODY_PART ||
+                               matcher->criteria == MATCHCRITERIA_BODY_PART))
+                                       continue;
+
+                               /* if the criteria is ~body_part or ~message, ZERO lines
+                                * must match for the rule to match.
+                                */
+                               if (matcher->criteria == MATCHCRITERIA_NOT_BODY_PART ||
+                                   matcher->criteria == MATCHCRITERIA_NOT_MESSAGE) {
+                                       if (matcherprop_string_match(matcher, buf, 
+                                                               _("body line"))) {
+                                               matcher->result = FALSE;
+                                               matcher->done = TRUE;
+                                       } else
+                                               matcher->result = TRUE;
+                               /* else, just one line has to match */
+                               } else if (matcherprop_criteria_body(matcher) ||
+                                          matcherprop_criteria_message(matcher)) {
+                                       if (matcherprop_string_match(matcher, buf,
+                                                               _("body line"))) {
+                                               matcher->result = TRUE;
+                                               matcher->done = TRUE;
+                                       }
                                }
-                       }
 
-                       /* if the matchers are OR'ed and the rule matched,
-                        * no need to check the others. */
-                       if (matcher->result && matcher->done) {
-                               if (!matchers->bool_and)
-                                       return TRUE;
+                               /* if the matchers are OR'ed and the rule matched,
+                                * no need to check the others. */
+                               if (matcher->result && matcher->done) {
+                                       if (!matchers->bool_and) {
+                                               procmime_mimeinfo_free_all(mimeinfo);
+                                               fclose(outfp);
+                                               return TRUE;
+                                       }
+                               }
                        }
                }
+               fclose(outfp);
+
+               if (body_only && first_text_found)
+                       break;
        }
+       procmime_mimeinfo_free_all(mimeinfo);
+
        return FALSE;
 }
 
@@ -1578,6 +1586,7 @@ static gboolean matcherlist_match_file(MatcherList *matchers, MsgInfo *info,
 {
        gboolean read_headers;
        gboolean read_body;
+       gboolean body_only;
        GSList *l;
        FILE *fp;
        gchar *file;
@@ -1586,6 +1595,7 @@ static gboolean matcherlist_match_file(MatcherList *matchers, MsgInfo *info,
 
        read_headers = FALSE;
        read_body = FALSE;
+       body_only = TRUE;
        for (l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
                MatcherProp *matcher = (MatcherProp *) l->data;
 
@@ -1596,6 +1606,7 @@ static gboolean matcherlist_match_file(MatcherList *matchers, MsgInfo *info,
                if (matcherprop_criteria_message(matcher)) {
                        read_headers = TRUE;
                        read_body = TRUE;
+                       body_only = FALSE;
                }
                matcher->result = FALSE;
                matcher->done = FALSE;
@@ -1625,7 +1636,7 @@ static gboolean matcherlist_match_file(MatcherList *matchers, MsgInfo *info,
 
        /* read the body */
        if (read_body) {
-               matcherlist_match_body(matchers, fp);
+               matcherlist_match_body(matchers, body_only, info);
        }
        
        for (l = matchers->matchers; l != NULL; l = g_slist_next(l)) {
index 7783f99..36dae9b 100644 (file)
@@ -190,8 +190,8 @@ MimeInfo *procmime_scan_message(MsgInfo *msginfo)
 {
        gchar *filename;
        MimeInfo *mimeinfo;
-       START_TIMING("");
-       filename = procmsg_get_message_file_path(msginfo);
+
+       filename = procmsg_get_message_file_path(msginfo);
        if (!filename || !is_file_exist(filename)) {
                g_free(filename);
                return NULL;
@@ -204,7 +204,6 @@ MimeInfo *procmime_scan_message(MsgInfo *msginfo)
                mimeinfo = procmime_scan_queue_file(filename);
        g_free(filename);
 
-       END_TIMING();
        return mimeinfo;
 }
 
@@ -672,7 +671,7 @@ gint procmime_get_part(const gchar *outfile, MimeInfo *mimeinfo)
        return 0;
 }
 
-static FILE *procmime_get_text_content(MimeInfo *mimeinfo)
+FILE *procmime_get_text_content(MimeInfo *mimeinfo)
 {
        FILE *tmpfp, *outfp;
        const gchar *src_codeset;
@@ -778,6 +777,38 @@ static FILE *procmime_get_text_content(MimeInfo *mimeinfo)
        return outfp;
 }
 
+FILE *procmime_get_binary_content(MimeInfo *mimeinfo)
+{
+       FILE *outfp;
+       gchar *tmpfile;
+
+       cm_return_val_if_fail(mimeinfo != NULL, NULL);
+
+       if (!procmime_decode_content(mimeinfo))
+               return NULL;
+
+       tmpfile = procmime_get_tmp_file_name(mimeinfo);
+       if (tmpfile == NULL)
+               return NULL;
+
+       if (procmime_get_part(tmpfile, mimeinfo) < 0) {
+               g_free(tmpfile);
+               return NULL;
+       }
+
+       outfp = g_fopen(tmpfile, "rb");
+       if (outfp == NULL) {
+               g_unlink(tmpfile);
+               g_free(tmpfile);
+               return NULL;
+       }
+
+       g_unlink(tmpfile);
+       g_free(tmpfile);
+
+       return outfp;
+}
+
 /* search the first text part of (multipart) MIME message,
    decode, convert it and output to outfp. */
 FILE *procmime_get_first_text_content(MsgInfo *msginfo)
@@ -785,8 +816,8 @@ FILE *procmime_get_first_text_content(MsgInfo *msginfo)
        FILE *outfp = NULL;
        MimeInfo *mimeinfo, *partinfo;
        gboolean empty_ok = FALSE, short_scan = TRUE;
-       START_TIMING("");
-       cm_return_val_if_fail(msginfo != NULL, NULL);
+
+       cm_return_val_if_fail(msginfo != NULL, NULL);
 
        /* first we try to short-scan (for speed), refusing empty parts */
 scan_again:
@@ -819,7 +850,6 @@ scan_again:
                goto scan_again;
        }
        procmime_mimeinfo_free_all(mimeinfo);
-       END_TIMING();
        return outfp;
 }
 
@@ -904,68 +934,6 @@ gboolean procmime_msginfo_is_encrypted(MsgInfo *msginfo)
        return result;
 }
 
-static gboolean procmime_find_string_part(MimeInfo *mimeinfo, const gchar *filename,
-                                  const gchar *str, StrFindFunc find_func)
-{
-       FILE *outfp;
-       gchar buf[BUFFSIZE];
-
-       cm_return_val_if_fail(mimeinfo != NULL, FALSE);
-       cm_return_val_if_fail(mimeinfo->type == MIMETYPE_TEXT, FALSE);
-       cm_return_val_if_fail(str != NULL, FALSE);
-       cm_return_val_if_fail(find_func != NULL, FALSE);
-
-       outfp = procmime_get_text_content(mimeinfo);
-
-       if (!outfp)
-               return FALSE;
-
-       while (fgets(buf, sizeof(buf), outfp) != NULL) {
-               strretchomp(buf);
-               if (find_func(buf, str)) {
-                       fclose(outfp);
-                       return TRUE;
-               }
-       }
-
-       fclose(outfp);
-
-       return FALSE;
-}
-
-gboolean procmime_find_string(MsgInfo *msginfo, const gchar *str,
-                             StrFindFunc find_func)
-{
-       MimeInfo *mimeinfo;
-       MimeInfo *partinfo;
-       gchar *filename;
-       gboolean found = FALSE;
-
-       cm_return_val_if_fail(msginfo != NULL, FALSE);
-       cm_return_val_if_fail(str != NULL, FALSE);
-       cm_return_val_if_fail(find_func != NULL, FALSE);
-
-       filename = procmsg_get_message_file(msginfo);
-       if (!filename) return FALSE;
-       mimeinfo = procmime_scan_message(msginfo);
-
-       for (partinfo = mimeinfo; partinfo != NULL;
-            partinfo = procmime_mimeinfo_next(partinfo)) {
-               if (partinfo->type == MIMETYPE_TEXT) {
-                       if (procmime_find_string_part
-                               (partinfo, filename, str, find_func) == TRUE) {
-                               found = TRUE;
-                               break;
-                       }
-               }
-       }
-
-       procmime_mimeinfo_free_all(mimeinfo);
-       g_free(filename);
-
-       return found;
-}
-
 gchar *procmime_get_tmp_file_name(MimeInfo *mimeinfo)
 {
        static guint32 id = 0;
index 122a530..67ce061 100644 (file)
@@ -205,10 +205,6 @@ FILE *procmime_get_first_text_content      (MsgInfo        *msginfo);
 FILE *procmime_get_first_encrypted_text_content
                                        (MsgInfo        *msginfo);
 
-gboolean procmime_find_string          (MsgInfo        *msginfo,
-                                        const gchar    *str,
-                                        StrFindFunc     find_func);
-
 gchar *procmime_get_tmp_file_name      (MimeInfo       *mimeinfo);
 gchar *procmime_get_part_file_name     (MimeInfo       *mimeinfo);
 
@@ -237,6 +233,8 @@ gint procmime_write_mimeinfo(MimeInfo *mimeinfo, FILE *fp);
 
 void procmime_mimeparser_register(MimeParser *mimeparser);
 void procmime_mimeparser_unregister(MimeParser *mimeparser);
+FILE *procmime_get_text_content(MimeInfo *mimeinfo);
+FILE *procmime_get_binary_content(MimeInfo *mimeinfo);
 
 #ifdef __cplusplus
 }
index 82a2b58..aa325ce 100644 (file)
@@ -502,10 +502,10 @@ static void summary_search_execute(gboolean backward, gboolean search_all)
        gchar *from_str = NULL, *to_str = NULL, *subject_str = NULL;
        gchar *body_str = NULL;
        gchar *adv_condition = NULL;
-       StrFindFunc str_find_func = NULL;
        gboolean is_fast = TRUE;
        gint interval = 1000;
        gint i = 0;
+       GSList *matchers = NULL;
 
        if (summary_is_locked(summaryview)) {
                return;
@@ -515,11 +515,11 @@ static void summary_search_execute(gboolean backward, gboolean search_all)
        adv_search = gtk_toggle_button_get_active
                (GTK_TOGGLE_BUTTON(search_window.adv_search_checkbtn));
 
+       if (search_window.matcher_list != NULL) {
+               matcherlist_free(search_window.matcher_list);
+               search_window.matcher_list = NULL;
+       }
        if (adv_search) {
-               if (search_window.matcher_list != NULL) {
-                       matcherlist_free(search_window.matcher_list);
-                       search_window.matcher_list = NULL;
-               }
                adv_condition = gtk_combo_box_get_active_text(GTK_COMBO_BOX(search_window.adv_condition_entry));
                if (!adv_condition)
                        adv_condition = gtk_editable_get_chars(
@@ -550,12 +550,6 @@ static void summary_search_execute(gboolean backward, gboolean search_all)
                case_sens = gtk_toggle_button_get_active
                        (GTK_TOGGLE_BUTTON(search_window.case_checkbtn));
 
-               if (case_sens) {
-                       str_find_func = str_find;
-               } else {
-                       str_find_func = str_case_find;
-               }
-
                from_str    = gtk_combo_box_get_active_text(GTK_COMBO_BOX(search_window.from_entry));
                to_str      = gtk_combo_box_get_active_text(GTK_COMBO_BOX(search_window.to_entry));
                subject_str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(search_window.subject_entry));
@@ -591,30 +585,51 @@ static void summary_search_execute(gboolean backward, gboolean search_all)
                }
 
                /* add to history */
-               if (from_str[0] != '\0')
+               if (from_str[0] != '\0') {
+                       MatcherProp *prop = matcherprop_new(MATCHCRITERIA_FROM,
+                                               NULL, case_sens ? MATCHTYPE_MATCH:MATCHTYPE_MATCHCASE,
+                                               from_str, 0);
+                       matchers = g_slist_append(matchers, prop);
                        combobox_unset_popdown_strings(GTK_COMBO_BOX(search_window.from_entry));
                        prefs_common.summary_search_from_history = add_history(
                                        prefs_common.summary_search_from_history, from_str);
                        combobox_set_popdown_strings(GTK_COMBO_BOX(search_window.from_entry),
                                        prefs_common.summary_search_from_history);
-               if (to_str[0] != '\0')
+               }
+               if (to_str[0] != '\0') {
+                       MatcherProp *prop = matcherprop_new(MATCHCRITERIA_TO,
+                                               NULL, case_sens ? MATCHTYPE_MATCH:MATCHTYPE_MATCHCASE,
+                                               to_str, 0);
+                       matchers = g_slist_append(matchers, prop);
                        combobox_unset_popdown_strings(GTK_COMBO_BOX(search_window.to_entry));
                        prefs_common.summary_search_to_history = add_history(
                                        prefs_common.summary_search_to_history, to_str);
                        combobox_set_popdown_strings(GTK_COMBO_BOX(search_window.to_entry),
                                        prefs_common.summary_search_to_history);
-               if (subject_str[0] != '\0')
+               }
+               if (subject_str[0] != '\0') {
+                       MatcherProp *prop = matcherprop_new(MATCHCRITERIA_SUBJECT,
+                                               NULL, case_sens ? MATCHTYPE_MATCH:MATCHTYPE_MATCHCASE,
+                                               subject_str, 0);
+                       matchers = g_slist_append(matchers, prop);
                        combobox_unset_popdown_strings(GTK_COMBO_BOX(search_window.subject_entry));
                        prefs_common.summary_search_subject_history = add_history(
                                        prefs_common.summary_search_subject_history, subject_str);
                        combobox_set_popdown_strings(GTK_COMBO_BOX(search_window.subject_entry),
                                        prefs_common.summary_search_subject_history);
-               if (body_str[0] != '\0')
+               }
+               if (body_str[0] != '\0') {
+                       MatcherProp *prop = matcherprop_new(MATCHCRITERIA_BODY_PART,
+                                               NULL, case_sens ? MATCHTYPE_MATCH:MATCHTYPE_MATCHCASE,
+                                               body_str, 0);
+                       matchers = g_slist_append(matchers, prop);
                        combobox_unset_popdown_strings(GTK_COMBO_BOX(search_window.body_entry));
                        prefs_common.summary_search_body_history = add_history(
                                        prefs_common.summary_search_body_history, body_str);
                        combobox_set_popdown_strings(GTK_COMBO_BOX(search_window.body_entry),
                                        prefs_common.summary_search_body_history);
+               }
+               search_window.matcher_list = matcherlist_new(matchers, bool_and);
        }
 
        search_window.is_searching = TRUE;
@@ -694,67 +709,7 @@ static void summary_search_execute(gboolean backward, gboolean search_all)
                msginfo = gtk_cmctree_node_get_row_data(ctree, node);
                body_matched = FALSE;
 
-               if (adv_search) {
-                       matched = matcherlist_match(search_window.matcher_list, msginfo);
-               } else {
-                       if (bool_and) {
-                               matched = TRUE;
-                               if (*from_str) {
-                                       if (!msginfo->from ||
-                                       !str_find_func(msginfo->from, from_str)) {
-                                               matched = FALSE;
-                                       }
-                               }
-                               if (matched && *to_str) {
-                                       if (!msginfo->to ||
-                                       !str_find_func(msginfo->to, to_str)) {
-                                               matched = FALSE;
-                                       }
-                               }
-                               if (matched && *subject_str) {
-                                       if (!msginfo->subject ||
-                                       !str_find_func(msginfo->subject, subject_str)) {
-                                               matched = FALSE;
-                                       }
-                               }
-                               if (matched && *body_str) {
-                                       if (procmime_find_string(msginfo, body_str,
-                                                                str_find_func)) {
-                                               body_matched = TRUE;
-                                       } else {
-                                               matched = FALSE;
-                                       }
-                               }
-                               if (matched && !*from_str && !*to_str &&
-                               !*subject_str && !*body_str) {
-                                       matched = FALSE;
-                               }
-                       } else {
-                               matched = FALSE;
-                               if (*from_str && msginfo->from) {
-                                       if (str_find_func(msginfo->from, from_str)) {
-                                               matched = TRUE;
-                                       }
-                               }
-                               if (!matched && *to_str && msginfo->to) {
-                                       if (str_find_func(msginfo->to, to_str)) {
-                                               matched = TRUE;
-                                       }
-                               }
-                               if (!matched && *subject_str && msginfo->subject) {
-                                       if (str_find_func(msginfo->subject, subject_str)) {
-                                               matched = TRUE;
-                                       }
-                               }
-                               if (!matched && *body_str) {
-                                       if (procmime_find_string(msginfo, body_str,
-                                                                str_find_func)) {
-                                               matched = TRUE;
-                                               body_matched = TRUE;
-                                       }
-                               }
-                       }
-               }
+               matched = matcherlist_match(search_window.matcher_list, msginfo);
 
                if (matched) {
                        if (search_all) {