mirror of
https://github.com/troglobit/finit.git
synced 2026-11-06 15:51:03 +00:00
service: support quoted arguments to run/task/service options
Fixes #441 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
2 files changed
+95
-2
No files matched your search
@@ -88,6 +88,21 @@ static void cgset(const char *path, char *ctrl, char *prop)
|
|||||||
}
|
}
|
||||||
*val++ = 0;
|
*val++ = 0;
|
||||||
|
|
||||||
|
/* unquote value, if quoted */
|
||||||
|
if (val[0] == '"' || val[0] == '\'') {
|
||||||
|
char q = val[0];
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
end = strchr(&val[1], q);
|
||||||
|
if (!end) {
|
||||||
|
errx(1, "Syntax error, unterminated quote in %s/%s.%s=%s", path, ctrl, prop, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val++;
|
||||||
|
*end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* disallow sneaky relative paths */
|
/* disallow sneaky relative paths */
|
||||||
if (strstr(ctrl, "..") || strstr(prop, "..")) {
|
if (strstr(ctrl, "..") || strstr(prop, "..")) {
|
||||||
errx(1, "Possible security violation; '..' not allowed in cgroup config!");
|
errx(1, "Possible security violation; '..' not allowed in cgroup config!");
|
||||||
|
|||||||
+80
-2
@@ -1190,6 +1190,83 @@ void service_runlevel(int newlevel)
|
|||||||
networking(0);
|
networking(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse run/task/service arguments with support for quoted strings, both
|
||||||
|
* single and double quotes to allow arguments containing spaces.
|
||||||
|
*
|
||||||
|
* Returns next argument or NULL if end of line
|
||||||
|
* Updates *line to point past the parsed argument
|
||||||
|
*/
|
||||||
|
static char *parse_args(char **line)
|
||||||
|
{
|
||||||
|
char *start, *end = NULL, *arg;
|
||||||
|
char in_quote = 0;
|
||||||
|
int has_colon = 0;
|
||||||
|
|
||||||
|
if (!line || !*line)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Skip leading whitespace */
|
||||||
|
while (**line && (**line == ' ' || **line == '\t'))
|
||||||
|
(*line)++;
|
||||||
|
|
||||||
|
if (!**line)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
start = *line;
|
||||||
|
|
||||||
|
/* Parse the token */
|
||||||
|
while (**line) {
|
||||||
|
if (in_quote) {
|
||||||
|
if (**line == in_quote) {
|
||||||
|
/* End quote found */
|
||||||
|
in_quote = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (**line == '\'' || **line == '"') {
|
||||||
|
/* Start quote */
|
||||||
|
in_quote = **line;
|
||||||
|
} else if (**line == ':') {
|
||||||
|
/* Found colon - this might be key:value format */
|
||||||
|
has_colon = 1;
|
||||||
|
} else if (**line == ' ' || **line == '\t') {
|
||||||
|
/* Whitespace - check if we're in key:value mode */
|
||||||
|
if (has_colon) {
|
||||||
|
/* Look ahead to see if there's a comma after whitespace */
|
||||||
|
char *lookahead = *line;
|
||||||
|
while (*lookahead && (*lookahead == ' ' || *lookahead == '\t'))
|
||||||
|
lookahead++;
|
||||||
|
if (*lookahead == ',') {
|
||||||
|
/* Continue parsing - this space is part of the token */
|
||||||
|
(*line)++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* End token at whitespace */
|
||||||
|
end = *line;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*line)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set end if we reached end of string */
|
||||||
|
if (!end)
|
||||||
|
end = *line;
|
||||||
|
|
||||||
|
/* Null terminate the argument */
|
||||||
|
if (end > start) {
|
||||||
|
arg = start;
|
||||||
|
if (*end) {
|
||||||
|
*end = '\0';
|
||||||
|
*line = end + 1;
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* log:/path/to/logfile,priority:facility.level,tag:ident
|
* log:/path/to/logfile,priority:facility.level,tag:ident
|
||||||
*/
|
*/
|
||||||
@@ -1564,7 +1641,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = strtok_r(line, " \t", &args);
|
args = line;
|
||||||
|
cmd = parse_args(&args);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
incomplete:
|
incomplete:
|
||||||
errx(1, "Incomplete service '%s', cannot register", cfg);
|
errx(1, "Incomplete service '%s', cannot register", cfg);
|
||||||
@@ -1644,7 +1722,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Check if valid command follows... */
|
/* Check if valid command follows... */
|
||||||
cmd = strtok_r(NULL, " ", &args);
|
cmd = parse_args(&args);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
goto incomplete;
|
goto incomplete;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user