This file is indexed.

/usr/include/dnscore/config_settings.h is in libyadifa-dev 2.1.6-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
/*------------------------------------------------------------------------------
*
* Copyright (c) 2011-2016, EURid. All rights reserved.
* The YADIFA TM software product is provided under the BSD 3-clause license:
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions
* are met:
*
*        * Redistributions of source code must retain the above copyright 
*          notice, this list of conditions and the following disclaimer.
*        * Redistributions in binary form must reproduce the above copyright 
*          notice, this list of conditions and the following disclaimer in the 
*          documentation and/or other materials provided with the distribution.
*        * Neither the name of EURid nor the names of its contributors may be 
*          used to endorse or promote products derived from this software 
*          without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*------------------------------------------------------------------------------
*
*/
/** @defgroup 
 *  @ingroup 
 *  @brief 
 *
 * @{
 */

#pragma once

#include <stddef.h>

#include <dnscore/output_stream.h>
#include <dnscore/input_stream.h>
#include <dnscore/host_address.h>

/*
 Each section/container descriptor is registered.
 
   config section descriptor -------> target base (ie: g_config)
              |
              V
  config table descriptor vtbl -----> callbacks (init, start, stop, finalise, ...)
              |
              V
      table descriptor (BEGIN/END, names, offsets in target base, setters)
*/

#define CONFIG_ERROR_BASE                       0x800C0000
#define CONFIG_ERROR_CODE(code_)                ((s32)(CONFIG_ERROR_BASE+(code_)))

// Bugs in the program
#define CONFIG_SECTION_ALREADY_REGISTERED       CONFIG_ERROR_CODE(0xff01)
#define CONFIG_ALIAS_CHAIN_TOO_BIG              CONFIG_ERROR_CODE(0xff02)
// Parsing issues
#define CONFIG_PARSE_SECTION_TAG_NOT_CLOSED     CONFIG_ERROR_CODE(0x0001)
#define CONFIG_PARSE_UNEXPECTED_SECTION_OPEN    CONFIG_ERROR_CODE(0x0002)
#define CONFIG_PARSE_UNEXPECTED_SECTION_CLOSE   CONFIG_ERROR_CODE(0x0003)
#define CONFIG_PARSE_CLOSED_WRONG_SECTION       CONFIG_ERROR_CODE(0x0004)
#define CONFIG_PARSE_SECTION_TAG_TOO_SMALL      CONFIG_ERROR_CODE(0x0005)
#define CONFIG_PARSE_INCLUDE_EXPECTED_FILE_PATH CONFIG_ERROR_CODE(0x0006)
#define CONFIG_PARSE_UNKNOWN_KEYWORD            CONFIG_ERROR_CODE(0x0007)
#define CONFIG_PARSE_EXPECTED_VALUE             CONFIG_ERROR_CODE(0x0008)
// Content issues
#define CONFIG_UNKNOWN_SETTING                  CONFIG_ERROR_CODE(0x0011)
#define CONFIG_VALUE_OUT_OF_RANGE               CONFIG_ERROR_CODE(0x0012)
#define CONFIG_FILE_PATH_TOO_BIG                CONFIG_ERROR_CODE(0x0013)
#define CONFIG_BAD_UID                          CONFIG_ERROR_CODE(0x0014)
#define CONFIG_BAD_GID                          CONFIG_ERROR_CODE(0x0015)
#define CONFIG_TEXT_LENGHT_TOO_BIG              CONFIG_ERROR_CODE(0x0016)
#define CONFIG_ARRAY_SIZE_TOO_BIG               CONFIG_ERROR_CODE(0x0017)

// Logger config specific issues
#define CONFIG_LOGGER_HANDLE_ALREADY_DEFINED    CONFIG_ERROR_CODE(0x1001)
#define CONFIG_LOGGER_INVALID_DEBUGLEVEL        CONFIG_ERROR_CODE(0x1002)

// TSIG key config specific issues
#define CONFIG_KEY_INCOMPLETE_KEY               CONFIG_ERROR_CODE(0x2001)
#define CONFIG_KEY_UNSUPPORTED_ALGORITHM        CONFIG_ERROR_CODE(0x2002)

/*
#define CONFIG_LOGGER_INVALID_DEBUGLEVEL              CONFIG_ERROR_CODE(0x0001)
*/

#define CONFIG_TABLE_SOURCE_NONE                0
#define CONFIG_TABLE_SOURCE_DEFAULT             1
#define CONFIG_TABLE_SOURCE_CONFIGURATION_FILE  2
#define CONFIG_TABLE_SOURCE_COMMAND_LINE        3

