Remove redundant file from freeradius-abfab list.
[freeradius.git] / src / include / conffile.h
1 #ifndef _CONFFILE_H
2 #define _CONFFILE_H
3
4 /*
5  * conffile.h   Defines for the conffile parsing routines.
6  *
7  * Version:     $Id$
8  *
9  */
10
11 RCSIDH(conffile_h, "$Id$")
12
13 #include <stddef.h>
14 #include <freeradius-devel/token.h>
15 #include <sys/time.h>
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /*
22  * Export the minimum amount of information about these structs
23  */
24 typedef struct conf_item CONF_ITEM;     //!< Generic configuration element, extended to become
25                                         ///< a #CONF_PAIR, a #CONF_SECTION or #CONF_DATA.
26 typedef struct conf_pair CONF_PAIR;     //!< #CONF_ITEM with an attribute, an operator and a value.
27 typedef struct conf_part CONF_SECTION;  //!< #CONF_ITEM used to group multiple #CONF_PAIR and #CONF_SECTION, together.
28 typedef struct conf_data CONF_DATA;     //!< #CONF_ITEM used to associate arbitrary data
29                                         ///< with a #CONF_PAIR or #CONF_SECTION.
30
31
32 typedef void conf_type_mismatch;        //!< Dummy type used to indicate PW_TYPE_*/C type mismatch.
33 typedef void conf_type_invalid;         //!< Dummy type used to indicate invalid PW_TYPE_*.
34
35 #if defined(HAVE_BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN_TYPES_COMPATIBLE_P)
36 /*
37  * Dumb hack for GCC which explodes with lots of errors masking the real
38  * error cause, if we don't use typdefs for these structures.
39  */
40 typedef struct timeval _timeval_t;
41
42 /** Check the type #_t matches the destination data type
43  *
44  * Validation macro to check the type of the pointer or offset #_p passed in
45  * matches the type #_t of the configuration item.
46  *
47  * Uses various magic builtin precompilation functions, so will likely only
48  * work with recent versions of clang and gcc.
49  *
50  * @note The warnings/errors emitted are usually awful.
51  *
52  * @param _t a #PW_TYPE value with optional PW_TYPE_* flags.
53  * @param _ct data type of global or struct field, obtained with ``__typeof__``.
54  * @param _p Pointer or offset.
55  */
56 #  define FR_CONF_TYPE_CHECK(_t, _ct, _p) \
57         __builtin_choose_expr((_t & PW_TYPE_TMPL),\
58                 __builtin_choose_expr(__builtin_types_compatible_p(vp_tmpl_t **, _ct), _p, (conf_type_mismatch) 0),\
59         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_STRING),\
60                 __builtin_choose_expr(__builtin_types_compatible_p(char const **, _ct), _p, (conf_type_mismatch) 0),\
61         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_BOOLEAN),\
62                 __builtin_choose_expr(__builtin_types_compatible_p(bool *, _ct), _p, (conf_type_mismatch) 0),\
63         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_SUBSECTION),\
64                 _p,\
65         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_INTEGER),\
66                 __builtin_choose_expr(__builtin_types_compatible_p(uint32_t *, _ct), _p, (conf_type_mismatch) 0),\
67         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_IPV4_ADDR),\
68                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
69         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_DATE),\
70                 __builtin_choose_expr(__builtin_types_compatible_p(uint32_t *, _ct), _p, (conf_type_mismatch) 0),\
71         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_ABINARY),\
72                 __builtin_choose_expr(__builtin_types_compatible_p(size_t[32/sizeof(size_t)], _ct), _p, (conf_type_mismatch) 0),\
73         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_OCTETS),\
74                 __builtin_choose_expr(__builtin_types_compatible_p(uint8_t *, _ct), _p, (conf_type_mismatch) 0),\
75         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_IFID),\
76                 __builtin_choose_expr(__builtin_types_compatible_p(uint8_t[8], _ct), _p, (conf_type_mismatch) 0),\
77         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_IPV6_ADDR),\
78                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
79         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_IPV6_PREFIX),\
80                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
81         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_BYTE),\
82                 __builtin_choose_expr(__builtin_types_compatible_p(uint8_t *, _ct), _p, (conf_type_mismatch) 0),\
83         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_SHORT),\
84                 __builtin_choose_expr(__builtin_types_compatible_p(uint16_t *, _ct), _p, (conf_type_mismatch) 0),\
85         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_ETHERNET),\
86                 __builtin_choose_expr(__builtin_types_compatible_p(uint8_t[6], _ct), _p, (conf_type_mismatch) 0),\
87         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_SIGNED),\
88                 __builtin_choose_expr(__builtin_types_compatible_p(int32_t *, _ct), _p, (conf_type_mismatch) 0),\
89         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_COMBO_IP_ADDR),\
90                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
91         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_INTEGER64),\
92                 __builtin_choose_expr(__builtin_types_compatible_p(uint64_t *, _ct), _p, (conf_type_mismatch) 0),\
93         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_IPV4_PREFIX),\
94                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
95         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_TIMEVAL),\
96                 __builtin_choose_expr(__builtin_types_compatible_p(_timeval_t *, _ct), _p, (conf_type_mismatch) 0),\
97         __builtin_choose_expr((((_t) & 0xff) == PW_TYPE_COMBO_IP_PREFIX),\
98                 __builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
99                 (conf_type_invalid) 0\
100         )))))))))))))))))))))
101
102 #  define FR_CONF_OFFSET(_t, _s, _f)    _t, FR_CONF_TYPE_CHECK((_t), __typeof__(&(((_s *)NULL)->_f)), offsetof(_s, _f)), NULL
103 #  define FR_CONF_POINTER(_t, _p)       _t, 0, FR_CONF_TYPE_CHECK((_t), __typeof__(_p), _p)
104 #  define FR_ITEM_POINTER(_t, _p)       _t, FR_CONF_TYPE_CHECK((_t), __typeof__(_p), _p)
105 #else
106 #  define FR_CONF_OFFSET(_t, _s, _f)    _t, offsetof(_s, _f), NULL
107 #  define FR_CONF_POINTER(_t, _p)       _t, 0, _p
108 #  define FR_ITEM_POINTER(_t, _p)       _t, _p
109 #endif
110
111 #define FR_CONF_DEPRECATED(_t, _p, _f) (_t) | PW_TYPE_DEPRECATED, 0, NULL
112
113 /*
114  *  Instead of putting the information into a configuration structure,
115  *  the configuration file routines MAY just parse it directly into
116  *  user-supplied variables.
117  */
118 #define PW_TYPE_SUBSECTION      102
119
120 /** @name #CONF_PARSER type flags
121  *
122  * These flags should be or'd with another PW_TYPE_* value to create validation
123  * rules for the #cf_item_parse function.
124  *
125  * @note File PW_TYPE_FILE_* types have a base type of string, so they're validated
126  *       correctly by the config parser.
127  * @{
128  */
129 #define PW_TYPE_DEPRECATED      (1 << 10) //!< If a matching #CONF_PAIR is found, error out with a deprecated message.
130 #define PW_TYPE_REQUIRED        (1 << 11) //!< Error out if no matching #CONF_PAIR is found, and no dflt value is set.
131 #define PW_TYPE_ATTRIBUTE       (1 << 12) //!< Value must resolve to attribute in dict (deprecated, use #PW_TYPE_TMPL).
132 #define PW_TYPE_SECRET          (1 << 13) //!< Only print value if debug level >= 3.
133
134 #define PW_TYPE_FILE_INPUT      ((1 << 14) | PW_TYPE_STRING) //!< File matching value must exist, and must be readable.
135 #define PW_TYPE_FILE_OUTPUT     ((1 << 15) | PW_TYPE_STRING) //!< File matching value must exist, and must be writeable.
136
137 #define PW_TYPE_XLAT            (1 << 16) //!< string will be dynamically expanded.
138 #define PW_TYPE_TMPL            (1 << 17) //!< CONF_PAIR should be parsed as a template.
139
140 #define PW_TYPE_MULTI           (1 << 18) //!< CONF_PAIR can have multiple copies.
141 #define PW_TYPE_NOT_EMPTY       (1 << 19) //!< CONF_PAIR is required to have a non zero length value.
142 /* @} **/
143
144 #define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\
145 do {\
146         if (!(_cond)) {\
147                 WARN("WARNING: Ignoring \"" _name " = %i\", forcing to \"" _name " = %i\"", _var, _new);\
148                 _var = _new;\
149         }\
150 } while (0)
151
152 #define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound) FR_INTEGER_COND_CHECK(_name, _var, (_var _op _bound), _bound)
153
154 #define FR_TIMEVAL_BOUND_CHECK(_name, _var, _op, _bound_sec, _bound_usec)\
155 do {\
156         struct timeval _bound = {_bound_sec, _bound_usec};\
157         if (!timercmp(_var, &_bound, _op)) {\
158                 WARN("WARNING: Ignoring \"" _name " = %d.%.06d\", forcing to \"" _name " = %d.%06d\"",\
159                         (int)(_var)->tv_sec, (int)(_var)->tv_usec,\
160                         (int)_bound.tv_sec, (int)_bound.tv_usec);\
161                 *_var = _bound;\
162         }\
163 } while (0)
164
165 #define FR_TIMEVAL_TO_MS(_x) (((_x)->tv_usec * 1000) + ((_x)->tv_sec / 1000))
166 extern bool                     check_config;
167
168 /** Defines a #CONF_PAIR to C data type mapping
169  *
170  * Is typically used to define mappings between module sections, and module instance structs.
171  * May also be used to set global configuration options.
172  *
173  * Offset/data values should be set using #FR_CONF_OFFSET or #FR_CONF_POINTER.
174  *
175  * Example with #FR_CONF_OFFSET :
176  @code{.c}
177    static CONF_PARSER module_config[] = {
178         { "example", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_NOT_EMPTY, example_instance_t, example), "default_value" },
179         CONF_PARSER_TERMINATOR
180    }
181  @endcode
182  *
183  * Example with #FR_CONF_POINTER :
184  @code{.c}
185    static CONF_PARSER global_config[] = {
186         { "example", FR_CONF_POINTER(PW_TYPE_STRING | PW_TYPE_NOT_EMPTY, &my_global), "default_value" },
187         CONF_PARSER_TERMINATOR
188    }
189  @endcode
190  *
191  * @see FR_CONF_OFFSET
192  * @see FR_CONF_POINTER
193  * @see cf_section_parse
194  * @see cf_item_parse
195  */
196 typedef struct CONF_PARSER {
197         char const      *name;                  //!< Name of the #CONF_ITEM to parse.
198         int             type;                   //!< A #PW_TYPE value, may be or'd with one or more PW_TYPE_* flags.
199                                                 //!< @see cf_item_parse.
200
201         size_t          offset;                 //!< Relative offset of field or structure to write the parsed value to.
202                                                 //!< When #type is set to #PW_TYPE_SUBSECTION, may be used to specify
203                                                 //!< a base offset to add to all offsets contained within the
204                                                 //!< subsection.
205                                                 //!< @note Must be used exclusively to #data.
206
207         void            *data;                  //!< Pointer to a static variable to write the parsed value to.
208                                                 //!< @note Must be used exclusively to #offset.
209
210         const void      *dflt;                  //!< Default as it would appear in radiusd.conf.
211                                                 //!< When #type is set to #PW_TYPE_SUBSECTION, should be a pointer
212                                                 //!< to the start of another array of #CONF_PARSER structs, forming
213                                                 //!< the subsection.
214 } CONF_PARSER;
215
216 #define CONF_PARSER_TERMINATOR  { NULL, -1, 0, NULL, NULL }
217
218 CONF_PAIR       *cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value,
219                                FR_TOKEN op, FR_TOKEN lhs_type, FR_TOKEN rhs_type);
220 CONF_PAIR       *cf_pair_dup(CONF_SECTION *parent, CONF_PAIR *cp);
221 void            cf_pair_add(CONF_SECTION *parent, CONF_PAIR *cp);
222
223 CONF_SECTION    *cf_section_alloc(CONF_SECTION *parent, char const *name1, char const *name2);
224 CONF_SECTION    *cf_section_dup(CONF_SECTION *parent, CONF_SECTION const *cs,
225                                 char const *name1, char const *name2, bool copy_meta);
226 void            cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs);
227 int             cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value);
228 int             cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt);
229 int             cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables);
230 int             cf_section_parse_pass2(CONF_SECTION *, void *base, CONF_PARSER const *variables);
231 const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs);
232 int             cf_file_read(CONF_SECTION *cs, char const *file);
233 void            cf_file_free(CONF_SECTION *cs);
234
235 CONF_PAIR       *cf_pair_find(CONF_SECTION const *, char const *name);
236 CONF_PAIR       *cf_pair_find_next(CONF_SECTION const *, CONF_PAIR const *, char const *name);
237 CONF_SECTION    *cf_section_find(char const *name);
238 CONF_SECTION    *cf_section_find_name2(CONF_SECTION const *section,
239                                        char const *name1, char const *name2);
240 CONF_SECTION    *cf_section_sub_find(CONF_SECTION const *, char const *name);
241 CONF_SECTION    *cf_section_sub_find_name2(CONF_SECTION const *, char const *name1, char const *name2);
242 char const      *cf_section_value_find(CONF_SECTION const *, char const *attr);
243 CONF_SECTION    *cf_top_section(CONF_SECTION *cs);
244
245 void *cf_data_find(CONF_SECTION const *, char const *);
246 int cf_data_add(CONF_SECTION *, char const *, void *, void (*)(void *));
247 void *cf_data_remove(CONF_SECTION *cs, char const *name);
248
249 char const *cf_pair_attr(CONF_PAIR const *pair);
250 char const *cf_pair_value(CONF_PAIR const *pair);
251 FR_TOKEN cf_pair_operator(CONF_PAIR const *pair);
252 FR_TOKEN cf_pair_attr_type(CONF_PAIR const *pair);
253 FR_TOKEN cf_pair_value_type(CONF_PAIR const *pair);
254 VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair);
255 char const *cf_section_name1(CONF_SECTION const *cs);
256 char const *cf_section_name2(CONF_SECTION const *cs);
257 char const *cf_section_name(CONF_SECTION const *cs);
258 FR_TOKEN cf_section_name2_type(CONF_SECTION const *cs);
259 int dump_config(CONF_SECTION const *cs);
260 CONF_SECTION *cf_subsection_find_next(CONF_SECTION const *section,
261                                       CONF_SECTION const *subsection,
262                                       char const *name1);
263 CONF_SECTION *cf_section_find_next(CONF_SECTION const *section,
264                                    CONF_SECTION const *subsection,
265                                    char const *name1);
266 int cf_section_lineno(CONF_SECTION const *section);
267 int cf_pair_lineno(CONF_PAIR const *pair);
268 char const *cf_pair_filename(CONF_PAIR const *pair);
269 char const *cf_section_filename(CONF_SECTION const *section);
270 CONF_ITEM *cf_item_find_next(CONF_SECTION const *section, CONF_ITEM const *item);
271 int cf_pair_count(CONF_SECTION const *cs);
272 CONF_SECTION *cf_item_parent(CONF_ITEM const *ci);
273 bool cf_item_is_section(CONF_ITEM const *item);
274 bool cf_item_is_pair(CONF_ITEM const *item);
275 CONF_PAIR *cf_item_to_pair(CONF_ITEM const *item);
276 CONF_SECTION *cf_item_to_section(CONF_ITEM const *item);
277 CONF_ITEM *cf_pair_to_item(CONF_PAIR const *cp);
278 CONF_ITEM *cf_section_to_item(CONF_SECTION const *cs);
279
280 void cf_log_err(CONF_ITEM const *ci, char const *fmt, ...)              CC_HINT(format (printf, 2, 3));
281 void cf_log_err_cs(CONF_SECTION const *cs, char const *fmt, ...)        CC_HINT(format (printf, 2, 3));
282 void cf_log_err_cp(CONF_PAIR const *cp, char const *fmt, ...)           CC_HINT(format (printf, 2, 3));
283 void cf_log_info(CONF_SECTION const *cs, char const *fmt, ...)          CC_HINT(format (printf, 2, 3));
284 void cf_log_module(CONF_SECTION const *cs, char const *fmt, ...)        CC_HINT(format (printf, 2, 3));
285
286 void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci);
287 CONF_ITEM *cf_reference_item(CONF_SECTION const *parentcs,
288                              CONF_SECTION *outercs,
289                              char const *ptr);
290
291 #define CF_FILE_NONE   (0)
292 #define CF_FILE_ERROR  (1)
293 #define CF_FILE_CONFIG (1 << 2)
294 #define CF_FILE_MODULE (1 << 3)
295 int cf_file_changed(CONF_SECTION *cs, rb_walker_t callback);
296
297 extern CONF_SECTION *root_config;
298 extern bool cf_new_escape;
299
300 #ifdef __cplusplus
301 }
302 #endif
303
304 #endif /* _CONFFILE_H */