chiark / gitweb /
systemctl: hide all information on --kill-mode= since it is mostly useless
[elogind.git] / src / conf-parser.c
index a6d4d92aa29468e63adc3405dd256484c4137259..02f740a04fb10b650c9514e02028854a4739c6a3 100644 (file)
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
   This file is part of systemd.
@@ -31,9 +31,6 @@
 #include "strv.h"
 #include "log.h"
 
-#define COMMENTS "#;\n"
-#define LINE_MAX 4096
-
 /* Run the user supplied parser for an assignment */
 static int next_assignment(
                 const char *filename,
@@ -50,7 +47,7 @@ static int next_assignment(
         assert(lvalue);
         assert(rvalue);
 
-        for (; t->parse; t++) {
+        for (; t->parse || t->lvalue; t++) {
 
                 if (t->lvalue && !streq(lvalue, t->lvalue))
                         continue;
@@ -64,7 +61,7 @@ static int next_assignment(
                 if (!t->parse)
                         return 0;
 
-                return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata);
+                return t->parse(filename, line, section, lvalue, t->ltype, rvalue, t->data, userdata);
         }
 
         /* Warn about unknown non-extension fields. */
@@ -123,7 +120,7 @@ static int parse_line(const char *filename, unsigned line, char **section, const
                 return 0;
         }
 
-        if (sections && !strv_contains((char**) sections, *section))
+        if (sections && (!*section || !strv_contains((char**) sections, *section)))
                 return 0;
 
         if (!(e = strchr(l, '='))) {
@@ -143,6 +140,7 @@ int config_parse(const char *filename, FILE *f, const char* const * sections, co
         char *section = NULL;
         int r;
         bool ours = false;
+        char *continuation = NULL;
 
         assert(filename);
         assert(t);
@@ -158,7 +156,8 @@ int config_parse(const char *filename, FILE *f, const char* const * sections, co
         }
 
         while (!feof(f)) {
-                char l[LINE_MAX];
+                char l[LINE_MAX], *p, *c = NULL, *e;
+                bool escaped = false;
 
                 if (!fgets(l, sizeof(l), f)) {
                         if (feof(f))
@@ -169,7 +168,44 @@ int config_parse(const char *filename, FILE *f, const char* const * sections, co
                         goto finish;
                 }
 
-                if ((r = parse_line(filename, ++line, &section, sections, t, relaxed, l, userdata)) < 0)
+                truncate_nl(l);
+
+                if (continuation) {
+                        if (!(c = strappend(continuation, l))) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        free(continuation);
+                        continuation = NULL;
+                        p = c;
+                } else
+                        p = l;
+
+                for (e = p; *e; e++) {
+                        if (escaped)
+                                escaped = false;
+                        else if (*e == '\\')
+                                escaped = true;
+                }
+
+                if (escaped) {
+                        *(e-1) = ' ';
+
+                        if (c)
+                                continuation = c;
+                        else if (!(continuation = strdup(l))) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        continue;
+                }
+
+                r = parse_line(filename, ++line, &section, sections, t, relaxed, p, userdata);
+                free(c);
+
+                if (r < 0)
                         goto finish;
         }
 
@@ -177,6 +213,7 @@ int config_parse(const char *filename, FILE *f, const char* const * sections, co
 
 finish:
         free(section);
+        free(continuation);
 
         if (f && ours)
                 fclose(f);
@@ -189,6 +226,7 @@ int config_parse_int(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -209,11 +247,64 @@ int config_parse_int(
         return 0;
 }
 
+int config_parse_long(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        long *i = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atoli(rvalue, i)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+                return r;
+        }
+
+        return 0;
+}
+
+int config_parse_uint64(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        uint64_t *u = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if ((r = safe_atou64(rvalue, u)) < 0) {
+                log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+                return r;
+        }
+
+        return 0;
+}
+
 int config_parse_unsigned(
                 const char *filename,
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -239,6 +330,7 @@ int config_parse_size(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -266,6 +358,7 @@ int config_parse_bool(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -292,6 +385,7 @@ int config_parse_string(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -321,6 +415,7 @@ int config_parse_path(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -354,6 +449,7 @@ int config_parse_strv(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -384,7 +480,7 @@ int config_parse_strv(
                 k = 0;
 
         FOREACH_WORD_QUOTED(w, l, rvalue, state)
-                if (!(n[k++] = strndup(w, l)))
+                if (!(n[k++] = cunescape_length(w, l)))
                         goto fail;
 
         n[k] = NULL;
@@ -406,6 +502,7 @@ int config_parse_path_strv(
                 unsigned line,
                 const char *section,
                 const char *lvalue,
+                int ltype,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
@@ -436,7 +533,7 @@ int config_parse_path_strv(
                         n[k] = (*sv)[k];
 
         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                if (!(n[k] = strndup(w, l))) {
+                if (!(n[k] = cunescape_length(w, l))) {
                         r = -ENOMEM;
                         goto fail;
                 }