]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/conf-parser.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "conf-parser.h"
34 /* Run the user supplied parser for an assignment */
35 static int next_assignment(
50 for (; t
->parse
|| t
->lvalue
; t
++) {
52 if (t
->lvalue
&& !streq(lvalue
, t
->lvalue
))
55 if (t
->section
&& !section
)
58 if (t
->section
&& !streq(section
, t
->section
))
64 return t
->parse(filename
, line
, section
, lvalue
, t
->ltype
, rvalue
, t
->data
, userdata
);
67 /* Warn about unknown non-extension fields. */
68 if (!relaxed
&& !startswith(lvalue
, "X-"))
69 log_info("[%s:%u] Unknown lvalue '%s' in section '%s'. Ignoring.", filename
, line
, lvalue
, strna(section
));
74 /* Parse a variable assignment line */
75 static int parse_line(const char *filename
, unsigned line
, char **section
, const char* const * sections
, const ConfigItem
*t
, bool relaxed
, char *l
, void *userdata
) {
83 if (strchr(COMMENTS
, *l
))
86 if (startswith(l
, ".include ")) {
90 if (!(fn
= file_in_same_dir(filename
, strstrip(l
+9))))
93 r
= config_parse(fn
, NULL
, sections
, t
, relaxed
, userdata
);
107 log_error("[%s:%u] Invalid section header.", filename
, line
);
111 if (!(n
= strndup(l
+1, k
-2)))
114 if (!relaxed
&& sections
&& !strv_contains((char**) sections
, n
))
115 log_info("[%s:%u] Unknown section '%s'. Ignoring.", filename
, line
, n
);
123 if (sections
&& (!*section
|| !strv_contains((char**) sections
, *section
)))
126 if (!(e
= strchr(l
, '='))) {
127 log_error("[%s:%u] Missing '='.", filename
, line
);
134 return next_assignment(filename
, line
, *section
, t
, relaxed
, strstrip(l
), strstrip(e
), userdata
);
137 /* Go through the file and parse each line */
138 int config_parse(const char *filename
, FILE *f
, const char* const * sections
, const ConfigItem
*t
, bool relaxed
, void *userdata
) {
140 char *section
= NULL
;
143 char *continuation
= NULL
;
149 if (!(f
= fopen(filename
, "re"))) {
151 log_error("Failed to open configuration file '%s': %s", filename
, strerror(-r
));
159 char l
[LINE_MAX
], *p
, *c
= NULL
, *e
;
160 bool escaped
= false;
162 if (!fgets(l
, sizeof(l
), f
)) {
167 log_error("Failed to read configuration file '%s': %s", filename
, strerror(-r
));
174 if (!(c
= strappend(continuation
, l
))) {
185 for (e
= p
; *e
; e
++) {
197 else if (!(continuation
= strdup(l
))) {
205 r
= parse_line(filename
, ++line
, §ion
, sections
, t
, relaxed
, p
, userdata
);
224 int config_parse_int(
225 const char *filename
,
242 if ((r
= safe_atoi(rvalue
, i
)) < 0) {
243 log_error("[%s:%u] Failed to parse numeric value: %s", filename
, line
, rvalue
);
250 int config_parse_long(
251 const char *filename
,
268 if ((r
= safe_atoli(rvalue
, i
)) < 0) {
269 log_error("[%s:%u] Failed to parse numeric value: %s", filename
, line
, rvalue
);
276 int config_parse_uint64(
277 const char *filename
,
294 if ((r
= safe_atou64(rvalue
, u
)) < 0) {
295 log_error("[%s:%u] Failed to parse numeric value: %s", filename
, line
, rvalue
);
302 int config_parse_unsigned(
303 const char *filename
,
320 if ((r
= safe_atou(rvalue
, u
)) < 0) {
321 log_error("[%s:%u] Failed to parse numeric value: %s", filename
, line
, rvalue
);
328 int config_parse_size(
329 const char *filename
,
347 if ((r
= safe_atou(rvalue
, &u
)) < 0) {
348 log_error("[%s:%u] Failed to parse numeric value: %s", filename
, line
, rvalue
);
356 int config_parse_bool(
357 const char *filename
,
374 if ((k
= parse_boolean(rvalue
)) < 0) {
375 log_error("[%s:%u] Failed to parse boolean value: %s", filename
, line
, rvalue
);
383 int config_parse_string(
384 const char *filename
,
402 if (!(n
= strdup(rvalue
)))
413 int config_parse_path(
414 const char *filename
,
431 if (!path_is_absolute(rvalue
)) {
432 log_error("[%s:%u] Not an absolute path: %s", filename
, line
, rvalue
);
436 if (!(n
= strdup(rvalue
)))
439 path_kill_slashes(n
);
447 int config_parse_strv(
448 const char *filename
,
469 k
= strv_length(*sv
);
470 FOREACH_WORD_QUOTED(w
, l
, rvalue
, state
)
473 if (!(n
= new(char*, k
+1)))
477 for (k
= 0; (*sv
)[k
]; k
++)
482 FOREACH_WORD_QUOTED(w
, l
, rvalue
, state
)
483 if (!(n
[k
++] = cunescape_length(w
, l
)))
500 int config_parse_path_strv(
501 const char *filename
,
523 k
= strv_length(*sv
);
524 FOREACH_WORD_QUOTED(w
, l
, rvalue
, state
)
527 if (!(n
= new(char*, k
+1)))
532 for (; (*sv
)[k
]; k
++)
535 FOREACH_WORD_QUOTED(w
, l
, rvalue
, state
) {
536 if (!(n
[k
] = cunescape_length(w
, l
))) {
541 if (!path_is_absolute(n
[k
])) {
542 log_error("[%s:%u] Not an absolute path: %s", filename
, line
, rvalue
);
547 path_kill_slashes(n
[k
]);