chiark / gitweb /
units: for all unit settings that take lists, allow the empty string for resetting...
[elogind.git] / src / shared / conf-parser.c
index 8c62fb959b8b292262e6eaa0bd5f8ab7a5bc385e..7f286096d234c591860d30aebf83826239b11bc0 100644 (file)
@@ -32,6 +32,8 @@
 #include "log.h"
 #include "utf8.h"
 #include "path-util.h"
+#include "set.h"
+#include "exit-status.h"
 
 int config_item_table_lookup(
                 void *table,
@@ -90,7 +92,7 @@ int config_item_perf_lookup(
         else {
                 char *key;
 
-                key = join(section, ".", lvalue, NULL);
+                key = strjoin(section, ".", lvalue, NULL);
                 if (!key)
                         return -ENOMEM;
 
@@ -375,7 +377,8 @@ int config_parse_int(
         assert(rvalue);
         assert(data);
 
-        if ((r = safe_atoi(rvalue, i)) < 0) {
+        r = safe_atoi(rvalue, i);
+        if (r < 0) {
                 log_error("[%s:%u] Failed to parse numeric value, ingoring: %s", filename, line, rvalue);
                 return 0;
         }
@@ -401,7 +404,8 @@ int config_parse_long(
         assert(rvalue);
         assert(data);
 
-        if ((r = safe_atoli(rvalue, i)) < 0) {
+        r = safe_atoli(rvalue, i);
+        if (r < 0) {
                 log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
                 return 0;
         }
@@ -427,7 +431,8 @@ int config_parse_uint64(
         assert(rvalue);
         assert(data);
 
-        if ((r = safe_atou64(rvalue, u)) < 0) {
+        r = safe_atou64(rvalue, u);
+        if (r < 0) {
                 log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue);
                 return 0;
         }
@@ -453,7 +458,8 @@ int config_parse_unsigned(
         assert(rvalue);
         assert(data);
 
-        if ((r = safe_atou(rvalue, u)) < 0) {
+        r = safe_atou(rvalue, u);
+        if (r < 0) {
                 log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
                 return r;
         }
@@ -591,9 +597,9 @@ int config_parse_string(
         assert(rvalue);
         assert(data);
 
-        n = cunescape(rvalue);
+        n = strdup(rvalue);
         if (!n)
-                return -ENOMEM;
+                return log_oom();
 
         if (!utf8_is_valid(n)) {
                 log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
@@ -642,7 +648,7 @@ int config_parse_path(
 
         n = strdup(rvalue);
         if (!n)
-                return -ENOMEM;
+                return log_oom();
 
         path_kill_slashes(n);
 
@@ -675,13 +681,19 @@ int config_parse_strv(
         assert(rvalue);
         assert(data);
 
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                strv_free(*sv);
+                *sv = NULL;
+        }
+
         k = strv_length(*sv);
         FOREACH_WORD_QUOTED(w, l, rvalue, state)
                 k++;
 
         n = new(char*, k+1);
         if (!n)
-                return -ENOMEM;
+                return log_oom();
 
         if (*sv)
                 for (k = 0; (*sv)[k]; k++)
@@ -692,7 +704,7 @@ int config_parse_strv(
         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
                 n[k] = cunescape_length(w, l);
                 if (!n[k]) {
-                        r = -ENOMEM;
+                        r = log_oom();
                         goto fail;
                 }
 
@@ -742,13 +754,19 @@ int config_parse_path_strv(
         assert(rvalue);
         assert(data);
 
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                strv_free(*sv);
+                *sv = NULL;
+        }
+
         k = strv_length(*sv);
         FOREACH_WORD_QUOTED(w, l, rvalue, state)
                 k++;
 
         n = new(char*, k+1);
         if (!n)
-                return -ENOMEM;
+                return log_oom();
 
         k = 0;
         if (*sv)
@@ -758,7 +776,7 @@ int config_parse_path_strv(
         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
                 n[k] = strndup(w, l);
                 if (!n[k]) {
-                        r = -ENOMEM;
+                        r = log_oom();
                         goto fail;
                 }
 
@@ -863,7 +881,7 @@ int config_parse_mode(
 
         errno = 0;
         l = strtol(rvalue, &x, 8);
-        if (!x || *x || errno) {
+        if (!x || x == rvalue || *x || errno) {
                 log_error("[%s:%u] Failed to parse mode value, ignoring: %s", filename, line, rvalue);
                 return 0;
         }
@@ -933,3 +951,83 @@ int config_parse_level(
         *o = (*o & LOG_FACMASK) | x;
         return 0;
 }
+
+int config_parse_set_status(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char *w;
+        size_t l;
+        char *state;
+        int r;
+        ExitStatusSet *status_set = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+
+                set_free(status_set->signal);
+                set_free(status_set->code);
+
+                status_set->signal = status_set->code = NULL;
+                return 0;
+        }
+
+        FOREACH_WORD(w, l, rvalue, state) {
+                int val;
+                char *temp;
+
+                temp = strndup(w, l);
+                if (!temp)
+                        return log_oom();
+
+                r = safe_atoi(temp, &val);
+                if (r < 0) {
+                        val = signal_from_string_try_harder(temp);
+                        free(temp);
+
+                        if (val > 0) {
+                                r = set_ensure_allocated(&status_set->signal, trivial_hash_func, trivial_compare_func);
+                                if (r < 0)
+                                        return log_oom();
+
+                                r = set_put(status_set->signal, INT_TO_PTR(val));
+                                if (r < 0) {
+                                        log_error("[%s:%u] Unable to store: %s", filename, line, w);
+                                        return r;
+                                }
+                        } else {
+                                log_error("[%s:%u] Failed to parse value, ignoring: %s", filename, line, w);
+                                return 0;
+                        }
+                } else {
+                        free(temp);
+
+                        if (val < 0 || val > 255)
+                                log_warning("[%s:%u] Value %d is outside range 0-255, ignoring", filename, line, val);
+                        else {
+                                r = set_ensure_allocated(&status_set->code, trivial_hash_func, trivial_compare_func);
+                                if (r < 0)
+                                        return log_oom();
+
+                                r = set_put(status_set->code, INT_TO_PTR(val));
+                                if (r < 0) {
+                                        log_error("[%s:%u] Unable to store: %s", filename, line, w);
+                                        return r;
+                                }
+                        }
+                }
+        }
+
+        return 0;
+}