1 #ifndef SETTINGS_PARSER_H
2 #define SETTINGS_PARSER_H
3 
4 struct var_expand_table;
5 struct var_expand_func_table;
6 
7 #define SETTINGS_SEPARATOR '/'
8 #define SETTINGS_SEPARATOR_S "/"
9 
10 /* STR_VARS pointer begins with either of these initially. Before actually
11    using the variables all variables in all unexpanded strings need to be
12    expanded. Afterwards the string pointers should be increased to skip
13    the initial '1' so it'll be easy to use them. */
14 #define SETTING_STRVAR_UNEXPANDED "0"
15 #define SETTING_STRVAR_EXPANDED "1"
16 
17 /* When parsing streams, this character is translated to LF. */
18 #define SETTING_STREAM_LF_CHAR "\003"
19 
20 enum setting_type {
21 	SET_BOOL,
22 	SET_UINT,
23 	SET_UINT_OCT,
24 	SET_TIME,
25 	SET_TIME_MSECS,
26 	SET_SIZE,
27 	SET_IN_PORT, /* internet port */
28 	SET_STR,
29 	SET_STR_VARS, /* string with %variables */
30 	SET_ENUM,
31 	SET_DEFLIST, /* of type array_t */
32 	SET_DEFLIST_UNIQUE,
33 	SET_STRLIST, /* of type ARRAY_TYPE(const_string) */
34 	SET_ALIAS /* alias name for above setting definition */
35 };
36 enum setting_flags {
37 	SET_FLAG_HIDDEN = BIT(0),
38 };
39 #define SETTING_TYPE_IS_DEFLIST(type) \
40 	((type) == SET_DEFLIST || (type) == SET_DEFLIST_UNIQUE)
41 
42 #define SETTING_DEFINE_LIST_END { 0, 0, NULL, 0, NULL }
43 
44 struct setting_define {
45 	enum setting_type type;
46 	enum setting_flags flags;
47 	const char *key;
48 
49 	size_t offset;
50 	const struct setting_parser_info *list_info;
51 };
52 
53 #define SETTING_DEFINE_STRUCT_TYPE(_enum_type, _flags, _c_type, _key, _name, _struct_name) \
54 	{ .type = (_enum_type) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
55 		((_struct_name *)0)->_name, _c_type), \
56 	  .flags = _flags, .key = _key, \
57 	  .offset = offsetof(_struct_name, _name) }
58 
59 #define SETTING_DEFINE_STRUCT_BOOL(key, name, struct_name) \
60 	SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, 0, bool, key, name, struct_name)
61 #define SETTING_DEFINE_STRUCT_UINT(key, name, struct_name) \
62 	SETTING_DEFINE_STRUCT_TYPE(SET_UINT, 0, unsigned int, key, name, struct_name)
63 #define SETTING_DEFINE_STRUCT_UINT_OCT(key, name, struct_name) \
64 	SETTING_DEFINE_STRUCT_TYPE(SET_UINT_OCT, 0, unsigned int, key, name, struct_name)
65 #define SETTING_DEFINE_STRUCT_TIME(key, name, struct_name) \
66 	SETTING_DEFINE_STRUCT_TYPE(SET_TIME, 0, unsigned int, key, name, struct_name)
67 #define SETTING_DEFINE_STRUCT_TIME_MSECS(key, name, struct_name) \
68 	SETTING_DEFINE_STRUCT_TYPE(SET_TIME_MSECS, 0, unsigned int, key, name, struct_name)
69 #define SETTING_DEFINE_STRUCT_SIZE(key, name, struct_name) \
70 	SETTING_DEFINE_STRUCT_TYPE(SET_SIZE, 0, uoff_t, key, name, struct_name)
71 #define SETTING_DEFINE_STRUCT_IN_PORT(key, name, struct_name) \
72 	SETTING_DEFINE_STRUCT_TYPE(SET_IN_PORT, 0, in_port_t, key, name, struct_name)
73 #define SETTING_DEFINE_STRUCT_STR(key, name, struct_name) \
74 	SETTING_DEFINE_STRUCT_TYPE(SET_STR, 0, const char *, key, name, struct_name)
75 #define SETTING_DEFINE_STRUCT_STR_VARS(key, name, struct_name) \
76 	SETTING_DEFINE_STRUCT_TYPE(SET_STR_VARS, 0, const char *, key, name, struct_name)
77 #define SETTING_DEFINE_STRUCT_ENUM(key, name, struct_name) \
78 	SETTING_DEFINE_STRUCT_TYPE(SET_ENUM, 0, const char *, key, name, struct_name)
79 
80 #define SETTING_DEFINE_STRUCT_BOOL_HIDDEN(key, name, struct_name) \
81 	SETTING_DEFINE_STRUCT_TYPE(SET_BOOL, SET_FLAG_HIDDEN, bool, key, name, struct_name)
82 #define SETTING_DEFINE_STRUCT_UINT_HIDDEN(key, name, struct_name) \
83 	SETTING_DEFINE_STRUCT_TYPE(SET_UINT, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name)
84 #define SETTING_DEFINE_STRUCT_UINT_OCT_HIDDEN(key, name, struct_name) \
85 	SETTING_DEFINE_STRUCT_TYPE(SET_UINT_OCT, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name)
86 #define SETTING_DEFINE_STRUCT_TIME_HIDDEN(key, name, struct_name) \
87 	SETTING_DEFINE_STRUCT_TYPE(SET_TIME, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name)
88 #define SETTING_DEFINE_STRUCT_TIME_MSECS_HIDDEN(key, name, struct_name) \
89 	SETTING_DEFINE_STRUCT_TYPE(SET_TIME_MSECS, SET_FLAG_HIDDEN, unsigned int, key, name, struct_name)
90 #define SETTING_DEFINE_STRUCT_SIZE_HIDDEN(key, name, struct_name) \
91 	SETTING_DEFINE_STRUCT_TYPE(SET_SIZE, SET_FLAG_HIDDEN, uoff_t, key, name, struct_name)
92 #define SETTING_DEFINE_STRUCT_IN_PORT_HIDDEN(key, name, struct_name) \
93 	SETTING_DEFINE_STRUCT_TYPE(SET_IN_PORT, SET_FLAG_HIDDEN, in_port_t, key, name, struct_name)
94 #define SETTING_DEFINE_STRUCT_STR_HIDDEN(key, name, struct_name) \
95 	SETTING_DEFINE_STRUCT_TYPE(SET_STR, SET_FLAG_HIDDEN, const char *, key, name, struct_name)
96 #define SETTING_DEFINE_STRUCT_STR_VARS_HIDDEN(key, name, struct_name) \
97 	SETTING_DEFINE_STRUCT_TYPE(SET_STR_VARS, SET_FLAG_HIDDEN, const char *, key, name, struct_name)
98 #define SETTING_DEFINE_STRUCT_ENUM_HIDDEN(key, name, struct_name) \
99 	SETTING_DEFINE_STRUCT_TYPE(SET_ENUM, SET_FLAG_HIDDEN, const char *, key, name, struct_name)
100 
101 struct setting_parser_info {
102 	const char *module_name;
103 	const struct setting_define *defines;
104 	const void *defaults;
105 
106 	size_t type_offset;
107 	size_t struct_size;
108 
109 	size_t parent_offset;
110 	const struct setting_parser_info *parent;
111 
112 	bool (*check_func)(void *set, pool_t pool, const char **error_r);
113 	bool (*expand_check_func)(void *set, pool_t pool, const char **error_r);
114 	const struct setting_parser_info *const *dependencies;
115 	struct dynamic_settings_parser *dynamic_parsers;
116 
117 };
118 ARRAY_DEFINE_TYPE(setting_parser_info, struct setting_parser_info);
119 
120 /* name=NULL-terminated list of parsers. These follow the static settings.
121    After this list follows the actual settings. */
122 struct dynamic_settings_parser {
123 	const char *name;
124 	const struct setting_parser_info *info;
125 	size_t struct_offset;
126 };
127 ARRAY_DEFINE_TYPE(dynamic_settings_parser, struct dynamic_settings_parser);
128 
129 enum settings_parser_flags {
130 	SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS	= 0x01,
131 	SETTINGS_PARSER_FLAG_TRACK_CHANGES		= 0x02
132 };
133 
134 struct setting_parser_context;
135 
136 struct setting_parser_context *
137 settings_parser_init(pool_t set_pool, const struct setting_parser_info *root,
138 		     enum settings_parser_flags flags);
139 struct setting_parser_context *
140 settings_parser_init_list(pool_t set_pool,
141 			  const struct setting_parser_info *const *roots,
142 			  unsigned int count, enum settings_parser_flags flags);
143 void settings_parser_deinit(struct setting_parser_context **ctx);
144 
145 /* Return pointer to root setting structure. */
146 void *settings_parser_get(struct setting_parser_context *ctx);
147 /* If there are multiple roots, return a NULL-terminated list to all of
148    their settings. */
149 void **settings_parser_get_list(const struct setting_parser_context *ctx);
150 /* Like settings_parser_get(), but return change struct. */
151 void *settings_parser_get_changes(struct setting_parser_context *ctx);
152 /* Returns the setting parser's roots (same as given to init()). */
153 const struct setting_parser_info *const *
154 settings_parser_get_roots(const struct setting_parser_context *ctx);
155 
156 /* Return the last error. */
157 const char *settings_parser_get_error(struct setting_parser_context *ctx);
158 /* Return the parser info used for the previously parsed line. */
159 const struct setting_parser_info *
160 settings_parse_get_prev_info(struct setting_parser_context *ctx);
161 
162 /* Returns TRUE if the given key is a valid setting. */
163 bool settings_parse_is_valid_key(struct setting_parser_context *ctx,
164 				 const char *key);
165 /* If key is an alias, return the primary key name. If key exists, return key
166    itself. If key doesn't exist, return NULL. */
167 const char *settings_parse_unalias(struct setting_parser_context *ctx,
168 				   const char *key);
169 /* Returns pointer to value for a key, or NULL if not found. */
170 const void *
171 settings_parse_get_value(struct setting_parser_context *ctx,
172 			 const char *key, enum setting_type *type_r);
173 /* Returns TRUE if setting has been changed by this parser. */
174 bool settings_parse_is_changed(struct setting_parser_context *ctx,
175 			       const char *key);
176 /* Parse a single line. Returns 1 if OK, 0 if key is unknown, -1 if error. */
177 int settings_parse_line(struct setting_parser_context *ctx, const char *line);
178 /* Parse key/value pair. Returns 1 if OK, 0 if key is unknown, -1 if error. */
179 int settings_parse_keyvalue(struct setting_parser_context *ctx,
180 			    const char *key, const char *value);
181 /* Parse data already read in input stream. */
182 int settings_parse_stream(struct setting_parser_context *ctx,
183 			  struct istream *input);
184 /* Read data from input stream and parser it. returns -1 = error,
185    0 = done, 1 = not finished yet (stream is non-blocking) */
186 int settings_parse_stream_read(struct setting_parser_context *ctx,
187          		       struct istream *input);
188 /* Open file and parse it. */
189 int settings_parse_file(struct setting_parser_context *ctx,
190 			const char *path, size_t max_line_length);
191 int settings_parse_environ(struct setting_parser_context *ctx);
192 /* Execute the given binary and wait for it to return the configuration. */
193 int settings_parse_exec(struct setting_parser_context *ctx,
194 			const char *bin_path, const char *config_path,
195 			const char *service);
196 /* Call all check_func()s to see if currently parsed settings are valid. */
197 bool settings_parser_check(struct setting_parser_context *ctx, pool_t pool,
198 			   const char **error_r);
199 bool settings_check(const struct setting_parser_info *info, pool_t pool,
200 		    void *set, const char **error_r);
201 
202 /* While parsing values, specifies if STR_VARS strings are already expanded. */
203 void settings_parse_set_expanded(struct setting_parser_context *ctx,
204 				 bool is_expanded);
205 /* Mark all the parsed settings with given keys as being already expanded. */
206 void settings_parse_set_key_expanded(struct setting_parser_context *ctx,
207 				     pool_t pool, const char *key);
208 void settings_parse_set_keys_expanded(struct setting_parser_context *ctx,
209 				      pool_t pool, const char *const *keys);
210 /* Update variable string pointers to skip over the '1' or '0'.
211    This is mainly useful when you want to run settings_parser_check() without
212    actually knowing what the variables are. */
213 void settings_parse_var_skip(struct setting_parser_context *ctx);
214 /* Expand all unexpanded variables using the given table. Update the string
215    pointers so that they can be used without skipping over the '1'.
216    Returns the same as var_expand(). */
217 int settings_var_expand(const struct setting_parser_info *info,
218 			void *set, pool_t pool,
219 			const struct var_expand_table *table,
220 			const char **error_r);
221 int settings_var_expand_with_funcs(const struct setting_parser_info *info,
222 				   void *set, pool_t pool,
223 				   const struct var_expand_table *table,
224 				   const struct var_expand_func_table *func_table,
225 				   void *func_context, const char **error_r);
226 /* Go through all the settings and return the first one that has an unexpanded
227    setting containing the given %key. */
228 bool settings_vars_have_key(const struct setting_parser_info *info, void *set,
229 			    char var_key, const char *long_var_key,
230 			    const char **key_r, const char **value_r);
231 /* Duplicate the entire settings structure. */
232 void *settings_dup(const struct setting_parser_info *info,
233 		   const void *set, pool_t pool);
234 /* Same as settings_dup(), but assume that the old pointers can still be safely
235    used. This saves memory since strings don't have to be duplicated. */
236 void *settings_dup_with_pointers(const struct setting_parser_info *info,
237 				 const void *set, pool_t pool);
238 /* Duplicate the entire setting parser. */
239 struct setting_parser_context *
240 settings_parser_dup(const struct setting_parser_context *old_ctx,
241 		    pool_t new_pool);
242 
243 /* parsers is a name=NULL -terminated list. The parsers are appended as
244    dynamic_settings_list structures to their parent. All must have the same
245    parent. The new structures are allocated from the given pool. */
246 void settings_parser_info_update(pool_t pool,
247 				 struct setting_parser_info *parent,
248 				 const struct dynamic_settings_parser *parsers);
249 void settings_parser_dyn_update(pool_t pool,
250 				const struct setting_parser_info *const **roots,
251 				const struct dynamic_settings_parser *dyn_parsers);
252 
253 /* Return pointer to beginning of settings for given name, or NULL if there is
254    no such registered name. */
255 const void *settings_find_dynamic(const struct setting_parser_info *info,
256 				  const void *base_set, const char *name);
257 
258 /* Copy changed settings from src to dest. If conflict_key_r is not NULL and
259    both src and dest have changed the same setting, return -1 and set the
260    key name. If it's NULL, the old setting is kept.
261 
262    KLUDGE: For SET_STRLIST types if both source and destination have identical
263    keys, the duplicates in the source side are ignored. This is required to
264    make the current config code work correctly. */
265 int settings_parser_apply_changes(struct setting_parser_context *dest,
266 				  const struct setting_parser_context *src,
267 				  pool_t pool, const char **conflict_key_r);
268 
269 /* Return section name escaped */
270 const char *settings_section_escape(const char *name);
271 /* Parse time interval string, return as seconds. */
272 int settings_get_time(const char *str, unsigned int *secs_r,
273 		      const char **error_r);
274 /* Parse time interval string, return as milliseconds. */
275 int settings_get_time_msecs(const char *str, unsigned int *msecs_r,
276 			    const char **error_r);
277 /* Parse size string, return as bytes. */
278 int settings_get_size(const char *str, uoff_t *bytes_r,
279 		      const char **error_r);
280 
281 #endif
282