From b94138fc387a4ff991738db86a7064221ef25959 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 9 Jan 2013 18:50:49 +0400 Subject: [PATCH] Copy hash table utility function. Slight fix for /symbols handler. --- src/cfg_xml.c | 14 +++++++++---- src/util.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 21 ++++++++++++++++++++ src/webui.c | 2 +- 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); -- 2.39.5