summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-02-11 14:05:10 -0500
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-02-20 23:30:50 -0500
commitccad1fd07ce4eb40a2fcf81cfb55d9b41fdcac48 (patch)
tree41b72c7747d8072e212ed58fd8b5c1e71c18d0b7 /src/basic
parentcb4499d0056a7c974d7d3695cc355c7e77edc938 (diff)
downloadsystemd-ccad1fd07ce4eb40a2fcf81cfb55d9b41fdcac48.tar.gz
Allow braceless variables to be expanded
(Only in environment.d files.) We have only basic compatibility with shell syntax, but specifying variables without using braces is probably more common, and I think a lot of people would be surprised if this didn't work.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/env-util.c45
-rw-r--r--src/basic/env-util.h1
-rw-r--r--src/basic/fileio.c7
3 files changed, 50 insertions, 3 deletions
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index 8774a81531..f370854673 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -523,7 +523,8 @@ char *replace_env(const char *format, char **env, unsigned flags) {
enum {
WORD,
CURLY,
- VARIABLE
+ VARIABLE,
+ VARIABLE_RAW,
} state = WORD;
const char *e, *word = format;
@@ -563,6 +564,18 @@ char *replace_env(const char *format, char **env, unsigned flags) {
word = e+1;
state = WORD;
+
+ } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
+ k = strnappend(r, word, e-word-1);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e-1;
+ state = VARIABLE_RAW;
+
} else
state = WORD;
break;
@@ -584,10 +597,38 @@ char *replace_env(const char *format, char **env, unsigned flags) {
state = WORD;
}
break;
+
+ case VARIABLE_RAW:
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
+ const char *t;
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e--;
+ state = WORD;
+ }
+ break;
}
}
- return strnappend(r, word, e-word);
+ if (state == VARIABLE_RAW) {
+ const char *t;
+
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+ return strappend(r, t);
+ } else
+ return strnappend(r, word, e-word);
}
char **replace_env_argv(char **argv, char **env) {
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index 4e83dcb43a..03bbc6af00 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -31,6 +31,7 @@ bool env_assignment_is_valid(const char *e);
enum {
REPLACE_ENV_USE_ENVIRONMENT = 1u,
+ REPLACE_ENV_ALLOW_BRACELESS = 2u,
};
char *replace_env(const char *format, char **env, unsigned flags);
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 49dd52bfd9..3c2dab1855 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -773,7 +773,8 @@ static int merge_env_file_push(
assert(env);
- expanded_value = replace_env(value, *env, REPLACE_ENV_USE_ENVIRONMENT);
+ expanded_value = replace_env(value, *env,
+ REPLACE_ENV_USE_ENVIRONMENT|REPLACE_ENV_ALLOW_BRACELESS);
if (!expanded_value)
return -ENOMEM;
@@ -787,6 +788,10 @@ int merge_env_file(
FILE *f,
const char *fname) {
+ /* NOTE: this function supports braceful and braceless variable expansions,
+ * unlike other exported parsing functions.
+ */
+
return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
}