aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cfg_file.h2
-rw-r--r--src/cfg_utils.c11
-rw-r--r--src/cfg_xml.c6
-rw-r--r--src/cfg_xml.h5
-rw-r--r--src/classifiers/bayes.c6
-rw-r--r--src/kvstorage_config.c362
-rw-r--r--src/kvstorage_config.h81
-rw-r--r--src/plugins/regexp.c2
-rw-r--r--src/tokenizers/tokenizers.c3
9 files changed, 461 insertions, 17 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h
index fc1ba547a..184a1aa16 100644
--- a/src/cfg_file.h
+++ b/src/cfg_file.h
@@ -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
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
index 203133e77..ffebd5c46 100644
--- a/src/cfg_utils.c
+++ b/src/cfg_utils.c
@@ -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;
}
diff --git a/src/cfg_xml.c b/src/cfg_xml.c
index 30192703c..d66912ab9 100644
--- a/src/cfg_xml.c
+++ b/src/cfg_xml.c
@@ -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;
diff --git a/src/cfg_xml.h b/src/cfg_xml.h
index 2e188d2f6..6740e135e 100644
--- a/src/cfg_xml.h
+++ b/src/cfg_xml.h
@@ -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
diff --git a/src/classifiers/bayes.c b/src/classifiers/bayes.c
index bf7e4d9d4..265957bc9 100644
--- a/src/classifiers/bayes.c
+++ b/src/classifiers/bayes.c
@@ -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
index 000000000..70c9ee182
--- /dev/null
+++ b/src/kvstorage_config.c
@@ -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
index 000000000..567dd18be
--- /dev/null
+++ b/src/kvstorage_config.h
@@ -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_ */
diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c
index 519666662..e4eb82398 100644
--- a/src/plugins/regexp.c
+++ b/src/plugins/regexp.c
@@ -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;
diff --git a/src/tokenizers/tokenizers.c b/src/tokenizers/tokenizers.c
index 902245e7d..2eb11eff8 100644
--- a/src/tokenizers/tokenizers.c
+++ b/src/tokenizers/tokenizers.c
@@ -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);