aboutsummaryrefslogtreecommitdiffstats
path: root/src/view.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-15 15:08:31 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-15 15:08:31 +0400
commit99cd57ba7f0e6b9178ccacc6987b0854ed137d83 (patch)
tree1e1cb2993f5b8f1965925180be43f24b31477902 /src/view.c
parent44e9a2cda785d6630b30c90707b7a00deb6b2b35 (diff)
downloadrspamd-99cd57ba7f0e6b9178ccacc6987b0854ed137d83.tar.gz
rspamd-99cd57ba7f0e6b9178ccacc6987b0854ed137d83.zip
* Add ability to make views by recipient
Diffstat (limited to 'src/view.c')
-rw-r--r--src/view.c95
1 files changed, 92 insertions, 3 deletions
diff --git a/src/view.c b/src/view.c
index 9a191fe80..13de5e8a9 100644
--- a/src/view.c
+++ b/src/view.c
@@ -65,6 +65,22 @@ add_view_from (struct rspamd_view * view, char *line)
}
gboolean
+add_view_rcpt (struct rspamd_view * view, char *line)
+{
+ struct rspamd_regexp *re = NULL;
+
+ if (add_map (line, read_host_list, fin_host_list, (void **)&view->rcpt_hash)) {
+ return TRUE;
+ }
+ else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) {
+ view->rcpt_re_list = g_list_prepend (view->rcpt_re_list, re);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
add_view_symbols (struct rspamd_view * view, char *line)
{
struct rspamd_regexp *re = NULL;
@@ -190,6 +206,77 @@ find_view_by_from (GList * views, struct worker_task *task)
return NULL;
}
+G_INLINE_FUNC gboolean
+check_view_rcpt (struct rspamd_view *v, struct worker_task *task)
+{
+ GList *cur, *cur_re;
+ char rcpt_user[256], *p;
+ gint l;
+ struct rspamd_regexp *re;
+
+ cur = task->rcpt;
+ while (cur) {
+ if ((p = strchr (cur->data, '@')) != NULL) {
+ l = MIN (sizeof (rcpt_user) - 1, p - (char *)cur->data);
+ memcpy (rcpt_user, cur->data, l);
+ rcpt_user[l] = '\0';
+ /* First try to lookup in hashtable */
+ if (g_hash_table_lookup (v->rcpt_hash, rcpt_user) != NULL) {
+ return TRUE;
+ }
+ /* Then try to match re */
+ cur_re = v->rcpt_re_list;
+
+ while (cur_re) {
+ re = cur_re->data;
+ if (g_regex_match (re->regexp, rcpt_user, 0, NULL) == TRUE) {
+ return TRUE;
+ }
+ cur_re = g_list_next (cur_re);
+ }
+ }
+ /* Now check the whole recipient */
+ if (g_hash_table_lookup (v->rcpt_hash, cur->data) != NULL) {
+ return TRUE;
+ }
+ /* Then try to match re */
+ cur_re = v->rcpt_re_list;
+
+ while (cur_re) {
+ re = cur_re->data;
+ if (g_regex_match (re->regexp, cur->data, 0, NULL) == TRUE) {
+ return TRUE;
+ }
+ cur_re = g_list_next (cur_re);
+ }
+ cur = g_list_next (cur);
+ }
+
+ return FALSE;
+}
+
+static struct rspamd_view *
+find_view_by_rcpt (GList * views, struct worker_task *task)
+{
+ GList *cur;
+ struct rspamd_view *v;
+
+ if (task->from == NULL) {
+ return NULL;
+ }
+
+ cur = views;
+ while (cur) {
+ v = cur->data;
+ if (check_view_rcpt (v, task)) {
+ return v;
+ }
+ cur = g_list_next (cur);
+ }
+
+ return NULL;
+}
+
static gboolean
match_view_symbol (struct rspamd_view *v, const char *symbol)
{
@@ -236,9 +323,11 @@ check_view (GList * views, const char *symbol, struct worker_task * task)
if ((selected = find_view_by_ip (views, task)) == NULL) {
if ((selected = find_view_by_client_ip (views, task)) == NULL) {
if ((selected = find_view_by_from (views, task)) == NULL) {
- /* No matching view for this task */
- task->view_checked = TRUE;
- return TRUE;
+ if ((selected = find_view_by_rcpt (views, task)) == NULL) {
+ /* No matching view for this task */
+ task->view_checked = TRUE;
+ return TRUE;
+ }
}
}
}