{MATCHCRITERIA_SCORE_LOWER, "score_lower"},
{MATCHCRITERIA_SCORE_EQUAL, "score_equal"},
+ {MATCHCRITERIA_SIZE_GREATER, "size_greater"},
+ {MATCHCRITERIA_SIZE_SMALLER, "size_smaller"},
+ {MATCHCRITERIA_SIZE_EQUAL, "size_equal"},
+
/* content have to be read */
{MATCHCRITERIA_HEADER, "header"},
{MATCHCRITERIA_NOT_HEADER, "~header"},
{MATCHACTION_FORWARD_AS_ATTACHMENT, "forward_as_attachment"},
{MATCHACTION_EXECUTE, "execute"},
{MATCHACTION_COLOR, "color"},
- {MATCHACTION_BOUNCE, "bounce"}
+ {MATCHACTION_BOUNCE, "bounce"},
+ {MATCHACTION_DELETE_ON_SERVER, "delete_on_server"}
};
-/*
- syntax for matcher
-
- header "x-mailing" match "toto" score -10
- subject match "regexp" & to regexp "regexp" score 50
- subject match "regexp" | to regexpcase "regexp" | age_sup 5 score 30
-
-*/
-
+/* get_matchparser_tab_str() - used by filtering.c to translate
+ * actions to debug strings */
gchar * get_matchparser_tab_str(gint id)
{
gint i;
return NULL;
}
+/* matcher_escape_str() - escapes a string returns newly allocated escaped string */
+gchar *matcher_escape_str(const gchar *str)
+{
+ register const gchar *walk;
+ register int escape;
+ gchar *res;
+ register char *reswalk;
+
+ if (str == NULL)
+ return NULL;
+
+ for (escape = 0, walk = str; *walk; walk++)
+ if (*walk == '\'' || *walk == '\"')
+ escape++;
+
+ if (!escape)
+ return g_strdup(str);
+
+ reswalk = res = g_new0(gchar, (walk - str) + escape + 1);
+ for (walk = str; *walk; walk++, reswalk++) {
+ if (*walk == '\'' || *walk == '\"')
+ *reswalk++ = '\\';
+ *reswalk = *walk;
+ }
+ *reswalk = 0;
+ return res;
+}
+/* matcher_unescape_str() - assumes that unescaping frees up room
+ * in the string, so it returns the unescaped string in the
+ * source */
gchar *matcher_unescape_str(gchar *str)
{
gchar *tmp = alloca(strlen(str) + 1);
else {
src++;
if (*src == '\\')
- *dst++ = '\\';
- else if (*src == 'n')
+ *dst++ = '\\'; /* insert backslash */
+ else if (*src == 'n') /* insert control characters */
*dst++ = '\n';
else if (*src == 'r')
*dst++ = '\r';
- else if (*src == '\'' || *src == '\"')
+ else if (*src == 't')
+ *dst++ = '\t';
+ else if (*src == 'r')
+ *dst++ = '\r';
+ else if (*src == 'b')
+ *dst++ = '\b';
+ else if (*src == 'f')
+ *dst++ = '\f';
+ else if (*src == '\'' || *src == '\"') /* insert \' or \" */
*dst++ = *src;
else {
+ /* FIXME: should perhaps escape character... */
src--;
*dst++ = *src;
}
/* **************** data structure allocation **************** */
-
+/* matcherprop_new() - allocates a structure for one condition
+ */
MatcherProp * matcherprop_new(gint criteria, gchar * header,
gint matchtype, gchar * expr,
int value)
prop = g_new0(MatcherProp, 1);
prop->criteria = criteria;
- if (header != NULL)
- prop->header = g_strdup(header);
- else
- prop->header = NULL;
- if (expr != NULL)
- prop->expr = g_strdup(expr);
- else
- prop->expr = NULL;
+ if (header != NULL) {
+ prop->header = g_strdup(header);
+ prop->unesc_header = matcher_unescape_str(g_strdup(header));
+ }
+ else {
+ prop->header = NULL;
+ prop->unesc_header = NULL;
+ }
+ if (expr != NULL) {
+ prop->expr = g_strdup(expr);
+ prop->unesc_expr = matcher_unescape_str(g_strdup(expr));
+ }
+ else {
+ prop->expr = NULL;
+ prop->unesc_expr = NULL;
+ }
prop->matchtype = matchtype;
prop->preg = NULL;
prop->value = value;
return prop;
}
+/* matcherprop_free()
+ */
void matcherprop_free(MatcherProp * prop)
{
- g_free(prop->expr);
+ if (prop->expr)
+ g_free(prop->expr);
+ if (prop->unesc_expr)
+ g_free(prop->unesc_expr);
+ if (prop->header)
+ g_free(prop->header);
+ if (prop->unesc_header)
+ g_free(prop->unesc_header);
if (prop->preg != NULL) {
regfree(prop->preg);
g_free(prop->preg);
/* ************** match ******************************/
-/* match the given string */
-
+/* matcherprop_string_match() - finds out if a string matches
+ * with a criterium */
static gboolean matcherprop_string_match(MatcherProp * prop, gchar * str)
{
gchar * str1;
case MATCHTYPE_REGEXP:
if (!prop->preg && (prop->error == 0)) {
prop->preg = g_new0(regex_t, 1);
+ /* if regexp then don't use the escaped string */
if (regcomp(prop->preg, prop->expr,
REG_NOSUB | REG_EXTENDED
| ((prop->matchtype == MATCHTYPE_REGEXPCASE)
return FALSE;
case MATCHTYPE_MATCH:
- return (strstr(str, prop->expr) != NULL);
+ return (strstr(str, prop->unesc_expr) != NULL);
+ /* FIXME: put upper in unesc_str */
case MATCHTYPE_MATCHCASE:
- str2 = alloca(strlen(prop->expr) + 1);
- strcpy(str2, prop->expr);
+ str2 = alloca(strlen(prop->unesc_expr) + 1);
+ strcpy(str2, prop->unesc_expr);
g_strup(str2);
str1 = alloca(strlen(str) + 1);
strcpy(str1, str);
if (file == NULL)
return FALSE;
- cmd = matching_build_command(prop->expr, info);
+ cmd = matching_build_command(prop->unesc_expr, info);
if (cmd == NULL)
return FALSE;
return info->score <= prop->value;
case MATCHCRITERIA_SCORE_EQUAL:
return info->score == prop->value;
+ case MATCHCRITERIA_SIZE_GREATER:
+ /* FIXME: info->size is an off_t */
+ return info->size > (off_t) prop->value;
+ case MATCHCRITERIA_SIZE_EQUAL:
+ /* FIXME: info->size is an off_t */
+ return info->size == (off_t) prop->value;
+ case MATCHCRITERIA_SIZE_SMALLER:
+ /* FIXME: info->size is an off_t */
+ return info->size < (off_t) prop->value;
case MATCHCRITERIA_NEWSGROUPS:
return matcherprop_string_match(prop, info->newsgroups);
case MATCHCRITERIA_NOT_NEWSGROUPS:
if (file == NULL)
return FALSE;
- if ((fp = fopen(file, "r")) == NULL) {
+ if ((fp = fopen(file, "rb")) == NULL) {
FILE_OP_ERROR(file, "fopen");
g_free(file);
return result;
MatcherProp * matcher = (MatcherProp *) l->data;
if (matcherprop_criteria_headers(matcher) ||
- matcherprop_criteria_body(matcher) ||
- matcherprop_criteria_message(matcher))
+ matcherprop_criteria_body(matcher) ||
+ matcherprop_criteria_message(matcher)) {
if (matcher->result) {
if (!matchers->bool_and) {
result = TRUE;
result = FALSE;
break;
}
- }
+ }
+ }
}
g_free(file);
case MATCHCRITERIA_SCORE_GREATER:
case MATCHCRITERIA_SCORE_LOWER:
case MATCHCRITERIA_SCORE_EQUAL:
+ case MATCHCRITERIA_SIZE_GREATER:
+ case MATCHCRITERIA_SIZE_SMALLER:
+ case MATCHCRITERIA_SIZE_EQUAL:
case MATCHCRITERIA_EXECUTE:
case MATCHCRITERIA_NOT_EXECUTE:
if (matcherprop_match(matcher, info)) {
case MATCHCRITERIA_SCORE_GREATER:
case MATCHCRITERIA_SCORE_LOWER:
case MATCHCRITERIA_SCORE_EQUAL:
+ case MATCHCRITERIA_SIZE_GREATER:
+ case MATCHCRITERIA_SIZE_SMALLER:
+ case MATCHCRITERIA_SIZE_EQUAL:
return g_strdup_printf("%s %i", criteria_str, matcher->value);
- break;
case MATCHCRITERIA_ALL:
case MATCHCRITERIA_UNREAD:
case MATCHCRITERIA_NOT_UNREAD:
case MATCHTYPE_MATCHCASE:
case MATCHTYPE_REGEXP:
case MATCHTYPE_REGEXPCASE:
- count = 0;
- for(p = matcher->expr; *p != 0 ; p++)
- if (*p == '\"') count ++;
-
- expr_str = g_new(char, strlen(matcher->expr) + count + 1);
-
- for(p = matcher->expr, out = expr_str ; *p != 0 ; p++, out++) {
- if (*p == '\"') {
- *out = '\\'; out++;
- *out = '\"';
- }
- else
- *out = *p;
- }
- * out = '\0';
-
if (matcher->header)
matcher_str =
g_strdup_printf("%s \"%s\" %s \"%s\"",
criteria_str, matcher->header,
- matchtype_str, expr_str);
+ matchtype_str, matcher->expr);
else
matcher_str =
g_strdup_printf("%s %s \"%s\"", criteria_str,
- matchtype_str, expr_str);
-
- g_free(expr_str);
-
- break;
-
- /*
- case MATCHTYPE_REGEXP:
- case MATCHTYPE_REGEXPCASE:
-
- if (matcher->header)
- matcher_str =
- g_strdup_printf("%s \"%s\" %s /%s/",
- criteria_str, matcher->header,
- matchtype_str, matcher->expr);
- else
- matcher_str =
- g_strdup_printf("%s %s /%s/", criteria_str,
matchtype_str, matcher->expr);
-
break;
- */
}
return matcher_str;
return result;
}
-
+/* matching_build_command() - preferably cmd should be unescaped */
gchar * matching_build_command(gchar * cmd, MsgInfo * info)
{
gchar * s = cmd;
gchar * p;
gint size;
- matcher_unescape_str(cmd);
-
size = strlen(cmd) + 1;
while (*s != '\0') {
if (*s == '%') {
return processed_cmd;
}
-
-/* ************************************************************ */
-/* ************************************************************ */
-/* ************************************************************ */
-/* ************************************************************ */
/* ************************************************************ */
-
static void prefs_scoring_write(FILE * fp, GSList * prefs_scoring)
{
GSList * cur;
gchar *filtering_str;
FilteringProp * prop;
- prop = (FilteringProp *) cur->data;
- filtering_str = filteringprop_to_string(prop);
+ if (NULL == (prop = (FilteringProp *) cur->data))
+ continue;
+
+ if (NULL == (filtering_str = filteringprop_to_string(prop)))
+ continue;
if (fputs(filtering_str, fp) == EOF ||
fputc('\n', fp) == EOF) {
}
}
-
-
-
-
-
/* ******************************************************************* */
void prefs_matcher_read_config(void)
prefs_filtering_clear();
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MATCHER_RC, NULL);
- f = fopen(rcpath, "r");
+ f = fopen(rcpath, "rb");
g_free(rcpath);
if (f != NULL)
else {
/* previous version compatibily */
- printf("reading filtering\n");
+ /* printf("reading filtering\n"); */
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
FILTERING_RC, NULL);
- f = fopen(rcpath, "r");
+ f = fopen(rcpath, "rb");
g_free(rcpath);
if (f != NULL) {
fclose(matcher_parserin);
}
- printf("reading scoring\n");
+ /* printf("reading scoring\n"); */
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
SCORING_RC, NULL);
- f = fopen(rcpath, "r");
+ f = fopen(rcpath, "rb");
g_free(rcpath);
if (f != NULL) {