]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/conf-parser.h
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / shared / conf-parser.h
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
c2f1db8f 2#pragma once
ed5bcfbe 3
a7334b09
LP
4/***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
12 (at your option) any later version.
13
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
5430f7f2 17 Lesser General Public License for more details.
a7334b09 18
5430f7f2 19 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
a8fbdf54 23#include <errno.h>
10e87ee7 24#include <stdbool.h>
a8fbdf54 25#include <stddef.h>
71d35b6b 26#include <stdio.h>
a8fbdf54 27#include <syslog.h>
ed5bcfbe 28
a8fbdf54
TA
29#include "alloc-util.h"
30#include "log.h"
e8e581bf
ZJS
31#include "macro.h"
32
bcde742e
LP
33/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
34
35typedef 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,
40} ConfigParseFlags;
ed5bcfbe 41
f975e971 42/* Prototype for a parser for a specific configuration setting */
e8e581bf
ZJS
43typedef int (*ConfigParserCallback)(const char *unit,
44 const char *filename,
45 unsigned line,
46 const char *section,
71a61510 47 unsigned section_line,
e8e581bf
ZJS
48 const char *lvalue,
49 int ltype,
50 const char *rvalue,
51 void *data,
52 void *userdata);
f975e971
LP
53
54/* Wraps information for parsing a specific configuration variable, to
55 * be stored in a simple array */
56typedef 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 */
62} ConfigTableItem;
63
64/* Wraps information for parsing a specific configuration variable, to
e5a7f173 65 * be stored in a gperf perfect hashtable */
f975e971
LP
66typedef 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 */
71} ConfigPerfItem;
72
73/* Prototype for a low-level gperf lookup function */
74typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length);
75
76/* Prototype for a generic high-level lookup function */
77typedef int (*ConfigItemLookup)(
e9f3d2d5 78 const void *table,
f975e971
LP
79 const char *section,
80 const char *lvalue,
81 ConfigParserCallback *func,
82 int *ltype,
83 void **data,
84 void *userdata);
85
86/* Linear table search implementation of ConfigItemLookup, based on
87 * ConfigTableItem arrays */
e9f3d2d5 88int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
f975e971
LP
89
90/* gperf implementation of ConfigItemLookup, based on gperf
91 * ConfigPerfItem tables */
e9f3d2d5 92int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
f975e971 93
43688c49
ZJS
94int config_parse(
95 const char *unit,
96 const char *filename,
97 FILE *f,
98 const char *sections, /* nulstr */
99 ConfigItemLookup lookup,
100 const void *table,
bcde742e 101 ConfigParseFlags flags,
43688c49
ZJS
102 void *userdata);
103
104int 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,
109 const void *table,
bcde742e 110 ConfigParseFlags flags,
43688c49 111 void *userdata);
e8461023 112
23bb31aa
ZJS
113int config_parse_many(
114 const char *conf_file, /* possibly NULL */
115 const char* const* conf_file_dirs,
116 const char *dropin_dirname,
117 const char *sections, /* nulstr */
118 ConfigItemLookup lookup,
119 const void *table,
bcde742e 120 ConfigParseFlags flags,
23bb31aa
ZJS
121 void *userdata);
122
ed5bcfbe 123/* Generic parsers */
71a61510
TG
124int config_parse_int(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);
125int config_parse_unsigned(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);
126int config_parse_long(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);
134e24e1 127int config_parse_uint8(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);
c7440e74 128int config_parse_uint16(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);
9b3a67c5 129int config_parse_uint32(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);
71a61510
TG
130int config_parse_uint64(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);
131int config_parse_double(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);
5556b5fe
LP
132int config_parse_iec_size(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);
133int config_parse_si_size(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);
59f448cf 134int config_parse_iec_uint64(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);
71a61510 135int config_parse_bool(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);
f757855e 136int config_parse_tristate(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);
71a61510
TG
137int config_parse_string(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);
138int config_parse_path(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);
139int 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);
71a61510
TG
140int config_parse_sec(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);
141int config_parse_nsec(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);
142int 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);
ca37242e
LP
143int config_parse_log_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);
144int config_parse_log_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);
f757855e
LP
145int config_parse_signal(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);
146int config_parse_personality(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);
d31645ad 147int config_parse_ifname(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);
177d0b20 148int config_parse_ip_port(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);
e8e581bf 149
487393e9 150#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
e8e581bf
ZJS
151 int function(const char *unit, \
152 const char *filename, \
153 unsigned line, \
154 const char *section, \
71a61510 155 unsigned section_line, \
e8e581bf
ZJS
156 const char *lvalue, \
157 int ltype, \
158 const char *rvalue, \
159 void *data, \
160 void *userdata) { \
487393e9
LP
161 \
162 type *i = data, x; \
163 \
164 assert(filename); \
165 assert(lvalue); \
166 assert(rvalue); \
167 assert(data); \
168 \
169 if ((x = name##_from_string(rvalue)) < 0) { \
e8e581bf
ZJS
170 log_syntax(unit, LOG_ERR, filename, line, -x, \
171 msg ", ignoring: %s", rvalue); \
c0b34696 172 return 0; \
487393e9
LP
173 } \
174 \
175 *i = x; \
487393e9
LP
176 return 0; \
177 }
916484f5
TG
178
179#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
180 int function(const char *unit, \
181 const char *filename, \
182 unsigned line, \
183 const char *section, \
71a61510 184 unsigned section_line, \
916484f5
TG
185 const char *lvalue, \
186 int ltype, \
187 const char *rvalue, \
188 void *data, \
189 void *userdata) { \
190 \
77c10205
TG
191 type **enums = data, x, *ys; \
192 _cleanup_free_ type *xs = NULL; \
a2a5291b 193 const char *word, *state; \
916484f5
TG
194 size_t l, i = 0; \
195 \
196 assert(filename); \
197 assert(lvalue); \
198 assert(rvalue); \
199 assert(data); \
200 \
201 xs = new0(type, 1); \
9ed794a3 202 if (!xs) \
83e341a6
TG
203 return -ENOMEM; \
204 \
916484f5
TG
205 *xs = invalid; \
206 \
a2a5291b 207 FOREACH_WORD(word, l, rvalue, state) { \
916484f5 208 _cleanup_free_ char *en = NULL; \
77c10205 209 type *new_xs; \
916484f5 210 \
a2a5291b 211 en = strndup(word, l); \
916484f5
TG
212 if (!en) \
213 return -ENOMEM; \
214 \
215 if ((x = name##_from_string(en)) < 0) { \
216 log_syntax(unit, LOG_ERR, filename, line, \
217 -x, msg ", ignoring: %s", en); \
218 continue; \
219 } \
220 \
221 for (ys = xs; x != invalid && *ys != invalid; ys++) { \
222 if (*ys == x) { \
223 log_syntax(unit, LOG_ERR, filename, \
224 line, -x, \
225 "Duplicate entry, ignoring: %s", \
226 en); \
227 x = invalid; \
228 } \
229 } \
230 \
231 if (x == invalid) \
232 continue; \
233 \
234 *(xs + i) = x; \
77c10205
TG
235 new_xs = realloc(xs, (++i + 1) * sizeof(type)); \
236 if (new_xs) \
237 xs = new_xs; \
238 else \
916484f5 239 return -ENOMEM; \
83e341a6 240 \
916484f5
TG
241 *(xs + i) = invalid; \
242 } \
243 \
244 free(*enums); \
245 *enums = xs; \
77c10205
TG
246 xs = NULL; \
247 \
916484f5
TG
248 return 0; \
249 }