From 3893d490abaa275fcadf180ff4ffc88e159f5c04 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 13 Nov 2013 17:59:29 +0000 Subject: [PATCH] Add support of path variables. Support expanding of path variables in rspamd: - $CONFDIR: configuration directory - $LOCALSTATESDIR: local states directory - $INSTALLPREFIX: installation prefix - $VERSION: rspamd version --- src/cfg_file.h | 9 ++++ src/cfg_rcl.c | 22 ++++---- src/cfg_rcl.h | 3 +- src/cfg_utils.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 10 deletions(-) diff --git a/src/cfg_file.h b/src/cfg_file.h index 9dec61bc3..b7deb1ca6 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -551,6 +551,15 @@ gboolean check_classifier_statfiles (struct classifier_config *cf); */ struct classifier_config* find_classifier_conf (struct config_file *cfg, const gchar *name); +/* + * Expand path that may contain configuration variables: + * $CONFDIR - configuration directory + * $LOCALSTATESDIR - local states directory + * $INSTALLPREFIX - installation prefix + * $VERSION - rspamd version + */ +const gchar* rspamd_expand_path (memory_pool_t *pool, const gchar *path); + #endif /* ifdef CFG_FILE_H */ /* * vi:ts=4 diff --git a/src/cfg_rcl.c b/src/cfg_rcl.c index 3f419ceb8..6fc92ed19 100644 --- a/src/cfg_rcl.c +++ b/src/cfg_rcl.c @@ -563,7 +563,7 @@ static gboolean rspamd_rcl_lua_handler (struct config_file *cfg, ucl_object_t *obj, gpointer ud, struct rspamd_rcl_section *section, GError **err) { - const gchar *lua_src = ucl_object_tostring (obj); + const gchar *lua_src = rspamd_expand_path (cfg->cfg_pool, ucl_object_tostring (obj)); gchar *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2; lua_State *L = cfg->lua_state; @@ -687,14 +687,14 @@ rspamd_rcl_modules_handler (struct config_file *cfg, ucl_object_t *obj, LL_FOREACH (val, cur) { if (ucl_object_tostring_safe (cur, &data)) { - if (!rspamd_rcl_add_module_path (cfg, data, err)) { + if (!rspamd_rcl_add_module_path (cfg, rspamd_expand_path (cfg->cfg_pool, data), err)) { return FALSE; } } } } else if (ucl_object_tostring_safe (obj, &data)) { - if (!rspamd_rcl_add_module_path (cfg, data, err)) { + if (!rspamd_rcl_add_module_path (cfg, rspamd_expand_path (cfg->cfg_pool, data), err)) { return FALSE; } } @@ -946,7 +946,7 @@ rspamd_rcl_config_init (void) rspamd_rcl_add_default_handler (sub, "statfile_pool_size", rspamd_rcl_parse_struct_integer, G_STRUCT_OFFSET (struct config_file, max_statfile_size), RSPAMD_CL_FLAG_INT_SIZE); rspamd_rcl_add_default_handler (sub, "cache_file", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct config_file, cache_filename), 0); + G_STRUCT_OFFSET (struct config_file, cache_filename), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (sub, "dns_nameserver", rspamd_rcl_parse_struct_string_list, G_STRUCT_OFFSET (struct config_file, nameservers), 0); rspamd_rcl_add_default_handler (sub, "dns_timeout", rspamd_rcl_parse_struct_time, @@ -960,9 +960,9 @@ rspamd_rcl_config_init (void) rspamd_rcl_add_default_handler (sub, "check_attachements", rspamd_rcl_parse_struct_boolean, G_STRUCT_OFFSET (struct config_file, check_text_attachements), 0); rspamd_rcl_add_default_handler (sub, "tempdir", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct config_file, temp_dir), 0); + G_STRUCT_OFFSET (struct config_file, temp_dir), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (sub, "pidfile", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct config_file, pid_file), 0); + G_STRUCT_OFFSET (struct config_file, pid_file), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (sub, "filters", rspamd_rcl_parse_struct_string, G_STRUCT_OFFSET (struct config_file, filters_str), 0); rspamd_rcl_add_default_handler (sub, "sync_interval", rspamd_rcl_parse_struct_time, @@ -976,9 +976,9 @@ rspamd_rcl_config_init (void) rspamd_rcl_add_default_handler (sub, "dynamic_conf", rspamd_rcl_parse_struct_string, G_STRUCT_OFFSET (struct config_file, dynamic_conf), 0); rspamd_rcl_add_default_handler (sub, "rrd", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct config_file, rrd_file), 0); + G_STRUCT_OFFSET (struct config_file, rrd_file), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (sub, "history_file", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct config_file, history_file), 0); + G_STRUCT_OFFSET (struct config_file, history_file), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (sub, "use_mlock", rspamd_rcl_parse_struct_boolean, G_STRUCT_OFFSET (struct config_file, mlock_statfile_pool), 0); @@ -1022,7 +1022,7 @@ rspamd_rcl_config_init (void) rspamd_rcl_add_default_handler (ssub, "symbol", rspamd_rcl_parse_struct_string, G_STRUCT_OFFSET (struct statfile, symbol), 0); rspamd_rcl_add_default_handler (ssub, "path", rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct statfile, path), 0); + G_STRUCT_OFFSET (struct statfile, path), RSPAMD_CL_FLAG_STRING_PATH); rspamd_rcl_add_default_handler (ssub, "label", rspamd_rcl_parse_struct_string, G_STRUCT_OFFSET (struct statfile, label), 0); rspamd_rcl_add_default_handler (ssub, "size", rspamd_rcl_parse_struct_integer, @@ -1171,6 +1171,10 @@ rspamd_rcl_parse_struct_string (struct config_file *cfg, ucl_object_t *obj, return FALSE; } + if (pd->flags & RSPAMD_CL_FLAG_STRING_PATH) { + *target = (gchar *)rspamd_expand_path (cfg->cfg_pool, *target); + } + return TRUE; } diff --git a/src/cfg_rcl.h b/src/cfg_rcl.h index 6949c48aa..272272ab4 100644 --- a/src/cfg_rcl.h +++ b/src/cfg_rcl.h @@ -50,7 +50,8 @@ struct rspamd_rcl_struct_parser { RSPAMD_CL_FLAG_INT_16 = 0x1 << 5, RSPAMD_CL_FLAG_INT_32 = 0x1 << 6, RSPAMD_CL_FLAG_INT_64 = 0x1 << 7, - RSPAMD_CL_FLAG_INT_SIZE = 0x1 << 8 + RSPAMD_CL_FLAG_INT_SIZE = 0x1 << 8, + RSPAMD_CL_FLAG_STRING_PATH = 0x1 << 9 } flags; }; diff --git a/src/cfg_utils.c b/src/cfg_utils.c index dd6b00dcd..6a9477e00 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -1150,6 +1150,139 @@ check_classifier_statfiles (struct classifier_config *cf) return res; } +/* + * Variables: + * $CONFDIR - configuration directory + * $LOCALSTATESDIR - local states directory + * $INSTALLPREFIX - installation prefix + * $VERSION - rspamd version + */ + +#define RSPAMD_CONFDIR_MACRO "CONFDIR" +#define RSPAMD_LOCALSTATESDIR_MACRO "LOCALSTATESDIR" +#define RSPAMD_INSTALLPREFIX_MACRO "INSTALLPREFIX" +#define RSPAMD_VERSION_MACRO "VERSION" + +static const gchar * +rspamd_check_path_variable (const gchar *in, gsize *len) +{ + switch (*in) { + case 'C': + if (strncmp (in, RSPAMD_CONFDIR_MACRO, sizeof (RSPAMD_CONFDIR_MACRO) - 1) == 0) { + *len += sizeof (ETC_PREFIX) - 1; + in += sizeof (RSPAMD_CONFDIR_MACRO) - 1; + } + break; + case 'L': + if (strncmp (in, RSPAMD_LOCALSTATESDIR_MACRO, sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1) == 0) { + *len += sizeof (LOCALSTATES_PREFIX) - 1; + in += sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1; + } + break; + case 'I': + if (strncmp (in, RSPAMD_INSTALLPREFIX_MACRO, sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1) == 0) { + *len += sizeof (CMAKE_PREFIX) - 1; + in += sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1; + } + break; + case 'V': + if (strncmp (in, RSPAMD_VERSION_MACRO, sizeof (RSPAMD_VERSION_MACRO) - 1) == 0) { + *len += sizeof (RVERSION) - 1; + in += sizeof (RSPAMD_VERSION_MACRO) - 1; + } + break; + } + + return in; +} + +static const gchar * +rspamd_expand_path_variable (const gchar *in, gchar **dest) +{ + gchar *d = *dest; + const gchar *v = in + 1; + + *d = *v; + in ++; + + switch (*v) { + case 'C': + if (strncmp (v, RSPAMD_CONFDIR_MACRO, sizeof (RSPAMD_CONFDIR_MACRO) - 1) == 0) { + memcpy (d, ETC_PREFIX, sizeof (ETC_PREFIX) - 1); + d += sizeof (ETC_PREFIX) - 1; + in += sizeof (RSPAMD_CONFDIR_MACRO) - 1; + } + break; + case 'L': + if (strncmp (v, RSPAMD_LOCALSTATESDIR_MACRO, sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1) == 0) { + memcpy (d, LOCALSTATES_PREFIX, sizeof (LOCALSTATES_PREFIX) - 1); + d += sizeof (LOCALSTATES_PREFIX) - 1; + in += sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1; + } + break; + case 'I': + if (strncmp (v, RSPAMD_INSTALLPREFIX_MACRO, sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1) == 0) { + memcpy (d, CMAKE_PREFIX, sizeof (CMAKE_PREFIX) - 1); + d += sizeof (CMAKE_PREFIX) - 1; + in += sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1; + } + break; + case 'V': + if (strncmp (v, RSPAMD_VERSION_MACRO, sizeof (RSPAMD_VERSION_MACRO) - 1) == 0) { + memcpy (d, RVERSION, sizeof (RVERSION) - 1); + d += sizeof (RVERSION) - 1; + in += sizeof (RSPAMD_VERSION_MACRO) - 1; + } + break; + } + + *dest = d; + return in; +} + +const gchar* +rspamd_expand_path (memory_pool_t *pool, const gchar *path) +{ + const gchar *p = path; + gchar *dest, *d; + gsize len = 0, orig_len = 0; + + while (*p != '\0') { + if (*p == '$') { + len ++; + p = rspamd_check_path_variable (p + 1, &len); + } + else { + len ++; + } + orig_len ++; + p ++; + } + + if (len == orig_len) { + return path; + } + + dest = memory_pool_alloc (pool, len + 1); + p = path; + d = dest; + + while (*p != '\0') { + if (*p == '$') { + p = rspamd_expand_path_variable (p, &d); + } + else { + *d++ = *p++; + } + } + + *d = '\0'; + + msg_debug ("expanded %s to %s", path, dest); + + return dest; +} + /* * vi:ts=4 */ -- 2.39.5