X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fload-fragment.c;h=334dd68146c175e9121611af9bc4022bd03827db;hp=4f94c6409e59e89ff602b9d942294ef697b507da;hb=afe4bfe2c1ed28a3e75c627edf458d2f40ff16f8;hpb=ead8e4788ee31bbdc38b4cd3c6e71c8a95bbc95a diff --git a/src/load-fragment.c b/src/load-fragment.c index 4f94c6409..334dd6814 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -433,7 +433,7 @@ static int config_parse_exec( k = 0; FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, ";", l) == 0) + if (strncmp(w, ";", MAX(l, 1U)) == 0) break; k++; @@ -444,7 +444,7 @@ static int config_parse_exec( k = 0; FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, ";", l) == 0) + if (strncmp(w, ";", MAX(l, 1U)) == 0) break; if (honour_argv0 && w == rvalue) { @@ -1077,11 +1077,11 @@ static int config_parse_mount_flags( assert(data); FOREACH_WORD_QUOTED(w, l, rvalue, state) { - if (strncmp(w, "shared", l) == 0) + if (strncmp(w, "shared", MAX(l, 6U)) == 0) flags |= MS_SHARED; - else if (strncmp(w, "slave", l) == 0) + else if (strncmp(w, "slave", MAX(l, 5U)) == 0) flags |= MS_SLAVE; - else if (strncmp(w, "private", l) == 0) + else if (strncmp(w, "private", MAX(l, 7U)) == 0) flags |= MS_PRIVATE; else { log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, rvalue); @@ -1348,19 +1348,31 @@ static int config_parse_env_file( FILE *f; int r; char ***env = data; + bool ignore = false; assert(filename); assert(lvalue); assert(rvalue); assert(data); + if (rvalue[0] == '-') { + ignore = true; + rvalue++; + } + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, rvalue); + return 0; + } + if (!(f = fopen(rvalue, "re"))) { - log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue); + if (!ignore) + log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue); return 0; } while (!feof(f)) { - char l[LINE_MAX], *p; + char l[LINE_MAX], *p, *u; char **t; if (!fgets(l, sizeof(l), f)) { @@ -1381,7 +1393,21 @@ static int config_parse_env_file( if (strchr(COMMENTS, *p)) continue; - t = strv_env_set(*env, p); + if (!(u = normalize_env_assignment(p))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + t = strv_env_set(*env, u); + free(u); + + if (!t) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + strv_free(*env); *env = t; } @@ -1444,11 +1470,12 @@ static int config_parse_condition_path( rvalue++; if (!path_is_absolute(rvalue)) { - log_error("[%s:%u] Path in condition not absolute: %s", filename, line, rvalue); + log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue); return 0; } - if (!(c = condition_new(CONDITION_PATH_EXISTS, rvalue, negate))) + if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY, + rvalue, negate))) return -ENOMEM; LIST_PREPEND(Condition, conditions, u->meta.conditions, c); @@ -1483,6 +1510,43 @@ static int config_parse_condition_kernel( return 0; } +static int config_parse_condition_null( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + Condition *c; + bool negate; + int b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if ((b = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!b) + negate = !negate; + + if (!(c = condition_new(CONDITION_NULL, NULL, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->meta.conditions, c); + return 0; +} + static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); #define FOLLOW_MAX 8 @@ -1656,6 +1720,7 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_ip_tos, "TOS" }, { config_parse_condition_path, "CONDITION" }, { config_parse_condition_kernel, "CONDITION" }, + { config_parse_condition_null, "CONDITION" }, }; assert(f); @@ -1777,7 +1842,9 @@ static int load_from_path(Unit *u, const char *path) { { "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" }, { "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" }, { "ConditionPathExists", config_parse_condition_path, u, "Unit" }, + { "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" }, { "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" }, + { "ConditionNull", config_parse_condition_null, u, "Unit" }, { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, { "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" },