#define CONFIG_HOST_LIST_FLAGS_IPV4             0x01
#define CONFIG_HOST_LIST_FLAGS_IPV6             0x02
#define CONFIG_HOST_LIST_FLAGS_FQDN             0x04
#define CONFIG_HOST_LIST_FLAGS_PORT             0x08
#define CONFIG_HOST_LIST_FLAGS_TSIG             0x10
#define CONFIG_HOST_LIST_FLAGS_APPEND           0x20

#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)

#define CONFIG_FLAG_ON  "1"
#define CONFIG_FLAG_OFF "0"

#define CONFIG_SOURCE_NONE    0
#define CONFIG_SOURCE_DEFAULT 1
#define CONFIG_SOURCE_FILE    128
#define CONFIG_SOURCE_CMDLINE 250
#define CONFIG_SOURCE_HIGHEST 255

#define CONFIG_SETTINGS_DEBUG 0

/**
 * This union covers 64 bits
 * Meant to be used to store different parameters
 */

union anytype_u
{
    /* DO NOT ADD THIS : bool    _bool; */
    intptr  _intptr;
    u8      _u8;
    u16     _u16;
    u32     _u32;
    u8      _8u8[8];
    u16     _4u16[4];
    u32     _2u32[2];
    u64     _u64;
    s8      _s8;
    s16     _s16;
    s32     _s32;
    s64     _s64;
    s8      _8s8[8];
    s16     _4s16[4];
    s32     _2s32[2];
    callback_function *void_callback;
    result_callback_function *result_callback;
    void*   _voidp;
    char*   _charp;
};

typedef union anytype_u anytype;

typedef ya_result config_set_field_function(const char*, void*, anytype);

struct config_section_descriptor_s;

/**
 * name is the name of the key, expected in the config file
 * field_offset is the offset of the value from the beginning of the target struct
 * setter is the function able to parse the value of the key and store it at target + offset
 * default_value_string is the string containing the default value for the key
 * function_specific is a parameter given to the setter.  The meaning is different for each setter.
 * source is the level that wrote the current value in the table
 */

struct config_table_descriptor_item_s
{
    const char *name;
    int field_offset;
    config_set_field_function *setter;
    const char *default_value_string;
    anytype function_specific;
    u8 source;
};

typedef struct config_table_descriptor_item_s config_table_descriptor_item_s;

typedef ya_result config_section_set_wild_method(struct config_section_descriptor_s *, const char *key, const char *value);
typedef ya_result config_section_print_wild_method(struct config_section_descriptor_s *, output_stream *os, const char *key);
typedef ya_result config_section_init_method(struct config_section_descriptor_s *);
typedef ya_result config_section_start_method(struct config_section_descriptor_s *);
typedef ya_result config_section_stop_method(struct config_section_descriptor_s *);
typedef ya_result config_section_postprocess_method(struct config_section_descriptor_s *);
typedef ya_result config_section_finalise_method(struct config_section_descriptor_s *);

struct config_section_descriptor_vtbl_s
{
    /// section name
    const char                                 *name; // the table name
    config_table_descriptor_item_s            *table; // the descriptor for the table
    
    config_section_set_wild_method         *set_wild; // sets an undefined (dynamic) field
    config_section_print_wild_method     *print_wild; // prints an undefined (dynamic) field
    config_section_init_method                 *init; // initialises
    config_section_start_method               *start; // called when a section starts
    config_section_stop_method                 *stop; // called when a section stops
    config_section_postprocess_method   *postprocess; // called after the section has been processed
    config_section_finalise_method         *finalise; // finishes
};

typedef struct config_section_descriptor_vtbl_s config_section_descriptor_vtbl_s;

struct config_section_descriptor_s
{
    void *base; // base of the structure to fill up
    const config_section_descriptor_vtbl_s *vtbl;
};

typedef struct config_section_descriptor_s config_section_descriptor_s;

/**
 * Here are the helper macro used to define the fields in the structure
 * 
 * The definition of the table always be done like this:
 * 
 * struct my_struct_type
 * {
 *      u32 field_name_in_my_struct_type;
 * };
 * 
 * typedef struct my_struct_type my_struct_type;
 * 
 * #define CONFIG_TYPE my_struct_type
 * CONFIG_BEGIN(my_struct_type_table_desc)
 * CONFIG_U32(field_name_in_my_struct_type,default_value_in_text_form)
 * CONFIG_END(my_struct_type_table_desc)
 * #undef CONFIG_TYPE
 * 
 * 
 */

#undef CONFIG_TYPE /* please_define_me */   

