/src/dovecot/src/lib-settings/settings-parser.h
Line | Count | Source |
1 | | #ifndef SETTINGS_PARSER_H |
2 | | #define SETTINGS_PARSER_H |
3 | | |
4 | | #include "str-parse.h" |
5 | | #include "settings-consts.h" |
6 | | |
7 | | struct stat; |
8 | | struct var_expand_table; |
9 | | struct var_expand_provider; |
10 | | |
11 | 0 | #define SETTINGS_SEPARATOR '/' |
12 | | #define SETTINGS_SEPARATOR_S "/" |
13 | | |
14 | 0 | #define SETTINGS_FILTER_ARRAY_SEPARATORS ",\t " |
15 | | |
16 | 0 | #define SET_LIST_APPEND "+" |
17 | 0 | #define SET_LIST_REPLACE "$" |
18 | 0 | #define SET_LIST_CLEAR "." |
19 | | |
20 | | #define SET_FILE_INLINE_PREFIX "inline:" |
21 | | |
22 | | enum setting_type { |
23 | | SET_BOOL, |
24 | | SET_UINTMAX, |
25 | | SET_UINT, |
26 | | SET_UINT_OCT, |
27 | | SET_TIME, |
28 | | SET_TIME_MSECS, |
29 | | SET_SIZE, |
30 | | SET_IN_PORT, /* internet port */ |
31 | | SET_STR, /* string with %variables */ |
32 | | SET_STR_NOVARS, /* string explicitly without %variables */ |
33 | | SET_ENUM, |
34 | | SET_FILE, /* string: <path> [<LF> file contents] */ |
35 | | SET_STRLIST, /* of type ARRAY_TYPE(const_string) */ |
36 | | SET_BOOLLIST, /* of type ARRAY_TYPE(const_string) - guaranteed NULL-terminated */ |
37 | | SET_ALIAS, /* alias name for above setting definition */ |
38 | | SET_FILTER_NAME, |
39 | | SET_FILTER_ARRAY, |
40 | | }; |
41 | | enum setting_flags { |
42 | | SET_FLAG_HIDDEN = BIT(0), |
43 | | /* Used only for SETTING_DEFINE_LIST_END */ |
44 | | SET_FLAG_EOL = BIT(1), |
45 | | /* Setting is normalized as Unicode Normalization Form C (NFC) */ |
46 | | SET_FLAG_UNICODE_NFC = BIT(2), |
47 | | }; |
48 | | |
49 | | enum setting_apply_flags { |
50 | | /* Used when applying override settings (e.g. userdb or -o parameter) */ |
51 | | SETTING_APPLY_FLAG_OVERRIDE = BIT(0), |
52 | | /* SETTINGS_GET_FLAG_NO_EXPAND is being used. */ |
53 | | SETTING_APPLY_FLAG_NO_EXPAND = BIT(1), |
54 | | }; |
55 | | |
56 | | #define SETTING_DEFINE_LIST_END { 0, SET_FLAG_EOL, NULL, 0, NULL, NULL, NULL } |
57 | | |
58 | | struct setting_filter_array_order { |
59 | | const struct setting_parser_info *info; |
60 | | const char *field_name; |
61 | | bool reverse; |
62 | | }; |
63 | | |
64 | | struct setting_define { |
65 | | enum setting_type type; |
66 | | enum setting_flags flags; |
67 | | const char *key; |
68 | | |
69 | | size_t offset; |
70 | | const char *filter_array_field_name; |
71 | | const struct setting_filter_array_order *filter_array_order; |
72 | | const char *required_setting; |
73 | | }; |
74 | | |
75 | | #define SETTING_DEFINE_STRUCT_TYPE(_enum_type, _flags, _c_type, _key, _name, _struct_name) \ |
76 | | { .type = (_enum_type) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \ |
77 | | ((_struct_name *)0)->_name, _c_type), \ |
78 | | .flags = _flags, .key = _key, \ |
79 | | .offset = offsetof(_struct_name, _name) } |
80 | | |
81 | | #define SETTING_DEFINE_STRUCT_BOOL(key, name, struct_name) \ |
82 | | SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, 0, bool, key, name, struct_name) |
83 | | #define SETTING_DEFINE_STRUCT_UINTMAX(key, name, struct_name) \ |
84 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINTMAX, 0, uintmax_t, key, name, struct_name) |
85 | | #define SETTING_DEFINE_STRUCT_UINT(key, name, struct_name) \ |
86 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINT, 0, unsigned int, key, name, struct_name) |
87 | | #define SETTING_DEFINE_STRUCT_UINT_OCT(key, name, struct_name) \ |
88 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINT_OCT, 0, unsigned int, key, name, struct_name) |
89 | | #define SETTING_DEFINE_STRUCT_TIME(key, name, struct_name) \ |
90 | | SETTING_DEFINE_STRUCT_TYPE(SET_TIME, 0, unsigned int, key, name, struct_name) |
91 | | #define SETTING_DEFINE_STRUCT_TIME_MSECS(key, name, struct_name) \ |
92 | | SETTING_DEFINE_STRUCT_TYPE(SET_TIME_MSECS, 0, unsigned int, key, name, struct_name) |
93 | | #define SETTING_DEFINE_STRUCT_SIZE(key, name, struct_name) \ |
94 | | SETTING_DEFINE_STRUCT_TYPE(SET_SIZE, 0, uoff_t, key, name, struct_name) |
95 | | #define SETTING_DEFINE_STRUCT_IN_PORT(key, name, struct_name) \ |
96 | | SETTING_DEFINE_STRUCT_TYPE(SET_IN_PORT, 0, in_port_t, key, name, struct_name) |
97 | | #define SETTING_DEFINE_STRUCT_STR(key, name, struct_name) \ |
98 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR, 0, const char *, key, name, struct_name) |
99 | | #define SETTING_DEFINE_STRUCT_STR_NOVARS(key, name, struct_name) \ |
100 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR_NOVARS, 0, const char *, key, name, struct_name) |
101 | | #define SETTING_DEFINE_STRUCT_ENUM(key, name, struct_name) \ |
102 | | SETTING_DEFINE_STRUCT_TYPE(SET_ENUM, 0, const char *, key, name, struct_name) |
103 | | #define SETTING_DEFINE_STRUCT_FILE(key, name, struct_name) \ |
104 | | SETTING_DEFINE_STRUCT_TYPE(SET_FILE, 0, const char *, key, name, struct_name) |
105 | | #define SETTING_DEFINE_STRUCT_BOOLLIST(key, name, struct_name) \ |
106 | | SETTING_DEFINE_STRUCT_TYPE(SET_BOOLLIST, 0, ARRAY_TYPE(const_string), key, name, struct_name) |
107 | | #define SETTING_DEFINE_STRUCT_STRLIST(key, name, struct_name) \ |
108 | | SETTING_DEFINE_STRUCT_TYPE(SET_STRLIST, 0, ARRAY_TYPE(const_string), key, name, struct_name) |
109 | | |
110 | | #define SETTING_DEFINE_STRUCT_BOOL_HIDDEN(key, name, struct_name) \ |
111 | | SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, SET_FLAG_HIDDEN, bool, key, name, struct_name) |
112 | | #define SETTING_DEFINE_STRUCT_UINTMAX_HIDDEN(key, name, struct_name) \ |
113 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINTMAX, SET_FLAG_HIDDEN, uintmax_t, key, name, struct_name) |
114 | | #define SETTING_DEFINE_STRUCT_UINT_HIDDEN(key, name, struct_name) \ |
115 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINT, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name) |
116 | | #define SETTING_DEFINE_STRUCT_UINT_OCT_HIDDEN(key, name, struct_name) \ |
117 | | SETTING_DEFINE_STRUCT_TYPE(SET_UINT_OCT, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name) |
118 | | #define SETTING_DEFINE_STRUCT_TIME_HIDDEN(key, name, struct_name) \ |
119 | | SETTING_DEFINE_STRUCT_TYPE(SET_TIME, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name) |
120 | | #define SETTING_DEFINE_STRUCT_TIME_MSECS_HIDDEN(key, name, struct_name) \ |
121 | | SETTING_DEFINE_STRUCT_TYPE(SET_TIME_MSECS, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name) |
122 | | #define SETTING_DEFINE_STRUCT_SIZE_HIDDEN(key, name, struct_name) \ |
123 | | SETTING_DEFINE_STRUCT_TYPE(SET_SIZE, SET_FLAG_HIDDEN, uoff_t, key, name, struct_name) |
124 | | #define SETTING_DEFINE_STRUCT_IN_PORT_HIDDEN(key, name, struct_name) \ |
125 | | SETTING_DEFINE_STRUCT_TYPE(SET_IN_PORT, SET_FLAG_HIDDEN, in_port_t, key, name, struct_name) |
126 | | #define SETTING_DEFINE_STRUCT_STR_HIDDEN(key, name, struct_name) \ |
127 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR, SET_FLAG_HIDDEN, const char *, key, name, struct_name) |
128 | | #define SETTING_DEFINE_STRUCT_STR_NOVARS_HIDDEN(key, name, struct_name) \ |
129 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR_NOVARS, SET_FLAG_HIDDEN, const char *, key, name, struct_name) |
130 | | #define SETTING_DEFINE_STRUCT_ENUM_HIDDEN(key, name, struct_name) \ |
131 | | SETTING_DEFINE_STRUCT_TYPE(SET_ENUM, SET_FLAG_HIDDEN, const char *, key, name, struct_name) |
132 | | #define SETTING_DEFINE_STRUCT_FILE_HIDDEN(key, name, struct_name) \ |
133 | | SETTING_DEFINE_STRUCT_TYPE(SET_FILE, SET_FLAG_HIDDEN, const char *, key, name, struct_name) |
134 | | #define SETTING_DEFINE_STRUCT_BOOLLIST_HIDDEN(key, name, struct_name) \ |
135 | | SETTING_DEFINE_STRUCT_TYPE(SET_BOOLLIST, SET_FLAG_HIDDEN, ARRAY_TYPE(const_string), key, name, struct_name) |
136 | | #define SETTING_DEFINE_STRUCT_STRLIST_HIDDEN(key, name, struct_name) \ |
137 | | SETTING_DEFINE_STRUCT_TYPE(SET_STRLIST, SET_FLAG_HIDDEN, ARRAY_TYPE(const_string), key, name, struct_name) |
138 | | |
139 | | #define SETTING_DEFINE_STRUCT_STR_NFC(key, name, struct_name) \ |
140 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR, SET_FLAG_UNICODE_NFC, const char *, key, name, struct_name) |
141 | | #define SETTING_DEFINE_STRUCT_STR_NFC_NOVARS(key, name, struct_name) \ |
142 | | SETTING_DEFINE_STRUCT_TYPE(SET_STR_NOVARS, SET_FLAG_UNICODE_NFC, const char *, key, name, struct_name) |
143 | | |
144 | | struct settings_file { |
145 | | /* Path to the file. May be "" if the content is inlined. */ |
146 | | const char *path; |
147 | | /* File contents - always available. NULs inside the file are not |
148 | | supported. */ |
149 | | const char *content; |
150 | | }; |
151 | | |
152 | | struct setting_keyvalue { |
153 | | const char *key; |
154 | | const char *value; |
155 | | }; |
156 | | |
157 | | struct setting_parser_info { |
158 | | /* Unique name for the settings struct */ |
159 | | const char *name; |
160 | | /* If non-NULL, config process verifies whether this plugin actually |
161 | | exists on filesystem before exposing these settings. This allows |
162 | | for example the plugins in Dovecot core to be extracted into |
163 | | separate optional packages, even though they don't have individual |
164 | | settings plugins. */ |
165 | | const char *plugin_dependency; |
166 | | |
167 | | const struct setting_define *defines; |
168 | | const void *defaults; |
169 | | /* Add defaults via strings on top of the of defaults struct. */ |
170 | | const struct setting_keyvalue *default_settings; |
171 | | |
172 | | size_t struct_size; |
173 | | size_t pool_offset1; /* 1 + offset to pool_t field */ |
174 | | |
175 | | /* This is called for every setting that is parsed. *value is already |
176 | | the final pointer stored into the settings struct. If it's modified, |
177 | | it should usually be allocated from set->pool. */ |
178 | | bool (*setting_apply)(struct event *event, void *set, |
179 | | const char *key, const char **value, |
180 | | enum setting_apply_flags flags, const char **error_r); |
181 | | /* This is called after %variable expansion. */ |
182 | | bool (*check_func)(void *set, pool_t pool, const char **error_r); |
183 | | /* The event parameter can be used with settings_get*() to access other |
184 | | settings structs. */ |
185 | | bool (*ext_check_func)(struct event *event, void *set, pool_t pool, const char **error_r); |
186 | | |
187 | | }; |
188 | | ARRAY_DEFINE_TYPE(setting_parser_info, struct setting_parser_info); |
189 | | |
190 | | enum settings_parser_flags { |
191 | | SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS = 0x01, |
192 | | /* Filters are added in reverse order. New filters are inserted to the |
193 | | beginning of the array. */ |
194 | | SETTINGS_PARSER_FLAG_INSERT_FILTERS = 0x04, |
195 | | }; |
196 | | |
197 | | enum settings_binary { |
198 | | SETTINGS_BINARY_OTHER, |
199 | | SETTINGS_BINARY_CONFIG, |
200 | | SETTINGS_BINARY_DOVECONF |
201 | | }; |
202 | | |
203 | | struct setting_parser_context; |
204 | | |
205 | | /* If a string setting value has this pointer, it means the setting isn't |
206 | | actually known because it contained %{variables}. [ext_]check_func() can use |
207 | | this to not give early errors when the variable value isn't known. */ |
208 | | extern const char *set_value_unknown; |
209 | | |
210 | | /* This is set for ext_check_func(event) when config binary checking settings. |
211 | | In this case for example %variables aren't expanded, so ext_check_func() |
212 | | shouldn't fail if it does further settings_get*() calls that fail. */ |
213 | | #define SETTINGS_EVENT_NO_EXPAND "settings_event_no_expand" |
214 | | |
215 | | struct setting_parser_context * |
216 | | settings_parser_init(pool_t set_pool, const struct setting_parser_info *root, |
217 | | enum settings_parser_flags flags); |
218 | | void settings_parser_ref(struct setting_parser_context *ctx); |
219 | | void settings_parser_unref(struct setting_parser_context **ctx); |
220 | | |
221 | | /* Returns number of defines in info->defines */ |
222 | | unsigned int |
223 | | setting_parser_info_get_define_count(const struct setting_parser_info *info); |
224 | | /* Find a specific key from info and return its index number in the defines |
225 | | array. "list/key" will return the list's define. If the key is an |
226 | | alias, the primary key's index is returned. */ |
227 | | bool setting_parser_info_find_key(const struct setting_parser_info *info, |
228 | | const char *key, unsigned int *idx_r); |
229 | | |
230 | | /* Returns the current settings. */ |
231 | | void *settings_parser_get_set(const struct setting_parser_context *ctx); |
232 | | |
233 | | /* Return the last error. */ |
234 | | const char *settings_parser_get_error(struct setting_parser_context *ctx); |
235 | | |
236 | | /* Returns pointer to value for a key, or NULL if not found. */ |
237 | | const void * |
238 | | settings_parse_get_value(struct setting_parser_context *ctx, |
239 | | const char **key, enum setting_type *type_r); |
240 | | /* Parse key/value pair. Returns 1 if OK, 0 if key is unknown, -1 if error. */ |
241 | | int settings_parse_keyvalue(struct setting_parser_context *ctx, |
242 | | const char *key, const char *value); |
243 | | /* Parse key index/value pair. The key_idx points to the key in |
244 | | info->defines[]. The key string is still needed to support lists, which |
245 | | need the key in "list/key" format. Returns 0 if OK, -1 if error. */ |
246 | | int settings_parse_keyidx_value(struct setting_parser_context *ctx, |
247 | | unsigned int key_idx, const char *key, |
248 | | const char *value); |
249 | | /* Same as settings_parse_keyvalue(), but don't strdup() the value. The value |
250 | | pointer's validity must be enforced by the caller. */ |
251 | | int settings_parse_keyvalue_nodup(struct setting_parser_context *ctx, |
252 | | const char *key, const char *value); |
253 | | /* Same as settings_parse_keyidx_value(), but don't strdup() the value. |
254 | | The value pointer's validity must be enforced by the caller. */ |
255 | | int settings_parse_keyidx_value_nodup(struct setting_parser_context *ctx, |
256 | | unsigned int key_idx, const char *key, |
257 | | const char *value); |
258 | | /* Ignore any further attempts to add to the named list filter or boollist. */ |
259 | | void settings_parse_array_stop(struct setting_parser_context *ctx, |
260 | | unsigned int key_idx); |
261 | | /* Returns TRUE if list has the specific key. The key must NOT include the |
262 | | list/ prefix. */ |
263 | | bool settings_parse_list_has_key(struct setting_parser_context *ctx, |
264 | | unsigned int key_idx, |
265 | | const char *key_suffix); |
266 | | /* Call all check_func()s and ext_check_func()s to see if currently parsed |
267 | | settings are valid. */ |
268 | | bool settings_parser_check(struct setting_parser_context *ctx, pool_t pool, |
269 | | struct event *event, const char **error_r); |
270 | | bool settings_check(struct event *event, const struct setting_parser_info *info, |
271 | | pool_t pool, void *set, const char **error_r); |
272 | | |
273 | | /* Read a SET_FILE from the given path and write |
274 | | "<prefix><value_path>\n<contents>" to output_r. Returns 0 on success, |
275 | | -1 on error. */ |
276 | | int settings_parse_read_file(const char *path, const char *value_path, |
277 | | pool_t pool, struct stat *st_r, |
278 | | const char *prefix, const char **output_r, |
279 | | const char **error_r); |
280 | | int settings_parse_boollist_string(const char *value, pool_t pool, |
281 | | ARRAY_TYPE(const_string) *dest, |
282 | | const char **error_r); |
283 | | /* Returns the boollist array NULL-terminated. The list is actually always |
284 | | already NULL-terminated, but to avoid confusion with regular non-NULL |
285 | | terminated arrays, use this function instead. Also, it includes some sanity |
286 | | checks to try to make sure it's used only for boollists. */ |
287 | | const char *const *settings_boollist_get(const ARRAY_TYPE(const_string) *array); |
288 | | /* Finish array into a boollist type by adding NULL-termination and optional |
289 | | stop flag. If stop=TRUE, this indicates that the boollist replaces the full |
290 | | list instead of adding to it. The boollist can still be updated afterwards, |
291 | | as long as this function is called again after modifications. */ |
292 | | void settings_boollist_finish(ARRAY_TYPE(const_string) *array, bool stop); |
293 | | |
294 | | /* Checks if boollist is marked as replacing the full list */ |
295 | | bool settings_boollist_is_stopped(const ARRAY_TYPE(const_string) *array); |
296 | | /* Split the settings value into path and content. The path is allocated from |
297 | | the path_pool, while content points directly to the value string. */ |
298 | | void settings_file_get(const char *value, pool_t path_pool, |
299 | | struct settings_file *file_r); |
300 | | /* Returns TRUE if the settings value contains a non-empty path. The value |
301 | | is expected to be in the SET_FILE format (path LF content). */ |
302 | | bool settings_file_has_path(const char *value); |
303 | | /* Convert settings_file into a value (path LF content). The file path may be |
304 | | NULL, but the content must exist. */ |
305 | | const char *settings_file_get_value(pool_t pool, |
306 | | const struct settings_file *file); |
307 | | |
308 | | /* Return hash of all the settings, except the specified fields |
309 | | (NULL = no exceptions). */ |
310 | | unsigned int settings_hash(const struct setting_parser_info *info, |
311 | | const void *set, const char *const *except_fields); |
312 | | /* Returns TRUE if the two settings structs are equal, except for the |
313 | | specified fields (NULL = no exceptions). */ |
314 | | bool settings_equal(const struct setting_parser_info *info, |
315 | | const void *set1, const void *set2, |
316 | | const char *const *except_fields); |
317 | | |
318 | | /* Allocate a new instance of a settings struct filled with the default |
319 | | settings. */ |
320 | | void *settings_defaults_dup(pool_t pool, const struct setting_parser_info *info); |
321 | | |
322 | | /* Return section name escaped */ |
323 | | const char *settings_section_escape(const char *name); |
324 | | const char *settings_section_unescape(const char *name); |
325 | | |
326 | | static inline bool settings_value_is_unlimited(const char *value) |
327 | 0 | { |
328 | | /* allow both as input for all types */ |
329 | 0 | return strcmp(value, SET_VALUE_UNLIMITED) == 0 || |
330 | 0 | strcmp(value, SET_VALUE_INFINITE) == 0; |
331 | 0 | } Unexecuted instantiation: smtp-server-connection.c:settings_value_is_unlimited Unexecuted instantiation: smtp-server.c:settings_value_is_unlimited Unexecuted instantiation: smtp-server-cmd-starttls.c:settings_value_is_unlimited Unexecuted instantiation: iostream-ssl.c:settings_value_is_unlimited Unexecuted instantiation: iostream-ssl-context-cache.c:settings_value_is_unlimited Unexecuted instantiation: ssl-settings.c:settings_value_is_unlimited Unexecuted instantiation: settings.c:settings_value_is_unlimited Unexecuted instantiation: settings-parser.c:settings_value_is_unlimited |
332 | | |
333 | | void settings_set_config_binary(enum settings_binary binary); |
334 | | enum settings_binary settings_get_config_binary(void); |
335 | | |
336 | | #endif |