1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup
36 * @ingroup
37 * @brief
38 *
39 * @{
40 */
41
42 #pragma once
43
44 #include <stddef.h>
45
46 #include <dnscore/output_stream.h>
47 #include <dnscore/input_stream.h>
48 #include <dnscore/host_address.h>
49 #include <dnscore/ptr_vector.h>
50 #include <dnscore/cmdline.h>
51
52 /*
53 Each section/container descriptor is registered.
54
55 config section descriptor -------> target base (ie: g_config)
56 |
57 V
58 config table descriptor vtbl -----> callbacks (init, start, stop, finalise, ...)
59 |
60 V
61 table descriptor (BEGIN/END, names, offsets in target base, setters)
62 */
63
64 #define CONFIG_ERROR_BASE 0x800C0000
65 #define CONFIG_ERROR_CODE(code_) ((s32)(CONFIG_ERROR_BASE+(code_)))
66
67 // Bugs in the program
68 #define CONFIG_SECTION_ALREADY_REGISTERED CONFIG_ERROR_CODE(0xff01)
69 #define CONFIG_ALIAS_CHAIN_TOO_BIG CONFIG_ERROR_CODE(0xff02)
70 // Parsing issues
71 #define CONFIG_PARSE_SECTION_TAG_NOT_CLOSED CONFIG_ERROR_CODE(0x0001)
72 #define CONFIG_PARSE_UNEXPECTED_SECTION_OPEN CONFIG_ERROR_CODE(0x0002)
73 #define CONFIG_PARSE_UNEXPECTED_SECTION_CLOSE CONFIG_ERROR_CODE(0x0003)
74 #define CONFIG_PARSE_CLOSED_WRONG_SECTION CONFIG_ERROR_CODE(0x0004)
75 #define CONFIG_PARSE_SECTION_TAG_TOO_SMALL CONFIG_ERROR_CODE(0x0005)
76 #define CONFIG_PARSE_INCLUDE_EXPECTED_FILE_PATH CONFIG_ERROR_CODE(0x0006)
77 #define CONFIG_PARSE_UNKNOWN_KEYWORD CONFIG_ERROR_CODE(0x0007)
78 #define CONFIG_PARSE_EXPECTED_VALUE CONFIG_ERROR_CODE(0x0008)
79 // Content issues
80 #define CONFIG_UNKNOWN_SETTING CONFIG_ERROR_CODE(0x0011)
81 #define CONFIG_VALUE_OUT_OF_RANGE CONFIG_ERROR_CODE(0x0012)
82 #define CONFIG_FILE_PATH_TOO_BIG CONFIG_ERROR_CODE(0x0013)
83 #define CONFIG_BAD_UID CONFIG_ERROR_CODE(0x0014)
84 #define CONFIG_BAD_GID CONFIG_ERROR_CODE(0x0015)
85 #define CONFIG_TEXT_LENGHT_TOO_BIG CONFIG_ERROR_CODE(0x0016)
86 #define CONFIG_ARRAY_SIZE_TOO_BIG CONFIG_ERROR_CODE(0x0017)
87
88 // Logger config specific issues
89 #define CONFIG_LOGGER_HANDLE_ALREADY_DEFINED CONFIG_ERROR_CODE(0x1001)
90 #define CONFIG_LOGGER_INVALID_DEBUGLEVEL CONFIG_ERROR_CODE(0x1002)
91
92 // TSIG key config specific issues
93 #define CONFIG_KEY_INCOMPLETE_KEY CONFIG_ERROR_CODE(0x2001)
94 #define CONFIG_KEY_UNSUPPORTED_ALGORITHM CONFIG_ERROR_CODE(0x2002)
95
96 /*
97 #define CONFIG_LOGGER_INVALID_DEBUGLEVEL CONFIG_ERROR_CODE(0x0001)
98 */
99
100 #define CONFIG_TABLE_SOURCE_NONE 0
101 #define CONFIG_TABLE_SOURCE_DEFAULT 1
102 #define CONFIG_TABLE_SOURCE_CONFIGURATION_FILE 2
103 #define CONFIG_TABLE_SOURCE_COMMAND_LINE 3
104
105 #define CONFIG_HOST_LIST_FLAGS_IPV4 0x01
106 #define CONFIG_HOST_LIST_FLAGS_IPV6 0x02
107 #define CONFIG_HOST_LIST_FLAGS_FQDN 0x04
108 #define CONFIG_HOST_LIST_FLAGS_PORT 0x08
109 #define CONFIG_HOST_LIST_FLAGS_TSIG 0x10
110 #define CONFIG_HOST_LIST_FLAGS_APPEND 0x20
111
112 #define CONFIG_HOST_LIST_FLAGS_DEFAULT (CONFIG_HOST_LIST_FLAGS_IPV4 | CONFIG_HOST_LIST_FLAGS_IPV6 | CONFIG_HOST_LIST_FLAGS_PORT | CONFIG_HOST_LIST_FLAGS_TSIG)
113
114 #define CONFIG_FLAG_ON "1"
115 #define CONFIG_FLAG_OFF "0"
116
117 #define CONFIG_SOURCE_NONE 0
118 #define CONFIG_SOURCE_DEFAULT 1
119 #define CONFIG_SOURCE_FILE 128
120 #define CONFIG_SOURCE_CMDLINE 250
121 #define CONFIG_SOURCE_HIGHEST 255
122
123 #define CONFIG_SETTINGS_DEBUG 0
124
125 #define CONFIG_FIELD_ALLOCATION_DIRECT 0 // direct value
126 #define CONFIG_FIELD_ALLOCATION_MALLOC 1 // mallocated value
127 #define CONFIG_FIELD_ALLOCATION_ZALLOC 2 // zallocated value
128
129 /**
130 * This union covers 64 bits
131 * Meant to be used to store different parameters
132 */
133
134 union anytype_u
135 {
136 /* DO NOT ADD THIS : bool _bool; */
137 intptr _intptr;
138 u8 _u8;
139 u16 _u16;
140 u32 _u32;
141 u64 _u64;
142 u8 _8u8[8];
143 u16 _4u16[4];
144 u32 _2u32[2];
145 s8 _s8;
146 s16 _s16;
147 s32 _s32;
148 s64 _s64;
149 s8 _8s8[8];
150 s16 _4s16[4];
151 s32 _2s32[2];
152 callback_function *void_callback;
153 result_callback_function *result_callback;
154 void* _voidp;
155 char* _charp;
156 u8* _u8p;
157 };
158
159 typedef union anytype_u anytype;
160
161
162
163 typedef ya_result config_set_field_function(const char*, void*, const anytype);
164
165 struct config_section_descriptor_s;
166
167 /**
168 * name is the name of the key, expected in the config file
169 * field_offset is the offset of the value from the beginning of the target struct
170 * setter is the function able to parse the value of the key and store it at target + offset
171 * default_value_string is the string containing the default value for the key
172 * function_specific is a parameter given to the setter. The meaning is different for each setter.
173 * source is the level that wrote the current value in the table
174 */
175
176 struct config_table_descriptor_item_s
177 {
178 const char *name;
179 size_t field_offset;
180 config_set_field_function *setter;
181 const char *default_value_string;
182 anytype function_specific;
183 size_t expected_size;
184 size_t field_size;
185 u8 source;
186 u8 allocation_mode;
187 // help text
188 };
189
190 typedef struct config_table_descriptor_item_s config_table_descriptor_item_s;
191
192 typedef ya_result config_section_set_wild_method(struct config_section_descriptor_s *, const char *key, const char *value);
193 typedef ya_result config_section_print_wild_method(const struct config_section_descriptor_s *, output_stream *os, const char *key);
194
195 typedef ya_result config_section_init_method(struct config_section_descriptor_s *);
196 typedef ya_result config_section_start_method(struct config_section_descriptor_s *);
197 typedef ya_result config_section_stop_method(struct config_section_descriptor_s *);
198 typedef ya_result config_section_postprocess_method(struct config_section_descriptor_s *);
199 typedef ya_result config_section_finalize_method(struct config_section_descriptor_s *);
200
201 #define CFGSVTBL_TAG 0x42545653474643
202
203 struct config_section_descriptor_vtbl_s
204 {
205 /// section name
206 const char *name; // the table name
207 config_table_descriptor_item_s *table; // the descriptor for the table (static fields)
208
209 config_section_set_wild_method *set_wild; // sets an undefined (dynamic) field
210 config_section_print_wild_method *print_wild; // prints an undefined (dynamic) field
211
212 config_section_init_method *init; // initialises
213 config_section_start_method *start; // called when a section starts
214 config_section_stop_method *stop; // called when a section stops
215 config_section_postprocess_method *postprocess; // called after the section has been processed
216 config_section_finalize_method *finalise; // finishes, deletes all memory for this section, this vtbl included (if needed)
217 };
218
219 typedef struct config_section_descriptor_vtbl_s config_section_descriptor_vtbl_s;
220
221 #define CFGSDESC_TAG 0x4353454453474643
222
223 struct config_section_descriptor_s
224 {
225 void *base; // base of the structure to fill up
226 const config_section_descriptor_vtbl_s *vtbl;
227 };
228
229 typedef struct config_section_descriptor_s config_section_descriptor_s;
230
231 /**
232 * Here are the helper macro used to define the fields in the structure
233 *
234 * The definition of the table always be done like this:
235 *
236 * struct my_struct_type
237 * {
238 * u32 field_name_in_my_struct_type;
239 * };
240 *
241 * typedef struct my_struct_type my_struct_type;
242 *
243 * #define CONFIG_TYPE my_struct_type
244 * CONFIG_BEGIN(my_struct_type_table_desc)
245 * CONFIG_U32(field_name_in_my_struct_type,default_value_in_text_form)
246 * CONFIG_END(my_struct_type_table_desc)
247 * #undef CONFIG_TYPE
248 *
249 *
250 */
251
252 #undef CONFIG_TYPE /* please_define_me */
253
254 #define CONFIG_BEGIN(name_) static /* DO NOT const */ config_table_descriptor_item_s name_[] = {
255 #define CONFIG_BOOL(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_bool, defaultvalue_,{._intptr=0}, sizeof(bool), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
256 #define CONFIG_FLAG8(fieldname_,defaultvalue_, realfieldname_, mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag8, defaultvalue_,{(u8)(mask_)}, sizeof(u8), sizeof(u8), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
257 #define CONFIG_FLAG16(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag16, defaultvalue_,{(u16)(mask_)}, sizeof(u16), sizeof(u16), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
258 #define CONFIG_FLAG32(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag32, defaultvalue_,{(u32)(mask_)}, sizeof(u32), sizeof(u32), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
259 #define CONFIG_FLAG64(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag64, defaultvalue_,{(u64)(mask_)}, sizeof(u64), sizeof(u64), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
260 #define CONFIG_U64(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u64, defaultvalue_,{._intptr=0}, sizeof(u64), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
261 #define CONFIG_U32(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u32, defaultvalue_,{._intptr=0}, sizeof(u32), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
262 #define CONFIG_S32(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_s32, defaultvalue_,{._intptr=0}, sizeof(u32), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
263 #define CONFIG_U32_RANGE(fieldname_,defaultvalue_,min_,max_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u32_range, defaultvalue_,{._2u32={(min_),(max_)}}, sizeof(u32), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
264 #define CONFIG_U32_CLAMP(fieldname_,defaultvalue_,min_,max_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u32_clamp, defaultvalue_,{._2u32={(min_),(max_)}}, sizeof(u32), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
265 #define CONFIG_U16(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u16, defaultvalue_,{._intptr=0}, sizeof(u16), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
266 #define CONFIG_DNS_TYPE(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnstype, defaultvalue_,{._intptr=0}, sizeof(u16), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
267 #define CONFIG_DNS_CLASS(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnsclass, defaultvalue_,{._intptr=0}, sizeof(u16), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
268 #define CONFIG_U8(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u8, defaultvalue_,{._intptr=0}, sizeof(u8), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
269 #define CONFIG_DNSKEY_ALGORITHM(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnskey_algorithm, defaultvalue_,{._intptr=0}, sizeof(u8), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
270 #define CONFIG_U8_INC(fieldname_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_inc_u8, 0,{._intptr=0}, sizeof(u8), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
271 #define CONFIG_STRING(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_string, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
272 #define CONFIG_STRING_COPY(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_string_copy, defaultvalue_,{._u32=(sizeof(((CONFIG_TYPE*)NULL)->fieldname_))}, sizeof(((CONFIG_TYPE*)NULL)->fieldname_), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
273 #define CONFIG_STRING_ARRAY(fieldname_,default_value_,max_size_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_append_string_array_item, default_value_,{._u32=(max_size_)}, sizeof(ptr_vector), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
274 #define CONFIG_PASSWORD(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_password, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
275 #define CONFIG_FQDN(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_fqdn, defaultvalue_,{._intptr=0}, sizeof(u8*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_MALLOC },
276 #define CONFIG_PATH(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_path, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
277 #define CONFIG_CHROOT(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_chroot, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
278 #define CONFIG_LOGPATH(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_logpath, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
279 #define CONFIG_FILE(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_file, defaultvalue_,{._intptr=0}, sizeof(char*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
280 #define CONFIG_UID(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_uid_t, defaultvalue_,{._intptr=0}, sizeof(uid_t), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
281 #define CONFIG_GID(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_gid_t, defaultvalue_,{._intptr=0}, sizeof(gid_t), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
282 //#define CONFIG_ACL(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, ac) + offsetof(access_control,fieldname_), (config_set_field_function*)config_set_acl_item, defaultvalue_,{._intptr=0}, sizeof(), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
283 //#define CONFIG_ACL_FILTER(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_acl_item, defaultvalue_,{._intptr=0}, sizeof(), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
284 //#define CONFIG_LIST_ITEM(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_add_list_item, defaultvalue_,{._intptr=0}, sizeof(), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
285 #define CONFIG_ENUM(fieldname_,defaultvalue_,enumtable_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_enum_value, defaultvalue_, {(intptr)(enumtable_)}, sizeof(u32), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
286 //#define CONFIG_ENUM8(fieldname_,defaultvalue_,enumtable_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_enum8_value, defaultvalue_, {(intptr)enumtable_}, sizeof(u8), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
287 #define CONFIG_HOST_LIST(fieldname_,defaultvalue_) {#fieldname_, offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_host_list, defaultvalue_,{._8u8={CONFIG_HOST_LIST_FLAGS_DEFAULT,255,0,0,0,0,0,0}}, sizeof(host_address*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
288 #define CONFIG_HOST_LIST_EX(fieldname_,defaultvalue_,flags_,host_list_max_) {#fieldname_, offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_host_list, defaultvalue_,{._8u8={(flags_),(host_list_max_),0,0,0,0,0,0}}, sizeof(host_address*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
289 #define CONFIG_BYTES(fieldname_,defaultvalue_,maxsize_) {#fieldname_, offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_bytes, defaultvalue_, {maxsize_}, maxsize_, sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
290 //#define CONFIG_DNSSEC(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnssec, defaultvalue_,{._intptr=0}, sizeof(), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
291 #define CONFIG_TSIG_ITEM(fieldname_,defaultvalue_) {#fieldname_, offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_tsig_item, defaultvalue_, {._intptr=0}, sizeof(struct tsig_item*), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
292 #define CONFIG_OBSOLETE(fieldname_) {#fieldname_,0, (config_set_field_function*)config_set_obsolete, NULL,{._intptr=0}, 0, 0, CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
293
294 #define CONFIG_ALIAS(fieldname_, aliasedname_) {#fieldname_, 0, NULL, #aliasedname_, {._intptr=0}, 0, 0, CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT},
295 /*#define CONFIG_CATEGORY(fieldname_, category_) {#fieldname_, 0, NULL, NULL, #category},*/
296
297 #define CONFIG_END(name_) {NULL,0,NULL,NULL, {._intptr=0}, 0, 0, CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT} }; // name_
298
299 struct tsig_item;
300
301 ya_result config_set_bool(const char *value, bool *dest, const anytype notused);
302 ya_result config_set_flag8(const char *value, u8 *dest, const anytype mask8);
303 ya_result config_set_flag16(const char *value, u16 *dest, const anytype mask16);
304 ya_result config_set_flag32(const char *value, u32 *dest, const anytype mask32);
305 ya_result config_set_flag64(const char *value, u64 *dest, const anytype mask64);
306 ya_result config_set_u64(const char *value,u64 *dest, const anytype notused);
307 ya_result config_set_u32(const char *value,u32 *dest, const anytype notused);
308 ya_result config_set_s32(const char *value,s32 *dest, const anytype notused);
309 ya_result config_set_u32_range(const char *value,u32 *dest, const anytype min_max);
310 ya_result config_set_u16(const char *value,u16 *dest, const anytype notused);
311 ya_result config_set_u8(const char *value,u8 *dest, const anytype notused);
312 ya_result config_inc_u8(const char *value_notused,u8 *dest, const anytype notused);
313 ya_result config_set_dnskey_algorithm(const char *value, u8 *dest, const anytype notused);
314 ya_result config_set_string(const char *value, char **dest, const anytype notused);
315 ya_result config_set_string_copy(const char *value, char *dest, const anytype maxlen);
316 ya_result config_append_string_array_item(const char *value, ptr_vector *dest, const anytype maxsize);
317 ya_result config_set_password(const char *value, char **dest, const anytype notused);
318 ya_result config_set_fqdn(const char *value, u8 **dest, const anytype notused);
319 ya_result config_set_path(const char *value, char **dest, const anytype notused);
320 ya_result config_set_chroot(const char *value, char **dest, const anytype notused);
321 ya_result config_set_logpath(const char *value, char **dest, const anytype notused);
322 ya_result config_set_file(const char *value, char **dest, const anytype notused);
323 ya_result config_set_uid_t(const char *value, uid_t *dest, const anytype notused);
324 ya_result config_set_gid_t(const char *value, gid_t *dest, const anytype notused);
325 ya_result config_set_dnstype(const char *value, u16 *dest, const anytype notused);
326 ya_result config_set_dnsclass(const char *value, u16 *dest, const anytype notused);
327 ya_result config_set_enum_value(const char *value, u32 *dest, const anytype enum_value_name_table);
328 ya_result config_set_enum8_value(const char *value, u8 *dest, const anytype enum_value_name_table);
329 ya_result config_set_host_list(const char *value, host_address **dest, const anytype notused);
330 ya_result config_set_bytes(const char *value, void *dest, const anytype sizeoftarget);
331 ya_result config_set_tsig_item(const char *value, struct tsig_item **dest, const anytype notused);
332 ya_result config_set_obsolete(const char *value, void *dest, const anytype sizeoftarget);
333
334 // life of the config processing
335
336 void config_init_error_codes();
337
338 struct config_error_s
339 {
340 const char *variable_name;
341 u32 line_number;
342 bool has_content;
343 char line[256];
344 char file[PATH_MAX];
345 };
346
347 typedef struct config_error_s config_error_s;
348
config_error_reset(config_error_s * cfgerr)349 static inline void config_error_reset(config_error_s* cfgerr)
350 {
351 if(cfgerr != NULL)
352 {
353 cfgerr->variable_name = "";
354 cfgerr->line_number = 0;
355 cfgerr->has_content = FALSE;
356 cfgerr->line[0] = '\0';
357 cfgerr->file[0] = '\0';
358 }
359 }
360
361 #define CONFIG_ERROR_INITIALISER { NULL, 0, "?", "?"}
362
363 struct config_source_s;
364
365 typedef ya_result config_source_provider_callback_function(struct config_source_s *source, input_stream *out_source, config_error_s *cfgerr);
366
367 struct config_source_file_name_s
368 {
369 const char* name;
370 };
371
372 struct config_source_buffer_s
373 {
374 const char* text;
375 u32 size;
376 };
377
378 /**
379 * An help tool to register many sources at once
380 */
381
382 struct config_source_s
383 {
384 config_source_provider_callback_function *get_source;
385 const char *name;
386 const char *__class__;
387 union
388 {
389 struct config_source_file_name_s file_name;
390 struct config_source_buffer_s buffer;
391 } source;
392 u8 level;
393 };
394
395 #ifdef TODO
396 struct config_s
397 {
398 u32_set section_descriptor_set = U32_SET_EMPTY;
399 }:
400 #endif
401
402 ya_result config_init();
403
404 /**
405 * Configuration:
406 *
407 * priority : the lowest value, the fastest to be parsed
408 * negative value : choose
409 *
410 * level : ex: 0 for none, 1 for default, 2 for config, 3 for command line
411 * command line has priority on everything else
412 */
413
414 /**
415 * Gets the current source level
416 * @return the current source level
417 */
418
419 u8 config_get_source();
420
421 /**
422 * Sets the current source level
423 *
424 * @param l the current source level
425 */
426
427 void config_set_source(u8 l);
428
429 /**
430 * If the source level has been parsed, automatically fill the default values
431 * for fields that are not set yet.
432 *
433 * @return after what level do we automatically set the default values in the container
434 */
435
436 u8 config_get_autodefault_after_source();
437
438 /**
439 * If the source level has been parsed, automatically fill the default values
440 * for fields that are not set yet.
441 *
442 * @param l after what level do we automatically set the default values in the container ?
443 */
444
445 void config_set_autodefault_after_source(u8 l); // if a configuration is read at this level, the default is automatically applied after
446
447 /**
448 * Gets the default source level
449 *
450 * @return the default source level
451 */
452
453 u8 config_get_default_source();
454
455 /**
456 * Sets the default source level (default = 1)
457 *
458 * @param l the default source level
459 */
460
461 void config_set_default_source(u8 l); // this level is meant for default (1)
462
463 #define CONFIG_CALLBACK_RESULT_CONTINUE 0
464 #define CONFIG_CALLBACK_RESULT_STOP 1
465
466 typedef ya_result config_callback_function(const char *section_name, int section_index);
467
468 /**
469 * Adds a callback called when a section has been read
470 *
471 * @param section_name the name of the section
472 * @param on_section_read the function to call
473 *
474 * * @return continue, stop or an error code to fail
475 */
476
477 ya_result config_add_on_section_read_callback(const char *section_name, config_callback_function *on_section_read);
478
479 /**
480 * Removes a callback called when a section has been read
481 *
482 * @param section_name the name of the section
483 * @param on_section_read the function to call
484 *
485 * @return continue, stop or an error code to fail
486 */
487
488 ya_result config_remove_on_section_read_callback(const char *section_name, config_callback_function *on_section_read);
489
490 /**
491 * Registers a descriptor at the given priority
492 *
493 * @param section_descritor config descriptor
494 * @param priority config priority
495 *
496 * @return an error code
497 */
498
499 ya_result config_register(config_section_descriptor_s *section_descritor, s32 priority);
500
501 ya_result config_register_const(const config_section_descriptor_s *section_descriptor, s32 priority);
502
503 ya_result config_unregister(config_section_descriptor_s *section_descriptor);
504
505 config_section_descriptor_s *config_unregister_by_name(const char *name);
506
507 /**
508 *
509 * Reads matching section/containers from a file on disk
510 *
511 * @param configuration_file_path the file path
512 * @param cfgerr error handling structure (can be NULL)
513 * @param section_name the name to match, or if NULL : all sections
514 *
515 * @return an error code
516 */
517
518 ya_result config_read_section(const char *configuration_file_path, config_error_s *cfgerr, const char *section_name);
519
520 /**
521 * Reads all sections/containers from a file
522 *
523 * @param configuration_file_path the file path
524 * @param cfgerr if not NULL, the error reporting structure
525 *
526 * @return an error code
527 */
528
529 ya_result config_read(const char *configuration_file_path, config_error_s *cfgerr);
530
531 /**
532 * Reads all sections/containers from a buffer
533 *
534 * @param buffer the text buffer
535 * @param buffer_len the text buffer length
536 * @param buffer_name the name of the buffer for error reporting
537 * @param cfgerr if not NULL, the error reporting structure
538 *
539 * @return an error code
540 */
541
542 ya_result config_read_from_buffer(const char *buffer, u32 buffer_len, const char *buffer_name, config_error_s *cfgerr);
543
544 /**
545 * Sets a text buffer in a source
546 *
547 * @param source the source struct to initialise
548 * @param name the name of the source
549 * @param level the level of the source
550 * @param buffer text for the source
551 * @param buffer_len text length for the source
552 */
553
554 void config_source_set_buffer(struct config_source_s *source, const char *name, u8 level, const char *buffer, u32 buffer_len);
555
556 /**
557 * Sets a file in a source
558 *
559 * @param source the source struct to initialise
560 * @param name the name of the file
561 * @param level the level of the source
562 */
563
564 void config_source_set_file(struct config_source_s *source, const char *name, u8 level);
565
566 ya_result config_source_set_commandline(struct config_source_s *source, const cmdline_desc_s *cmdline, int argc, char **argv);
567
568 /**
569 * Read all sources from a table
570 *
571 * @param sources a pointer to the first source
572 * @param sources_count the number of sources
573 * @param cfgerr if not NULL, the error reporting structure
574 *
575 * @return an error code
576 */
577
578 ya_result config_read_from_sources(struct config_source_s *sources, u32 sources_count, config_error_s *cfgerr);
579
580 /**
581 * Applies default values to uninitialised fields. * @param cfgerr
582 *
583 * @param cfgerr if not NULL, the error reporting structure
584 *
585 * @return an error code
586 */
587
588 ya_result config_set_default(config_error_s *cfgerr);
589
590 /**
591 * Gets the section descriptor for the section/container name
592 *
593 * @param name the name of the section descriptor
594 *
595 * @return a pointer to the section descriptor or NULL if not found
596 */
597
598 config_section_descriptor_s *config_section_get_descriptor(const char *name);
599
600 /**
601 * Sets the table default values
602 *
603 * @param section_descriptor the descriptor to use (points to the table)
604 * @param cfgerr if not NULL, the error reporting structure
605 *
606 * @return an error code
607 */
608
609 ya_result config_set_section_default(config_section_descriptor_s *section_descriptor, config_error_s *cfgerr);
610
611
612 /**
613 * Sets the key to a value
614 * Source level is taken into account.
615 * ie: config_value_set(&yadifa_config_main_desc, "daemon", "on");
616 *
617 * @param section_descriptor the descriptor pointing to the table
618 * @param key the key to set
619 * @param value to value to set it to
620 * @param cfgerr a structure that contains details about an error
621 *
622 * @return an error code
623 */
624
625 ya_result config_value_set(config_section_descriptor_s *section_descriptor, const char *key, const char *value, config_error_s *cfgerr);
626
627 ya_result config_source_set_by_target(config_section_descriptor_s *section_descriptor, void *target_ptr);
628
629 /**
630 *
631 * Sets the key of the section/container to its default value
632 *
633 * @param section_name name of the section
634 * @param name key of the value
635 * @param cfgerr if not NULL, the error reporting structure
636 *
637 * @return an error code
638 */
639
640 ya_result config_value_set_to_default(const char *section_name, const char *name, config_error_s *cfgerr);
641
642 /**
643 *
644 * Returns the source of a value from the given section/container
645 *
646 * Look at CONFIG_SOURCE_* defines above for the predefined sources.
647 *
648 * @param section_name name of the section
649 * @param name key of the value
650 *
651 * @return the source index or an error code
652 */
653
654 ya_result config_value_get_source(const char *section_name, const char *name);
655
656 typedef bool config_section_struct_type_handler(output_stream *os, const char *name, void *ptr);
657
658 bool config_section_struct_register_type_handler(config_set_field_function* setter, config_section_struct_type_handler *handler);
659
660 /**
661 *
662 * Prints the content of every supported types of the table using the descriptor
663 *
664 * @param section_descriptor the descriptor
665 * @param os where to print to
666 */
667
668 void config_section_print(const config_section_descriptor_s *section_descriptor, output_stream *os);
669
670 /**
671 *
672 * Prints the content of every supported types of the table using the given descriptor on the given struct
673 *
674 * @param section_descriptor the descriptor
675 * @param a pointer to the config struct base
676 * @param os where to print to
677 */
678
679 void config_section_struct_print(const config_section_descriptor_s *section_descriptor, const void* configbase, output_stream *os);
680
681 /**
682 *
683 * Gets the index of the key on the table
684 *
685 * @param table a config table
686 * @param name the field key name
687 *
688 * @return an error code
689 */
690
691 ya_result config_item_index_get(const config_table_descriptor_item_s *table, const char *name);
692
693 /**
694 * Prints the config to the output stream
695 *
696 * @param os the output stream
697 */
698
699 void config_print(output_stream *os);
700
701 /**
702 * Call the postproces callback on the registered tables
703 */
704
705 ya_result config_postprocess();
706
707 /**
708 * Call the finalise callback on the registered tables
709 *
710 */
711
712 ya_result config_finalize();
713
714 // helpers
715
716 typedef void *config_section_struct_collection_get_next_method(void *previous_data_struct);
717
718 /**
719 *
720 * Registers a struct with its descriptor and name, for configuration.
721 *
722 * @param name name of the struct
723 * @param table table describing the struct
724 * @param data_struct pointer to the struct
725 * @param priority priority level (order of read)
726 *
727 * @return an error code
728 */
729
730 ya_result config_register_struct(const char *name, config_table_descriptor_item_s *table, void *data_struct, s32 priority);
731
732 void* config_unregister_struct(const char *name, const config_table_descriptor_item_s *table);
733
734 /**
735 *
736 * Registers the logger configuration.
737 *
738 * @note logger_handle_create("handle-name",logger_handle_for_handle_name_ptr_ptr) MUST be called
739 * before the config_read is done
740 *
741 * @param null_or_channels_name
742 * @param null_or_loggers_name
743 * @param priority
744 *
745 * @return an error code
746 */
747
748 ya_result config_register_logger(const char *null_or_channels_name, const char *null_or_loggers_name, s32 priority);
749
750 /**
751 * Returns TRUE iff any logging section has been found.
752 *
753 * @return TRUE iff any logging section has been found.
754 */
755
756 bool config_logger_isconfigured();
757
758 /**
759 * Clears the logger-configured flag
760 */
761
762 void config_logger_clearconfigured();
763
764 /**
765 * Sets the base path for the logger
766 *
767 * @param null_or_key_name
768 * @param priority
769 * @return
770 */
771
772 void config_set_log_base_path(const char *path);
773
774 /**
775 * Registers the key configuration (TSIG)
776 *
777 * @param null_or_key_name
778 * @param priority
779 * @return
780 */
781 ya_result config_register_key(const char *null_or_key_name, s32 priority);
782
783 /** @} */
784