#define CONFIG_BEGIN(name_) static config_table_descriptor_item_s name_[] = {
#define CONFIG_BOOL(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_bool, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FLAG8(fieldname_,defaultvalue_, realfieldname_, mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag8, defaultvalue_,{(u8)mask_}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FLAG16(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag16, defaultvalue_,{(u16)mask_}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FLAG32(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag32, defaultvalue_,{(u32)mask_}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FLAG64(fieldname_,defaultvalue_, realfieldname_,mask_) {#fieldname_,offsetof(CONFIG_TYPE, realfieldname_), (config_set_field_function*)config_set_flag64, defaultvalue_,{(u64)mask_}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_U64(fieldname_,defaultvalue_)                 {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u64,       defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_U32(fieldname_,defaultvalue_)                 {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u32,       defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#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_)}}, CONFIG_TABLE_SOURCE_NONE},
#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_)}}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_U16(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u16, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_DNS_TYPE(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnstype, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_DNS_CLASS(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnsclass, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_U8(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_u8, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_U8_INC(fieldname_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_inc_u8, 0,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_STRING(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_string, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#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_))}, CONFIG_TABLE_SOURCE_NONE},
#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_)}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_PASSWORD(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_password, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FQDN(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_fqdn, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_PATH(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_path, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_CHROOT(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_chroot, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_LOGPATH(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_logpath, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_FILE(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_file, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_UID(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_uid_t, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_GID(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_gid_t, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
//#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}, CONFIG_TABLE_SOURCE_NONE},
//#define CONFIG_ACL_FILTER(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_acl_item, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_LIST_ITEM(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_add_list_item, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_ENUM(fieldname_,defaultvalue_,enumtable_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_enum_value, defaultvalue_, {(intptr)enumtable_}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_ENUM8(fieldname_,defaultvalue_,enumtable_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_enum8_value, defaultvalue_, {(intptr)enumtable_}, CONFIG_TABLE_SOURCE_NONE},
#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}}, CONFIG_TABLE_SOURCE_NONE},
#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}}, CONFIG_TABLE_SOURCE_NONE},
#define CONFIG_BYTES(fieldname_,defaultvalue_,maxsize_) {#fieldname_, offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_bytes, defaultvalue_, {maxsize_}, CONFIG_TABLE_SOURCE_NONE},
//#define CONFIG_DNSSEC(fieldname_,defaultvalue_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)config_set_dnssec, defaultvalue_,{._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
    
#define CONFIG_ALIAS(fieldname_, aliasedname_) {#fieldname_, 0, NULL, #aliasedname_, {._intptr=0}, CONFIG_TABLE_SOURCE_NONE},
    /*#define CONFIG_CATEGORY(fieldname_, category_) {#fieldname_, 0, NULL, NULL, #category},*/

#define CONFIG_END(name_) {NULL,0,NULL,NULL, {._intptr=0}, CONFIG_TABLE_SOURCE_NONE} }; // name_
 
ya_result config_set_bool(const char *value, bool *dest, anytype notused);
ya_result config_set_flag8(const char *value, u8 *dest, anytype mask8);
ya_result config_set_flag16(const char *value, u16 *dest, anytype mask16);
ya_result config_set_flag32(const char *value, u32 *dest, anytype mask32);
ya_result config_set_flag64(const char *value, u64 *dest, anytype mask64);
ya_result config_set_u64(const char *value,u64 *dest, anytype notused);
ya_result config_set_u32(const char *value,u32 *dest, anytype notused);
ya_result config_set_u32_range(const char *value,u32 *dest, anytype min_max);
ya_result config_set_u16(const char *value,u16 *dest, anytype notused);
ya_result config_set_u8(const char *value,u8 *dest, anytype notused);
ya_result config_inc_u8(const char *value_notused,u8 *dest, anytype notused);
ya_result config_set_string(const char *value, char **dest, anytype notused);
ya_result config_set_string_copy(const char *value, char *dest, anytype maxlen);
ya_result config_append_string_array_item(const char *value, ptr_vector *dest, anytype maxsize);
ya_result config_set_password(const char *value, char **dest, anytype notused);
ya_result config_set_fqdn(const char *value, u8 **dest, anytype notused);
ya_result config_set_path(const char *value, char **dest, anytype notused);
ya_result config_set_chroot(const char *value, char **dest, anytype notused);
ya_result config_set_logpath(const char *value, char **dest, anytype notused);
ya_result config_set_file(const char *value, char **dest, anytype notused);
ya_result config_set_uid_t(const char *value, uid_t *dest, anytype notused);
ya_result config_set_gid_t(const char *value, gid_t *dest, anytype notused);
ya_result config_set_dnstype(const char *value, u16 *dest, anytype notused);
ya_result config_set_dnsclass(const char *value, u16 *dest, anytype notused);
ya_result config_set_enum_value(const char *value, u32 *dest, anytype enum_value_name_table);
ya_result config_set_enum8_value(const char *value, u8 *dest, anytype enum_value_name_table);
ya_result config_set_host_list(const char *value, host_address **dest, anytype notused);
ya_result config_set_bytes(const char *value, void *dest, anytype sizeoftarget);

