From 6c292f6b369f019cc9a72a0ee65d60e172ee3370 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 26 Nov 2006 18:09:23 +0100 Subject: [PATCH] make mutt_match_spam_list a generic rx function: rx_list_match2 that does the same as rx_list_match + expand a template into the given buffer. Signed-off-by: Pierre Habouzit --- lib-lib/rx.c | 48 +++++++++++++++++++++++++++++++++++++++--- lib-lib/rx.h | 1 + lib-mime/rfc822parse.c | 38 +++++++++++++++------------------ muttlib.c | 42 ------------------------------------ protos.h | 1 - 5 files changed, 63 insertions(+), 67 deletions(-) diff --git a/lib-lib/rx.c b/lib-lib/rx.c index 8604ad5..21cbd33 100644 --- a/lib-lib/rx.c +++ b/lib-lib/rx.c @@ -67,13 +67,13 @@ void rx_delete(rx_t **p) p_delete(p); } -int rx_list_match(rx_t *l, const char *pat) +int rx_list_match(rx_t *l, const char *s) { - if (!pat || !*pat) + if (m_strisempty(s)) return 0; while (l) { - if (!REGEXEC(l->rx, pat)) + if (!REGEXEC(l->rx, s)) return 1; l = l->next; } @@ -81,6 +81,48 @@ int rx_list_match(rx_t *l, const char *pat) return 0; } +int rx_list_match2(rx_t *l, const char *s, char *dst, int dlen) +{ + static regmatch_t *pmatch = NULL; + static int nmatch = 0; + int pos = 0; + + if (m_strisempty(s)) + return 0; + + for (; l; l = l->next) { + if (l->nmatch > nmatch) { + p_realloc(&pmatch, l->nmatch); + nmatch = l->nmatch; + } + + if (regexec(l->rx, s, l->nmatch, pmatch, 0) == 0) { + /* Copy template into dst, with substitutions. */ + const char *p = l->template, *q; + + for (q = strchr(p, '%'); q; q = strchr(p + 1, '%')) { + int n; + + pos += m_strncpy(dst + pos, dlen - pos, p, q - p); + + if (!isdigit((unsigned char)q[1])) { + p = q + (q[1] == '%'); + continue; + } + + n = strtol(q + 1, (char **)&p, 10); /* find pmatch index */ + pos += m_strncpy(dst + pos, dlen - pos, s + pmatch[n].rm_so, + pmatch[n].rm_eo - pmatch[n].rm_so); + } + + pos += m_strcpy(dst + pos, dlen - pos, p); + return 1; + } + } + + return 0; +} + rx_t **rx_lookup(rx_t **l, const char *pat) { if (!pat || !*pat) diff --git a/lib-lib/rx.h b/lib-lib/rx.h index a827b82..af86374 100644 --- a/lib-lib/rx.h +++ b/lib-lib/rx.h @@ -55,6 +55,7 @@ DO_SLIST(rx_t, rx, rx_delete); /* for handling lists */ int rx_list_match(rx_t *, const char*); /* match all items list agains string */ +int rx_list_match2(rx_t *l, const char *s, char *dst, int dlen); rx_t **rx_lookup(rx_t**, const char*); /* lookup pattern */ int rx_sanitize_string(char *, ssize_t, const char *); diff --git a/lib-mime/rfc822parse.c b/lib-mime/rfc822parse.c index 65b03b4..b03a17a 100644 --- a/lib-mime/rfc822parse.c +++ b/lib-mime/rfc822parse.c @@ -1044,29 +1044,25 @@ mutt_read_rfc822_header(FILE *f, HEADER *hdr, short user_hdrs, short weed) break; /* end of header */ } - if (mutt_match_spam_list(line, SpamList, buf, sizeof(buf))) { - if (!rx_list_match(NoSpamList, line)) { - /* if spam tag already exists, figure out how to amend it */ - if (e->spam && *buf) { - if (SpamSep) { - /* If SpamSep defined, append with separator */ - mutt_buffer_addstr(e->spam, SpamSep); - mutt_buffer_addstr(e->spam, buf); - } else { - /* else overwrite */ - mutt_buffer_reset(e->spam); - mutt_buffer_addstr(e->spam, buf); - } - } - else if (!e->spam && *buf) { - /* spam tag is new, and match expr is non-empty; copy */ - e->spam = mutt_buffer_from(NULL, buf); - } - else if (!e->spam) { - /* match expr is empty; plug in null string if no existing tag */ - e->spam = mutt_buffer_from(NULL, ""); + if (rx_list_match2(SpamList, line, buf, sizeof(buf)) + && !rx_list_match(NoSpamList, line)) + { + /* if spam tag already exists, figure out how to amend it */ + if (e->spam && *buf) { + if (SpamSep) { + /* If SpamSep defined, append with separator */ + mutt_buffer_addstr(e->spam, SpamSep); + mutt_buffer_addstr(e->spam, buf); + } else { + /* else overwrite */ + mutt_buffer_reset(e->spam); + mutt_buffer_addstr(e->spam, buf); } } + + if (!e->spam) { + e->spam = mutt_buffer_from(NULL, buf); + } } *p++ = '\0'; diff --git a/muttlib.c b/muttlib.c index 1f6b751..65007ae 100644 --- a/muttlib.c +++ b/muttlib.c @@ -618,48 +618,6 @@ const char *mutt_make_version (int full) return vstring; } -int mutt_match_spam_list (const char *s, rx_t * l, char *text, int x) -{ - static regmatch_t *pmatch = NULL; - static int nmatch = 0; - int i, n, tlen; - char *p; - - if (!s) - return 0; - - tlen = 0; - - for (; l; l = l->next) { - /* If this pattern needs more matches, expand pmatch. */ - if (l->nmatch > nmatch) { - p_realloc(&pmatch, l->nmatch); - nmatch = l->nmatch; - } - - /* Does this pattern match? */ - if (regexec(l->rx, s, l->nmatch, (regmatch_t *)pmatch, (int) 0) == 0) { - /* Copy template into text, with substitutions. */ - for (p = l->template; *p;) { - if (*p == '%') { - n = atoi (++p); /* find pmatch index */ - while (isdigit ((unsigned char) *p)) - ++p; /* skip subst token */ - for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < x); i++) - text[tlen++] = s[i]; - } - else { - text[tlen++] = *p++; - } - } - text[tlen] = '\0'; - return 1; - } - } - - return 0; -} - /* return 1 if address lists are strictly identical */ static int mutt_cmp_addr (const address_t * a, const address_t * b) { diff --git a/protos.h b/protos.h index 20b04ac..acad95d 100644 --- a/protos.h +++ b/protos.h @@ -130,7 +130,6 @@ int mutt_invoke_mta (address_t *, address_t *, address_t *, address_t *, const c int mutt_is_list_cc (int, address_t *, address_t *); int mutt_is_list_recipient (int, address_t *, address_t *); int mutt_lookup_mime_type (BODY *, const char *); -int mutt_match_spam_list (const char *, rx_t *, char *, int); int mutt_num_postponed (int); int mutt_parse_bind (BUFFER *, BUFFER *, unsigned long, BUFFER *); int mutt_parse_exec (BUFFER *, BUFFER *, unsigned long, BUFFER *); -- 2.20.1