summaryrefslogtreecommitdiffstats
path: root/src/cfg_utils.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-04-21 16:25:51 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-04-21 16:25:51 +0100
commit61555065f3d1c8badcc9573691232f1b6e42988c (patch)
tree563d5b7cb8c468530f7e79c4da0a75267b1184e1 /src/cfg_utils.c
parentad5bf825b7f33bc10311673991f0cc888e69c0b1 (diff)
downloadrspamd-61555065f3d1c8badcc9573691232f1b6e42988c.tar.gz
rspamd-61555065f3d1c8badcc9573691232f1b6e42988c.zip
Rework project structure, remove trash files.
Diffstat (limited to 'src/cfg_utils.c')
-rw-r--r--src/cfg_utils.c969
1 files changed, 0 insertions, 969 deletions
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
deleted file mode 100644
index 2ca846ebd..000000000
--- a/src/cfg_utils.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * Copyright (c) 2009-2012, Vsevolod Stakhov
- * 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 AUTHOR ''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 AUTHOR 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.
- */
-
-
-#include "config.h"
-
-#include "cfg_file.h"
-#include "main.h"
-#include "filter.h"
-#include "settings.h"
-#include "classifiers/classifiers.h"
-#include "lua/lua_common.h"
-#include "kvstorage_config.h"
-#include "map.h"
-#include "dynamic_cfg.h"
-
-#define DEFAULT_SCORE 10.0
-
-#define DEFAULT_RLIMIT_NOFILE 2048
-#define DEFAULT_RLIMIT_MAXCORE 0
-#define DEFAULT_MAP_TIMEOUT 10
-
-struct rspamd_ucl_map_cbdata {
- struct config_file *cfg;
- GString *buf;
-};
-static gchar* rspamd_ucl_read_cb (rspamd_mempool_t * pool, gchar * chunk, gint len, struct map_cb_data *data);
-static void rspamd_ucl_fin_cb (rspamd_mempool_t * pool, struct map_cb_data *data);
-
-static gboolean
-parse_host_port_priority_strv (rspamd_mempool_t *pool, gchar **tokens,
- gchar **addr, guint16 *port, guint *priority, guint default_port)
-{
- gchar *err_str, portbuf[8];
- const gchar *cur_tok, *cur_port;
- struct addrinfo hints, *res;
- guint port_parsed, priority_parsed, saved_errno = errno;
- gint r;
- union {
- struct sockaddr_in v4;
- struct sockaddr_in6 v6;
- } addr_holder;
-
- /* Now try to parse host and write address to ina */
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM; /* Type of the socket */
- hints.ai_flags = AI_NUMERICSERV;
-
- cur_tok = tokens[0];
-
- if (strcmp (cur_tok, "*v6") == 0) {
- hints.ai_family = AF_INET6;
- hints.ai_flags |= AI_PASSIVE;
- cur_tok = NULL;
- }
- else if (strcmp (cur_tok, "*v4") == 0) {
- hints.ai_family = AF_INET;
- hints.ai_flags |= AI_PASSIVE;
- cur_tok = NULL;
- }
- else {
- hints.ai_family = AF_UNSPEC;
- }
-
- if (tokens[1] != NULL) {
- /* Port part */
- rspamd_strlcpy (portbuf, tokens[1], sizeof (portbuf));
- cur_port = portbuf;
- if (port != NULL) {
- errno = 0;
- port_parsed = strtoul (tokens[1], &err_str, 10);
- if (*err_str != '\0' || errno != 0) {
- msg_warn ("cannot parse port: %s, at symbol %c, error: %s", tokens[1], *err_str, strerror (errno));
- hints.ai_flags ^= AI_NUMERICSERV;
- }
- else if (port_parsed > G_MAXUINT16) {
- errno = ERANGE;
- msg_warn ("cannot parse port: %s, error: %s", tokens[1], *err_str, strerror (errno));
- hints.ai_flags ^= AI_NUMERICSERV;
- }
- else {
- *port = port_parsed;
- }
- }
- if (priority != NULL) {
- if (port != NULL) {
- cur_tok = tokens[2];
- }
- else {
- cur_tok = tokens[1];
- }
- if (cur_tok != NULL) {
- /* Priority part */
- errno = 0;
- priority_parsed = strtoul (cur_tok, &err_str, 10);
- if (*err_str != '\0' || errno != 0) {
- msg_warn ("cannot parse priority: %s, at symbol %c, error: %s", tokens[1], *err_str, strerror (errno));
- }
- else {
- *priority = priority_parsed;
- }
- }
- }
- }
- else if (default_port != 0) {
- rspamd_snprintf (portbuf, sizeof (portbuf), "%ud", default_port);
- cur_port = portbuf;
- }
- else {
- cur_port = NULL;
- }
-
- if ((r = getaddrinfo (cur_tok, cur_port, &hints, &res)) == 0) {
- memcpy (&addr_holder, res->ai_addr, MIN (sizeof (addr_holder), res->ai_addrlen));
- if (res->ai_family == AF_INET) {
- if (pool != NULL) {
- *addr = rspamd_mempool_alloc (pool, INET_ADDRSTRLEN + 1);
- }
- inet_ntop (res->ai_family, &addr_holder.v4.sin_addr, *addr, INET_ADDRSTRLEN + 1);
- }
- else {
- if (pool != NULL) {
- *addr = rspamd_mempool_alloc (pool, INET6_ADDRSTRLEN + 1);
- }
- inet_ntop (res->ai_family, &addr_holder.v6.sin6_addr, *addr, INET6_ADDRSTRLEN + 1);
- }
- freeaddrinfo (res);
- }
- else {
- msg_err ("address resolution for %s failed: %s", tokens[0], gai_strerror (r));
- goto err;
- }
-
- /* Restore errno */
- errno = saved_errno;
- return TRUE;
-
-err:
- errno = saved_errno;
- return FALSE;
-}
-
-gboolean
-parse_host_port_priority (rspamd_mempool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority)
-{
- gchar **tokens;
- gboolean ret;
-
- tokens = g_strsplit_set (str, ":", 0);
- if (!tokens || !tokens[0]) {
- return FALSE;
- }
-
- ret = parse_host_port_priority_strv (pool, tokens, addr, port, priority, 0);
-
- g_strfreev (tokens);
-
- return ret;
-}
-
-gboolean
-parse_host_port (rspamd_mempool_t *pool, const gchar *str, gchar **addr, guint16 *port)
-{
- return parse_host_port_priority (pool, str, addr, port, NULL);
-}
-
-gboolean
-parse_host_priority (rspamd_mempool_t *pool, const gchar *str, gchar **addr, guint *priority)
-{
- return parse_host_port_priority (pool, str, addr, NULL, priority);
-}
-
-gboolean
-parse_bind_line (struct config_file *cfg, struct worker_conf *cf, const gchar *str)
-{
- struct rspamd_worker_bind_conf *cnf;
- gchar **tokens, *tmp, *err;
- gboolean ret = TRUE;
-
- if (str == NULL) {
- return FALSE;
- }
-
- tokens = g_strsplit_set (str, ":", 0);
- if (!tokens || !tokens[0]) {
- return FALSE;
- }
-
- cnf = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_worker_bind_conf));
- cnf->bind_port = DEFAULT_BIND_PORT;
- cnf->bind_host = rspamd_mempool_strdup (cfg->cfg_pool, str);
- cnf->ai = AF_UNSPEC;
-
- if (*tokens[0] == '/' || *tokens[0] == '.') {
- cnf->ai = AF_UNIX;
- LL_PREPEND (cf->bind_conf, cnf);
- return TRUE;
- }
- else if (strcmp (tokens[0], "*") == 0) {
- /* We need to add two listen entries: one for ipv4 and one for ipv6 */
- tmp = tokens[0];
- tokens[0] = "*v4";
- cnf->ai = AF_INET;
- if ((ret = parse_host_port_priority_strv (cfg->cfg_pool, tokens,
- &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
- LL_PREPEND (cf->bind_conf, cnf);
- }
- cnf = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_worker_bind_conf));
- cnf->bind_port = DEFAULT_BIND_PORT;
- cnf->bind_host = rspamd_mempool_strdup (cfg->cfg_pool, str);
- cnf->ai = AF_INET6;
- tokens[0] = "*v6";
- if ((ret &= parse_host_port_priority_strv (cfg->cfg_pool, tokens,
- &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
- LL_PREPEND (cf->bind_conf, cnf);
- }
- tokens[0] = tmp;
- }
- else if (strcmp (tokens[0], "systemd") == 0) {
- /* The actual socket will be passed by systemd environment */
- cnf->bind_host = rspamd_mempool_strdup (cfg->cfg_pool, str);
- cnf->ai = strtoul (tokens[1], &err, 10);
- cnf->is_systemd = TRUE;
- if (err == NULL || *err == '\0') {
- LL_PREPEND (cf->bind_conf, cnf);
- }
- }
- else {
- if ((ret = parse_host_port_priority_strv (cfg->cfg_pool, tokens,
- &cnf->bind_host, &cnf->bind_port, NULL, DEFAULT_BIND_PORT))) {
- LL_PREPEND (cf->bind_conf, cnf);
- }
- }
-
- g_strfreev (tokens);
-
- return ret;
-}
-
-void
-init_defaults (struct config_file *cfg)
-{
-
- cfg->memcached_error_time = DEFAULT_UPSTREAM_ERROR_TIME;
- cfg->memcached_dead_time = DEFAULT_UPSTREAM_DEAD_TIME;
- cfg->memcached_maxerrors = DEFAULT_UPSTREAM_MAXERRORS;
- cfg->memcached_protocol = TCP_TEXT;
-
- cfg->dns_timeout = 1000;
- cfg->dns_retransmits = 5;
- /* After 20 errors do throttling for 10 seconds */
- cfg->dns_throttling_errors = 20;
- cfg->dns_throttling_time = 10000;
- /* 16 sockets per DNS server */
- cfg->dns_io_per_server = 16;
-
- cfg->statfile_sync_interval = 60000;
- cfg->statfile_sync_timeout = 20000;
-
- /* 20 Kb */
- cfg->max_diff = 20480;
-
- cfg->metrics = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->c_modules = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->composite_symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->classifiers_symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->cfg_params = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->metrics_symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
-
- cfg->map_timeout = DEFAULT_MAP_TIMEOUT;
-
- cfg->log_level = G_LOG_LEVEL_WARNING;
- cfg->log_extended = TRUE;
-
- init_settings (cfg);
-
-}
-
-void
-free_config (struct config_file *cfg)
-{
- GList *cur;
- struct symbols_group *gr;
-
- remove_all_maps (cfg);
- ucl_obj_unref (cfg->rcl_obj);
- g_hash_table_remove_all (cfg->metrics);
- g_hash_table_unref (cfg->metrics);
- g_hash_table_remove_all (cfg->c_modules);
- g_hash_table_unref (cfg->c_modules);
- g_hash_table_remove_all (cfg->composite_symbols);
- g_hash_table_unref (cfg->composite_symbols);
- g_hash_table_remove_all (cfg->cfg_params);
- g_hash_table_unref (cfg->cfg_params);
- g_hash_table_destroy (cfg->metrics_symbols);
- g_hash_table_destroy (cfg->classifiers_symbols);
- /* Free symbols groups */
- cur = cfg->symbols_groups;
- while (cur) {
- gr = cur->data;
- if (gr->symbols) {
- g_list_free (gr->symbols);
- }
- cur = g_list_next (cur);
- }
- if (cfg->symbols_groups) {
- g_list_free (cfg->symbols_groups);
- }
-
- if (cfg->checksum) {
- g_free (cfg->checksum);
- }
- g_list_free (cfg->classifiers);
- g_list_free (cfg->metrics_list);
- rspamd_mempool_delete (cfg->cfg_pool);
-}
-
-const ucl_object_t *
-get_module_opt (struct config_file *cfg, const gchar *module_name, const gchar *opt_name)
-{
- const ucl_object_t *res = NULL, *sec;
-
- sec = ucl_obj_get_key (cfg->rcl_obj, module_name);
- if (sec != NULL) {
- res = ucl_obj_get_key (sec, opt_name);
- }
-
- return res;
-}
-
-guint64
-parse_limit (const gchar *limit, guint len)
-{
- guint64 result = 0;
- const gchar *err_str;
-
- if (!limit || *limit == '\0' || len == 0) {
- return 0;
- }
-
- errno = 0;
- result = strtoull (limit, (gchar **)&err_str, 10);
-
- if (*err_str != '\0') {
- /* Megabytes */
- if (*err_str == 'm' || *err_str == 'M') {
- result *= 1048576L;
- }
- /* Kilobytes */
- else if (*err_str == 'k' || *err_str == 'K') {
- result *= 1024;
- }
- /* Gigabytes */
- else if (*err_str == 'g' || *err_str == 'G') {
- result *= 1073741824L;
- }
- else if (len > 0 && err_str - limit != (gint)len) {
- msg_warn ("invalid limit value '%s' at position '%s'", limit, err_str);
- result = 0;
- }
- }
-
- return result;
-}
-
-gchar
-parse_flag (const gchar *str)
-{
- guint len;
- gchar c;
-
- if (!str || !*str) {
- return -1;
- }
-
- len = strlen (str);
-
- switch (len) {
- case 1:
- c = g_ascii_tolower (*str);
- if (c == 'y' || c == '1') {
- return 1;
- }
- else if (c == 'n' || c == '0') {
- return 0;
- }
- break;
- case 2:
- if (g_ascii_strncasecmp (str, "no", len) == 0) {
- return 0;
- }
- else if (g_ascii_strncasecmp (str, "on", len) == 0) {
- return 1;
- }
- break;
- case 3:
- if (g_ascii_strncasecmp (str, "yes", len) == 0) {
- return 1;
- }
- else if (g_ascii_strncasecmp (str, "off", len) == 0) {
- return 0;
- }
- break;
- case 4:
- if (g_ascii_strncasecmp (str, "true", len) == 0) {
- return 1;
- }
- break;
- case 5:
- if (g_ascii_strncasecmp (str, "false", len) == 0) {
- return 0;
- }
- break;
- }
-
- return -1;
-}
-
-gboolean
-get_config_checksum (struct config_file *cfg)
-{
- gint fd;
- void *map;
- struct stat st;
-
- /* Compute checksum for config file that should be used by xml dumper */
- if ((fd = open (cfg->cfg_name, O_RDONLY)) == -1) {
- msg_err ("config file %s is no longer available, cannot calculate checksum");
- return FALSE;
- }
- if (stat (cfg->cfg_name, &st) == -1) {
- msg_err ("cannot stat %s: %s", cfg->cfg_name, strerror (errno));
- return FALSE;
- }
-
- /* Now mmap this file to simplify reading process */
- if ((map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
- msg_err ("cannot mmap %s: %s", cfg->cfg_name, strerror (errno));
- close (fd);
- return FALSE;
- }
- close (fd);
-
- /* Get checksum for a file */
- cfg->checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, map, st.st_size);
- munmap (map, st.st_size);
-
- return TRUE;
-}
-/*
- * Perform post load actions
- */
-void
-post_load_config (struct config_file *cfg)
-{
-#ifdef HAVE_CLOCK_GETTIME
- struct timespec ts;
-#endif
- struct metric *def_metric;
-
-#ifdef HAVE_CLOCK_GETTIME
-#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
- clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts);
-# elif defined(HAVE_CLOCK_VIRTUAL)
- clock_getres (CLOCK_VIRTUAL, &ts);
-# else
- clock_getres (CLOCK_REALTIME, &ts);
-# endif
-
- cfg->clock_res = (gint)log10 (1000000 / ts.tv_nsec);
- if (cfg->clock_res < 0) {
- cfg->clock_res = 0;
- }
- if (cfg->clock_res > 3) {
- cfg->clock_res = 3;
- }
-#else
- /* For gettimeofday */
- cfg->clock_res = 1;
-#endif
-
- if ((def_metric = g_hash_table_lookup (cfg->metrics, DEFAULT_METRIC)) == NULL) {
- def_metric = check_metric_conf (cfg, NULL);
- def_metric->name = DEFAULT_METRIC;
- def_metric->actions[METRIC_ACTION_REJECT].score = DEFAULT_SCORE;
- cfg->metrics_list = g_list_prepend (cfg->metrics_list, def_metric);
- g_hash_table_insert (cfg->metrics, DEFAULT_METRIC, def_metric);
- }
-
- cfg->default_metric = def_metric;
-
- /* Lua options */
- (void)lua_post_load_config (cfg);
- init_dynamic_config (cfg);
-}
-
-#if 0
-void
-parse_err (const gchar *fmt, ...)
-{
- va_list aq;
- gchar logbuf[BUFSIZ], readbuf[32];
- gint r;
-
- va_start (aq, fmt);
- rspamd_strlcpy (readbuf, yytext, sizeof (readbuf));
-
- r = snprintf (logbuf, sizeof (logbuf), "config file parse error! line: %d, text: %s, reason: ", yylineno, readbuf);
- r += vsnprintf (logbuf + r, sizeof (logbuf) - r, fmt, aq);
-
- va_end (aq);
- g_critical ("%s", logbuf);
-}
-
-void
-parse_warn (const gchar *fmt, ...)
-{
- va_list aq;
- gchar logbuf[BUFSIZ], readbuf[32];
- gint r;
-
- va_start (aq, fmt);
- rspamd_strlcpy (readbuf, yytext, sizeof (readbuf));
-
- r = snprintf (logbuf, sizeof (logbuf), "config file parse warning! line: %d, text: %s, reason: ", yylineno, readbuf);
- r += vsnprintf (logbuf + r, sizeof (logbuf) - r, fmt, aq);
-
- va_end (aq);
- g_warning ("%s", logbuf);
-}
-#endif
-
-void
-unescape_quotes (gchar *line)
-{
- gchar *c = line, *t;
-
- while (*c) {
- if (*c == '\\' && *(c + 1) == '"') {
- t = c;
- while (*t) {
- *t = *(t + 1);
- t++;
- }
- }
- c++;
- }
-}
-
-GList *
-parse_comma_list (rspamd_mempool_t * pool, const gchar *line)
-{
- GList *res = NULL;
- const gchar *c, *p;
- gchar *str;
-
- c = line;
- p = c;
-
- while (*p) {
- if (*p == ',' && *c != *p) {
- str = rspamd_mempool_alloc (pool, p - c + 1);
- rspamd_strlcpy (str, c, p - c + 1);
- res = g_list_prepend (res, str);
- /* Skip spaces */
- while (g_ascii_isspace (*(++p)));
- c = p;
- continue;
- }
- p++;
- }
- if (res != NULL) {
- rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_list_free, res);
- }
-
- return res;
-}
-
-struct classifier_config *
-check_classifier_conf (struct config_file *cfg, struct classifier_config *c)
-{
- if (c == NULL) {
- c = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct classifier_config));
- }
- if (c->opts == NULL) {
- c->opts = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t) g_hash_table_destroy, c->opts);
- }
- if (c->labels == NULL) {
- c->labels = g_hash_table_new_full (rspamd_str_hash, rspamd_str_equal, NULL, (GDestroyNotify)g_list_free);
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t) g_hash_table_destroy, c->labels);
- }
-
- return c;
-}
-
-struct statfile*
-check_statfile_conf (struct config_file *cfg, struct statfile *c)
-{
- if (c == NULL) {
- c = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct statfile));
- }
-
- return c;
-}
-
-struct metric *
-check_metric_conf (struct config_file *cfg, struct metric *c)
-{
- int i;
- if (c == NULL) {
- c = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
- c->grow_factor = 1.0;
- c->symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- c->descriptions = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
- c->actions[i].score = -1.0;
- }
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t) g_hash_table_destroy, c->symbols);
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t) g_hash_table_destroy, c->descriptions);
- }
-
- return c;
-}
-
-struct worker_conf *
-check_worker_conf (struct config_file *cfg, struct worker_conf *c)
-{
- if (c == NULL) {
- c = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct worker_conf));
- c->params = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- c->active_workers = g_queue_new ();
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t)g_hash_table_destroy, c->params);
- rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t)g_queue_free, c->active_workers);
-#ifdef HAVE_SC_NPROCESSORS_ONLN
- c->count = sysconf (_SC_NPROCESSORS_ONLN);
-#else
- c->count = DEFAULT_WORKERS_NUM;
-#endif
- c->rlimit_nofile = DEFAULT_RLIMIT_NOFILE;
- c->rlimit_maxcore = DEFAULT_RLIMIT_MAXCORE;
- }
-
- return c;
-}
-
-
-static bool
-rspamd_include_map_handler (const guchar *data, gsize len, void* ud)
-{
- struct config_file *cfg = (struct config_file *)ud;
- struct rspamd_ucl_map_cbdata *cbdata, **pcbdata;
- gchar *map_line;
-
- map_line = rspamd_mempool_alloc (cfg->cfg_pool, len + 1);
- rspamd_strlcpy (map_line, data, len + 1);
-
- cbdata = g_malloc (sizeof (struct rspamd_ucl_map_cbdata));
- pcbdata = g_malloc (sizeof (struct rspamd_ucl_map_cbdata *));
- cbdata->buf = NULL;
- cbdata->cfg = cfg;
- *pcbdata = cbdata;
-
- return add_map (cfg, map_line, "ucl include", rspamd_ucl_read_cb, rspamd_ucl_fin_cb, (void **)pcbdata);
-}
-
-/*
- * Variables:
- * $CONFDIR - configuration directory
- * $RUNDIR - local states directory
- * $DBDIR - databases dir
- * $LOGDIR - logs dir
- * $PLUGINSDIR - pluggins dir
- * $PREFIX - installation prefix
- * $VERSION - rspamd version
- */
-
-#define RSPAMD_CONFDIR_MACRO "CONFDIR"
-#define RSPAMD_RUNDIR_MACRO "RUNDIR"
-#define RSPAMD_DBDIR_MACRO "DBDIR"
-#define RSPAMD_LOGDIR_MACRO "LOGDIR"
-#define RSPAMD_PLUGINSDIR_MACRO "PLUGINSDIR"
-#define RSPAMD_PREFIX_MACRO "PREFIX"
-#define RSPAMD_VERSION_MACRO "VERSION"
-
-static void
-rspamd_ucl_add_conf_variables (struct ucl_parser *parser)
-{
- ucl_parser_register_variable (parser, RSPAMD_CONFDIR_MACRO, RSPAMD_CONFDIR);
- ucl_parser_register_variable (parser, RSPAMD_RUNDIR_MACRO, RSPAMD_RUNDIR);
- ucl_parser_register_variable (parser, RSPAMD_DBDIR_MACRO, RSPAMD_DBDIR);
- ucl_parser_register_variable (parser, RSPAMD_LOGDIR_MACRO, RSPAMD_LOGDIR);
- ucl_parser_register_variable (parser, RSPAMD_PLUGINSDIR_MACRO, RSPAMD_PLUGINSDIR);
- ucl_parser_register_variable (parser, RSPAMD_PREFIX_MACRO, RSPAMD_PREFIX);
- ucl_parser_register_variable (parser, RSPAMD_VERSION_MACRO, RVERSION);
-}
-
-static void
-rspamd_ucl_add_conf_macros (struct ucl_parser *parser, struct config_file *cfg)
-{
- ucl_parser_register_macro (parser, "include_map", rspamd_include_map_handler, cfg);
-}
-
-gboolean
-read_rspamd_config (struct config_file *cfg, const gchar *filename,
- const gchar *convert_to, rspamd_rcl_section_fin_t logger_fin,
- gpointer logger_ud)
-{
- struct stat st;
- gint fd;
- gchar *data;
- GError *err = NULL;
- struct rspamd_rcl_section *top, *logger;
- gboolean res;
- struct ucl_parser *parser;
-
- if (stat (filename, &st) == -1) {
- msg_err ("cannot stat %s: %s", filename, strerror (errno));
- return FALSE;
- }
- if ((fd = open (filename, O_RDONLY)) == -1) {
- msg_err ("cannot open %s: %s", filename, strerror (errno));
- return FALSE;
-
- }
- /* Now mmap this file to simplify reading process */
- if ((data = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
- msg_err ("cannot mmap %s: %s", filename, strerror (errno));
- close (fd);
- return FALSE;
- }
- close (fd);
-
- parser = ucl_parser_new (0);
- rspamd_ucl_add_conf_variables (parser);
- rspamd_ucl_add_conf_macros (parser, cfg);
- if (!ucl_parser_add_chunk (parser, data, st.st_size)) {
- msg_err ("ucl parser error: %s", ucl_parser_get_error (parser));
- ucl_parser_free (parser);
- munmap (data, st.st_size);
- return FALSE;
- }
- munmap (data, st.st_size);
- cfg->rcl_obj = ucl_parser_get_object (parser);
- ucl_parser_free (parser);
- res = TRUE;
-
- if (!res) {
- return FALSE;
- }
-
- top = rspamd_rcl_config_init ();
- err = NULL;
-
- HASH_FIND_STR(top, "logging", logger);
- if (logger != NULL) {
- logger->fin = logger_fin;
- logger->fin_ud = logger_ud;
- }
-
- if (!rspamd_read_rcl_config (top, cfg, cfg->rcl_obj, &err)) {
- msg_err ("rcl parse error: %s", err->message);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-symbols_classifiers_callback (gpointer key, gpointer value, gpointer ud)
-{
- struct config_file *cfg = ud;
-
- register_virtual_symbol (&cfg->cache, key, 1.0);
-}
-
-void
-insert_classifier_symbols (struct config_file *cfg)
-{
- g_hash_table_foreach (cfg->classifiers_symbols, symbols_classifiers_callback, cfg);
-}
-
-struct classifier_config*
-find_classifier_conf (struct config_file *cfg, const gchar *name)
-{
- GList *cur;
- struct classifier_config *cf;
-
- if (name == NULL) {
- return NULL;
- }
-
- cur = cfg->classifiers;
- while (cur) {
- cf = cur->data;
-
- if (g_ascii_strcasecmp (cf->classifier->name, name) == 0) {
- return cf;
- }
-
- cur = g_list_next (cur);
- }
-
- return NULL;
-}
-
-gboolean
-check_classifier_statfiles (struct classifier_config *cf)
-{
- struct statfile *st;
- gboolean has_other = FALSE, res = FALSE, cur_class;
- GList *cur;
-
- /* First check classes directly */
- cur = cf->statfiles;
- while (cur) {
- st = cur->data;
- if (!has_other) {
- cur_class = st->is_spam;
- has_other = TRUE;
- }
- else {
- if (cur_class != st->is_spam) {
- return TRUE;
- }
- }
-
- cur = g_list_next (cur);
- }
-
- if (!has_other) {
- /* We have only one statfile */
- return FALSE;
- }
- /* We have not detected any statfile that has different class, so turn on euristic based on symbol's name */
- has_other = FALSE;
- cur = cf->statfiles;
- while (cur) {
- st = cur->data;
- if (rspamd_strncasestr (st->symbol, "spam", -1) != NULL) {
- st->is_spam = TRUE;
- }
- else if (rspamd_strncasestr (st->symbol, "ham", -1) != NULL) {
- st->is_spam = FALSE;
- }
-
- if (!has_other) {
- cur_class = st->is_spam;
- has_other = TRUE;
- }
- else {
- if (cur_class != st->is_spam) {
- res = TRUE;
- }
- }
-
- cur = g_list_next (cur);
- }
-
- return res;
-}
-
-static gchar*
-rspamd_ucl_read_cb (rspamd_mempool_t * pool, gchar * chunk, gint len, struct map_cb_data *data)
-{
- struct rspamd_ucl_map_cbdata *cbdata = data->cur_data, *prev;
-
- if (cbdata == NULL) {
- cbdata = g_malloc (sizeof (struct rspamd_ucl_map_cbdata));
- prev = data->prev_data;
- cbdata->buf = g_string_sized_new (BUFSIZ);
- cbdata->cfg = prev->cfg;
- data->cur_data = cbdata;
- }
- g_string_append_len (cbdata->buf, chunk, len);
-
- /* Say not to copy any part of this buffer */
- return NULL;
-}
-
-static void
-rspamd_ucl_fin_cb (rspamd_mempool_t * pool, struct map_cb_data *data)
-{
- struct rspamd_ucl_map_cbdata *cbdata = data->cur_data, *prev = data->prev_data;
- ucl_object_t *obj;
- struct ucl_parser *parser;
- guint32 checksum;
-
- if (prev != NULL) {
- if (prev->buf != NULL) {
- g_string_free (prev->buf, TRUE);
- }
- g_free (prev);
- }
-
- if (cbdata == NULL) {
- msg_err ("map fin error: new data is NULL");
- return;
- }
-
- checksum = murmur32_hash (cbdata->buf->str, cbdata->buf->len);
- if (data->map->checksum != checksum) {
- /* New data available */
- parser = ucl_parser_new (0);
- if (!ucl_parser_add_chunk (parser, cbdata->buf->str, cbdata->buf->len)) {
- msg_err ("cannot parse map %s: %s", data->map->uri, ucl_parser_get_error (parser));
- ucl_parser_free (parser);
- }
- else {
- obj = ucl_parser_get_object (parser);
- ucl_parser_free (parser);
- /* XXX: add replace objects code */
- ucl_object_unref (obj);
- data->map->checksum = checksum;
- }
- }
- else {
- msg_info ("do not reload map %s, checksum is the same: %d", data->map->uri, checksum);
- }
-}
-
-gboolean
-rspamd_parse_ip_list (const gchar *ip_list, radix_tree_t **tree)
-{
- gchar **strvec, **cur;
- struct in_addr ina;
- guint32 mask;
-
- strvec = g_strsplit_set (ip_list, ",", 0);
- cur = strvec;
-
- while (*cur != NULL) {
- /* XXX: handle only ipv4 addresses */
- if (parse_ipmask_v4 (*cur, &ina, &mask)) {
- if (*tree == NULL) {
- *tree = radix_tree_create ();
- }
- radix32tree_add (*tree, htonl (ina.s_addr), mask, 1);
- }
- cur ++;
- }
-
- return (*tree != NULL);
-}
-
-/*
- * vi:ts=4
- */