1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2010 Lennart Poettering
16 #include "alloc-util.h"
20 /* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */
22 typedef 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,
29 /* Prototype for a parser for a specific configuration setting */
30 typedef int (*ConfigParserCallback
)(const char *unit
,
34 unsigned section_line
,
41 /* Wraps information for parsing a specific configuration variable, to
42 * be stored in a simple array */
43 typedef 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 */
51 /* Wraps information for parsing a specific configuration variable, to
52 * be stored in a gperf perfect hashtable */
53 typedef 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 */
60 /* Prototype for a low-level gperf lookup function */
61 typedef const ConfigPerfItem
* (*ConfigPerfItemLookup
)(const char *section_and_lvalue
, unsigned length
);
63 /* Prototype for a generic high-level lookup function */
64 typedef int (*ConfigItemLookup
)(
68 ConfigParserCallback
*func
,
73 /* Linear table search implementation of ConfigItemLookup, based on
74 * ConfigTableItem arrays */
75 int config_item_table_lookup(const void *table
, const char *section
, const char *lvalue
, ConfigParserCallback
*func
, int *ltype
, void **data
, void *userdata
);
77 /* gperf implementation of ConfigItemLookup, based on gperf
78 * ConfigPerfItem tables */
79 int config_item_perf_lookup(const void *table
, const char *section
, const char *lvalue
, ConfigParserCallback
*func
, int *ltype
, void **data
, void *userdata
);
85 const char *sections
, /* nulstr */
86 ConfigItemLookup lookup
,
88 ConfigParseFlags flags
,
91 int 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
,
97 ConfigParseFlags flags
,
100 int 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
,
107 ConfigParseFlags flags
,
110 /* Generic parsers */
111 #define GENERIC_PARSER_ARGS \
113 const char *filename, \
115 const char *section, \
116 unsigned section_line, \
117 const char *lvalue, \
119 const char *rvalue, \
122 int config_parse_int(GENERIC_PARSER_ARGS
);
123 int config_parse_unsigned(GENERIC_PARSER_ARGS
);
124 int config_parse_long(GENERIC_PARSER_ARGS
);
125 int config_parse_uint8(GENERIC_PARSER_ARGS
);
126 int config_parse_uint16(GENERIC_PARSER_ARGS
);
127 int config_parse_uint32(GENERIC_PARSER_ARGS
);
128 int config_parse_uint64(GENERIC_PARSER_ARGS
);
129 int config_parse_double(GENERIC_PARSER_ARGS
);
130 int config_parse_iec_size(GENERIC_PARSER_ARGS
);
131 int config_parse_si_size(GENERIC_PARSER_ARGS
);
132 int config_parse_iec_uint64(GENERIC_PARSER_ARGS
);
133 int config_parse_bool(GENERIC_PARSER_ARGS
);
134 int config_parse_tristate(GENERIC_PARSER_ARGS
);
135 int config_parse_string(GENERIC_PARSER_ARGS
);
136 int config_parse_path(GENERIC_PARSER_ARGS
);
137 int config_parse_strv(GENERIC_PARSER_ARGS
);
138 int config_parse_sec(GENERIC_PARSER_ARGS
);
139 int config_parse_nsec(GENERIC_PARSER_ARGS
);
140 int config_parse_mode(GENERIC_PARSER_ARGS
);
141 int config_parse_warn_compat(GENERIC_PARSER_ARGS
);
142 int config_parse_log_facility(GENERIC_PARSER_ARGS
);
143 int config_parse_log_level(GENERIC_PARSER_ARGS
);
144 int config_parse_signal(GENERIC_PARSER_ARGS
);
145 int config_parse_personality(GENERIC_PARSER_ARGS
);
146 int config_parse_ifname(GENERIC_PARSER_ARGS
);
147 int config_parse_ip_port(GENERIC_PARSER_ARGS
);
148 int config_parse_join_controllers(GENERIC_PARSER_ARGS
);
150 typedef enum Disabled
{
151 DISABLED_CONFIGURATION
,
153 DISABLED_EXPERIMENTAL
,
156 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
157 int function(GENERIC_PARSER_ARGS) { \
165 if ((x = name##_from_string(rvalue)) < 0) { \
166 log_syntax(unit, LOG_ERR, filename, line, -x, \
167 msg ", ignoring: %s", rvalue); \
175 #define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
176 int function(GENERIC_PARSER_ARGS) { \
177 type **enums = data, x, *ys; \
178 _cleanup_free_ type *xs = NULL; \
179 const char *word, *state; \
187 xs = new0(type, 1); \
193 FOREACH_WORD(word, l, rvalue, state) { \
194 _cleanup_free_ char *en = NULL; \
197 en = strndup(word, l); \
201 if ((x = name##_from_string(en)) < 0) { \
202 log_syntax(unit, LOG_ERR, filename, line, \
203 -x, msg ", ignoring: %s", en); \
207 for (ys = xs; x != invalid && *ys != invalid; ys++) { \
209 log_syntax(unit, LOG_ERR, filename, \
211 "Duplicate entry, ignoring: %s", \
221 new_xs = realloc(xs, (++i + 1) * sizeof(type)); \
227 *(xs + i) = invalid; \