diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/map.c | 365 | ||||
-rw-r--r-- | src/map.h | 55 | ||||
-rw-r--r-- | src/plugins/emails.c | 9 | ||||
-rw-r--r-- | src/plugins/surbl.c | 25 | ||||
-rw-r--r-- | src/util.c | 185 | ||||
-rw-r--r-- | src/util.h | 6 | ||||
-rw-r--r-- | src/view.c | 20 | ||||
-rw-r--r-- | src/worker.c | 4 |
9 files changed, 451 insertions, 221 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c4dcbb72..2a76296d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ PROJECT(rspamd C) SET(RSPAMD_VERSION_MAJOR 0) SET(RSPAMD_VERSION_MINOR 2) -SET(RSPAMD_VERSION_PATCH 4) +SET(RSPAMD_VERSION_PATCH 5) SET(RSPAMD_VERSION "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}.${RSPAMD_VERSION_PATCH}") SET(RSPAMD_MASTER_SITE_URL "http://cebka.pp.ru/hg/rspamd") @@ -321,6 +321,7 @@ SET(RSPAMDSRC src/modules.c src/lmtp_proto.c src/radix.c src/view.c + src/map.c src/symbols_cache.c) IF(ENABLE_PERL MATCHES "ON") diff --git a/src/map.c b/src/map.c new file mode 100644 index 000000000..a1ba5251d --- /dev/null +++ b/src/map.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2009, Rambler media + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Implementation of map files handling + */ +#include "config.h" +#include "map.h" +#include "main.h" +#include "util.h" +#include "mem_pool.h" + +static memory_pool_t *map_pool = NULL; + +static GList *maps = NULL; +static char *hash_fill = "1"; + +/* Value in seconds after whitch we would try to do stat on list file */ +#define MON_TIMEOUT 10 + +static void +read_map_file (struct rspamd_map *map, struct file_map_data *data) +{ + struct map_cb_data cbdata; + char buf[BUFSIZ]; + ssize_t r; + int fd; + + if (map->read_callback == NULL || map->fin_callback == NULL) { + msg_err ("read_map_file: bad callback for reading map file"); + return; + } + + if ((fd = open (data->filename, O_RDONLY)) == -1) { + msg_warn ("read_map_file: cannot open file '%s': %s", data->filename, strerror (errno)); + return; + } + + cbdata.state = 0; + cbdata.prev_data = *map->user_data; + cbdata.cur_data = NULL; + + while ((r = read (fd, buf, sizeof (buf) - 1)) > 0) { + buf[r ++] = '\0'; + map->read_callback (map->pool, buf, r, &cbdata); + } + + close (fd); + + map->fin_callback (map->pool, &cbdata); + *map->user_data = cbdata.cur_data; +} + +gboolean +add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data) +{ + struct rspamd_map *new_map; + enum fetch_proto proto; + const char *def, *p; + struct file_map_data *fdata; + struct http_map_data *hdata; + char portbuf[6]; + int i, s, fd; + struct hostent *hent; + + /* First of all detect protocol line */ + if (strncmp (map_line, "http://", sizeof ("http://") - 1) == 0) { + proto = PROTO_HTTP; + def = map_line + sizeof ("http://") - 1; + } + else if (strncmp (map_line, "file://", sizeof ("file://") - 1) == 0) { + proto = PROTO_FILE; + def = map_line + sizeof ("file://") - 1; + } + else { + msg_err ("add_map: invalid map fetching protocol: %s", map_line); + return FALSE; + } + /* Constant pool */ + if (map_pool == NULL) { + map_pool = memory_pool_new (memory_pool_get_size ()); + } + new_map = memory_pool_alloc (map_pool, sizeof (struct rspamd_map)); + new_map->read_callback = read_callback; + new_map->fin_callback = fin_callback; + new_map->user_data = user_data; + new_map->protocol = proto; + + /* Now check for each proto separately */ + if (proto == PROTO_FILE) { + if ((fd = open (def, O_RDONLY)) == -1) { + msg_warn ("add_map: cannot open file '%s': %s", def, strerror (errno)); + return FALSE; + } + fdata = memory_pool_alloc (map_pool, sizeof (struct file_map_data)); + fdata->filename = memory_pool_strdup (map_pool, def); + fstat (fd, &fdata->st); + new_map->map_data = fdata; + } + else if (proto == PROTO_HTTP) { + hdata = memory_pool_alloc (map_pool, sizeof (struct http_map_data)); + /* Try to search port */ + if ((p = strchr (def, ':')) != NULL) { + i = 0; + while (g_ascii_isdigit (*p) && i < sizeof (portbuf) - 1) { + portbuf[i ++] = *p ++; + } + if (*p != '/') { + msg_info ("add_map: bad http map definition: %s", def); + return FALSE; + } + portbuf[i] = '\0'; + hdata->port = atoi (portbuf); + } + else { + /* Default http port */ + hdata->port = 80; + /* Now separate host from path */ + if ((p = strchr (def, '/')) == NULL) { + msg_info ("add_map: bad http map definition: %s", def); + return FALSE; + } + } + hdata->host = memory_pool_alloc (map_pool, p - def + 1); + g_strlcpy (hdata->host, def, p - def + 1); + hdata->path = memory_pool_strdup (map_pool, p); + /* Now try to resolve */ + if (!inet_aton (hdata->host, &hdata->addr)) { + /* Resolve using dns */ + hent = gethostbyname (hdata->host); + if (hent == NULL) { + msg_info ("add_map: cannot resolve: %s", hdata->host); + return FALSE; + } + else { + memcpy (&hdata->addr, hent->h_addr, sizeof(struct in_addr)); + } + } + /* Now try to connect */ + if ((s = make_tcp_socket (&hdata->addr, hdata->port, FALSE)) == -1) { + msg_info ("add_map: cannot connect to http server %s: %d, %s", hdata->host, errno, strerror (errno)); + return FALSE; + } + close (s); + new_map->map_data = hdata; + } + /* Temp pool */ + new_map->pool = memory_pool_new (memory_pool_get_size ()); + + maps = g_list_prepend (maps, new_map); + + return TRUE; +} + +typedef void (*insert_func)(gpointer st, gconstpointer key, gpointer value); + +static gboolean +abstract_parse_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data, insert_func func) +{ + u_char *s, *p, *str; + + p = chunk; + + str = g_malloc (len + 1); + s = str; + + while (*p) { + switch (data->state) { + /* READ_SYMBOL */ + case 0: + if (*p == '#') { + if (s != str) { + *s = '\0'; + s = memory_pool_strdup (pool, str); + func (data->cur_data, s, hash_fill); + s = str; + } + data->state = 1; + } + else if (*p == '\r' || *p == '\n') { + if (s != str) { + *s = '\0'; + s = memory_pool_strdup (pool, str); + func (data->cur_data, s, hash_fill); + s = str; + } + while (*p == '\r' || *p == '\n') { + p ++; + } + } + else if (g_ascii_isspace (*p)) { + p ++; + } + else { + *s = *p; + s ++; + p ++; + } + break; + /* SKIP_COMMENT */ + case 1: + if (*p == '\r' || *p == '\n') { + while (*p == '\r' || *p == '\n') { + p ++; + } + s = str; + data->state = 0; + } + else { + p ++; + } + break; + } + } + + g_free (str); + + return TRUE; +} + +static void +radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value) +{ + radix_tree_t *tree = st; + + uint32_t mask = 0xFFFFFFFF; + uint32_t ip; + char *token, *ipnet; + struct in_addr ina; + int k; + + k = strlen ((char *)key) + 1; + ipnet = alloca (k); + g_strlcpy (ipnet, key, k); + token = strsep (&ipnet, "/"); + + if (ipnet != NULL) { + k = atoi (ipnet); + if (k > 32 || k < 0) { + msg_warn ("radix_tree_insert_helper: invalid netmask value: %d", k); + k = 32; + } + k = 32 - k; + mask = mask << k; + } + + if (inet_aton (token, &ina) == 0) { + msg_err ("radix_tree_insert_helper: invalid ip address: %s", token); + return; + } + + ip = ntohl ((uint32_t)ina.s_addr); + k = radix32tree_insert (tree, ip, mask, 1); + if (k == -1) { + msg_warn ("radix_tree_insert_helper: cannot insert ip to tree: %s, mask %X", inet_ntoa (ina), mask); + } + else if (k == 1) { + msg_warn ("add_ip_radix: ip %s, mask %X, value already exists", inet_ntoa (ina), mask); + } +} + +void +read_host_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data) +{ + if (data->cur_data == NULL) { + data->cur_data = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); + } + (void)abstract_parse_list (pool, chunk, len, data, (insert_func)g_hash_table_insert); +} + +void +fin_host_list (memory_pool_t *pool, struct map_cb_data *data) +{ + if (data->prev_data) { + g_hash_table_destroy (data->prev_data); + } +} + +void +read_radix_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data) +{ + if (data->cur_data == NULL) { + data->cur_data = radix_tree_create (); + } + (void)abstract_parse_list (pool, chunk, len, data, (insert_func)radix_tree_insert_helper); +} + +void +fin_radix_list (memory_pool_t *pool, struct map_cb_data *data) +{ + if (data->prev_data) { + radix_tree_free (data->prev_data); + } +} + +static void +file_callback (int fd, short what, void *ud) +{ + struct rspamd_map *map = ud; + struct file_map_data *data = map->map_data; + struct stat st; + + /* Plan event again with jitter */ + evtimer_del (&map->ev); + map->tv.tv_sec = MON_TIMEOUT + MON_TIMEOUT * g_random_double (); + map->tv.tv_usec = 0; + evtimer_add (&map->ev, &map->tv); + + if (stat (data->filename, &st) != -1 && st.st_mtime > data->st.st_mtime) { + memcpy (&data->st, &st, sizeof (struct stat)); + } + else { + return; + } + + msg_info ("rereading map file %s", data->filename); + read_map_file (map, data); +} + +/* Start watching event for all maps */ +void +start_map_watch (void) +{ + GList *cur = maps; + struct rspamd_map *map; + + /* First of all do synced read of data */ + while (cur) { + map = cur->data; + if (map->protocol == PROTO_FILE) { + evtimer_set (&map->ev, file_callback, map); + /* Read initial data */ + read_map_file (map, map->map_data); + /* Plan event with jitter */ + map->tv.tv_sec = MON_TIMEOUT + MON_TIMEOUT * g_random_double (); + map->tv.tv_usec = 0; + evtimer_add (&map->ev, &map->tv); + } + else { + /* XXX */ + } + cur = g_list_next (cur); + } +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 000000000..dfd63a06d --- /dev/null +++ b/src/map.h @@ -0,0 +1,55 @@ +#ifndef RSPAMD_MAP_H +#define RSPAMD_MAP_H + +#include "config.h" +#include "mem_pool.h" +#include "radix.h" + +enum fetch_proto { + PROTO_FILE, + PROTO_HTTP, +}; + +struct map_cb_data { + int state; + void *prev_data; + void *cur_data; +}; + +struct file_map_data { + const char *filename; + struct stat st; +}; + +struct http_map_data { + struct in_addr addr; + uint16_t port; + char *path; + char *host; + time_t last_checked; +}; + +typedef void (*map_cb_t)(memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data); +typedef void (*map_fin_cb_t)(memory_pool_t *pool, struct map_cb_data *data); + +struct rspamd_map { + memory_pool_t *pool; + enum fetch_proto protocol; + map_cb_t read_callback; + map_fin_cb_t fin_callback; + void **user_data; + struct event ev; + struct timeval tv; + void *map_data; +}; + +gboolean add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data); +void start_map_watch (void); + +/* Common callbacks */ +void read_radix_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data); +void fin_radix_list (memory_pool_t *pool, struct map_cb_data *data); +void read_host_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data); +void fin_host_list (memory_pool_t *pool, struct map_cb_data *data); + +#endif diff --git a/src/plugins/emails.c b/src/plugins/emails.c index ef886ecf5..e08d3ff8f 100644 --- a/src/plugins/emails.c +++ b/src/plugins/emails.c @@ -34,6 +34,7 @@ #include "../expressions.h" #include "../util.h" #include "../view.h" +#include "../map.h" #define DEFAULT_SYMBOL "R_BAD_EMAIL" @@ -100,10 +101,8 @@ emails_module_config (struct config_file *cfg) email_module_ctx->symbol = DEFAULT_SYMBOL; } if ((value = get_module_opt (cfg, "emails", "blacklist")) != NULL) { - if (g_ascii_strncasecmp (value, "file://", sizeof ("file://") - 1) == 0) { - if (parse_host_list (email_module_ctx->email_pool, email_module_ctx->blacklist, value + sizeof ("file://") - 1)) { - email_module_ctx->blacklist_file = memory_pool_strdup (email_module_ctx->email_pool, value + sizeof ("file://") - 1); - } + if (add_map (value, read_host_list, fin_host_list, (void **)&email_module_ctx->blacklist)) { + email_module_ctx->blacklist_file = memory_pool_strdup (email_module_ctx->email_pool, value + sizeof ("file://") - 1); } } @@ -216,9 +215,9 @@ emails_symbol_callback (struct worker_task *task, void *unused) { GList *emails, *cur; - emails = extract_emails (task); if (check_view (task->cfg->views, email_module_ctx->symbol, task)) { + emails = extract_emails (task); if (email_module_ctx->blacklist && emails) { cur = g_list_first (emails); diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index 15bdc149b..452f8749a 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -30,6 +30,7 @@ #include "../util.h" #include "../message.h" #include "../view.h" +#include "../map.h" #include <evdns.h> #include "surbl.h" @@ -65,11 +66,11 @@ surbl_module_init (struct config_file *cfg, struct module_ctx **ctx) surbl_module_ctx->tld2_file = NULL; surbl_module_ctx->whitelist_file = NULL; - surbl_module_ctx->tld2 = g_hash_table_new (g_str_hash, g_str_equal); + surbl_module_ctx->tld2 = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); /* Register destructors */ memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_hash_table_remove_all, surbl_module_ctx->tld2); - surbl_module_ctx->whitelist = g_hash_table_new (g_str_hash, g_str_equal); + surbl_module_ctx->whitelist = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); /* Register destructors */ memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_hash_table_remove_all, surbl_module_ctx->whitelist); @@ -158,17 +159,13 @@ surbl_module_config (struct config_file *cfg) surbl_module_ctx->metric = DEFAULT_METRIC; } if ((value = get_module_opt (cfg, "surbl", "2tld")) != NULL) { - if (g_ascii_strncasecmp (value, "file://", sizeof ("file://") - 1) == 0) { - if (parse_host_list (surbl_module_ctx->surbl_pool, surbl_module_ctx->tld2, value + sizeof ("file://") - 1)) { - surbl_module_ctx->tld2_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); - } + if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->tld2)) { + surbl_module_ctx->tld2_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); } } if ((value = get_module_opt (cfg, "surbl", "whitelist")) != NULL) { - if (g_ascii_strncasecmp (value, "file://", sizeof ("file://") - 1) == 0) { - if (parse_host_list (surbl_module_ctx->surbl_pool, surbl_module_ctx->whitelist, value + sizeof ("file://") - 1)) { - surbl_module_ctx->whitelist_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); - } + if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->whitelist)) { + surbl_module_ctx->whitelist_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); } } @@ -766,14 +763,6 @@ surbl_test_url (struct worker_task *task, void *user_data) struct redirector_param param; struct suffix_item *suffix = user_data; - /* Try to check lists */ - if (surbl_module_ctx->tld2_file) { - maybe_parse_host_list (surbl_module_ctx->surbl_pool, surbl_module_ctx->tld2, surbl_module_ctx->tld2_file); - } - if (surbl_module_ctx->whitelist_file) { - maybe_parse_host_list (surbl_module_ctx->surbl_pool, surbl_module_ctx->whitelist, surbl_module_ctx->whitelist_file); - } - url_tree = g_tree_new ((GCompareFunc)g_ascii_strcasecmp); param.tree = url_tree; diff --git a/src/util.c b/src/util.c index 86be3c65e..8001fcb18 100644 --- a/src/util.c +++ b/src/util.c @@ -28,25 +28,15 @@ #include "cfg_file.h" #include "main.h" -/* Value in seconds after whitch we would try to do stat on list file */ -#define MON_TIMEOUT 10 sig_atomic_t do_reopen_log = 0; extern rspamd_hash_t *counters; -static char *hash_fill = "1"; - -struct list_file { - char *filename; - struct stat st; -}; struct logger_params { GLogFunc log_func; struct config_file *cfg; }; - -static GHashTable *listfiles = NULL; static struct logger_params log_params; int @@ -880,181 +870,18 @@ set_counter (const char *name, long int value) return cd->value; } -typedef void (*insert_func)(gpointer st, gconstpointer key, gpointer value); - -static gboolean -abstract_parse_list (memory_pool_t *pool, void *arg, insert_func func, const char *filename) -{ - int fd; - char buf[BUFSIZ], str[BUFSIZ], *s, *p; - ssize_t r; - enum { - READ_SYMBOL, - SKIP_COMMENT, - } state = READ_SYMBOL; - - struct list_file *new_file; - - if (listfiles == NULL) { - listfiles = g_hash_table_new (g_str_hash, g_str_equal); - } - - if ((fd = open (filename, O_RDONLY)) == -1) { - msg_warn ("parse_host_list: cannot open file '%s': %s", filename, strerror (errno)); - return FALSE; - } - - new_file = memory_pool_alloc (pool, sizeof (struct list_file)); - new_file->filename = memory_pool_strdup (pool, filename); - fstat (fd, &new_file->st); - g_hash_table_insert (listfiles, new_file->filename, new_file); - - s = str; - - while ((r = read (fd, buf, sizeof (buf) - 1)) > 0) { - buf[r] = '\0'; - p = buf; - while (*p) { - switch (state) { - case READ_SYMBOL: - if (*p == '#') { - if (s != str) { - *s = '\0'; - s = memory_pool_strdup (pool, str); - func (arg, s, hash_fill); - s = str; - } - state = SKIP_COMMENT; - } - else if (*p == '\r' || *p == '\n') { - if (s != str) { - *s = '\0'; - s = memory_pool_strdup (pool, str); - func (arg, s, hash_fill); - s = str; - } - while (*p == '\r' || *p == '\n') { - p ++; - } - } - else if (g_ascii_isspace (*p)) { - p ++; - } - else { - *s = *p; - s ++; - p ++; - } - break; - case SKIP_COMMENT: - if (*p == '\r' || *p == '\n') { - while (*p == '\r' || *p == '\n') { - p ++; - } - s = str; - state = READ_SYMBOL; - } - else { - p ++; - } - break; - } - } - } - - close (fd); - - return TRUE; -} - -static void -radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value) -{ - radix_tree_t *tree = st; - - uint32_t mask = 0xFFFFFFFF; - uint32_t ip; - char *token, *ipnet; - struct in_addr ina; - int k; - - k = strlen ((char *)key) + 1; - ipnet = alloca (k); - g_strlcpy (ipnet, key, k); - token = strsep (&ipnet, "/"); - - if (ipnet != NULL) { - k = atoi (ipnet); - if (k > 32 || k < 0) { - msg_warn ("radix_tree_insert_helper: invalid netmask value: %d", k); - k = 32; - } - k = 32 - k; - mask = mask << k; - } - - if (inet_aton (token, &ina) == 0) { - msg_err ("radix_tree_insert_helper: invalid ip address: %s", token); - return; - } - - ip = ntohl ((uint32_t)ina.s_addr); - k = radix32tree_insert (tree, ip, mask, 1); - if (k == -1) { - msg_warn ("radix_tree_insert_helper: cannot insert ip to tree: %s, mask %X", inet_ntoa (ina), mask); - } - else if (k == 1) { - msg_warn ("add_ip_radix: ip %s, mask %X, value already exists", inet_ntoa (ina), mask); - } -} - -gboolean -parse_host_list (memory_pool_t *pool, GHashTable *tbl, const char *filename) -{ - return abstract_parse_list (pool, (void *)tbl, (insert_func)g_hash_table_insert, filename); -} - -gboolean -parse_radix_list (memory_pool_t *pool, radix_tree_t *tree, const char *filename) -{ - return abstract_parse_list (pool, (void *)tree, (insert_func)radix_tree_insert_helper, filename); -} - -gboolean -maybe_parse_host_list (memory_pool_t *pool, GHashTable *tbl, const char *filename) -{ - struct list_file *lf; - struct stat cur_st; - time_t cur_time = time (NULL); - - if (listfiles == NULL || (lf = g_hash_table_lookup (listfiles, filename)) == NULL) { - /* Do not try to parse unknown files */ - return FALSE; - } - - if (cur_time - lf->st.st_mtime > MON_TIMEOUT) { - /* Try to stat */ - if (stat (lf->filename, &cur_st) != -1) { - if (cur_st.st_mtime > lf->st.st_mtime) { - g_hash_table_remove (listfiles, lf->filename); - g_hash_table_remove_all (tbl); - msg_info ("maybe_parse_host_list: file %s was modified and rereaded", filename); - return parse_host_list (pool, tbl, filename); - } - } - } - - return TRUE; -} - #ifndef g_tolower #define g_tolower(x) (((x) >= 'A' && (x) <= 'Z') ? (x) - 'A' + 'a' : (x)) #endif -gint +gboolean rspamd_strcase_equal (gconstpointer v, gconstpointer v2) { - return g_ascii_strcasecmp ((const char *) v, (const char *) v2); + if (g_ascii_strcasecmp ((const char *) v, (const char *) v2) == 0) { + return TRUE; + } + + return FALSE; } diff --git a/src/util.h b/src/util.h index 91de0a291..aa08bcc3a 100644 --- a/src/util.h +++ b/src/util.h @@ -64,12 +64,8 @@ const char* calculate_check_time (struct timespec *begin, int resolution); double set_counter (const char *name, long int value); -gboolean parse_host_list (memory_pool_t *pool, GHashTable *tbl, const char *filename); -gboolean maybe_parse_host_list (memory_pool_t *pool, GHashTable *tbl, const char *filename); -gboolean parse_radix_list (memory_pool_t *pool, radix_tree_t *tree, const char *filename); - guint rspamd_strcase_hash (gconstpointer key); -gint rspamd_strcase_equal (gconstpointer v, gconstpointer v2); +gboolean rspamd_strcase_equal (gconstpointer v, gconstpointer v2); #endif diff --git a/src/view.c b/src/view.c index 0a03d4304..ec10eb120 100644 --- a/src/view.c +++ b/src/view.c @@ -28,6 +28,7 @@ #include "view.h" #include "expressions.h" #include "cfg_file.h" +#include "map.h" struct rspamd_view* init_view (memory_pool_t *pool) @@ -51,10 +52,8 @@ add_view_from (struct rspamd_view *view, char *line) { struct rspamd_regexp *re = NULL; - if (g_ascii_strncasecmp (line, "file://", sizeof ("file://") - 1) == 0) { - if (parse_host_list (view->pool, view->from_hash, line + sizeof ("file://") - 1)) { - return TRUE; - } + if (add_map (line, read_host_list, fin_host_list, (void **)&view->from_hash)) { + return TRUE; } else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) { view->from_re_list = g_list_prepend (view->from_re_list, re); @@ -70,10 +69,8 @@ add_view_symbols (struct rspamd_view *view, char *line) struct rspamd_regexp *re = NULL; GList *symbols; - if (g_ascii_strncasecmp (line, "file://", sizeof ("file://") - 1) == 0) { - if (parse_host_list (view->pool, view->symbols_hash, line + sizeof ("file://") - 1)) { - return TRUE; - } + if (add_map (line, read_host_list, fin_host_list, (void **)&view->symbols_hash)) { + return TRUE; } else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) { view->symbols_re_list = g_list_prepend (view->symbols_re_list, re); @@ -96,14 +93,11 @@ add_view_symbols (struct rspamd_view *view, char *line) gboolean add_view_ip (struct rspamd_view *view, char *line) { - if (g_ascii_strncasecmp (line, "file://", sizeof ("file://") - 1) == 0) { - if (parse_radix_list (view->pool, view->ip_tree, line + sizeof ("file://") - 1)) { - return TRUE; - } + if (add_map (line, read_radix_list, fin_radix_list, (void **)&view->symbols_hash)) { + return TRUE; } return FALSE; - } diff --git a/src/worker.c b/src/worker.c index 01732135c..726f7fe00 100644 --- a/src/worker.c +++ b/src/worker.c @@ -35,6 +35,7 @@ #include "url.h" #include "modules.h" #include "message.h" +#include "map.h" #include <evdns.h> @@ -367,6 +368,9 @@ start_worker (struct rspamd_worker *worker) event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); event_add(&worker->bind_ev, NULL); + /* Maps events */ + start_map_watch (); + /* Send SIGUSR2 to parent */ kill (getppid (), SIGUSR2); |