// life of the config processing

void config_init_error_codes();

struct config_error_s
{
    u32 line_number;
    char line[256];
    char file[PATH_MAX];
};

typedef struct config_error_s config_error_s;

struct config_source_s;

typedef ya_result config_source_provider_callback_function(struct config_source_s *source, input_stream *out_source, config_error_s *cfgerr);

struct config_source_file_name_s
{
    const char* name;
};

struct config_source_buffer_s
{
    const char* text;
    u32 size;
};

/**
 * An help tool to register many sources at once
 */

struct config_source_s
{
    config_source_provider_callback_function *get_source;
    const char *name;
    const char *__class__;
    union
    {
        struct config_source_file_name_s file_name;
        struct config_source_buffer_s buffer;
    } source;
    u8 level;
};



#ifdef TODO
struct config_s
{
    u32_set section_descriptor_set = U32_SET_EMPTY;
}:
#endif

ya_result config_init();

/**
 * Configuration:
 * 
 * priority : the lowest value, the fastest to be parsed 
 *            negative value : choose
 *
 * level    : ex: 0 for none, 1 for default, 2 for config, 3 for command line
 *           command line has priority on everything else
 */

/**
 * Gets the current source level
 * @return the current source level
 */

u8 config_get_source();

/**
 * Sets the current source level
 * 
 * @param l the current source level
 */

void config_set_source(u8 l);

/**
 * If the source level has been parsed, automatically fill the default values
 * for fields that are not set yet.
 * 
 * @return after what level do we automatically set the default values in the container
 */

u8 config_get_autodefault_after_source();

/**
 * If the source level has been parsed, automatically fill the default values
 * for fields that are not set yet.
 * 
 * @param l after what level do we automatically set the default values in the container ?
 */

void config_set_autodefault_after_source(u8 l); // if a configuration is read at this level, the default is automatically applied after

/**
 * Gets the default source level
 * 
 * @return the default source level
 */

u8 config_get_default_source();

/**
 * Sets the default source level (default = 1)
 * 
 * @param l the default source level
 */

void config_set_default_source(u8 l);           // this level is meant for default (1)


#define CONFIG_CALLBACK_RESULT_CONTINUE 0
#define CONFIG_CALLBACK_RESULT_STOP     1

typedef ya_result config_callback_function(const char *section_name, int section_index);

/**
 * Adds a callback called when a section has been read
 * 
 * @param section_name the name of the section
 * @param on_section_read the function to call
 *
 *  * @return continue, stop or an error code to fail
 */

ya_result config_add_on_section_read_callback(const char *section_name, config_callback_function *on_section_read);

/**
 * Removes a callback called when a section has been read
 * 
 * @param section_name the name of the section
 * @param on_section_read the function to call
 *
 * @return continue, stop or an error code to fail
 */

ya_result config_remove_on_section_read_callback(const char *section_name, config_callback_function *on_section_read);

/**
 * Registers a descriptor at the given priority
 * 
 * @param section_descritor config descriptor
 * @param priority config priority
 * 
 * @return an error code
 */

ya_result config_register(const config_section_descriptor_s *section_descritor, s32 priority);

/**
 * 
 * Reads matching section/containers from a file on disk
 * 
 * @param configuration_file_path the file path
 * @param cfgerr error handling structure (can be NULL)
 * @param section_name the name to match, or if NULL : all sections
 * 
 * @return an error code
 */

ya_result config_read_section(const char *configuration_file_path, config_error_s *cfgerr, const char *section_name);

/**
 * Reads all sections/containers from a file
 * 
 * @param configuration_file_path the file path
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_read(const char *configuration_file_path, config_error_s *cfgerr);

/**
 * Reads all sections/containers from a buffer
 * 
 * @param buffer the text buffer
 * @param buffer_len the text buffer length
 * @param buffer_name the name of the buffer for error reporting
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_read_from_buffer(const char *buffer, u32 buffer_len, const char *buffer_name, config_error_s *cfgerr);

/**
 * Sets a text buffer in a source
 * 
 * @param source the source struct to initialise
 * @param name the name of the source
 * @param level the level of the source
 * @param buffer text for the source
 * @param buffer_len text length for the source
 */

