1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2010 Lennart Poettering
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "alloc-util.h"
33 /* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
35 typedef enum ConfigParseFlags {
36 CONFIG_PARSE_RELAXED = 1U << 0,
37 CONFIG_PARSE_ALLOW_INCLUDE = 1U << 1,
38 CONFIG_PARSE_WARN = 1U << 2,
39 CONFIG_PARSE_REFUSE_BOM = 1U << 3,
42 /* Prototype for a parser for a specific configuration setting */
43 typedef int (*ConfigParserCallback)(const char *unit,
47 unsigned section_line,
54 /* Wraps information for parsing a specific configuration variable, to
55 * be stored in a simple array */
56 typedef struct ConfigTableItem {
57 const char *section; /* Section */
58 const char *lvalue; /* Name of the variable */
59 ConfigParserCallback parse; /* Function that is called to parse the variable's value */
60 int ltype; /* Distinguish different variables passed to the same callback */
61 void *data; /* Where to store the variable's data */
64 /* Wraps information for parsing a specific configuration variable, to
65 * be stored in a gperf perfect hashtable */
66 typedef struct ConfigPerfItem {
67 const char *section_and_lvalue; /* Section + "." + name of the variable */
68 ConfigParserCallback parse; /* Function that is called to parse the variable's value */
69 int ltype; /* Distinguish different variables passed to the same callback */
70 size_t offset; /* Offset where to store data, from the beginning of userdata */
73 /* Prototype for a low-level gperf lookup function */
74 typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length);
76 /* Prototype for a generic high-level lookup function */
77 typedef int (*ConfigItemLookup)(
81 ConfigParserCallback *func,
86 /* Linear table search implementation of ConfigItemLookup, based on
87 * ConfigTableItem arrays */
88 int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
90 /* gperf implementation of ConfigItemLookup, based on gperf
91 * ConfigPerfItem tables */
92 int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
98 const char *sections, /* nulstr */
99 ConfigItemLookup lookup,
101 ConfigParseFlags flags,
104 int config_parse_many_nulstr(
105 const char *conf_file, /* possibly NULL */
106 const char *conf_file_dirs, /* nulstr */
107 const char *sections, /* nulstr */
108 ConfigItemLookup lookup,
110 ConfigParseFlags flags,
113 #if 0 /// UNNEEDED by elogind
114 int config_parse_many(
115 const char *conf_file, /* possibly NULL */
116 const char* const* conf_file_dirs,
117 const char *dropin_dirname,
118 const char *sections, /* nulstr */
119 ConfigItemLookup lookup,
121 ConfigParseFlags flags,
125 /* Generic parsers */
126 #if 0 /// UNNEEDED by elogind
128 #if 0 /// UNNEEDED by elogind
130 #if 0 /// UNNEEDED by elogind
132 #if 0 /// UNNEEDED by elogind
134 #if 0 /// UNNEEDED by elogind
136 #if 0 /// UNNEEDED by elogind
138 #define GENERIC_PARSER_ARGS \
140 const char *filename, \
142 const char *section, \
143 unsigned section_line, \
144 const char *lvalue, \
146 const char *rvalue, \
149 int config_parse_int(GENERIC_PARSER_ARGS);
150 int config_parse_unsigned(GENERIC_PARSER_ARGS);
151 int config_parse_long(GENERIC_PARSER_ARGS);
152 int config_parse_uint8(GENERIC_PARSER_ARGS);
153 int config_parse_uint16(GENERIC_PARSER_ARGS);
154 int config_parse_uint32(GENERIC_PARSER_ARGS);
155 int config_parse_uint64(GENERIC_PARSER_ARGS);
156 int config_parse_double(GENERIC_PARSER_ARGS);
157 int config_parse_iec_size(GENERIC_PARSER_ARGS);
158 int config_parse_si_size(GENERIC_PARSER_ARGS);
159 int config_parse_iec_uint64(GENERIC_PARSER_ARGS);
160 int config_parse_bool(GENERIC_PARSER_ARGS);
161 int config_parse_tristate(GENERIC_PARSER_ARGS);
162 int config_parse_string(GENERIC_PARSER_ARGS);
163 int config_parse_path(GENERIC_PARSER_ARGS);
164 int config_parse_strv(GENERIC_PARSER_ARGS);
165 int config_parse_sec(GENERIC_PARSER_ARGS);
166 int config_parse_nsec(GENERIC_PARSER_ARGS);
167 int config_parse_mode(GENERIC_PARSER_ARGS);
168 int config_parse_log_facility(GENERIC_PARSER_ARGS);
169 int config_parse_log_level(GENERIC_PARSER_ARGS);
170 int config_parse_signal(GENERIC_PARSER_ARGS);
171 int config_parse_personality(GENERIC_PARSER_ARGS);
172 int config_parse_ifname(GENERIC_PARSER_ARGS);
173 int config_parse_ip_port(GENERIC_PARSER_ARGS);
175 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
176 int function(GENERIC_PARSER_ARGS) { \
184 if ((x = name##_from_string(rvalue)) < 0) { \
185 log_syntax(unit, LOG_ERR, filename, line, -x, \
186 msg ", ignoring: %s", rvalue); \
194 #define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
195 int function(GENERIC_PARSER_ARGS) { \
196 type **enums = data, x, *ys; \
197 _cleanup_free_ type *xs = NULL; \
198 const char *word, *state; \
206 xs = new0(type, 1); \
212 FOREACH_WORD(word, l, rvalue, state) { \
213 _cleanup_free_ char *en = NULL; \
216 en = strndup(word, l); \
220 if ((x = name##_from_string(en)) < 0) { \
221 log_syntax(unit, LOG_ERR, filename, line, \
222 -x, msg ", ignoring: %s", en); \
226 for (ys = xs; x != invalid && *ys != invalid; ys++) { \
228 log_syntax(unit, LOG_ERR, filename, \
230 "Duplicate entry, ignoring: %s", \
240 new_xs = realloc(xs, (++i + 1) * sizeof(type)); \
246 *(xs + i) = invalid; \