X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fconf-parser.c;h=aac64b29a3811c734ecc121f5b4ecaa7f6178ee7;hp=13f873869fe353b11fa87178c5397590cbb2cb89;hb=1a6f4df6c9437ed631080b7e006f666326063d36;hpb=827119a9cbf617aa42eef63e5b99e981776c744a diff --git a/src/conf-parser.c b/src/conf-parser.c index 13f873869..aac64b29a 100644 --- a/src/conf-parser.c +++ b/src/conf-parser.c @@ -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, @@ -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, §ion, 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, §ion, 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); @@ -209,6 +246,31 @@ int config_parse_int( return 0; } +int config_parse_uint64( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + 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, @@ -384,7 +446,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; @@ -436,7 +498,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; }