conf-parser.c revision d450b6f2a9dd8a7fb14e9f8f771ddd70de7afc5e
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/***
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2010 Lennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering***/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <string.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <stdio.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <errno.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <assert.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <stdlib.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <netinet/ether.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "conf-parser.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "macro.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "strv.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "log.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "utf8.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "path-util.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "set.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "exit-status.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "sd-messages.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint log_syntax_internal(const char *unit, int level,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *file, unsigned line, const char *func,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *config_file, unsigned config_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int error, const char *format, ...) {
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *msg = NULL;
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering va_list ap;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering va_start(ap, format);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = vasprintf(&msg, format, ap);
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallace va_end(ap);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (unit)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = log_struct_internal(level,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering file, line, func,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "CONFIG_FILE=%s", config_file,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "CONFIG_LINE=%u", config_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "ERRNO=%d", error > 0 ? error : EINVAL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = log_struct_internal(level,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering file, line, func,
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering "CONFIG_FILE=%s", config_file,
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering "CONFIG_LINE=%u", config_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "ERRNO=%d", error > 0 ? error : EINVAL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_item_table_lookup(
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *table,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ConfigParserCallback *func,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int *ltype,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void **data,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ConfigTableItem *t;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(table);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(func);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(ltype);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(data);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (t = table; t->lvalue; t++) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!streq(lvalue, t->lvalue))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!streq_ptr(section, t->section))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *func = t->parse;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ltype = t->ltype;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *data = t->data;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers}
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversint config_item_perf_lookup(
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers void *table,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers const char *section,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers const char *lvalue,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers ConfigParserCallback *func,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int *ltype,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers void **data,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers void *userdata) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers const ConfigPerfItem *p;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(table);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(func);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers assert(ltype);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers assert(data);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (!section)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers p = lookup(lvalue, strlen(lvalue));
6046278f405b3ebaf84fcf17f6e834c4c4bd6a42Djalal Harouni else {
6046278f405b3ebaf84fcf17f6e834c4c4bd6a42Djalal Harouni char *key;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
6046278f405b3ebaf84fcf17f6e834c4c4bd6a42Djalal Harouni key = strjoin(section, ".", lvalue, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!key)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOMEM;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers p = lookup(key, strlen(key));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(key);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!p)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers *func = p->parse;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ltype = p->ltype;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *data = (uint8_t*) userdata + p->offset;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/* Run the user supplied parser for an assignment */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int next_assignment(const char *unit,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering const char *filename,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering unsigned line,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering ConfigItemLookup lookup,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *table,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering const char *lvalue,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers const char *rvalue,
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering bool relaxed,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers ConfigParserCallback func = NULL;
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering int ltype = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *data = NULL;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(line > 0);
c49b30a23583ff39daaa26696bcab478d2fee0bbLennart Poettering assert(lookup);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers assert(lvalue);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering assert(rvalue);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = lookup(table, section, lvalue, &func, &ltype, &data, userdata);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r > 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (func)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return func(unit, filename, line, section, section_line,
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna lvalue, ltype, rvalue, data, userdata);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering return 0;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering /* Warn about unknown non-extension fields. */
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering if (!relaxed && !startswith(lvalue, "X-"))
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering "Unknown lvalue '%s' in section '%s'", lvalue, section);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek/* Parse a variable assignment line */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int parse_line(const char* unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers unsigned line,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers const char *sections,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ConfigItemLookup lookup,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering void *table,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool relaxed,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool allow_include,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned *section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *l,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *e;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(line > 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lookup);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering l = strstrip(l);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!*l)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (strchr(COMMENTS "\n", *l))
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (startswith(l, ".include ")) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering _cleanup_free_ char *fn = NULL;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (!allow_include) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, EBADMSG,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ".include not allowed here. Ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering fn = file_in_same_dir(filename, strstrip(l+9));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!fn)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOMEM;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, userdata);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (*l == '[') {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering size_t k;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *n;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering k = strlen(l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(k > 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (l[k-1] != ']') {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EBADMSG,
2b6bf07dd23bb467099d213c97b3875c5e453491Zbigniew Jędrzejewski-Szmek "Invalid section header '%s'", l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EBADMSG;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering n = strndup(l+1, k-2);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!n)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOMEM;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (sections && !nulstr_contains(sections, n)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!relaxed)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek "Unknown section '%s'. Ignoring.", n);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(*section);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *section = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *section_line = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(*section);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *section = n;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers *section_line = line;
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer }
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (sections && !*section) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek if (!relaxed)
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Assignment outside of section. Ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e = strchr(l, '=');
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!e) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Missing '='.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EBADMSG;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *e = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e++;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return next_assignment(unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering lookup,
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen table,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering strstrip(l),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering strstrip(e),
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers relaxed,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers userdata);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/* Go through the file and parse each line */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse(const char *unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering FILE *f,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *sections,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ConfigItemLookup lookup,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *table,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool relaxed,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool allow_include,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_free_ char *section = NULL, *continuation = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_fclose_ FILE *ours = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned line = 0, section_line = 0;
6b2b6f30e38d67b032d6bdc6b47ae05e143e96c5Michal Schmidt int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering assert(filename);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering assert(lookup);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!f) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = ours = fopen(filename, "re");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!f) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_error("Failed to open configuration file '%s': %m", filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -errno;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering while (!feof(f)) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering char l[LINE_MAX], *p, *c = NULL, *e;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering bool escaped = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!fgets(l, sizeof(l), f)) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (feof(f))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering break;
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_error("Failed to read configuration file '%s': %m", filename);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return -errno;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering truncate_nl(l);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (continuation) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering c = strappend(continuation, l);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (!c)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return -ENOMEM;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(continuation);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continuation = NULL;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering p = c;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else
c62e11ce3966c55d23520b9f0785c7e839cf7f37Lennart Poettering p = l;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering for (e = p; *e; e++) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (escaped)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering escaped = false;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (*e == '\\')
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering escaped = true;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (escaped) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering *(e-1) = ' ';
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (c)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continuation = c;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continuation = strdup(l);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (!continuation)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return -ENOMEM;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = parse_line(unit,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering filename,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering ++line,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sections,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering lookup,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering table,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering relaxed,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering allow_include,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering &section,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering &section_line,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering p,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering userdata);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r < 0)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return r;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering}
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#define DEFINE_PARSER(type, vartype, conv_func) \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int config_parse_##type(const char *unit, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *filename, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unsigned line, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *section, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unsigned section_line, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *lvalue, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int ltype, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *rvalue, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering void *data, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering void *userdata) { \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering vartype *i = data; \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int r; \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(filename); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(lvalue); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(rvalue); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(data); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = conv_func(rvalue, i); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r < 0) \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r, \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering "Failed to parse %s value, ignoring: %s", \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering #vartype, rvalue); \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0; \
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(int, int, safe_atoi)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(long, long, safe_atoli)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(uint64, uint64_t, safe_atou64)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(unsigned, unsigned, safe_atou)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(double, double, safe_atod)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(nsec, nsec_t, parse_nsec)
50cfc579280fb42569488079bd2e249e32a27df2Lennart PoetteringDEFINE_PARSER(sec, usec_t, parse_sec)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poetteringint config_parse_bytes_size(const char* unit,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *filename,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unsigned line,
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
82c1d8f4eb74ddd9be2c9b9b56d9dc564c599effLennart Poettering const char *lvalue,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int ltype,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *rvalue,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering void *data,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering void *userdata) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering size_t *sz = data;
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering off_t o;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(filename);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(lvalue);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(rvalue);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(data);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = parse_bytes(rvalue, &o);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r < 0 || (off_t) (size_t) o != o) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering "Failed to parse byte value, ignoring: %s", rvalue);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0;
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek }
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *sz = (size_t) o;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse_bytes_off(const char* unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ltype,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers const char *rvalue,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers void *data,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers void *userdata) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers off_t *bytes = data;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers int r;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(data);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert_cc(sizeof(off_t) == sizeof(uint64_t));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = parse_bytes(rvalue, bytes);
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Failed to parse bytes value, ignoring: %s", rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek}
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse_bool(const char* unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ltype,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *rvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *data,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int k;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool *b = data;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen assert(filename);
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen assert(lvalue);
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen assert(rvalue);
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen assert(data);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers k = parse_boolean(rvalue);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (k < 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_syntax(unit, LOG_ERR, filename, line, -k,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers "Failed to parse boolean value, ignoring: %s", rvalue);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers *b = !!k;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse_show_status(const char* unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering unsigned line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ltype,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *rvalue,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers void *data,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int k;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ShowStatus *b = data;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(data);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering k = parse_show_status(rvalue, b);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (k < 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -k,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering "Failed to parse show status setting, ignoring: %s", rvalue);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering}
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poetteringint config_parse_string(const char *unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ltype,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *rvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *data,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **s = data;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *n;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(data);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering n = strdup(rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!n)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!utf8_is_valid(n)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "String is not UTF-8 clean, ignoring assignment: %s", rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(*s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (*n)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *s = n;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *s = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse_path(const char *unit,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *section,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned section_line,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *lvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ltype,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *rvalue,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *data,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *userdata) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **s = data;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *n;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int offset;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(lvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(rvalue);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(data);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!utf8_is_valid(rvalue)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers "Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering return 0;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner offset = rvalue[0] == '-' && (streq(lvalue, "InaccessibleDirectories") ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering streq(lvalue, "ReadOnlyDirectories"));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!path_is_absolute(rvalue + offset)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Not an absolute path, ignoring: %s", rvalue);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers n = strdup(rvalue);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (!n)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return log_oom();
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering path_kill_slashes(n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers free(*s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *s = n;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint config_parse_strv(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char *** sv = data, *w, *state;
size_t l;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
char **empty;
/* Empty assignment resets the list. As a special rule
* we actually fill in a real empty array here rather
* than NULL, since some code wants to know if
* something was set at all... */
empty = strv_new(NULL, NULL);
if (!empty)
return log_oom();
strv_free(*sv);
*sv = empty;
return 0;
}
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
_cleanup_free_ char *n;
n = cunescape_length(w, l);
if (!n)
return log_oom();
if (!utf8_is_valid(n)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"String is not UTF-8 clean, ignoring: %s", rvalue);
continue;
}
r = strv_extend(sv, n);
if (r < 0)
return log_oom();
}
return 0;
}
int config_parse_path_strv(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char*** sv = data, *w, *state;
size_t l;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
/* Empty assignment resets the list */
strv_free(*sv);
*sv = NULL;
return 0;
}
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
_cleanup_free_ char *n;
int offset;
n = strndup(w, l);
if (!n)
return log_oom();
if (!utf8_is_valid(n)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
continue;
}
offset = n[0] == '-' && (streq(lvalue, "InaccessibleDirectories") ||
streq(lvalue, "ReadOnlyDirectories"));
if (!path_is_absolute(n + offset)) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Not an absolute path, ignoring: %s", rvalue);
continue;
}
path_kill_slashes(n);
r = strv_extend(sv, n);
if (r < 0)
return log_oom();
}
return 0;
}
int config_parse_mode(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
mode_t *m = data;
long l;
char *x = NULL;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
errno = 0;
l = strtol(rvalue, &x, 8);
if (!x || x == rvalue || *x || errno) {
log_syntax(unit, LOG_ERR, filename, line, errno,
"Failed to parse mode value, ignoring: %s", rvalue);
return 0;
}
if (l < 0000 || l > 07777) {
log_syntax(unit, LOG_ERR, filename, line, ERANGE,
"Mode value out of range, ignoring: %s", rvalue);
return 0;
}
*m = (mode_t) l;
return 0;
}
int config_parse_facility(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *o = data, x;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
x = log_facility_unshifted_from_string(rvalue);
if (x < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse log facility, ignoring: %s", rvalue);
return 0;
}
*o = (x << 3) | LOG_PRI(*o);
return 0;
}
int config_parse_level(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
int *o = data, x;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
x = log_level_from_string(rvalue);
if (x < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Failed to parse log level, ignoring: %s", rvalue);
return 0;
}
*o = (*o & LOG_FACMASK) | x;
return 0;
}
int config_parse_set_status(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
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_syntax(unit, LOG_ERR, filename, line, -r,
"Unable to store: %s", w);
return r;
}
} else {
log_syntax(unit, LOG_ERR, filename, line, -val,
"Failed to parse value, ignoring: %s", w);
return 0;
}
} else {
free(temp);
if (val < 0 || val > 255)
log_syntax(unit, LOG_ERR, filename, line, ERANGE,
"Value %d is outside range 0-255, ignoring", 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_syntax(unit, LOG_ERR, filename, line, -r,
"Unable to store: %s", w);
return r;
}
}
}
}
return 0;
}