]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/conf-parser.h
conf-parse: add a generic config_parse_mtu() conf file parser function
[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
a7334b09
LP
8***/
9
a8fbdf54 10#include <errno.h>
10e87ee7 11#include <stdbool.h>
a8fbdf54 12#include <stddef.h>
71d35b6b 13#include <stdio.h>
a8fbdf54 14#include <syslog.h>
ed5bcfbe 15
a8fbdf54
TA
16#include "alloc-util.h"
17#include "log.h"
e8e581bf
ZJS
18#include "macro.h"
19
bcde742e
LP
20/* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
21
22typedef enum ConfigParseFlags {
23 CONFIG_PARSE_RELAXED = 1U << 0,
24 CONFIG_PARSE_ALLOW_INCLUDE = 1U << 1,
25 CONFIG_PARSE_WARN = 1U << 2,
26 CONFIG_PARSE_REFUSE_BOM = 1U << 3,
27} ConfigParseFlags;
ed5bcfbe 28
f975e971 29/* Prototype for a parser for a specific configuration setting */
e8e581bf
ZJS
30typedef int (*ConfigParserCallback)(const char *unit,
31 const char *filename,
32 unsigned line,
33 const char *section,
71a61510 34 unsigned section_line,
e8e581bf
ZJS
35 const char *lvalue,
36 int ltype,
37 const char *rvalue,
38 void *data,
39 void *userdata);
f975e971
LP
40
41/* Wraps information for parsing a specific configuration variable, to
42 * be stored in a simple array */
43typedef struct ConfigTableItem {
44 const char *section; /* Section */
45 const char *lvalue; /* Name of the variable */
46 ConfigParserCallback parse; /* Function that is called to parse the variable's value */
47 int ltype; /* Distinguish different variables passed to the same callback */
48 void *data; /* Where to store the variable's data */
49} ConfigTableItem;
50
51/* Wraps information for parsing a specific configuration variable, to
e5a7f173 52 * be stored in a gperf perfect hashtable */
f975e971
LP
53typedef struct ConfigPerfItem {
54 const char *section_and_lvalue; /* Section + "." + name of the variable */
55 ConfigParserCallback parse; /* Function that is called to parse the variable's value */
56 int ltype; /* Distinguish different variables passed to the same callback */
57 size_t offset; /* Offset where to store data, from the beginning of userdata */
58} ConfigPerfItem;
59
60/* Prototype for a low-level gperf lookup function */
61typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length);
62
63/* Prototype for a generic high-level lookup function */
64typedef int (*ConfigItemLookup)(
e9f3d2d5 65 const void *table,
f975e971
LP
66 const char *section,
67 const char *lvalue,
68 ConfigParserCallback *func,
69 int *ltype,
70 void **data,
71 void *userdata);
72
73/* Linear table search implementation of ConfigItemLookup, based on
74 * ConfigTableItem arrays */
e9f3d2d5 75int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
f975e971
LP
76
77/* gperf implementation of ConfigItemLookup, based on gperf
78 * ConfigPerfItem tables */
e9f3d2d5 79int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
f975e971 80
43688c49
ZJS
81int config_parse(
82 const char *unit,
83 const char *filename,
84 FILE *f,
85 const char *sections, /* nulstr */
86 ConfigItemLookup lookup,
87 const void *table,
bcde742e 88 ConfigParseFlags flags,
43688c49
ZJS
89 void *userdata);
90
91int config_parse_many_nulstr(
92 const char *conf_file, /* possibly NULL */
93 const char *conf_file_dirs, /* nulstr */
94 const char *sections, /* nulstr */
95 ConfigItemLookup lookup,
96 const void *table,
bcde742e 97 ConfigParseFlags flags,
43688c49 98 void *userdata);
e8461023 99
23bb31aa
ZJS
100int config_parse_many(
101 const char *conf_file, /* possibly NULL */
102 const char* const* conf_file_dirs,
103 const char *dropin_dirname,
104 const char *sections, /* nulstr */
105 ConfigItemLookup lookup,
106 const void *table,
bcde742e 107 ConfigParseFlags flags,
23bb31aa
ZJS
108 void *userdata);
109
ed5bcfbe 110/* Generic parsers */
b48382e4
ZJS
111#define GENERIC_PARSER_ARGS \
112 const char *unit, \
113 const char *filename, \
114 unsigned line, \
115 const char *section, \
116 unsigned section_line, \
117 const char *lvalue, \
118 int ltype, \
119 const char *rvalue, \
120 void *data, \
121 void *userdata
122int config_parse_int(GENERIC_PARSER_ARGS);
123int config_parse_unsigned(GENERIC_PARSER_ARGS);
124int config_parse_long(GENERIC_PARSER_ARGS);
125int config_parse_uint8(GENERIC_PARSER_ARGS);
126int config_parse_uint16(GENERIC_PARSER_ARGS);
127int config_parse_uint32(GENERIC_PARSER_ARGS);
128int config_parse_uint64(GENERIC_PARSER_ARGS);
129int config_parse_double(GENERIC_PARSER_ARGS);
130int config_parse_iec_size(GENERIC_PARSER_ARGS);
131int config_parse_si_size(GENERIC_PARSER_ARGS);
132int config_parse_iec_uint64(GENERIC_PARSER_ARGS);
133int config_parse_bool(GENERIC_PARSER_ARGS);
134int config_parse_tristate(GENERIC_PARSER_ARGS);
135int config_parse_string(GENERIC_PARSER_ARGS);
136int config_parse_path(GENERIC_PARSER_ARGS);
137int config_parse_strv(GENERIC_PARSER_ARGS);
138int config_parse_sec(GENERIC_PARSER_ARGS);
139int config_parse_nsec(GENERIC_PARSER_ARGS);
140int config_parse_mode(GENERIC_PARSER_ARGS);
1e35c5ab 141int config_parse_warn_compat(GENERIC_PARSER_ARGS);
b48382e4
ZJS
142int config_parse_log_facility(GENERIC_PARSER_ARGS);
143int config_parse_log_level(GENERIC_PARSER_ARGS);
144int config_parse_signal(GENERIC_PARSER_ARGS);
145int config_parse_personality(GENERIC_PARSER_ARGS);
146int config_parse_ifname(GENERIC_PARSER_ARGS);
147int config_parse_ip_port(GENERIC_PARSER_ARGS);
9ecdba8c 148int config_parse_join_controllers(GENERIC_PARSER_ARGS);
79138a38 149int config_parse_mtu(GENERIC_PARSER_ARGS);
e8e581bf 150
1e35c5ab
RP
151typedef enum Disabled {
152 DISABLED_CONFIGURATION,
153 DISABLED_LEGACY,
154 DISABLED_EXPERIMENTAL,
155} Disabled;
156
487393e9 157#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
b48382e4 158 int function(GENERIC_PARSER_ARGS) { \
487393e9
LP
159 type *i = data, x; \
160 \
161 assert(filename); \
162 assert(lvalue); \
163 assert(rvalue); \
164 assert(data); \
165 \
166 if ((x = name##_from_string(rvalue)) < 0) { \
e8e581bf
ZJS
167 log_syntax(unit, LOG_ERR, filename, line, -x, \
168 msg ", ignoring: %s", rvalue); \
c0b34696 169 return 0; \
487393e9
LP
170 } \
171 \
172 *i = x; \
487393e9
LP
173 return 0; \
174 }
916484f5
TG
175
176#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
b48382e4 177 int function(GENERIC_PARSER_ARGS) { \
77c10205
TG
178 type **enums = data, x, *ys; \
179 _cleanup_free_ type *xs = NULL; \
a2a5291b 180 const char *word, *state; \
916484f5
TG
181 size_t l, i = 0; \
182 \
183 assert(filename); \
184 assert(lvalue); \
185 assert(rvalue); \
186 assert(data); \
187 \
188 xs = new0(type, 1); \
9ed794a3 189 if (!xs) \
83e341a6
TG
190 return -ENOMEM; \
191 \
916484f5
TG
192 *xs = invalid; \
193 \
a2a5291b 194 FOREACH_WORD(word, l, rvalue, state) { \
916484f5 195 _cleanup_free_ char *en = NULL; \
77c10205 196 type *new_xs; \
916484f5 197 \
a2a5291b 198 en = strndup(word, l); \
916484f5
TG
199 if (!en) \
200 return -ENOMEM; \
201 \
202 if ((x = name##_from_string(en)) < 0) { \
203 log_syntax(unit, LOG_ERR, filename, line, \
204 -x, msg ", ignoring: %s", en); \
205 continue; \
206 } \
207 \
208 for (ys = xs; x != invalid && *ys != invalid; ys++) { \
209 if (*ys == x) { \
210 log_syntax(unit, LOG_ERR, filename, \
211 line, -x, \
212 "Duplicate entry, ignoring: %s", \
213 en); \
214 x = invalid; \
215 } \
216 } \
217 \
218 if (x == invalid) \
219 continue; \
220 \
221 *(xs + i) = x; \
77c10205
TG
222 new_xs = realloc(xs, (++i + 1) * sizeof(type)); \
223 if (new_xs) \
224 xs = new_xs; \
225 else \
916484f5 226 return -ENOMEM; \
83e341a6 227 \
916484f5
TG
228 *(xs + i) = invalid; \
229 } \
230 \
231 free(*enums); \
232 *enums = xs; \
77c10205
TG
233 xs = NULL; \
234 \
916484f5
TG
235 return 0; \
236 }