aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--src/map.c365
-rw-r--r--src/map.h55
-rw-r--r--src/plugins/emails.c9
-rw-r--r--src/plugins/surbl.c25
-rw-r--r--src/util.c185
-rw-r--r--src/util.h6
-rw-r--r--src/view.c20
-rw-r--r--src/worker.c4
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);