diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-07-07 20:59:20 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-07-07 20:59:20 +0200 |
commit | 61e5d8ed877b6389ea94c05e0e2f646f8b66d8bd (patch) | |
tree | 2463dc13d87e63d2d78d57417782dbdd9d880646 /src/load-fragment.c | |
parent | f60f22dfbb8cfa0eb55d1896db0e4c3f7d3cfacb (diff) |
service: allow configuration of more than one Exec command in one line
Diffstat (limited to 'src/load-fragment.c')
-rw-r--r-- | src/load-fragment.c | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/src/load-fragment.c b/src/load-fragment.c index 43b8093fa0..c3909e9563 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -364,73 +364,94 @@ static int config_parse_exec( void *data, void *userdata) { - ExecCommand **e = data, *nce = NULL; - char **n; - char *w; + ExecCommand **e = data, *nce; + char *path, **n; unsigned k; - size_t l; - char *state, *path = NULL; - bool honour_argv0, write_to_path; assert(filename); assert(lvalue); assert(rvalue); - assert(data); + assert(e); /* We accept an absolute path as first argument, or * alternatively an absolute prefixed with @ to allow * overriding of argv[0]. */ - honour_argv0 = rvalue[0] == '@'; + for (;;) { + char *w; + size_t l; + char *state; + bool honour_argv0, write_to_path; - if (rvalue[honour_argv0 ? 1 : 0] != '/') { - log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue); - return -EINVAL; - } + path = NULL; + nce = NULL; + n = NULL; - k = 0; - FOREACH_WORD_QUOTED(w, l, rvalue, state) - k++; + rvalue += strspn(rvalue, WHITESPACE); - if (!(n = new(char*, k + (honour_argv0 ? 0 : 1)))) - return -ENOMEM; + if (rvalue[0] == 0) + break; - k = 0; - write_to_path = honour_argv0; - FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (write_to_path) { - if (!(path = strndup(w+1, l-1))) - goto fail; - write_to_path = false; - } else { - if (!(n[k++] = strndup(w, l))) - goto fail; + honour_argv0 = rvalue[0] == '@'; + + if (rvalue[honour_argv0 ? 1 : 0] != '/') { + log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue); + return -EINVAL; } - } - n[k] = NULL; + k = 0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", l) == 0) + break; - if (!n[0]) { - log_error("[%s:%u] Invalid command line: %s", filename, line, rvalue); - strv_free(n); - return -EINVAL; - } + k++; + } - if (!path) - if (!(path = strdup(n[0]))) - goto fail; + if (!(n = new(char*, k + (honour_argv0 ? 0 : 1)))) + return -ENOMEM; + + k = 0; + write_to_path = honour_argv0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", l) == 0) + break; + + if (write_to_path) { + if (!(path = cunescape_length(w+1, l-1))) + goto fail; + write_to_path = false; + } else { + if (!(n[k++] = cunescape_length(w, l))) + goto fail; + } + } - assert(path_is_absolute(path)); + n[k] = NULL; - if (!(nce = new0(ExecCommand, 1))) - goto fail; + if (!n[0]) { + log_error("[%s:%u] Invalid command line: %s", filename, line, rvalue); + strv_free(n); + return -EINVAL; + } - nce->argv = n; - nce->path = path; + if (!path) + if (!(path = strdup(n[0]))) + goto fail; - path_kill_slashes(nce->path); + assert(path_is_absolute(path)); + + if (!(nce = new0(ExecCommand, 1))) + goto fail; - exec_command_append_list(e, nce); + nce->argv = n; + nce->path = path; + + path_kill_slashes(nce->path); + + exec_command_append_list(e, nce); + + rvalue = state; + } return 0; |