From 59b100ac0e907fe976492d3596349c1f4fdc110e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 5 Jan 2014 18:18:51 +0000 Subject: [PATCH] Add include_map macro to ucl language. --- src/cfg_utils.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 8e57ea1c9..282f72b7a 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -42,6 +42,12 @@ #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 (memory_pool_t * pool, gchar * chunk, gint len, struct map_cb_data *data); +static void rspamd_ucl_fin_cb (memory_pool_t * pool, struct map_cb_data *data); gboolean parse_host_port_priority (memory_pool_t *pool, const gchar *str, gchar **addr, guint16 *port, guint *priority) @@ -719,6 +725,24 @@ get_filename_extension (const char *filename) return NULL; } +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 = memory_pool_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: @@ -751,6 +775,12 @@ rspamd_ucl_add_conf_variables (struct ucl_parser *parser) 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, @@ -807,6 +837,7 @@ read_rspamd_config (struct config_file *cfg, const gchar *filename, else { 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)); munmap (data, st.st_size); @@ -952,6 +983,65 @@ check_classifier_statfiles (struct classifier_config *cf) return res; } +static gchar* +rspamd_ucl_read_cb (memory_pool_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 (memory_pool_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); + } +} + /* * vi:ts=4 */ -- 2.39.5