summaryrefslogtreecommitdiff
path: root/src/core/load-fragment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/load-fragment.c')
-rw-r--r--src/core/load-fragment.c120
1 files changed, 71 insertions, 49 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 970eed27c1..6b36b2fc3a 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -579,6 +579,7 @@ int config_parse_exec(
void *userdata) {
ExecCommand **e = data;
+ Unit *u = userdata;
const char *p;
bool semicolon;
int r;
@@ -604,7 +605,7 @@ int config_parse_exec(
_cleanup_free_ ExecCommand *nce = NULL;
_cleanup_strv_free_ char **n = NULL;
size_t nlen = 0, nbufsize = 0;
- char *f;
+ const char *f;
int i;
semicolon = false;
@@ -631,47 +632,47 @@ int config_parse_exec(
f++;
}
- if (isempty(f)) {
+ r = unit_full_printf(u, f, &path);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
+ return 0;
+ }
+
+ if (isempty(path)) {
/* First word is either "-" or "@" with no command. */
log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
return 0;
}
- if (!string_is_safe(f)) {
+ if (!string_is_safe(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
return 0;
}
- if (!path_is_absolute(f)) {
+ if (!path_is_absolute(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
return 0;
}
- if (endswith(f, "/")) {
+ if (endswith(path, "/")) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
return 0;
}
- if (f == firstword) {
- path = firstword;
- firstword = NULL;
- } else {
- path = strdup(f);
- if (!path)
- return log_oom();
- }
-
if (!separate_argv0) {
+ char *w = NULL;
+
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- f = strdup(path);
- if (!f)
+
+ w = strdup(path);
+ if (!w)
return log_oom();
- n[nlen++] = f;
+ n[nlen++] = w;
n[nlen] = NULL;
}
path_kill_slashes(path);
while (!isempty(p)) {
- _cleanup_free_ char *word = NULL;
+ _cleanup_free_ char *word = NULL, *resolved = NULL;
/* Check explicitly for an unquoted semicolon as
* command separator token. */
@@ -682,18 +683,21 @@ int config_parse_exec(
break;
}
- /* Check for \; explicitly, to not confuse it with \\;
- * or "\;" or "\\;" etc. extract_first_word would
- * return the same for all of those. */
+ /* Check for \; explicitly, to not confuse it with \\; or "\;" or "\\;" etc.
+ * extract_first_word() would return the same for all of those. */
if (p[0] == '\\' && p[1] == ';' && (!p[2] || strchr(WHITESPACE, p[2]))) {
+ char *w;
+
p += 2;
p += strspn(p, WHITESPACE);
+
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- f = strdup(";");
- if (!f)
+
+ w = strdup(";");
+ if (!w)
return log_oom();
- n[nlen++] = f;
+ n[nlen++] = w;
n[nlen] = NULL;
continue;
}
@@ -701,14 +705,20 @@ int config_parse_exec(
r = extract_first_word_and_warn(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
if (r == 0)
break;
- else if (r < 0)
+ if (r < 0)
return 0;
+ r = unit_full_printf(u, word, &resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
+ return 0;
+ }
+
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
return log_oom();
- n[nlen++] = word;
+ n[nlen++] = resolved;
n[nlen] = NULL;
- word = NULL;
+ resolved = NULL;
}
if (!n || !n[0]) {
@@ -1326,7 +1336,7 @@ int config_parse_exec_selinux_context(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1374,7 +1384,7 @@ int config_parse_exec_apparmor_profile(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1422,7 +1432,7 @@ int config_parse_exec_smack_process_label(
} else
ignore = false;
- r = unit_name_printf(u, rvalue, &k);
+ r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
return 0;
@@ -1689,7 +1699,7 @@ int config_parse_fdname(
return 0;
}
- r = unit_name_printf(UNIT(s), rvalue, &p);
+ r = unit_full_printf(UNIT(s), rvalue, &p);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
return 0;
@@ -2555,7 +2565,7 @@ int config_parse_unit_requires_mounts_for(
assert(data);
for (p = rvalue;; ) {
- _cleanup_free_ char *word = NULL;
+ _cleanup_free_ char *word = NULL, *resolved = NULL;
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
if (r == 0)
@@ -2573,9 +2583,15 @@ int config_parse_unit_requires_mounts_for(
continue;
}
- r = unit_require_mounts_for(u, word);
+ r = unit_full_printf(u, word, &resolved);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", word);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit name \"%s\", ignoring: %m", word);
+ continue;
+ }
+
+ r = unit_require_mounts_for(u, resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", resolved);
continue;
}
}
@@ -3710,7 +3726,7 @@ int config_parse_runtime_directory(
return 0;
}
- r = unit_name_printf(u, word, &k);
+ r = unit_full_printf(u, word, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to resolve specifiers in \"%s\", ignoring: %m", word);
@@ -3812,8 +3828,8 @@ int config_parse_namespace_path_strv(
void *data,
void *userdata) {
+ Unit *u = userdata;
char*** sv = data;
- const char *prev;
const char *cur;
int r;
@@ -3828,10 +3844,10 @@ int config_parse_namespace_path_strv(
return 0;
}
- prev = cur = rvalue;
+ cur = rvalue;
for (;;) {
- _cleanup_free_ char *word = NULL;
- int offset;
+ _cleanup_free_ char *word = NULL, *resolved = NULL, *joined = NULL;
+ bool ignore_enoent;
r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
if (r == 0)
@@ -3839,31 +3855,37 @@ int config_parse_namespace_path_strv(
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Trailing garbage, ignoring: %s", prev);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract first word, ignoring: %s", rvalue);
return 0;
}
if (!utf8_is_valid(word)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
- prev = cur;
continue;
}
- offset = word[0] == '-';
- if (!path_is_absolute(word + offset)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", word);
- prev = cur;
+ ignore_enoent = word[0] == '-';
+
+ r = unit_full_printf(u, word + ignore_enoent, &resolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s: %m", word);
+ continue;
+ }
+
+ if (!path_is_absolute(resolved)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
continue;
}
- path_kill_slashes(word + offset);
+ path_kill_slashes(resolved);
- r = strv_push(sv, word);
+ joined = strjoin(ignore_enoent ? "-" : "", resolved);
+
+ r = strv_push(sv, joined);
if (r < 0)
return log_oom();
- prev = cur;
- word = NULL;
+ joined = NULL;
}
return 0;