int filter_rule_add(filter_t *filter, int include, const char *pattern) { filter_rule_t **rules = realloc(filter->rules, sizeof(filter_rule_t*)*(filter->rule_count+1)); if (!rules) { perror("out of memory"); return -1; } filter->rules = rules; filter_rule_t *rule = malloc(sizeof(filter_rule_t)); if (!rule) { perror("out of memory"); return -1; } rules[filter->rule_count] = rule; if (filter_rule_init(rule, include, pattern)) { fprintf(stderr, "filter_rule_init failed\n"); free(rule); return -1; } filter->rule_count++; if (_filter_match_add(filter->match, rule, 0)) { fprintf(stderr, "_filter_match_add failed\n"); filter_rule_free(rule); free(rule); return -1; } return 0; }
void filter_free(filter_t *filter) { for (size_t i = 0; i < filter->rule_count; i++) { filter_rule_free(filter->rules[i]); free(filter->rules[i]); } if (filter->rules) { free(filter->rules); } for (size_t i = 0; i < filter->max_depth; i++) { free(filter->match[i].rules); free(filter->match[i].idx); } if (filter->max_depth) { free(filter->match); } }
GSList *quick_search_filter(QuickSearch *qsearch, QSearchCondType type, const gchar *key) { SummaryView *summaryview = qsearch->summaryview; FilterCondType ftype; FilterRule *status_rule = NULL; FilterRule *rule = NULL; FilterCond *cond; FilterInfo fltinfo; GSList *cond_list = NULL; GSList *rule_list = NULL; GSList *flt_mlist = NULL; GSList *cur; gint count = 0, total = 0; gchar status_text[1024]; gboolean dmode; if (!summaryview->all_mlist) return NULL; debug_print("quick_search_filter: filtering summary (type: %d)\n", type); switch (type) { case QS_UNREAD: case QS_MARK: case QS_CLABEL: case QS_MIME: ftype = qsearch_cond_types[type].ftype; cond = filter_cond_new(ftype, 0, 0, NULL, NULL); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_W1DAY: cond = filter_cond_new(FLT_COND_AGE_GREATER, 0, FLT_NOT_MATCH, NULL, "1"); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_LAST5: cond = filter_cond_new(FLT_COND_AGE_GREATER, 0, FLT_NOT_MATCH, NULL, "5"); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_LAST7: cond = filter_cond_new(FLT_COND_AGE_GREATER, 0, FLT_NOT_MATCH, NULL, "7"); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_LAST30: cond = filter_cond_new(FLT_COND_AGE_GREATER, 0, FLT_NOT_MATCH, NULL, "30"); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_IN_ADDRESSBOOK: cond = filter_cond_new(FLT_COND_HEADER, FLT_IN_ADDRESSBOOK, 0, "From", NULL); cond_list = g_slist_append(cond_list, cond); status_rule = filter_rule_new("Status filter rule", FLT_OR, cond_list, NULL); break; case QS_ALL: default: break; } if (key) { gchar **keys; gint i; keys = g_strsplit(key, " ", -1); for (i = 0; keys[i] != NULL; i++) { cond_list = NULL; if (keys[i] == '\0') continue; cond = filter_cond_new(FLT_COND_HEADER, FLT_CONTAIN, 0, "Subject", keys[i]); cond_list = g_slist_append(cond_list, cond); cond = filter_cond_new(FLT_COND_HEADER, FLT_CONTAIN, 0, "From", keys[i]); cond_list = g_slist_append(cond_list, cond); if (FOLDER_ITEM_IS_SENT_FOLDER(summaryview->folder_item)) { cond = filter_cond_new(FLT_COND_TO_OR_CC, FLT_CONTAIN, 0, NULL, keys[i]); cond_list = g_slist_append(cond_list, cond); } if (cond_list) { rule = filter_rule_new("Quick search rule", FLT_OR, cond_list, NULL); rule_list = g_slist_append(rule_list, rule); } } g_strfreev(keys); } memset(&fltinfo, 0, sizeof(FilterInfo)); dmode = get_debug_mode(); set_debug_mode(FALSE); for (cur = summaryview->all_mlist; cur != NULL; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; GSList *hlist = NULL; gboolean matched = TRUE; total++; if (status_rule) { if (type == QS_IN_ADDRESSBOOK) hlist = procheader_get_header_list_from_msginfo (msginfo); if (!filter_match_rule(status_rule, msginfo, hlist, &fltinfo)) { if (hlist) procheader_header_list_destroy(hlist); continue; } } if (rule_list) { GSList *rcur; if (!hlist) hlist = procheader_get_header_list_from_msginfo (msginfo); /* AND keyword match */ for (rcur = rule_list; rcur != NULL; rcur = rcur->next) { rule = (FilterRule *)rcur->data; if (!filter_match_rule(rule, msginfo, hlist, &fltinfo)) { matched = FALSE; break; } } } if (matched) { flt_mlist = g_slist_prepend(flt_mlist, msginfo); count++; } if (hlist) procheader_header_list_destroy(hlist); } flt_mlist = g_slist_reverse(flt_mlist); set_debug_mode(dmode); if (status_rule || rule) { if (count > 0) g_snprintf(status_text, sizeof(status_text), _("%1$d in %2$d matched"), count, total); else g_snprintf(status_text, sizeof(status_text), _("No messages matched")); gtk_label_set_text(GTK_LABEL(qsearch->status_label), status_text); } else gtk_label_set_text(GTK_LABEL(qsearch->status_label), ""); filter_rule_list_free(rule_list); filter_rule_free(status_rule); return flt_mlist; }