aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2013-01-09 18:50:49 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2013-01-09 18:50:49 +0400
commitb94138fc387a4ff991738db86a7064221ef25959 (patch)
tree92fa01bcc3c22e020afe3fa97d5a9d9e73205d32
parent823c263b9d417a9d28344c469b253e0dfe76e640 (diff)
downloadrspamd-b94138fc387a4ff991738db86a7064221ef25959.tar.gz
rspamd-b94138fc387a4ff991738db86a7064221ef25959.zip
Copy hash table utility function.
Slight fix for /symbols handler.
-rw-r--r--src/cfg_xml.c14
-rw-r--r--src/util.c54
-rw-r--r--src/util.h21
-rw-r--r--src/webui.c2
4 files changed, 86 insertions, 5 deletions
diff --git a/src/cfg_xml.c b/src/cfg_xml.c
index 71767cc3c..b7e5a7ab9 100644
--- a/src/cfg_xml.c
+++ b/src/cfg_xml.c
@@ -885,6 +885,7 @@ struct wrk_param {
gchar *param;
GList *list;
} d;
+ GHashTable *attrs;
};
static void
@@ -904,12 +905,12 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud)
if (param->is_list) {
cur = param->d.list;
while (cur) {
- cparam->handler (cd->cfg, cd->ctx, NULL, cur->data, k, cd->wrk->ctx, cparam->offset);
+ cparam->handler (cd->cfg, cd->ctx, param->attrs, cur->data, k, cd->wrk->ctx, cparam->offset);
cur = g_list_next (cur);
}
}
else {
- cparam->handler (cd->cfg, cd->ctx, NULL, param->d.param, k, cd->wrk->ctx, cparam->offset);
+ cparam->handler (cd->cfg, cd->ctx, param->attrs, param->d.param, k, cd->wrk->ctx, cparam->offset);
}
}
else {
@@ -926,12 +927,12 @@ worker_foreach_callback (gpointer k, gpointer v, gpointer ud)
if (param->is_list) {
cur = param->d.list;
while (cur) {
- cparam->handler (cd->cfg, cd->ctx, NULL, cur->data, NULL, cd->wrk->ctx, cparam->offset);
+ cparam->handler (cd->cfg, cd->ctx, param->attrs, cur->data, NULL, cd->wrk->ctx, cparam->offset);
cur = g_list_next (cur);
}
}
else {
- cparam->handler (cd->cfg, cd->ctx, NULL, param->d.param, NULL, cd->wrk->ctx, cparam->offset);
+ cparam->handler (cd->cfg, cd->ctx, param->attrs, param->d.param, NULL, cd->wrk->ctx, cparam->offset);
}
}
else {
@@ -962,6 +963,10 @@ worker_handle_param (struct config_file *cfg, struct rspamd_xml_userdata *ctx, c
param->is_list = FALSE;
param->d.param = memory_pool_strdup (cfg->cfg_pool, data);
g_hash_table_insert (wrk->params, (char *)name, param);
+ /* Copy attributes */
+ param->attrs = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal);
+ memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)g_hash_table_destroy, param->attrs);
+ rspamd_hash_table_copy (attrs, param->attrs, rspamd_str_pool_copy, rspamd_str_pool_copy, cfg->cfg_pool);
}
else {
if (param->is_list) {
@@ -975,6 +980,7 @@ worker_handle_param (struct config_file *cfg, struct rspamd_xml_userdata *ctx, c
param->d.list = g_list_append (param->d.list, memory_pool_strdup (cfg->cfg_pool, data));
memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)g_list_free, param->d.list);
}
+ rspamd_hash_table_copy (attrs, param->attrs, rspamd_str_pool_copy, rspamd_str_pool_copy, cfg->cfg_pool);
}
return TRUE;
diff --git a/src/util.c b/src/util.c
index 2784e6a78..9c4d8bf4c 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1772,6 +1772,60 @@ murmur128_hash (const guint8 *in, gsize len, guint64 out[])
out[1] = h2;
}
+struct hash_copy_callback_data {
+ gpointer (*key_copy_func)(gconstpointer data, gpointer ud);
+ gpointer (*value_copy_func)(gconstpointer data, gpointer ud);
+ gpointer ud;
+ GHashTable *dst;
+};
+
+static void
+copy_foreach_callback (gpointer key, gpointer value, gpointer ud)
+{
+ struct hash_copy_callback_data *cb = ud;
+ gpointer nkey, nvalue;
+
+ nkey = cb->key_copy_func ? cb->key_copy_func (key, cb->ud) : (gpointer)key;
+ nvalue = cb->value_copy_func ? cb->value_copy_func (value, cb->ud) : (gpointer)value;
+ g_hash_table_insert (cb->dst, nkey, nvalue);
+}
+/**
+ * Deep copy of one hash table to another
+ * @param src source hash
+ * @param dst destination hash
+ * @param key_copy_func function called to copy or modify keys (or NULL)
+ * @param value_copy_func function called to copy or modify values (or NULL)
+ * @param ud user data for copy functions
+ */
+void rspamd_hash_table_copy (GHashTable *src, GHashTable *dst,
+ gpointer (*key_copy_func)(gconstpointer data, gpointer ud),
+ gpointer (*value_copy_func)(gconstpointer data, gpointer ud),
+ gpointer ud)
+{
+ struct hash_copy_callback_data cb;
+ if (src != NULL && dst != NULL) {
+ cb.key_copy_func = key_copy_func;
+ cb.value_copy_func = value_copy_func;
+ cb.ud = ud;
+ cb.dst = dst;
+ g_hash_table_foreach (src, copy_foreach_callback, &cb);
+ }
+}
+
+/**
+ * Utility function to provide mem_pool copy for rspamd_hash_table_copy function
+ * @param data string to copy
+ * @param ud memory pool to use
+ * @return
+ */
+gpointer
+rspamd_str_pool_copy (gconstpointer data, gpointer ud)
+{
+ memory_pool_t *pool = ud;
+
+ return data ? memory_pool_strdup (pool, data) : NULL;
+}
+
/*
* vi:ts=4
*/
diff --git a/src/util.h b/src/util.h
index bd57ef59b..6bec21f46 100644
--- a/src/util.h
+++ b/src/util.h
@@ -359,4 +359,25 @@ guint32 murmur32_hash (const guint8 *in, gsize len);
*/
void murmur128_hash (const guint8 *in, gsize len, guint64 out[]);
+/**
+ * Deep copy of one hash table to another
+ * @param src source hash
+ * @param dst destination hash
+ * @param key_copy_func function called to copy or modify keys (or NULL)
+ * @param value_copy_func function called to copy or modify values (or NULL)
+ * @param ud user data for copy functions
+ */
+void rspamd_hash_table_copy (GHashTable *src, GHashTable *dst,
+ gpointer (*key_copy_func)(gconstpointer data, gpointer ud),
+ gpointer (*value_copy_func)(gconstpointer data, gpointer ud),
+ gpointer ud);
+
+/**
+ * Utility function to provide mem_pool copy for rspamd_hash_table_copy function
+ * @param data string to copy
+ * @param ud memory pool to use
+ * @return
+ */
+gpointer rspamd_str_pool_copy (gconstpointer data, gpointer ud);
+
#endif
diff --git a/src/webui.c b/src/webui.c
index 7e3963b64..c7f734512 100644
--- a/src/webui.c
+++ b/src/webui.c
@@ -1350,7 +1350,7 @@ http_handle_save_symbols (struct evhttp_request *req, gpointer arg)
val = json_number_value (jvalue);
sym = g_hash_table_lookup (metric->symbols, json_string_value (jname));
if (sym && fabs (sym->score - val) > 0.01) {
- if (!add_dynamic_symbol (ctx->cfg, DEFAULT_METRIC, sym->name, val)) {
+ if (!add_dynamic_symbol (ctx->cfg, DEFAULT_METRIC, json_string_value (jname), val)) {
evbuffer_free (evb);
json_delete (json);
evhttp_send_reply (req, HTTP_INTERNAL, "506 cannot write symbol's value", NULL);