chiark / gitweb /
fragment: allow prefixing of the EnvironmentFile= path with - to ignore errors
[elogind.git] / src / load-fragment.c
index 424e6c37bb9d8d6e82572d986713a407ae04eec5..334dd68146c175e9121611af9bc4022bd03827db 100644 (file)
@@ -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;
         }
@@ -1448,7 +1474,8 @@ static int config_parse_condition_path(
                 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);
@@ -1815,6 +1842,7 @@ 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"    },