void config_source_set_buffer(struct config_source_s *source, const char *name, u8 level, const char *buffer, u32 buffer_len);

/**
 * Sets a file in a source
 * 
 * @param source the source struct to initialise
 * @param name the name of the file
 * @param level the level of the source
 */

void config_source_set_file(struct config_source_s *source, const char *name, u8 level);

/**
 * Read all sources from a table
 * 
 * @param sources a pointer to the first source
 * @param sources_count the number of sources
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_read_from_sources(struct config_source_s *sources, u32 sources_count, config_error_s *cfgerr);

/**
 * Applies default values to uninitialised fields. * @param cfgerr
 * 
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_set_default(config_error_s *cfgerr);

/**
 * Gets the section descriptor for the section/container name
 * 
 * @param name the name of the section descriptor
 * 
 * @return a pointer to the section descriptor or NULL if not found
 */

config_section_descriptor_s *config_section_get_descriptor(const char *name);

/**
 * Sets the table default values
 * 
 * @param section_descriptor the descriptor to use (points to the table)
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_set_section_default(config_section_descriptor_s *section_descriptor, config_error_s *cfgerr);


/**
 * Sets the key to a value
 * Source level is taken into account.
 * ie: config_value_set(&yadifa_config_main_desc, "daemon", "on");
 * 
 * @param section_descriptor the descriptor pointing to the table
 * @param key the key to set
 * @param value to value to set it to
 * 
 * @return an error code
 */

ya_result config_value_set(config_section_descriptor_s *section_descriptor, const char *key, const char *value);

/**
 * 
 * Sets the key of the section/container to its default value
 * 
 * @param section_name name of the section
 * @param name key of the value
 * @param cfgerr if not NULL, the error reporting structure
 * 
 * @return an error code
 */

ya_result config_value_set_to_default(const char *section_name, const char *name, config_error_s *cfgerr);

typedef bool config_section_struct_type_handler(output_stream *os, const char *name, void *ptr);

bool config_section_struct_register_type_handler(config_set_field_function* setter, config_section_struct_type_handler *handler);

/**
 * 
 * Prints the content of every supported types of the table using the descriptor
 * 
 * @param section_descriptor the descriptor
 * @param os where to print to
 */

void config_section_print(const config_section_descriptor_s *section_descriptor, output_stream *os);

/**
 * 
 * Prints the content of every supported types of the table using the given descriptor on the given struct
 * 
 * @param section_descriptor the descriptor
 * @param a pointer to the config struct base
 * @param os where to print to
 */

void config_section_struct_print(const config_section_descriptor_s *section_descriptor, const void* configbase, output_stream *os);

/**
 * 
 * Gets the index of the key on the table
 * 
 * @param table a config table
 * @param name the field key name
 *
 * @return an error code
 */

ya_result config_item_index_get(const config_table_descriptor_item_s *table, const char *name);

/**
 * Prints the config to the output stream
 * 
 * @param os the output stream
 */

void config_print(output_stream *os);

/**
 * Call the postproces callback on the registered tables
 */

ya_result config_postprocess();

/**
 * Call the finalise callback on the registered tables
 * 
 */

ya_result config_finalise();

// helpers

typedef void *config_section_struct_collection_get_next_method(void *previous_data_struct);

/**
 * 
 * Registers a struct with its descriptor and name, for configuration.
 * 
 * @param name name of the struct
 * @param table table describing the struct
 * @param data_struct pointer to the struct
 * @param priority priority level (order of read)
 * 
 * @return an error code
 */

ya_result config_register_struct(const char *name, config_table_descriptor_item_s *table, void *data_struct, s32 priority);

/**
 * 
 * Registers the logger configuration.
 * 
 * @note logger_handle_create("handle-name",logger_handle_for_handle_name_ptr_ptr) MUST be called
 *        before the config_read is done
 * 
 * @param null_or_channels_name
 * @param null_or_loggers_name
 * @param priority
 * 
 * @return an error code
 */

ya_result config_register_logger(const char *null_or_channels_name, const char *null_or_loggers_name, s32 priority);

/**
 * Returns TRUE iff any logging section has been found.
 * 
 * @return TRUE iff any logging section has been found.
 */

bool config_logger_isconfigured();

/**
 * Clears the logger-configured flag
 */

void config_logger_clearconfigured();

/**
 * Sets the base path for the logger
 * 
 * @param null_or_key_name
 * @param priority
 * @return 
 */

void config_set_log_base_path(const char *path);

/**
 * Registers the key configuration (TSIG)
 * 
 * @param null_or_key_name
 * @param priority
 * @return 
 */
ya_result config_register_key(const char *null_or_key_name, s32 priority);

/** @} */