From 88b5a391bc2f9eb85066219e453682a746730ead Mon Sep 17 00:00:00 2001 From: Aaron Carroll Date: Tue, 7 Oct 2008 11:25:20 +0200 Subject: [PATCH 1/1] Add environment-variable substitution to config options Strings of the form ${VARNAME} in config option strings are substituted with the value of the environment variable VARNAME. Only the right hand side of an option assignment undergoes substitution. If VARNAME is empty or undefined, the empty string is substituted. Signed-off-by: Aaron Carroll Signed-off-by: Jens Axboe --- parse.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- parse.h | 1 + 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/parse.c b/parse.c index b9466901..456e3baf 100644 --- a/parse.c +++ b/parse.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "parse.h" #include "debug.h" @@ -529,12 +530,61 @@ int parse_cmd_option(const char *opt, const char *val, return 1; } +/* + * Return a copy of the input string with substrings of the form ${VARNAME} + * substituted with the value of the environment variable VARNAME. The + * substitution always occurs, even if VARNAME is empty or the corresponding + * environment variable undefined. + */ +static char *option_dup_subs(const char *opt) +{ + char out[OPT_LEN_MAX+1]; + char in[OPT_LEN_MAX+1]; + char *outptr = out; + char *inptr = in; + char *ch1, *ch2, *env; + ssize_t nchr = OPT_LEN_MAX; + size_t envlen; + + in[OPT_LEN_MAX] = '\0'; + strncpy(in, opt, OPT_LEN_MAX); + + while (*inptr && nchr > 0) { + if (inptr[0] == '$' && inptr[1] == '{') { + ch2 = strchr(inptr, '}'); + if (ch2 && inptr+1 < ch2) { + ch1 = inptr+2; + inptr = ch2+1; + *ch2 = '\0'; + + env = getenv(ch1); + if (env) { + envlen = strlen(env); + if (envlen <= nchr) { + memcpy(outptr, env, envlen); + outptr += envlen; + nchr -= envlen; + } + } + + continue; + } + } + + *outptr++ = *inptr++; + --nchr; + } + + *outptr = '\0'; + return strdup(out); +} + int parse_option(const char *opt, struct fio_option *options, void *data) { struct fio_option *o; char *post, *tmp; - tmp = strdup(opt); + tmp = option_dup_subs(opt); o = get_option(tmp, options, &post); if (!o) { diff --git a/parse.h b/parse.h index 4f3f94d0..45462596 100644 --- a/parse.h +++ b/parse.h @@ -26,6 +26,7 @@ struct value_pair { const char *help; /* help text for sub option */ }; +#define OPT_LEN_MAX 1024 #define PARSE_MAX_VP 16 /* -- 2.25.1