diff options
author | cebka@mailsupport.rambler.ru <cebka@mailsupport.rambler.ru> | 2008-09-18 18:25:00 +0400 |
---|---|---|
committer | cebka@mailsupport.rambler.ru <cebka@mailsupport.rambler.ru> | 2008-09-18 18:25:00 +0400 |
commit | bb2e8a89d2e4caf5345e565f4da5aeb6fc39655b (patch) | |
tree | c586d56f6ba24e651fd4ad099a5c0397c33851d4 /cfg_utils.c | |
parent | 4ad814a6c631883bbb55ae3db2f8806c63f31c9a (diff) | |
download | rspamd-bb2e8a89d2e4caf5345e565f4da5aeb6fc39655b.tar.gz rspamd-bb2e8a89d2e4caf5345e565f4da5aeb6fc39655b.zip |
* Add support of variables and variable substitution in config file
Diffstat (limited to 'cfg_utils.c')
-rw-r--r-- | cfg_utils.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/cfg_utils.c b/cfg_utils.c index 3339e2bd0..a00a075b3 100644 --- a/cfg_utils.c +++ b/cfg_utils.c @@ -149,6 +149,7 @@ init_defaults (struct config_file *cfg) cfg->workers_number = DEFAULT_WORKERS_NUM; cfg->modules_opts = g_hash_table_new (g_str_hash, g_str_equal); + cfg->variables = g_hash_table_new (g_str_hash, g_str_equal); LIST_INIT (&cfg->filters); LIST_INIT (&cfg->perl_modules); @@ -205,6 +206,8 @@ free_config (struct config_file *cfg) g_hash_table_foreach (cfg->modules_opts, clean_hash_bucket, NULL); g_hash_table_remove_all (cfg->modules_opts); g_hash_table_unref (cfg->modules_opts); + g_hash_table_remove_all (cfg->variables); + g_hash_table_unref (cfg->variables); } int @@ -324,5 +327,80 @@ parse_flag (const char *str) } /* + * Try to substitute all variables in given string + * Return: newly allocated string with substituted variables (original string may be freed if variables are found) + */ +char * +substitute_variable (struct config_file *cfg, char *str, u_char recursive) +{ + char *var, *new, *v_begin, *v_end; + size_t len; + + while ((v_begin = strstr (str, "${")) != NULL) { + len = strlen (str); + *v_begin = '\0'; + v_begin += 2; + if ((v_end = strstr (v_begin, "}")) == NULL) { + /* Not a variable, skip */ + continue; + } + *v_end = '\0'; + var = g_hash_table_lookup (cfg->variables, v_begin); + if (var == NULL) { + yywarn ("substitute_variable: variable %s is not defined", v_begin); + /* Substitute unknown variables with empty string */ + var = ""; + } + else if (recursive) { + var = substitute_variable (cfg, var, recursive); + } + /* Allocate new string */ + new = g_malloc (len - strlen (v_begin) + strlen (var) + 1); + + snprintf (new, len - strlen (v_begin) + strlen (var) + 1, "%s%s%s", + str, var, v_end + 1); + g_free (str); + str = new; + } + + return str; +} + +static void +substitute_module_variables (gpointer key, gpointer value, gpointer data) +{ + struct config_file *cfg = (struct config_file *)data; + LIST_HEAD (moduleoptq, module_opt) *cur_module_opt = (struct moduleoptq *)value; + struct module_opt *cur, *tmp; + + LIST_FOREACH_SAFE (cur, cur_module_opt, next, tmp) { + if (cur->value) { + cur->value = substitute_variable (cfg, cur->value, 0); + } + } +} + +static void +substitute_all_variables (gpointer key, gpointer value, gpointer data) +{ + struct config_file *cfg = (struct config_file *)data; + char *var; + + var = value; + /* Do recursive substitution */ + var = substitute_variable (cfg, var, 1); +} + +/* + * Substitute all variables in strings + */ +void +post_load_config (struct config_file *cfg) +{ + g_hash_table_foreach (cfg->variables, substitute_all_variables, cfg); + g_hash_table_foreach (cfg->modules_opts, substitute_module_variables, cfg); +} + +/* * vi:ts=4 */ |