From: Aki Tuomi Date: Mon, 18 Jan 2021 12:11:28 +0000 (+0200) Subject: lib-settings: Add support for $ENV:name X-Git-Tag: 2.3.14.rc1~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b0ffe1630f88cf398d705dddeb272df395404ed;p=thirdparty%2Fdovecot%2Fcore.git lib-settings: Add support for $ENV:name Expands into given environment variable --- diff --git a/src/lib-settings/settings.c b/src/lib-settings/settings.c index 134c765040..228fab787a 100644 --- a/src/lib-settings/settings.c +++ b/src/lib-settings/settings.c @@ -50,6 +50,45 @@ static const char *get_uint(const char *value, unsigned int *result) return NULL; } +#define IS_WHITE(c) ((c) == ' ' || (c) == '\t') + +static const char *expand_environment_vars(const char *value) +{ + const char *pvalue = value, *p; + + /* Fast path when there are no candidates */ + if ((pvalue = strchr(pvalue, '$')) == NULL) + return value; + + string_t *expanded_value = t_str_new(strlen(value)); + str_append_data(expanded_value, value, pvalue - value); + + while (pvalue != NULL && (p = strchr(pvalue, '$')) != NULL) { + const char *var_end; + str_append_data(expanded_value, pvalue, p - pvalue); + if ((p == value || IS_WHITE(p[-1])) && + str_begins(p, "$ENV:")) { + const char *var_name, *envval; + var_end = strchr(p, ' '); + if (var_end == NULL) + var_name = p + 5; + else + var_name = t_strdup_until(p + 5, var_end); + if ((envval = getenv(var_name)) != NULL) + str_append(expanded_value, envval); + } else { + str_append_c(expanded_value, '$'); + var_end = p + 1; + } + pvalue = var_end; + } + + if (pvalue != NULL) + str_append(expanded_value, pvalue); + + return str_c(expanded_value); +} + const char * parse_setting_from_defs(pool_t pool, const struct setting_def *defs, void *base, const char *key, const char *value) @@ -165,8 +204,6 @@ settings_include(const char *pattern, struct input_stack **inputp, #endif } -#define IS_WHITE(c) ((c) == ' ' || (c) == '\t') - bool settings_read_i(const char *path, const char *section, settings_callback_t *callback, settings_section_callback_t *sect_callback, void *context, @@ -259,6 +296,7 @@ prevfile: line = str_c_modifiable(full_line); } + bool quoted = FALSE; /* a) key = value b) section_type [section_name] { c) } */ @@ -288,8 +326,14 @@ prevfile: (*line == '\'' && line[len-1] == '\''))) { line[len-1] = '\0'; line = str_unescape(line+1); + quoted = TRUE; } + /* @UNSAFE: Cast to modifiable datastack value, + but it will not be actually modified after this. */ + if (!quoted) + line = (char *)expand_environment_vars(line); + errormsg = skip > 0 ? NULL : callback(key, line, context); } else if (strcmp(key, "}") != 0 || *line != '\0') {