The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
cf_parse.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 167dd9c277bc7be1431f936547bc091340bebbbe $
20 *
21 * @file lib/server/cf_parse.h
22 * @brief API to parse internal format configuration items into native C types.
23 *
24 * @copyright 2015 The FreeRADIUS server project
25 */
26RCSIDH(cf_parse_h, "$Id: 167dd9c277bc7be1431f936547bc091340bebbbe $")
27
29
30#include <unistd.h>
31#include <sys/time.h>
32#include <freeradius-devel/util/rb.h>
33#include <freeradius-devel/util/table.h>
34#include <freeradius-devel/util/value.h>
35#include <freeradius-devel/server/cf_util.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#ifdef HAVE_BUILTIN_CHOOSE_EXPR
42typedef void _mismatch_abinary_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
43typedef void _mismatch_abinary; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
44typedef void _mismatch_bool_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
45typedef void _mismatch_bool; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
46typedef void _mismatch_char_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
47typedef void _mismatch_char; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
48typedef void _mismatch_double_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
49typedef void _mismatch_double; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
50typedef void _mismatch_ethernet_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
51typedef void _mismatch_ethernet; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
52typedef void _mismatch_float_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
53typedef void _mismatch_float; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
54typedef void _mismatch_fripaddr_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
55typedef void _mismatch_fripaddr; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
56typedef void _mismatch_ifid_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
57typedef void _mismatch_ifid; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
58typedef void _mismatch_int32_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
59typedef void _mismatch_int32; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
60typedef void _mismatch_size_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
61typedef void _mismatch_size; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
62typedef void _mismatch_time_delta_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
63typedef void _mismatch_time_delta; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
64typedef void _mismatch_time_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
65typedef void _mismatch_time; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
66typedef void _mismatch_uint16_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
67typedef void _mismatch_uint16; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
68typedef void _mismatch_uint32_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
69typedef void _mismatch_uint32; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
70typedef void _mismatch_uint64_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
71typedef void _mismatch_uint64; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
72typedef void _mismatch_uint8_m_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
73typedef void _mismatch_uint8_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
74typedef void _mismatch_uint8; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
75typedef void _mismatch_void_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
76typedef void _mismatch_void; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
77typedef void _mismatch_tmpl_m; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
78typedef void _mismatch_vp_tmpl; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
79
80
81typedef void _mismatch_default; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
82typedef void conf_type_mismatch; //!< Dummy type used to indicate FR_TYPE_*/C type mismatch.
83typedef void conf_type_invalid; //!< Dummy type used to indicate invalid FR_TYPE_*.
84
85/** Check the #fr_type_t matches the destination data type
86 *
87 * Validation macro to check the type of the pointer or offset _p passed in
88 * matches the #fr_type_t of the configuration item.
89 *
90 * Uses various magic builtin precompilation functions, so will likely only
91 * work with recent versions of clang and gcc.
92 *
93 * @note The warnings/errors emitted are usually awful.
94 *
95 * @param[in] _t a #fr_type_t value.
96 * @param[in] _f additional flags that control parsing.
97 * @param[in] _ct data type of global or struct field, obtained with ``__typeof__``.
98 * @param[in] _p Pointer or offset.
99 */
100# define FR_CONF_FLAG_CHECK(_t, _f, _ct, _p) \
101__builtin_choose_expr(((_f) & CONF_FLAG_SUBSECTION), _p, \
102__builtin_choose_expr((_t == FR_TYPE_VOID), _p, \
103__builtin_choose_expr((_t == FR_TYPE_SIZE) && !((_f) & CONF_FLAG_MULTI), \
104 __builtin_choose_expr(IS_COMPATIBLE((_ct), size_t *), _p, (_mismatch_size) 0), \
105__builtin_choose_expr((_t == FR_TYPE_SIZE) && ((_f) & CONF_FLAG_MULTI), \
106 __builtin_choose_expr(IS_COMPATIBLE((_ct), size_t **), _p, (_mismatch_size_m) 0), \
107_Generic((_ct), \
108 fr_time_t * : __builtin_choose_expr((_t == FR_TYPE_DATE) && !((_f) & CONF_FLAG_MULTI), \
109 _p, (_mismatch_time) 0), \
110 fr_time_t ** : __builtin_choose_expr((_t == FR_TYPE_DATE) && ((_f) & CONF_FLAG_MULTI), \
111 _p, (_mismatch_time_m) 0), \
112 fr_ethernet_t * : __builtin_choose_expr((_t == FR_TYPE_ETHERNET) && !((_f) & CONF_FLAG_MULTI), \
113 _p, (_mismatch_ethernet) 0), \
114 fr_ethernet_t ** : __builtin_choose_expr((_t == FR_TYPE_ETHERNET) && ((_f) & CONF_FLAG_MULTI), \
115 _p, (_mismatch_ethernet_m) 0), \
116 fr_ifid_t * : __builtin_choose_expr((_t == FR_TYPE_IFID) && !((_f) & CONF_FLAG_MULTI), \
117 _p, (_mismatch_ifid) 0), \
118 fr_ifid_t ** : __builtin_choose_expr((_t == FR_TYPE_IFID) && ((_f) & CONF_FLAG_MULTI), \
119 _p, (_mismatch_ifid_m) 0), \
120 fr_time_delta_t *: __builtin_choose_expr((_t == FR_TYPE_TIME_DELTA) && !((_f) & CONF_FLAG_MULTI), \
121 _p, (_mismatch_time_delta) 0), \
122 fr_time_delta_t **: __builtin_choose_expr((_t == FR_TYPE_TIME_DELTA) && ((_f) & CONF_FLAG_MULTI), \
123 _p, (_mismatch_time_delta_m) 0), \
124 tmpl_t ** : __builtin_choose_expr(((_f) & CONF_FLAG_TMPL) && !((_f) & CONF_FLAG_MULTI), \
125 _p, (_mismatch_vp_tmpl) 0), \
126 tmpl_t *** : __builtin_choose_expr(((_f) & CONF_FLAG_TMPL) && ((_f) & CONF_FLAG_MULTI), \
127 _p, (_mismatch_tmpl_m) 0), \
128 char const ** : __builtin_choose_expr((_t == FR_TYPE_STRING) && !((_f) & CONF_FLAG_MULTI), \
129 _p, (_mismatch_char) 0), \
130 char const *** : __builtin_choose_expr((_t == FR_TYPE_STRING) && ((_f) & CONF_FLAG_MULTI), \
131 _p, (_mismatch_char_m) 0), \
132 bool * : __builtin_choose_expr((_t == FR_TYPE_BOOL) && !((_f) & CONF_FLAG_MULTI), \
133 _p, (_mismatch_bool) 0), \
134 bool ** : __builtin_choose_expr((_t == FR_TYPE_BOOL) && ((_f) & CONF_FLAG_MULTI), \
135 _p, (_mismatch_bool_m) 0), \
136 uint32_t * : __builtin_choose_expr((_t == FR_TYPE_UINT32) && !((_f) & CONF_FLAG_MULTI), \
137 _p, (_mismatch_uint32) 0), \
138 uint32_t ** : __builtin_choose_expr((_t == FR_TYPE_UINT32) && ((_f) & CONF_FLAG_MULTI), \
139 _p, (_mismatch_uint32_m) 0), \
140 fr_ipaddr_t * : __builtin_choose_expr(((_t == FR_TYPE_IPV4_ADDR) || \
141 (_t == FR_TYPE_IPV4_PREFIX) || \
142 (_t == FR_TYPE_IPV6_ADDR) || \
143 (_t == FR_TYPE_IPV6_PREFIX) || \
144 (_t == FR_TYPE_COMBO_IP_PREFIX) || \
145 (_t == FR_TYPE_COMBO_IP_ADDR)) && \
146 !((_f) & CONF_FLAG_MULTI), _p, (_mismatch_fripaddr) 0), \
147 fr_ipaddr_t ** : __builtin_choose_expr(((_t == FR_TYPE_IPV4_ADDR) || \
148 (_t == FR_TYPE_IPV4_PREFIX) || \
149 (_t == FR_TYPE_IPV6_ADDR) || \
150 (_t == FR_TYPE_IPV6_PREFIX) || \
151 (_t == FR_TYPE_COMBO_IP_PREFIX) || \
152 (_t == FR_TYPE_COMBO_IP_ADDR)) && \
153 ((_f) & CONF_FLAG_MULTI), _p, (_mismatch_fripaddr_m) 0), \
154 uint8_t const ** : __builtin_choose_expr((_t == FR_TYPE_OCTETS) && !((_f) & CONF_FLAG_MULTI), \
155 _p, (_mismatch_uint8) 0), \
156 uint8_t const ***: __builtin_choose_expr((_t == FR_TYPE_OCTETS) && ((_f) & CONF_FLAG_MULTI), \
157 _p, (_mismatch_uint8_m) 0), \
158 uint8_t * : __builtin_choose_expr((_t == FR_TYPE_UINT8) && !((_f) & CONF_FLAG_MULTI), \
159 _p, (_mismatch_uint8) 0), \
160 uint8_t ** : __builtin_choose_expr((_t == FR_TYPE_UINT8) && ((_f) & CONF_FLAG_MULTI), \
161 _p, (_mismatch_uint8_m) 0), \
162 uint16_t * : __builtin_choose_expr((_t == FR_TYPE_UINT16) && !((_f) & CONF_FLAG_MULTI), \
163 _p, (_mismatch_uint16) 0), \
164 uint16_t ** : __builtin_choose_expr((_t == FR_TYPE_UINT16) && ((_f) & CONF_FLAG_MULTI), \
165 _p, (_mismatch_uint16_m) 0), \
166 int32_t * : __builtin_choose_expr((_t == FR_TYPE_INT32) && !((_f) & CONF_FLAG_MULTI), \
167 _p, (_mismatch_int32) 0), \
168 int32_t ** : __builtin_choose_expr((_t == FR_TYPE_INT32) && ((_f) & CONF_FLAG_MULTI), \
169 _p, (_mismatch_int32_m) 0), \
170 uint64_t * : __builtin_choose_expr((_t == FR_TYPE_UINT64) && !((_f) & CONF_FLAG_MULTI), \
171 _p, (_mismatch_uint64) 0), \
172 uint64_t ** : __builtin_choose_expr((_t == FR_TYPE_UINT64) && ((_f) & CONF_FLAG_MULTI), \
173 _p, (_mismatch_uint64_m) 0), \
174 float * : __builtin_choose_expr((_t == FR_TYPE_FLOAT32) && !((_f) & CONF_FLAG_MULTI), \
175 _p, (_mismatch_float) 0), \
176 float ** : __builtin_choose_expr((_t == FR_TYPE_FLOAT32) && ((_f) & CONF_FLAG_MULTI), \
177 _p, (_mismatch_float_m) 0), \
178 double * : __builtin_choose_expr((_t == FR_TYPE_FLOAT64) && !((_f) & CONF_FLAG_MULTI), \
179 _p, (_mismatch_double) 0), \
180 double ** : __builtin_choose_expr((_t == FR_TYPE_FLOAT64) && ((_f) & CONF_FLAG_MULTI), \
181 _p, (_mismatch_double_m) 0), \
182 default: (conf_type_mismatch)0)))))
183#else
184# define FR_CONF_FLAG_CHECK(_type, _flags, _c_type, _ptr_or_offset) _ptr_or_offset
185#endif
186
187#define CONF_CTYPE_TO_FLAGS(_ct) \
188_Generic(&(_ct), \
189 tmpl_t ** : CONF_FLAG_TMPL, \
190 tmpl_t *** : CONF_FLAG_TMPL | CONF_FLAG_MULTI, \
191 xlat_t ** : CONF_FLAG_XLAT, \
192 xlat_t *** : CONF_FLAG_XLAT | CONF_FLAG_MULTI, \
193 fr_ethernet_t * : 0, \
194 fr_ethernet_t ** : CONF_FLAG_MULTI, \
195 fr_ifid_t * : 0, \
196 fr_ifid_t ** : CONF_FLAG_MULTI, \
197 fr_time_t * : 0, \
198 fr_time_t ** : CONF_FLAG_MULTI, \
199 fr_time_delta_t * : 0, \
200 fr_time_delta_t ** : CONF_FLAG_MULTI, \
201 char const ** : 0, \
202 char const *** : CONF_FLAG_MULTI, \
203 bool * : 0, \
204 bool ** : CONF_FLAG_MULTI, \
205 uint8_t const ** : 0, \
206 uint8_t const *** : CONF_FLAG_MULTI, \
207 uint8_t * : 0, \
208 uint8_t ** : CONF_FLAG_MULTI, \
209 uint16_t * : 0, \
210 uint16_t ** : CONF_FLAG_MULTI, \
211 uint32_t * : 0, \
212 uint32_t ** : CONF_FLAG_MULTI, \
213 uint64_t * : 0, \
214 uint64_t ** : CONF_FLAG_MULTI, \
215 int8_t * : 0, \
216 int8_t ** : CONF_FLAG_MULTI, \
217 int16_t * : 0, \
218 int16_t ** : CONF_FLAG_MULTI, \
219 int32_t * : 0, \
220 int32_t ** : CONF_FLAG_MULTI, \
221 int64_t * : 0, \
222 int64_t ** : CONF_FLAG_MULTI, \
223 float * : 0, \
224 float ** : CONF_FLAG_MULTI, \
225 double * : 0, \
226 double ** : CONF_FLAG_MULTI)
227
228/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
229 *
230 * This variant takes output type and flags manually, instead of determining them automatically.
231 *
232 * @param[in] _name of the CONF_PAIR to search for.
233 * @param[in] _type to parse the CONF_PAIR as.
234 * @param[in] _flags controlling parsing behaviour.
235 * @param[in] _struct containing the field to write the result to.
236 * @param[in] _field to write the result to.
237 */
238# define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field) \
239 .name1 = _name, \
240 .type = (fr_type_t)(_type), \
241 .flags = (conf_parser_flags_t)(_flags), \
242 .offset = FR_CONF_FLAG_CHECK((_type), (_flags), &(((_struct *)NULL)->_field), offsetof(_struct, _field))
243
244/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
245 *
246 * This variant takes output hint type. If the type is a bare word, it MUST be of the relevant data type.
247 *
248 * @param[in] _name of the CONF_PAIR to search for.
249 * @param[in] _type to parse the CONF_PAIR as.
250 * @param[in] _struct containing the field to write the result to.
251 * @param[in] _field to write the result to.
252 */
253# define FR_CONF_OFFSET_HINT_TYPE(_name, _type, _struct, _field) \
254 .name1 = _name, \
255 .type = (fr_type_t)(_type), \
256 .flags = CONF_FLAG_TMPL, \
257 .offset = FR_CONF_FLAG_CHECK(FR_TYPE_VOID, CONF_FLAG_TMPL, &(((_struct *)NULL)->_field), offsetof(_struct, _field))
258
259/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
260 *
261 * This variant takes additional flags, and will add CONF_FLAG_MULTI automatically if the field is an array.
262 *
263 * @param[in] _name of the CONF_PAIR to search for.
264 * @param[in] _flags controlling parsing behaviour.
265 * @param[in] _struct containing the field to write the result to.
266 * @param[in] _field to write the result to.
267 */
268# define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field) \
269 FR_CONF_OFFSET_TYPE_FLAGS(_name, \
270 FR_CTYPE_TO_TYPE((((_struct *)NULL)->_field)), \
271 (_flags) | CONF_CTYPE_TO_FLAGS((((_struct *)NULL)->_field)),\
272 _struct, _field)
273
274/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
275 *
276 * @param[in] _name of the CONF_PAIR to search for.
277 * @param[in] _struct containing the field to write the result to.
278 * @param[in] _field to write the result to.
279 */
280# define FR_CONF_OFFSET(_name, _struct, _field) \
281 FR_CONF_OFFSET_TYPE_FLAGS(_name, \
282 FR_CTYPE_TO_TYPE((((_struct *)NULL)->_field)), \
283 CONF_CTYPE_TO_FLAGS((((_struct *)NULL)->_field)),\
284 _struct, _field)
285
286/** conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct, recording if a default was used in `<_field>`_is_set
287 *
288 * @param[in] _name of the CONF_PAIR to search for.
289 * @param[in] _type to parse the CONF_PAIR as.
290 * @param[in] _flags controlling parsing behaviour.
291 * @param[in] _struct containing the field to write the result to.
292 * @param[in] _field to write the result to.
293 */
294# define FR_CONF_OFFSET_IS_SET(_name, _type, _flags, _struct, _field) \
295 .name1 = _name, \
296 .type = (fr_type_t)(_type), \
297 .flags = (conf_parser_flags_t)(CONF_FLAG_IS_SET | (_flags)), \
298 .offset = FR_CONF_FLAG_CHECK((_type), (_flags), &(((_struct *)NULL)->_field), offsetof(_struct, _field)), \
299 .is_set_offset = offsetof(_struct, _field ## _is_set)
300
301/** conf_parser_t which populates a sub-struct using a CONF_SECTION
302 *
303 * @param[in] _name of the CONF_SECTION to search for.
304 * @param[in] _flags controlling parsing behaviour.
305 * @param[in] _struct containing the sub-struct to populate.
306 * @param[in] _field containing the sub-struct to populate.
307 * @param[in] _subcs CONF_SECTION to parse.
308 */
309# define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs) \
310 .name1 = _name, \
311 .flags = (conf_parser_flags_t)(CONF_FLAG_SUBSECTION | (_flags)), \
312 .offset = offsetof(_struct, _field), \
313 .subcs = _subcs
314
315/** conf_parser_t which populates a sub-struct using a CONF_SECTION, recording if the CONF_SECTION was found in `<_is_set_field>`
316 *
317 * @param[in] _name of the CONF_SECTION to search for.
318 * @param[in] _flags controlling parsing behaviour.
319 * @param[in] _struct containing the sub-struct to populate.
320 * @param[in] _field containing the sub-struct to populate.
321 * @param[in] _is_set_field bool to write the is set state to.
322 * @param[in] _subcs CONF_SECTION to parse.
323 */
324# define FR_CONF_OFFSET_SUBSECTION_IS_SET(_name, _flags, _struct, _field, _is_set_field, _subcs) \
325 .name1 = _name, \
326 .flags = (conf_parser_flags_t)(CONF_FLAG_SUBSECTION | CONF_FLAG_IS_SET | (_flags)), \
327 .offset = offsetof(_struct, _field), \
328 .is_set_offset = offsetof(_struct, _is_set_field), \
329 .subcs = _subcs
330
331/** conf_parser_t which populates a sub-struct using a CONF_SECTION
332 *
333 * @param[in] _struct containing the sub-struct to populate.
334 * @param[in] _field containing the sub-struct to populate.
335 * @param[in] _subcs conf_parser_t to include in-line in this section
336 */
337# define FR_CONF_OFFSET_REF(_struct, _field, _subcs) \
338 .name1 = CF_IDENT_ANY, \
339 .flags = CONF_FLAG_REF, \
340 .offset = offsetof(_struct, _field), \
341 .subcs = _subcs
342
343/** conf_parser_t which parses a single CONF_PAIR producing a single global result
344 *
345 * @param[in] _name of the CONF_PAIR to search for.
346 * @param[in] _type to parse the CONF_PAIR as.
347 * @param[in] _flags controlling parsing behaviour.
348 * @param[out] _res_p pointer to a global var, where the result will be written.
349 */
350# define FR_CONF_POINTER(_name, _type, _flags, _res_p) \
351 .name1 = _name, \
352 .type = (fr_type_t)(_type), \
353 .flags = (conf_parser_flags_t)(_flags), \
354 .data = FR_CONF_FLAG_CHECK((_type), (_flags), (_res_p), _res_p)
355
356/** conf_parser_t which parses a single CONF_PAIR producing a single global result, recording if a default was used in `<_res_p>`_is_set
357 *
358 * @note is set state is recorded in variable `<_res_p>`_is_set.
359 *
360 * @param[in] _name of the CONF_PAIR to search for.
361 * @param[in] _type to parse the CONF_PAIR as.
362 * @param[in] _flags controlling parsing behaviour.
363 * @param[out] _res_p pointer to a global var, where the result will be written.
364 */
365# define FR_CONF_POINTER_IS_SET(_name, _type, _flags, _res_p) \
366 .name1 = _name, \
367 .type = (fr_type_t)(_type), \
368 .flags = (conf_parser_flags_t)(CONF_FLAG_IS_SET | (_flags)), \
369 .data = FR_CONF_FLAG_CHECK((_type), (_flags), (_res_p), _res_p), \
370 .is_set_ptr = _res_p ## _is_set
371# define FR_ITEM_POINTER(_type, _res_p) _type, FR_CONF_FLAG_CHECK((_type), 0, (_res_p), _res_p)
372
373/** conf_parser_t which allocates a struct and populates it from a subsection
374 *
375 * The parser allocates the struct, so `_field` is a pointer to the struct.
376 * Set `.subcs_type` on the rule to name the talloc chunk.
377 *
378 * @param[in] _name name of subsection to search for.
379 * @param[in] _flags flags controlling parsing behaviour.
380 * @param[in] _struct instance data struct.
381 * @param[in] _field pointer field in instance data struct.
382 * @param[in] _subcs conf_parser_t array to use to parse subsection data.
383 */
384# define FR_CONF_SUBSECTION_ALLOC(_name, _flags, _struct, _field, _subcs) \
385 .name1 = _name, \
386 .flags = (conf_parser_flags_t)(CONF_FLAG_SUBSECTION | (_flags)), \
387 .offset = offsetof(_struct, _field), \
388 .subcs = _subcs, \
389 .subcs_size = sizeof(*(((_struct *)0)->_field))
390
391/** conf_parser_t which allocates one struct for each instance of a subsection
392 *
393 * The parser allocates an array of pointers with one struct per matching
394 * subsection, so `_field` is a pointer to a pointer to the struct.
395 * Set `.subcs_type` on the rule to name the talloc chunks.
396 *
397 * @param[in] _name name of subsection to search for.
398 * @param[in] _flags flags controlling parsing behaviour.
399 * @param[in] _struct instance data struct.
400 * @param[in] _field array field in instance data struct.
401 * @param[in] _subcs conf_parser_t array to use to parse subsection data.
402 */
403# define FR_CONF_SUBSECTION_ALLOC_MULTI(_name, _flags, _struct, _field, _subcs) \
404 .name1 = _name, \
405 .flags = (conf_parser_flags_t)(CONF_FLAG_SUBSECTION | CONF_FLAG_MULTI | (_flags)), \
406 .offset = offsetof(_struct, _field), \
407 .subcs = _subcs, \
408 .subcs_size = sizeof(**(((_struct *)0)->_field))
409
410/** conf_parser_t entry which doesn't fill in a pointer or offset, but relies on functions to record values
411 *
412 * @param[in] _name name of pair to search for.
413 * @param[in] _type base type to parse pair as.
414 * @param[in] _flags flags controlling parsing behaviour.
415 * @param[in] _func to use to record value.
416 * @param[in] _dflt_func to use to get defaults from a 3rd party library.
417 */
418# define FR_CONF_PAIR_GLOBAL(_name, _type, _flags, _func, _dflt_func) \
419 .name1 = _name, \
420 .type = (fr_type_t)(_type), \
421 .flags = (conf_parser_flags_t)(CONF_FLAG_NO_OUTPUT | (_flags)), \
422 .func = _func, \
423 .dflt_func = _dflt_func
424
425/** conf_parser_t entry which runs conf_parser_t entries for a subsection without any output
426 *
427 * @param[in] _name of pair to search for.
428 * @param[in] _flags flags controlling parsing behaviour.
429 * @param[in] _subcs to use to get defaults from a 3rd party library.
430 */
431# define FR_CONF_SUBSECTION_GLOBAL(_name, _flags, _subcs) \
432 .name1 = _name, \
433 .flags = (conf_parser_flags_t)(CONF_FLAG_SUBSECTION | CONF_FLAG_NO_OUTPUT | (_flags)), \
434 .subcs = _subcs
435
436/** conf_parser_t entry which raises an error if a deprecated v3 item is found
437 *
438 * We don't want to include v3 compatibility support forever. But we do want to
439 * catch the cases where people use the v3 config. So we add CONF_PARSER entries
440 * for the old config, and then produce errors when they're seen.
441 *
442 * @param[in] _name of pair to search for.
443 * @param[in] _struct where the result was previously written.
444 * @param[in] _field in the struct where the result was previously written.
445 */
446#define FR_CONF_V3_DEPRECATED(_name, _struct, _field) \
447 .name1 = _name, \
448 .flags = CONF_FLAG_V3_DEPRECATED
449
450/** @name #conf_parser_t type flags
451 *
452 * These flags should be or'd with another FR_TYPE_* value to create validation
453 * rules for the #cf_pair_parse function.
454 *
455 * @{
456 */
457DIAG_OFF(attributes)
458typedef enum CC_HINT(flag_enum) : uint32_t {
459 CONF_FLAG_NONE = 0, //!< No special flags.
460 CONF_FLAG_SUBSECTION = (1 << 1), //!< Instead of putting the information into a
461 ///< configuration structure, the configuration
462 ///< file routines MAY just parse it directly into
463 ///< user-supplied variables.
464 CONF_FLAG_V3_DEPRECATED = (1 << 10), //!< If a matching #CONF_PAIR is found,
465 //!< error out with a deprecated message.
466 CONF_FLAG_REQUIRED = (1 << 11), //!< Error out if no matching #CONF_PAIR
467 //!< is found, and no dflt value is set.
468 CONF_FLAG_ATTRIBUTE = (1 << 12), //!< Value must resolve to attribute in dict
469 //!< (deprecated, use #CONF_FLAG_TMPL).
470 CONF_FLAG_SECRET = (1 << 13), //!< Only print value if debug level >= 3.
471
472 CONF_FLAG_FILE_READABLE = (1 << 14), //!< File matching value must exist,
473 //!< and must be readable.
474 CONF_FLAG_FILE_WRITABLE = (1 << 15), //!< File matching value must exist,
475 //!< and must be writable.
476 CONF_FLAG_FILE_SOCKET = (1 << 16), //!< File matching value must exist,
477 //!< and must be a unix socket.
478 CONF_FLAG_FILE_EXISTS = (1 << 17), //!< File matching value must exist
479
480 CONF_FLAG_XLAT = (1 << 18), //!< string will be dynamically expanded.
481 CONF_FLAG_TMPL = (1 << 19), //!< CONF_PAIR should be parsed as a template.
482
483 CONF_FLAG_MULTI = (1 << 20), //!< CONF_PAIR can have multiple copies.
484 CONF_FLAG_NOT_EMPTY = (1 << 21), //!< CONF_PAIR is required to have a non zero
485 //!< length value.
486
487
488 CONF_FLAG_IS_SET = (1 << 22), //!< Write whether this config item was
489 //!< left as the default to is_set_offset
490 //!< or is_set_ptr.
491 CONF_FLAG_OK_MISSING = (1 << 23), //!< OK if it's missing
492 CONF_FLAG_HIDDEN = (1 << 24), //!< Used by scripts to omit items from the
493 ///< generated documentation.
494 CONF_FLAG_REF = (1 << 25), //!< reference another conf_parser_t inline in this one
495 CONF_FLAG_OPTIONAL = (1 << 26), //!< subsection is pushed only if a non-optional matching one is pushed
496 CONF_FLAG_ALWAYS_PARSE = (1 << 27), //!< Run this rule even against items already marked
497 ///< parsed. Useful for CF_IDENT_ANY observer rules that
498 ///< want to see every item, not just the leftovers, or for
499 ///< a second-pass rule that needs to re-examine something
500 ///< an earlier rule already claimed.
501 CONF_FLAG_NO_OUTPUT = (1 << 28), //!< Rule has no framework-managed output destination.
502 ///< The parse function owns its own side effects - the
503 ///< framework will not pre-zero `base + offset` for
504 ///< strings, nor write a MULTI array pointer through
505 ///< that offset. Set automatically by `FR_CONF_PAIR_GLOBAL`
506 ///< so its default `offset = 0` doesn't clobber the
507 ///< first field of `base`.
508 CONF_FLAG_STATIC = (1 << 29), //!< The #tmpl_t must hold a fixed value. The code
509 ///< that reads the value does not expand the tmpl
510 ///< at runtime, so an expansion, an attribute
511 ///< reference or an exec is a configuration error.
513DIAG_ON(attributes)
514
515/** @} */
516
517/** @name #conf_parser_t flags checks
518 *
519 * @{
520 */
521#define fr_rule_v3_deprecated(_rule) ((_rule)->flags & CONF_FLAG_V3_DEPRECATED)
522
523#define fr_rule_required(_rule) ((_rule)->flags & CONF_FLAG_REQUIRED)
524
525#define fr_rule_secret(_rule) ((_rule)->flags & CONF_FLAG_SECRET)
526
527#define fr_rule_file_readable(_rule) ((_rule)->flags & CONF_FLAG_FILE_READABLE)
528
529#define fr_rule_file_writable(_rule) ((_rule)->flags & CONF_FLAG_FILE_WRITABLE)
530
531#define fr_rule_file_socket(_rule) ((_rule)->flags & CONF_FLAG_FILE_SOCKET)
532
533#define fr_rule_file_exists(_rule) ((_rule)->flags & CONF_FLAG_FILE_EXISTS)
534
535#define fr_rule_multi(_rule) ((_rule)->flags & CONF_FLAG_MULTI)
536
537#define fr_rule_not_empty(_rule) ((_rule)->flags & CONF_FLAG_NOT_EMPTY)
538
539#define fr_rule_is_set(_rule) ((_rule)->flags & CONF_FLAG_IS_SET)
540
541#define fr_rule_ok_missing(_rule) ((_rule)->flags & CONF_FLAG_OK_MISSING)
542
543#define fr_rule_dflt(_rule) ((_rule)->dflt || (_rule)->dflt_func)
544
545#define fr_rule_is_attribute(_rule) ((_rule)->flags & CONF_FLAG_ATTRIBUTE)
546
547#define fr_rule_is_xlat(_rule) ((_rule)->flags & CONF_FLAG_XLAT)
548
549#define fr_rule_is_tmpl(_rule) ((_rule)->flags & CONF_FLAG_TMPL)
550
551#define fr_rule_is_static(_rule) ((_rule)->flags & CONF_FLAG_STATIC)
552/** @} */
553
554#define FR_SIZE_COND_CHECK(_name, _var, _cond, _new)\
555do {\
556 if (!(_cond)) {\
557 WARN("Ignoring \"" _name " = %zu\", forcing to \"" _name " = %zu\"", _var, _new);\
558 _var = _new;\
559 }\
560} while (0)
561
562#define FR_SIZE_BOUND_CHECK(_name, _var, _op, _bound) FR_SIZE_COND_CHECK(_name, _var, (_var _op _bound), _bound)
563
564#define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\
565do {\
566 if (!(_cond)) {\
567 WARN("Ignoring \"" _name " = %u\", forcing to \"" _name " = %u\"", (unsigned int) (_var), (unsigned int) (_new));\
568 _var = _new;\
569 }\
570} while (0)
571
572#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound) FR_INTEGER_COND_CHECK(_name, _var, (_var _op _bound), _bound)
573
574#define FR_TIME_DELTA_COND_CHECK(_name, _var, _cond, _new)\
575do {\
576 if (!(_cond)) {\
577 WARN("Ignoring \"" _name " = %pV\", forcing to \"" _name " = %pV\"", \
578 fr_box_time_delta(_var), fr_box_time_delta(_new));\
579 _var = _new;\
580 }\
581} while (0)
582
583#define FR_TIME_DELTA_BOUND_CHECK(_name, _var, _op, _bound)\
584do {\
585 if (!fr_time_delta_cond(_var, _op, _bound)) { \
586 WARN("Ignoring \"" _name " = %pV\", forcing to \"" _name " = %pV\"",\
587 fr_box_time_delta(_var),\
588 fr_box_time_delta(_bound));\
589 _var = _bound;\
590 }\
591} while (0)
592
593extern bool check_config;
594
595/** Callback for performing custom parsing of a #CONF_SECTION or CONF_PAIR
596 *
597 * @param[in] ctx to allocate any data in.
598 * @param[out] out Where to write the result of parsing.
599 * @param[in] parent The base address of the structure.
600 * @param[in] ci The #CONF_SECTION or #CONF_PAIR to parse.
601 * @param[in] rule Parse rules - How the #CONF_PAIR or #CONF_SECTION should be converted.
602 * @return
603 * - 0 on success.
604 * - -1 on failure.
605 */
606typedef int (*cf_parse_t)(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule);
607
608/** Callback for producing dynamic defaults from 3rd party libraries
609 *
610 * @param[out] out Where to write default conf pair.
611 * @param[in] parent being populated.
612 * @param[in] cs to allocate pair in.
613 * @param[in] quote to use when allocing the pair. Provided as a convenience.
614 * @param[in] rule to produce default for.
615 * @return
616 * - 0 on success.
617 * - -1 on failure.
618 */
619typedef int (*cf_dflt_t)(CONF_PAIR **out, void *parent, CONF_SECTION *cs, fr_token_t quote, conf_parser_t const *rule);
620
621/** Defines a #CONF_PAIR to C data type mapping
622 *
623 * Is typically used to define mappings between module sections, and module instance structs.
624 * May also be used to set global configuration options.
625 *
626 * Offset/data values should be set using #FR_CONF_OFFSET or #FR_CONF_POINTER.
627 *
628 * Example with #FR_CONF_OFFSET :
629 @code{.c}
630 static conf_parser_t module_config[] = {
631 { FR_CONF_OFFSET_TYPE_FLAGS("example", FR_TYPE_STRING | CONF_FLAG_NOT_EMPTY, 0, 0, example_instance_t, example), .dflt = "default_value" },
632 CONF_PARSER_TERMINATOR
633 }
634 @endcode
635 *
636 * Example with #FR_CONF_POINTER :
637 @code{.c}
638 static conf_parser_t global_config[] = {
639 { FR_CONF_POINTER("example", FR_TYPE_STRING | CONF_FLAG_NOT_EMPTY, 0, 0, 0, &my_global), .dflt = "default_value" },
640 CONF_PARSER_TERMINATOR
641 }
642 @endcode
643 *
644 * @see FR_CONF_OFFSET
645 * @see FR_CONF_POINTER
646 * @see cf_section_parse
647 * @see cf_pair_parse
648 */
650 char const *name1; //!< Name of the #CONF_ITEM to parse.
651 char const *name2; //!< Second identifier for #CONF_SECTION.
652
653 fr_type_t type; //!< An #fr_type_t value, controls the output type.
654
655 conf_parser_flags_t flags; //!< Flags which control parsing behaviour.
656
657 size_t offset; //!< Relative offset of field or structure to write the parsed value to.
658 //!< When #flags is set to #CONF_FLAG_SUBSECTION, may be used to specify
659 //!< a base offset to add to all offsets contained within the
660 //!< subsection.
661 //!< @note Must be used exclusively to #data.
662
663 void *data; //!< Pointer to a static variable to write the parsed value to.
664 //!< @note Must be used exclusively to #offset.
665
666 cf_parse_t func; //!< Override default parsing behaviour for the specified type with
667 //!< a custom parsing function.
668
669 cf_parse_t on_read; //!< Function to call as the item is being read, just after
670 //!< it has been allocated and initialized.
671
672 void const *uctx; //!< User data accessible by the #cf_parse_t func. Useful for
673 ///< building reusable functions.
674
675 /** Where to write status if FR_TYPE_IS_DEFAULT is set
676 *
677 * @note Which field is used, is determined by whether
678 * data ptr is set.
679 */
680 union {
681 size_t is_set_offset; //!< If type contains FR_TYPE_IS_DEFAULT write status to bool.
682 //!< at this address.
683 void *is_set_ptr; //!< If type contains FR_TYPE_IS_DEFAULT write status to ptr
684 //!< at this address.
685 };
686
687 union {
688 struct {
689 char const *dflt; //!< Default as it would appear in radiusd.conf.
690
691 cf_dflt_t dflt_func; //!< Function to produce dynamic defaults.
692 };
693
694 struct {
695 conf_parser_t const *subcs; //!< When #CONF_FLAG_SUBSECTION is set, should
696 //!< be a pointer to the start of another array of
697 //!< #conf_parser_t structs, forming the subsection.
698 size_t subcs_size; //!< If non-zero, allocate structs of this size to hold
699 //!< the parsed data.
700 char const *subcs_type; //!< Set a specific talloc type for subcs structures.
701 };
702 };
703
704 fr_token_t quote; //!< Quoting around the default value. Only used for templates.
705};
706
707typedef struct {
709 size_t *len;
711
712/** Bounds for #cf_parse_time_delta_bounded, passed as the rule's uctx
713 */
714typedef struct {
715 fr_time_delta_t min; //!< Smallest value accepted.
716 fr_time_delta_t max; //!< Largest value accepted. 0 means no maximum.
718
721
722#define CONF_PARSER_TERMINATOR { .name1 = NULL, .type = (fr_type_t)~(UINT32_MAX - 1), \
723 .offset = 0, .data = NULL, .dflt = NULL, .quote = T_INVALID }
724
725#define CONF_PARSER_PARTIAL_TERMINATOR { .name1 = NULL, .type = (fr_type_t)~(UINT32_MAX - 1), \
726 .offset = 1, .data = NULL, .dflt = NULL, .quote = T_INVALID }
727
728#define CF_FILE_NONE (0)
729#define CF_FILE_ERROR (1)
730#define CF_FILE_CONFIG (1 << 2)
731#define CF_FILE_MODULE (1 << 3)
732
733void cf_pair_debug_log(CONF_SECTION const *cs, CONF_PAIR *cp, conf_parser_t const *rule);
734
735/*
736 * Type validation and conversion
737 */
738int cf_pair_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, CONF_PAIR *cp, conf_parser_t const *rule)
739 CC_HINT(nonnull(2, 3, 4));
740
741int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, void *base, CONF_ITEM *ci, conf_parser_t const *rule)
742 CC_HINT(nonnull(2, 4, 5));
743
744int cf_pair_parse(TALLOC_CTX *ctx, CONF_SECTION *cs, char const *name,
745 unsigned int type, void *data, char const *dflt, fr_token_t dflt_quote) CC_HINT(nonnull(2,3));
746int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs);
747int cf_section_parse_pass2(void *base, CONF_SECTION *cs);
748
749/*
750 * Runtime parse rules
751 */
752#define cf_section_rule_push(_cs, _rule) _cf_section_rule_push(_cs, _rule, __FILE__, __LINE__)
753int _cf_section_rule_push(CONF_SECTION *cs, conf_parser_t const *rule, char const *filename, int lineno);
754#define cf_section_rules_push(_cs, _rule) _cf_section_rules_push(_cs, _rule, __FILE__, __LINE__)
755int _cf_section_rules_push(CONF_SECTION *cs, conf_parser_t const *rules, char const *filename, int lineno);
756
757/*
758 * Generic parsing callback functions
759 */
760
761/** @name Table lookups, one function per field type
762 *
763 * Each function resolves the #CONF_PAIR value in the table passed as the
764 * rule's uctx, and writes the result as the type in its name. Use the
765 * function matching the field's type. An enum field gets the function
766 * matching the enum's fixed underlying type.
767 * @{
768 */
769int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
770 CONF_ITEM *ci, conf_parser_t const *rule);
771int cf_table_parse_int8(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
772 CONF_ITEM *ci, conf_parser_t const *rule);
773int cf_table_parse_int16(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
774 CONF_ITEM *ci, conf_parser_t const *rule);
775int cf_table_parse_int32(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
776 CONF_ITEM *ci, conf_parser_t const *rule);
777int cf_table_parse_uint8(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
778 CONF_ITEM *ci, conf_parser_t const *rule);
779int cf_table_parse_uint16(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
780 CONF_ITEM *ci, conf_parser_t const *rule);
781int cf_table_parse_uint32(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
782 CONF_ITEM *ci, conf_parser_t const *rule);
783/** @} */
784
785int cf_parse_uid(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
786 CONF_ITEM *ci, conf_parser_t const *rule);
787
788int cf_parse_gid(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
789 CONF_ITEM *ci, conf_parser_t const *rule);
790
791int cf_parse_permissions(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
792 CONF_ITEM *ci, conf_parser_t const *rule);
793
794int cf_parse_time_delta_bounded(TALLOC_CTX *ctx, void *out, void *parent,
795 CONF_ITEM *ci, conf_parser_t const *rule);
796
797int cf_null_on_read(TALLOC_CTX *ctx, void *out, void *parent,
798 CONF_ITEM *ci, conf_parser_t const *rule);
799
800/** Return the source-identifier name for a single CONF_FLAG_* bit.
801 *
802 * `mask` MUST be a single-bit mask from `conf_parser_flags_t`
803 * (e.g. `CONF_FLAG_REQUIRED`). Used by tooling that wants to
804 * stringify a flag set bit-by-bit (radmod2json).
805 *
806 * @param[in] mask single-bit `CONF_FLAG_*` value.
807 * @return the enum-identifier name, or `NULL` if `mask`
808 * is not a known flag bit.
809 */
811
812#ifdef __cplusplus
813}
814#endif
#define DIAG_ON(_x)
Definition build.h:576
#define RCSIDH(h, id)
Definition build.h:604
#define UNUSED
Definition build.h:415
#define DIAG_OFF(_x)
Definition build.h:575
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:666
int cf_table_parse_uint32(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int(* cf_dflt_t)(CONF_PAIR **out, void *parent, CONF_SECTION *cs, fr_token_t quote, conf_parser_t const *rule)
Callback for producing dynamic defaults from 3rd party libraries.
Definition cf_parse.h:619
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition cf_parse.c:1360
void const * uctx
User data accessible by the cf_parse_t func.
Definition cf_parse.h:672
char const * cf_parser_flag_to_enum_str(conf_parser_flags_t mask)
Return the source-identifier name for a single CONF_FLAG_* bit.
Definition cf_parse.c:1988
void * data
Pointer to a static variable to write the parsed value to.
Definition cf_parse.h:663
int cf_table_parse_int32(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int cf_pair_parse(TALLOC_CTX *ctx, CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt, fr_token_t dflt_quote))
Parses a CONF_PAIR into a C data type, with a default value.
Definition cf_parse.c:844
bool check_config
Definition cf_file.c:61
int cf_parse_uid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
conf_parser_flags_t flags
Flags which control parsing behaviour.
Definition cf_parse.h:655
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int cf_table_parse_uint16(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int cf_parse_permissions(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
fr_type_t type
An fr_type_t value, controls the output type.
Definition cf_parse.h:653
int cf_table_parse_int8(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
size_t offset
Relative offset of field or structure to write the parsed value to.
Definition cf_parse.h:657
char const * name2
Second identifier for CONF_SECTION.
Definition cf_parse.h:651
conf_parser_flags_t
Definition cf_parse.h:458
@ CONF_FLAG_STATIC
The tmpl_t must hold a fixed value.
Definition cf_parse.h:508
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:466
@ CONF_FLAG_FILE_SOCKET
File matching value must exist, and must be a unix socket.
Definition cf_parse.h:476
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition cf_parse.h:483
@ CONF_FLAG_V3_DEPRECATED
If a matching CONF_PAIR is found, error out with a deprecated message.
Definition cf_parse.h:464
@ CONF_FLAG_REF
reference another conf_parser_t inline in this one
Definition cf_parse.h:494
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition cf_parse.h:470
@ CONF_FLAG_NO_OUTPUT
Rule has no framework-managed output destination.
Definition cf_parse.h:501
@ CONF_FLAG_IS_SET
Write whether this config item was left as the default to is_set_offset or is_set_ptr.
Definition cf_parse.h:488
@ CONF_FLAG_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use CONF_FLAG_TMPL).
Definition cf_parse.h:468
@ CONF_FLAG_NONE
No special flags.
Definition cf_parse.h:459
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
Definition cf_parse.h:484
@ CONF_FLAG_XLAT
string will be dynamically expanded.
Definition cf_parse.h:480
@ CONF_FLAG_OPTIONAL
subsection is pushed only if a non-optional matching one is pushed
Definition cf_parse.h:495
@ CONF_FLAG_FILE_READABLE
File matching value must exist, and must be readable.
Definition cf_parse.h:472
@ CONF_FLAG_OK_MISSING
OK if it's missing.
Definition cf_parse.h:491
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:460
@ CONF_FLAG_FILE_EXISTS
File matching value must exist.
Definition cf_parse.h:478
@ CONF_FLAG_TMPL
CONF_PAIR should be parsed as a template.
Definition cf_parse.h:481
@ CONF_FLAG_HIDDEN
Used by scripts to omit items from the generated documentation.
Definition cf_parse.h:492
@ CONF_FLAG_ALWAYS_PARSE
Run this rule even against items already marked parsed.
Definition cf_parse.h:496
@ CONF_FLAG_FILE_WRITABLE
File matching value must exist, and must be writable.
Definition cf_parse.h:474
void cf_pair_debug_log(CONF_SECTION const *cs, CONF_PAIR *cp, conf_parser_t const *rule)
Definition cf_parse.c:50
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:704
fr_table_num_sorted_t const * table
Definition cf_parse.h:708
fr_time_delta_t max
Largest value accepted. 0 means no maximum.
Definition cf_parse.h:716
int(* cf_parse_t)(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Callback for performing custom parsing of a CONF_SECTION or CONF_PAIR.
Definition cf_parse.h:606
int cf_table_parse_uint8(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int cf_null_on_read(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
int cf_pair_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, CONF_PAIR *cp, conf_parser_t const *rule))
Parses a CONF_PAIR into a boxed value.
Definition cf_parse.c:127
char const * name1
Name of the CONF_ITEM to parse.
Definition cf_parse.h:650
int cf_parse_gid(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
cf_time_delta_bounds_t const cf_time_delta_bounds_int_sec
Bounds which keep a time delta within an int of seconds, for libraries which take one.
Definition cf_parse.c:1891
fr_time_delta_t min
Smallest value accepted.
Definition cf_parse.h:715
int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
Fixup xlat expansions and attributes.
Definition cf_parse.c:1470
cf_time_delta_bounds_t const cf_time_delta_bounds_int_msec
Bounds which keep a time delta within an int of milliseconds, for libraries which take one.
Definition cf_parse.c:1885
int _cf_section_rule_push(CONF_SECTION *cs, conf_parser_t const *rule, char const *filename, int lineno)
Add a single rule to a CONF_SECTION.
Definition cf_parse.c:1662
int _cf_section_rules_push(CONF_SECTION *cs, conf_parser_t const *rules, char const *filename, int lineno)
Add an array of parse rules to a CONF_SECTION.
Definition cf_parse.c:1776
cf_parse_t on_read
Function to call as the item is being read, just after it has been allocated and initialized.
Definition cf_parse.h:669
int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, void *base, CONF_ITEM *ci, conf_parser_t const *rule))
int cf_parse_time_delta_bounded(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Parse a time delta, and force it within the bounds passed as the rule's uctx.
Definition cf_parse.c:1909
int cf_table_parse_int16(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Bounds for cf_parse_time_delta_bounded, passed as the rule's uctx.
Definition cf_parse.h:714
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:649
Common header for all CONF_* types.
Definition cf_priv.h:54
Configuration AVP similar to a fr_pair_t.
Definition cf_priv.h:77
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
fr_type_t
unsigned int uint32_t
static uint32_t mask
Definition rbmonkey.c:39
static char const * name
fr_aka_sim_id_type_t type
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
enum fr_token fr_token_t
static fr_slen_t parent
Definition pair.h:864
static fr_slen_t data
Definition value.h:1366
static fr_sbuff_err_t char ** out
Definition value.h:1061
int nonnull(2, 5))