]> source.dussan.org Git - rspamd.git/commitdiff
* Add configuration utils for kvstorage
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 17 Oct 2011 18:04:29 +0000 (21:04 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 17 Oct 2011 18:04:29 +0000 (21:04 +0300)
lib/CMakeLists.txt
src/cfg_file.h
src/cfg_utils.c
src/cfg_xml.c
src/cfg_xml.h
src/classifiers/bayes.c
src/kvstorage_config.c [new file with mode: 0644]
src/kvstorage_config.h [new file with mode: 0644]
src/plugins/regexp.c
src/tokenizers/tokenizers.c

index 38674d6e7a2ef48efd1ea78b21fa08d0842f8c9c..f84a70227ad90d58cceda7e321d62d56302a9701 100644 (file)
@@ -48,6 +48,7 @@ SET(RSPAMDLIBSRC ../src/binlog.c
                                ../src/html.c
                                ../src/images.c
                                ../src/kvstorage.c
+                               ../src/kvstorage_config.c
                                ../src/lmtp_proto.c
                                ../src/logger.c
                                ../src/map.c
index fc1ba547aed51e4e18ec73a87b4245e005ff58ff..184a1aa16727a836653c86fc92e94e3c770e55dd 100644 (file)
@@ -378,7 +378,7 @@ gchar* get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_n
  * @param limit string representation of limit (eg. 1M)
  * @return numeric value of limit
  */
-gsize parse_limit (const gchar *limit);
+gsize parse_limit (const gchar *limit, guint len);
 
 /**
  * Parse time
index 203133e77d16a961f2dfffa863d4d78666bcb1a6..ffebd5c46e524d6debf50e31c1328989c4c2fb8b 100644 (file)
@@ -268,16 +268,17 @@ get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_name)
 }
 
 gsize
-parse_limit (const gchar *limit)
+parse_limit (const gchar *limit, guint len)
 {
        gsize                          result = 0;
-       gchar                           *err_str;
+       const gchar                   *err_str;
 
-       if (!limit || *limit == '\0')
+       if (!limit || *limit == '\0' || len == 0) {
                return 0;
+       }
 
        errno = 0;
-       result = strtoul (limit, &err_str, 10);
+       result = strtoul (limit, (gchar **)&err_str, 10);
 
        if (*err_str != '\0') {
                /* Megabytes */
@@ -292,7 +293,7 @@ parse_limit (const gchar *limit)
                else if (*err_str == 'g' || *err_str == 'G') {
                        result *= 1073741824L;
                }
-               else {
+               else if (len > 0 && err_str - limit != len) {
                        msg_warn ("invalid limit value '%s' at position '%s'", limit, err_str);
                        result = 0;
                }
index 30192703ce1c63f59449a4230508510e9be1242c..d66912ab99a45fee84566fa6946d5a09c1b28f6e 100644 (file)
@@ -1521,7 +1521,7 @@ xml_handle_size (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHash
        gsize                      *dest;
 
        dest = (gsize *)G_STRUCT_MEMBER_P (dest_struct, offset);
-       *dest = parse_limit (data);
+       *dest = parse_limit (data, -1);
        
        return TRUE;
 }
@@ -1792,7 +1792,7 @@ if (g_ascii_strcasecmp (element_name, (x)) == 0) {                                                                                                                                                                                        \
 else {                                                                                                                                                                                                                                                                         \
        res = FALSE;                                                                                                                                                                                                                                                    \
        if ((required) == TRUE) {                                                                                                                                                                                                                               \
-       *error = g_error_new (xml_error_quark (), XML_UNMATCHED_TAG, "element %s is unexpected in this state, expected %s", element_name, (x)); \
+       if (*error == NULL) *error = g_error_new (xml_error_quark (), XML_UNMATCHED_TAG, "element %s is unexpected in this state, expected %s", element_name, (x));     \
        ud->state = XML_ERROR;                                                                                                                                                                                                                                  \
        }                                                                                                                                                                                                                                                                               \
 }                                                                                                                                                                                                                                                                                      \
@@ -2137,7 +2137,7 @@ check_module_option (const gchar *mname, const gchar *optname, const gchar *data
                }
                break;
        case MODULE_OPT_TYPE_SIZE:
-               (void)parse_limit (data);
+               (void)parse_limit (data, -1);
                if (errno != 0) {
                        msg_warn ("non-numeric data for option: '%s' for module: '%s': %s", optname, mname, strerror (errno));
                        return FALSE;
index 2e188d2f63d487d11e0bb72821b4877bc068730e..6740e135eae523e03ce11e2ba6c55089a2c8fe18 100644 (file)
@@ -167,7 +167,7 @@ void register_worker_opt (gint wtype, const gchar *optname, element_handler_func
 void register_classifier_opt (const gchar *ctype, const gchar *optname);
 
 /* Register new xml subparser */
-void register_suparser (const gchar *tag, enum xml_read_state state, const GMarkupParser *parser, gpointer user_data);
+void register_subparser (const gchar *tag, enum xml_read_state state, const GMarkupParser *parser, gpointer user_data);
 
 /* Check validity of module option */
 gboolean check_module_option (const gchar *mname, const gchar *optname, const gchar *data);
@@ -175,4 +175,7 @@ gboolean check_module_option (const gchar *mname, const gchar *optname, const gc
 /* Dumper functions */
 gboolean xml_dump_config (struct config_file *cfg, const gchar *filename);
 
+/* XML error quark for reporting errors */
+GQuark xml_error_quark (void);
+
 #endif
index bf7e4d9d464092eaee399ea93d543c4bee237c5f..265957bc92ac52fcfc2303a2e2e01b5041d917e5 100644 (file)
@@ -221,7 +221,7 @@ bayes_classify (struct classifier_ctx* ctx, statfile_pool_t *pool, GTree *input,
 
        data.learned_tokens = 0;
        if (ctx->cfg->opts && (value = g_hash_table_lookup (ctx->cfg->opts, "max_tokens")) != NULL) {
-               minnodes = parse_limit (value);
+               minnodes = parse_limit (value, -1);
                data.max_tokens = minnodes;
        }
        else {
@@ -320,7 +320,7 @@ bayes_learn (struct classifier_ctx* ctx, statfile_pool_t *pool, const char *symb
        data.learned_tokens = 0;
        data.learned_tokens = 0;
        if (ctx->cfg->opts && (value = g_hash_table_lookup (ctx->cfg->opts, "max_tokens")) != NULL) {
-               minnodes = parse_limit (value);
+               minnodes = parse_limit (value, -1);
                data.max_tokens = minnodes;
        }
        else {
@@ -425,7 +425,7 @@ bayes_learn_spam (struct classifier_ctx* ctx, statfile_pool_t *pool,
 
        data.learned_tokens = 0;
        if (ctx->cfg->opts && (value = g_hash_table_lookup (ctx->cfg->opts, "max_tokens")) != NULL) {
-               minnodes = parse_limit (value);
+               minnodes = parse_limit (value, -1);
                data.max_tokens = minnodes;
        }
        else {
diff --git a/src/kvstorage_config.c b/src/kvstorage_config.c
new file mode 100644 (file)
index 0000000..70c9ee1
--- /dev/null
@@ -0,0 +1,362 @@
+/* Copyright (c) 2010, 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 ''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.
+ */
+
+#include "kvstorage_config.h"
+#include "main.h"
+#include "cfg_xml.h"
+
+/* Global hash of storages indexed by id */
+GHashTable *storages = NULL;
+/* Last used id for explicit numbering */
+gint last_id = 0;
+
+struct kvstorage_config_parser {
+       enum {
+               KVSTORAGE_STATE_INIT,
+               KVSTORAGE_STATE_PARAM,
+               KVSTORAGE_STATE_BACKEND,
+               KVSTORAGE_STATE_EXPIRE,
+               KVSTORAGE_STATE_ID,
+               KVSTORAGE_STATE_NAME,
+               KVSTORAGE_STATE_CACHE_TYPE,
+               KVSTORAGE_STATE_CACHE_MAX_ELTS,
+               KVSTORAGE_STATE_CACHE_MAX_MEM,
+               KVSTORAGE_STATE_BACKEND_TYPE,
+               KVSTORAGE_STATE_EXPIRE_TYPE,
+               KVSTORAGE_STATE_ERROR
+       } state;
+       struct kvstorage_config *current_storage;
+       memory_pool_t *pool;
+       gchar *cur_elt;
+};
+
+static void
+kvstorage_config_destroy (gpointer k)
+{
+       struct kvstorage_config                         *kconf = k;
+
+       if (kconf->name) {
+               g_free (kconf->name);
+       }
+
+       g_free (kconf);
+}
+
+
+/* XML parse callbacks */
+/* Called for open tags <foo bar="baz"> */
+void kvstorage_xml_start_element (GMarkupParseContext  *context,
+                                                               const gchar         *element_name,
+                                                               const gchar        **attribute_names,
+                                                               const gchar        **attribute_values,
+                                                               gpointer             user_data,
+                                                               GError             **error)
+{
+       struct kvstorage_config_parser  *kv_parser = user_data;
+
+       switch (kv_parser->state) {
+       case KVSTORAGE_STATE_INIT:
+               /* Make temporary pool */
+               if (kv_parser->pool != NULL) {
+                       memory_pool_delete (kv_parser->pool);
+               }
+               kv_parser->pool = memory_pool_new (memory_pool_get_size ());
+
+               /* Create new kvstorage_config */
+               kv_parser->current_storage = g_malloc0 (sizeof (struct kvstorage_config));
+               kv_parser->current_storage->id = ++last_id;
+               break;
+       case KVSTORAGE_STATE_PARAM:
+               if (g_ascii_strcasecmp (element_name, "type") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_CACHE_TYPE;
+               }
+               else if (g_ascii_strcasecmp (element_name, "max_elements") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_CACHE_MAX_ELTS;
+               }
+               else if (g_ascii_strcasecmp (element_name, "max_memory") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_CACHE_MAX_MEM;
+               }
+               else if (g_ascii_strcasecmp (element_name, "id") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_ID;
+               }
+               else if (g_ascii_strcasecmp (element_name, "name") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_NAME;
+               }
+               else if (g_ascii_strcasecmp (element_name, "backend") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_BACKEND;
+               }
+               else if (g_ascii_strcasecmp (element_name, "expire") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_EXPIRE;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected",
+                                               element_name);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               kv_parser->cur_elt = memory_pool_strdup (kv_parser->pool, element_name);
+               break;
+       case KVSTORAGE_STATE_BACKEND:
+               if (g_ascii_strcasecmp (element_name, "type") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_BACKEND_TYPE;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected in backend definition",
+                                               element_name);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       case KVSTORAGE_STATE_EXPIRE:
+               if (g_ascii_strcasecmp (element_name, "type") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_EXPIRE_TYPE;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected in expire definition",
+                                               element_name);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       default:
+               /* Do nothing at other states */
+               break;
+       }
+
+}
+
+#define CHECK_TAG(s)                                                                                                                                                                                                                                   \
+do {                                                                                                                                                                                                                                                                   \
+if (g_ascii_strcasecmp (element_name, kv_parser->cur_elt) == 0) {                                                                                                                                              \
+       kv_parser->state = (s);                                                                                                                                                                                                                         \
+}                                                                                                                                                                                                                                                                              \
+else {                                                                                                                                                                                                                                                                 \
+       if (*error == NULL) *error = g_error_new (xml_error_quark (), XML_UNMATCHED_TAG, "element %s is unexpected in this state, expected %s", element_name, kv_parser->cur_elt);      \
+       kv_parser->state = KVSTORAGE_STATE_ERROR;                                                                                                                                                                                       \
+}                                                                                                                                                                                                                                                                              \
+} while (0)
+
+/* Called for close tags </foo> */
+void kvstorage_xml_end_element (GMarkupParseContext    *context,
+                                                               const gchar         *element_name,
+                                                               gpointer             user_data,
+                                                               GError             **error)
+{
+       struct kvstorage_config_parser  *kv_parser = user_data;
+
+       switch (kv_parser->state) {
+       case KVSTORAGE_STATE_INIT:
+       case KVSTORAGE_STATE_PARAM:
+               if (g_ascii_strcasecmp (element_name, "keystorage") == 0) {
+                       /* XXX: Init actual storage */
+                       g_hash_table_insert (storages, &kv_parser->current_storage->id, kv_parser->current_storage);
+                       kv_parser->state = KVSTORAGE_STATE_INIT;
+                       g_markup_parse_context_pop (context);
+                       return;
+               }
+               if (*error == NULL) {
+                       *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "end element %s is unexpected, expected start element",
+                                       element_name);
+               }
+               kv_parser->state = KVSTORAGE_STATE_ERROR;
+               break;
+       case KVSTORAGE_STATE_ID:
+       case KVSTORAGE_STATE_NAME:
+       case KVSTORAGE_STATE_CACHE_TYPE:
+       case KVSTORAGE_STATE_CACHE_MAX_ELTS:
+       case KVSTORAGE_STATE_CACHE_MAX_MEM:
+               CHECK_TAG (KVSTORAGE_STATE_PARAM);
+               break;
+       case KVSTORAGE_STATE_BACKEND_TYPE:
+               CHECK_TAG (KVSTORAGE_STATE_BACKEND);
+               break;
+       case KVSTORAGE_STATE_EXPIRE_TYPE:
+               CHECK_TAG (KVSTORAGE_STATE_EXPIRE);
+               break;
+       case KVSTORAGE_STATE_BACKEND:
+               if (g_ascii_strcasecmp (element_name, "backend") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_PARAM;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected",
+                                               element_name);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       case KVSTORAGE_STATE_EXPIRE:
+               if (g_ascii_strcasecmp (element_name, "expire") == 0) {
+                       kv_parser->state = KVSTORAGE_STATE_PARAM;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected",
+                                               element_name);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       default:
+               /* Do nothing at other states */
+               break;
+       }
+}
+#undef CHECK_TAG
+
+/* text is not nul-terminated */
+void kvstorage_xml_text       (GMarkupParseContext             *context,
+                                                               const gchar         *text,
+                                                               gsize                text_len,
+                                                               gpointer             user_data,
+                                                               GError             **error)
+{
+       struct kvstorage_config_parser  *kv_parser = user_data;
+       gchar                           *err_str;
+
+       switch (kv_parser->state) {
+       case KVSTORAGE_STATE_INIT:
+       case KVSTORAGE_STATE_PARAM:
+               if (*error == NULL) {
+                       *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "text is unexpected, expected start element");
+               }
+               kv_parser->state = KVSTORAGE_STATE_ERROR;
+               break;
+       case KVSTORAGE_STATE_ID:
+               kv_parser->current_storage->id = strtoul (text, &err_str, 10);
+               if ((gsize)(err_str - text) != text_len) {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "invalid number: %*s", (int)text_len, text);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               else {
+                       last_id = kv_parser->current_storage->id;
+               }
+               break;
+       case KVSTORAGE_STATE_NAME:
+               kv_parser->current_storage->name = g_malloc (text_len + 1);
+               rspamd_strlcpy (kv_parser->current_storage->name, text, text_len + 1);
+               break;
+       case KVSTORAGE_STATE_CACHE_MAX_ELTS:
+               kv_parser->current_storage->cache.max_elements = parse_limit (text, text_len);
+               break;
+       case KVSTORAGE_STATE_CACHE_MAX_MEM:
+               kv_parser->current_storage->cache.max_memory = parse_limit (text, text_len);
+               break;
+       case KVSTORAGE_STATE_CACHE_TYPE:
+               if (g_ascii_strncasecmp (text, "hash", MIN (text_len, sizeof ("hash") - 1)) == 0) {
+                       kv_parser->current_storage->cache.type = KVSTORAGE_TYPE_CACHE_HASH;
+               }
+               else if (g_ascii_strncasecmp (text, "radix", MIN (text_len, sizeof ("radix") - 1)) == 0) {
+                       kv_parser->current_storage->cache.type = KVSTORAGE_TYPE_CACHE_RADIX;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "invalid cache type: %*s", (int)text_len, text);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       case KVSTORAGE_STATE_BACKEND_TYPE:
+               if (g_ascii_strncasecmp (text, "null", MIN (text_len, sizeof ("null") - 1)) == 0) {
+                       kv_parser->current_storage->backend.type = KVSTORAGE_TYPE_BACKEND_NULL;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "invalid backend type: %*s", (int)text_len, text);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       case KVSTORAGE_STATE_EXPIRE_TYPE:
+               if (g_ascii_strncasecmp (text, "lru", MIN (text_len, sizeof ("lru") - 1)) == 0) {
+                       kv_parser->current_storage->expire.type = KVSTORAGE_TYPE_EXPIRE_LRU;
+               }
+               else {
+                       if (*error == NULL) {
+                               *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "invalid expire type: %*s", (int)text_len, text);
+                       }
+                       kv_parser->state = KVSTORAGE_STATE_ERROR;
+               }
+               break;
+       default:
+               /* Do nothing at other states */
+               break;
+       }
+
+}
+
+/* Called on error, including one set by other
+* methods in the vtable. The GError should not be freed.
+*/
+void kvstorage_xml_error       (GMarkupParseContext            *context,
+                                                               GError              *error,
+                                                               gpointer             user_data)
+{
+       msg_err ("kvstorage xml parser error: %s", error->message);
+}
+
+/** Public API */
+
+/* Init subparser of kvstorage config */
+void
+init_kvstorage_config (void)
+{
+       GMarkupParser                                   *parser;
+       struct kvstorage_config_parser  *kv_parser;
+
+       if (storages == NULL) {
+               storages = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, kvstorage_config_destroy);
+       }
+       else {
+               /* Create new global table */
+               g_hash_table_destroy (storages);
+               storages = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, kvstorage_config_destroy);
+       }
+
+       /* Create and register subparser */
+       parser = g_malloc0 (sizeof (GMarkupParser));
+       parser->start_element = kvstorage_xml_start_element;
+       parser->end_element = kvstorage_xml_end_element;
+       parser->error = kvstorage_xml_error;
+       parser->text = kvstorage_xml_text;
+
+       kv_parser = g_malloc0 (sizeof (struct kvstorage_config_parser));
+       kv_parser->state = KVSTORAGE_STATE_PARAM;
+
+       register_subparser ("keystorage", XML_READ_START, parser, kv_parser);
+}
+
+/* Get configuration for kvstorage with specified ID */
+struct kvstorage_config*
+get_kvstorage_config (gint id)
+{
+       if (storages == NULL) {
+               return NULL;
+       }
+       return g_hash_table_lookup (storages, &id);
+}
diff --git a/src/kvstorage_config.h b/src/kvstorage_config.h
new file mode 100644 (file)
index 0000000..567dd18
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (c) 2010, 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 ''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.
+ */
+
+
+#ifndef KVSTORAGE_CONFIG_H_
+#define KVSTORAGE_CONFIG_H_
+
+#include "config.h"
+#include "kvstorage.h"
+
+/* Type of kvstorage cache */
+enum kvstorage_cache_type {
+       KVSTORAGE_TYPE_CACHE_HASH,
+       KVSTORAGE_TYPE_CACHE_RADIX
+};
+
+/* Type of kvstorage backend */
+enum kvstorage_backend_type {
+       KVSTORAGE_TYPE_BACKEND_NULL = 0
+};
+
+/* Type of kvstorage expire */
+enum kvstorage_expire_type {
+       KVSTORAGE_TYPE_EXPIRE_LRU
+};
+
+/* Cache config */
+struct kvstorage_cache_config {
+       gsize max_elements;
+       gsize max_memory;
+       enum kvstorage_cache_type type;
+};
+
+/* Backend config */
+struct kvstorage_backend_config {
+       enum kvstorage_backend_type type;
+};
+
+
+/* Expire config */
+struct kvstorage_expire_config {
+       enum kvstorage_expire_type type;
+};
+
+/* The main keystorage config */
+struct kvstorage_config {
+       gint id;
+       gchar *name;
+       struct kvstorage_cache_config cache;
+       struct kvstorage_backend_config backend;
+       struct kvstorage_expire_config expire;
+       struct rspamd_kv_storage *storage;
+};
+
+/* Init subparser of kvstorage config */
+void init_kvstorage_config (void);
+
+/* Get configuration for kvstorage with specified ID */
+struct kvstorage_config* get_kvstorage_config (gint id);
+
+#endif /* KVSTORAGE_CONFIG_H_ */
index 5196666621df9b96531f4b2203ebfb127a589b8f..e4eb823988fb6cab8ba480ee8a176749f50ae754 100644 (file)
@@ -498,7 +498,7 @@ regexp_module_config (struct config_file *cfg)
                regexp_module_ctx->statfile_prefix = DEFAULT_STATFILE_PREFIX;
        }
        if ((value = get_module_opt (cfg, "regexp", "max_size")) != NULL) {
-               regexp_module_ctx->max_size = parse_limit (value);
+               regexp_module_ctx->max_size = parse_limit (value, -1);
        }
        else {
                regexp_module_ctx->max_size = 0;
index 902245e7d963c69d0fd8b1ab73aef1eb8f64b63a..2eb11eff86e393594cb3bead7884dd7e90be5aec 100644 (file)
@@ -256,7 +256,6 @@ tokenize_subject (struct worker_task *task, GTree ** tree)
 {
        f_str_t                         subject;
        const gchar                    *sub;
-       token_node_t                   *new = NULL;
        struct tokenizer               *osb_tokenizer;
 
        if (*tree == NULL) {
@@ -268,13 +267,11 @@ tokenize_subject (struct worker_task *task, GTree ** tree)
 
        /* Try to use pre-defined subject */
        if (task->subject != NULL) {
-               new = memory_pool_alloc (task->task_pool, sizeof (token_node_t));
                subject.begin = task->subject;
                subject.len = strlen (task->subject);
                osb_tokenizer->tokenize_func (osb_tokenizer, task->task_pool, &subject, tree, FALSE, TRUE, NULL);
        }
        if ((sub = g_mime_message_get_subject (task->message)) != NULL) {
-               new = memory_pool_alloc (task->task_pool, sizeof (token_node_t));
                subject.begin = (gchar *)sub;
                subject.len = strlen (sub);
                osb_tokenizer->tokenize_func (osb_tokenizer, task->task_pool, &subject, tree, FALSE, TRUE, NULL);