The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
xlat_func.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 528ed7661e0c5a3459b0af180518843caa077933 $
19 *
20 * @file xlat_func.c
21 * @brief Registration API for xlat functions
22 *
23 * @copyright 2023 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25
26RCSID("$Id: 528ed7661e0c5a3459b0af180518843caa077933 $")
27
28#include <freeradius-devel/server/module_rlm.h>
29#include <freeradius-devel/unlang/xlat_priv.h>
30
31static fr_rb_tree_t *xlat_root = NULL;
32
33/** Compare two xlat_t by the registered name
34 *
35 * @param[in] one First xlat_t to compare.
36 * @param[in] two Second xlat_t to compare.
37 * @return
38 * - -1 if one < two
39 * - 0 if one == two
40 * - 1 if one > two
41 */
42static fr_cmp_ret_t xlat_name_cmp(void const *one, void const *two)
43{
44 xlat_t const *a = one, *b = two;
45 size_t a_len, b_len;
46 int ret;
47
48 a_len = strlen(a->name);
49 b_len = strlen(b->name);
50
51 ret = CMP(a_len, b_len);
52 if (ret != 0) return ret;
53
54 ret = memcmp(a->name, b->name, a_len);
55 return CMP(ret, 0);
56}
57
58/** Compare two xlat_t by the underlying function
59 *
60 * @param[in] one First xlat_t to compare.
61 * @param[in] two Second xlat_t to compare.
62 * @return
63 * - -1 if one < two
64 * - 0 if one == two
65 * - 1 if one > two
66 */
67fr_cmp_ret_t xlat_func_cmp(void const *one, void const *two)
68{
69 xlat_t const *a = one, *b = two;
70
71 return CMP((uintptr_t)a->func, (uintptr_t)b->func);
72}
73
74/*
75 * find the appropriate registered xlat function.
76 */
78{
79 char buffer[256];
80 xlat_t *found;
81
82 if (!xlat_root) return NULL;
83
84 if (inlen < 0) {
85 fr_rb_find((void **)&found, xlat_root, &(xlat_t){ .name = in });
86 return found;
87 }
88
89 if ((size_t) inlen >= sizeof(buffer)) return NULL;
90
91 memcpy(buffer, in, inlen);
92 buffer[inlen] = '\0';
93
94 fr_rb_find((void **)&found, xlat_root, &(xlat_t){ .name = buffer });
95
96 return found;
97}
98
99/** Remove an xlat function from the function tree
100 *
101 * @param[in] xlat to free.
102 * @return 0
103 */
105{
106 if (!xlat_root) return 0;
107
108 fr_rb_delete(xlat_root, xlat);
109 if (fr_rb_num_elements(xlat_root) == 0) TALLOC_FREE(xlat_root);
110
111 return 0;
112}
113
114
115/** Callback for the rbtree to clear out any xlats still registered
116 *
117 */
118static void _xlat_func_tree_free(void *xlat)
119{
120 talloc_free(xlat);
121}
122
123#if 0
124/** Compare two argument entries to see if they're equivalent
125 *
126 * @note Does not check escape function or uctx pointers.
127 *
128 * @param[in] a First argument structure.
129 * @param[in] b Second argument structure.
130 * @return
131 * - 1 if a > b
132 * - 0 if a == b
133 * - -1 if a < b
134 */
135static int xlat_arg_cmp_no_escape(xlat_arg_parser_t const *a, xlat_arg_parser_t const *b)
136{
137 int8_t ret;
138
139 ret = CMP(a->required, b->required);
140 if (ret != 0) return ret;
141
142 ret = CMP(a->concat, b->concat);
143 if (ret != 0) return ret;
144
145 ret = CMP(a->single, b->single);
146 if (ret != 0) return ret;
147
148 ret = CMP(a->variadic, b->variadic);
149 if (ret != 0) return ret;
150
151 ret = CMP(a->always_escape, b->always_escape);
152 if (ret != 0) return ret;
153
154 return CMP(a->type, b->type);
155}
156
157/** Compare two argument lists to see if they're equivalent
158 *
159 * @note Does not check escape function or uctx pointers.
160 *
161 * @param[in] a First argument structure.
162 * @param[in] b Second argument structure.
163 * @return
164 * - 1 if a > b
165 * - 0 if a == b
166 * - -1 if a < b
167 */
168static int xlat_arg_cmp_list_no_escape(xlat_arg_parser_t const a[], xlat_arg_parser_t const b[])
169{
170 xlat_arg_parser_t const *arg_a_p;
171 xlat_arg_parser_t const *arg_b_p;
172
173 for (arg_a_p = a, arg_b_p = b;
174 (arg_a_p->type != FR_TYPE_NULL) && (arg_b_p->type != FR_TYPE_NULL);
175 arg_a_p++, arg_b_p++) {
176 int8_t ret;
177
178 ret = xlat_arg_cmp_no_escape(arg_a_p, arg_b_p);
179 if (ret != 0) return ret;
180 }
181
182 return CMP(arg_a_p, arg_b_p); /* Check we ended at the same point */
183}
184#endif
185
187{
188 char inst_name[256];
189 xlat_t *found;
190
192
193 if (!*name) {
194 ERROR("%s: Invalid xlat name", __FUNCTION__);
195 return NULL;
196 }
197
198 /*
199 * Name xlats other than those which are just the module instance
200 * as <instance name>.<function name>
201 */
202 if (mctx && name != mctx->mi->name) {
203 snprintf(inst_name, sizeof(inst_name), "%s.%s", mctx->mi->name, name);
204 name = inst_name;
205 }
206
207 /*
208 * If it already exists, replace the instance.
209 */
210 fr_rb_find((void **)&found, xlat_root, &(xlat_t){ .name = name });
211
212 return found;
213}
214
215/** Register an xlat function
216 *
217 * @param[in] ctx Used to automate deregistration of the xlat function.
218 * @param[in] name of the xlat.
219 * @param[in] func to register.
220 * @param[in] return_type what type of output the xlat function will produce.
221 * @return
222 * - A handle for the newly registered xlat function on success.
223 * - NULL on failure.
224 */
225xlat_t *xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
226{
227 xlat_t *c;
229 size_t len, used;
230
232
233 if (!*name) {
234 invalid_name:
235 ERROR("%s: Invalid xlat name", __FUNCTION__);
236 return NULL;
237 }
238
239 len = strlen(name);
240 if ((len == 1) && (strchr("InscCdDeGHlmMStTY", *name) != NULL)) goto invalid_name;
241
242 in = FR_SBUFF_IN(name, len);
245
246 if (used < len) {
247 ERROR("%s: Invalid character '%c' in dynamic expansion name '%s'", __FUNCTION__, name[used], name);
248 return NULL;
249 }
250
251 /*
252 * If it already exists, replace the instance.
253 */
254 fr_rb_find((void **)&c, xlat_root, &(xlat_t){ .name = name });
255 if (c) {
256 if (c->internal) {
257 ERROR("%s: Cannot re-define internal expansion %s", __FUNCTION__, name);
258 return NULL;
259 }
260
261 if (c->func != func) {
262 ERROR("%s: Cannot change callback function for %s", __FUNCTION__, name);
263 return NULL;
264 }
265
266 return c;
267 }
268
269 /*
270 * Doesn't exist. Create it.
271 */
272 MEM(c = talloc(NULL, xlat_t));
273 *c = (xlat_t){
274 .name = talloc_strdup(c, name),
275 .func = func,
276 .return_type = return_type,
277 };
278
279 /*
280 * Don't allocate directly in the parent ctx, it might be mprotected
281 * later, and that'll cause segfaults if any of the xlat_t are still
282 * protected when we start shuffling the contents of the rbtree.
283 *
284 * But we do want "c" to be freed when "ctx" is freed.
285 */
286 if (ctx) talloc_link_ctx(ctx, c);
287
288 talloc_set_destructor(c, _xlat_func_talloc_free);
289 DEBUG3("%s: %s", __FUNCTION__, c->name);
290
291 if (fr_rb_replace(NULL, xlat_root, c) < 0) {
292 ERROR("%s: Failed inserting xlat registration for %s", __FUNCTION__, c->name);
293 talloc_free(c);
294 return NULL;
295 }
296
297 return c;
298}
299
300/** Associate a module calling ctx with the xlat
301 *
302 * @note Intended to be called from the module_rlm
303 *
304 * @param[in] x to set the mctx for.
305 * @param[in] mctx Is duplicated and bound to the lifetime of the xlat.
306 */
308{
309 module_inst_ctx_t *our_mctx = NULL;
310
311 TALLOC_FREE(x->mctx);
312 MEM(our_mctx = talloc_zero(x, module_inst_ctx_t)); /* Original won't stick around */
313 memcpy(our_mctx, mctx, sizeof(*our_mctx));
314 x->mctx = our_mctx;
315}
316
317/** Verify xlat arg specifications are valid
318 *
319 * @param[in] x we're setting arguments for.
320 * @param[in] arg specification to validate.
321 * @param[in] last Is this the last argument in the list.
322 */
323static inline int xlat_arg_parser_validate(xlat_t *x, xlat_arg_parser_t const *arg, bool last)
324{
325 if (arg->concat) {
326 if (!fr_cond_assert_msg((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS),
327 "%s - concat type must be string or octets", x->name)) return -1;
328
329 if (!fr_cond_assert_msg(!arg->single, "%s - concat and single are mutually exclusive", x->name)) return -1;
330 }
331
332 if (arg->single) {
333 if (!fr_cond_assert_msg(!arg->concat, "%s - single and concat are mutually exclusive", x->name)) return -1;
334 }
335
336 if (arg->variadic) {
337 if (!fr_cond_assert_msg(last, "%s - variadic can only be set on the last argument", x->name)) return -1;
338 if (!fr_cond_assert_msg(!arg->required, "%s - required can't be set on a variadic argument. "
339 "Set required in the preceding entry", x->name)) return -1;
340 }
341
342 if (arg->always_escape) {
343 if (!fr_cond_assert_msg(arg->func, "%s - always_escape requires an escape func", x->name)) return -1;
344 }
345
346 if (arg->uctx) {
347 if (!fr_cond_assert_msg(arg->func, "%s - uctx requires an escape func", x->name)) return -1;
348 }
349
350 switch (arg->type) {
351 case FR_TYPE_LEAF:
352 case FR_TYPE_VOID:
354 break;
355
356 default:
357 fr_assert_fail("%s - type must be a leaf box type", x->name);
358 return -1;
359 }
360
361 return 0;
362}
363
364/** Register the arguments of an xlat
365 *
366 * For xlats that take multiple arguments
367 *
368 * @param[in,out] x to have it's arguments registered
369 * @param[in] args to be registered
370 * @return
371 * - 0 on success.
372 * - < 0 on failure.
373 */
375{
376 xlat_arg_parser_t const *arg_p = args;
377
378 for (arg_p = args; arg_p->type != FR_TYPE_NULL; arg_p++) {
379 if (xlat_arg_parser_validate(x, arg_p, (arg_p + 1)->type == FR_TYPE_NULL) < 0) return -1;
380 }
381 x->args = args;
382
383 return 0;
384}
385
386/** Register call environment of an xlat
387 *
388 * @param[in,out] x to have it's module method env registered.
389 * @param[in] env_method to be registered.
390 */
392{
393 x->call_env_method = env_method;
394}
395
396/** Specify flags that alter the xlat's behaviour
397 *
398 * @param[in] x xlat to set flags for.
399 * @param[in] flags to set.
400 */
408
409/** Set a print routine for an xlat function.
410 *
411 * @param[in] xlat to set
412 * @param[in] func for printing
413 */
415{
416 xlat->print = func;
417}
418
419/** Set a resolve routine for an xlat function.
420 *
421 * @param[in] xlat to set
422 * @param[in] func to resolve xlat.
423 */
425{
426 xlat->resolve = func;
427}
428
429/** Set a resolve routine for an xlat function.
430 *
431 * @param[in] xlat to set
432 * @param[in] func to purify xlat
433 */
435{
436 xlat->purify = func;
437}
438
439/** Set the escaped values for output boxes
440 *
441 * @param[in] xlat function to set the escaped value for (as returned by xlat_register).
442 * @param[in] safe_for escaped value to write to output boxes.
443 */
445{
446 xlat->return_safe_for = safe_for;
447}
448
449/** Set global instantiation/detach callbacks
450 *
451 * @param[in] xlat to set instantiation callbacks for.
452 * @param[in] instantiate Instantiation function. Called whenever a xlat is
453 * compiled.
454 * @param[in] inst_type Name of the instance structure.
455 * @param[in] inst_size The size of the instance struct.
456 * Pre-allocated for use by the instantiate function.
457 * If 0, no memory will be allocated.
458 * @param[in] detach Called when an xlat_exp_t is freed.
459 * @param[in] uctx Passed to the instantiation function.
460 */
462 xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
463 xlat_detach_t detach,
464 void *uctx)
465{
466 xlat_t *c = UNCONST(xlat_t *, xlat);
467
468 c->instantiate = instantiate;
469 c->inst_type = inst_type;
470 c->inst_size = inst_size;
471 c->detach = detach;
472 c->uctx = uctx;
473}
474
475/** Register an async xlat
476 *
477 * All functions registered must be !pure
478 *
479 * @param[in] xlat to set instantiation callbacks for.
480 * @param[in] thread_instantiate Instantiation function. Called for every compiled xlat
481 * every time a thread is started.
482 * @param[in] thread_inst_type Name of the thread instance structure.
483 * @param[in] thread_inst_size The size of the thread instance struct.
484 * Pre-allocated for use by the instantiate function.
485 * If 0, no memory will be allocated.
486 * @param[in] thread_detach Called when the thread is freed.
487 * @param[in] uctx Passed to the thread instantiate function.
488 */
491 char const *thread_inst_type, size_t thread_inst_size,
493 void *uctx)
494{
495 xlat_t *c = UNCONST(xlat_t *, xlat);
496
497 /*
498 * Pure functions can't use any thread-local
499 * variables. They MUST operate only on constant
500 * instantiation data, and on their (possibly constant)
501 * inputs.
502 */
503 fr_assert(!c->flags.pure);
504
506 c->thread_inst_type = thread_inst_type;
507 c->thread_inst_size = thread_inst_size;
509 c->thread_uctx = uctx;
510}
511
512/** Unregister an xlat function
513 *
514 * We can only have one function to call per name, so the passing of "func"
515 * here is extraneous.
516 *
517 * @param[in] name xlat to unregister.
518 */
519void xlat_func_unregister(char const *name)
520{
521 xlat_t *c;
522
523 if (!name || !xlat_root) return;
524
525 fr_rb_find((void **)&c, xlat_root, &(xlat_t){ .name = name });
526 if (!c) return;
527
528 (void) talloc_get_type_abort(c, xlat_t);
529
530 talloc_free(c); /* Should also remove from tree */
531}
532
534{
535 xlat_t *c;
537
538 if (!xlat_root) return; /* All xlats have already been freed */
539
540 for (c = fr_rb_iter_init_inorder(xlat_root, &iter);
541 c;
543 if (!c->mctx) continue;
544 if (c->mctx->mi != inst) continue;
545
547 }
548}
549
551{
552 if (xlat_root) return 0;
553
554 /*
555 * Create the function tree
556 */
558 if (!xlat_root) {
559 ERROR("%s: Failed to create tree", __FUNCTION__);
560 return -1;
561 }
562
563 return 0;
564}
565
567{
568 fr_rb_tree_t *xr = xlat_root; /* Make sure the tree can't be freed multiple times */
569
570 if (!xr) return;
571
572 xlat_root = NULL;
573 talloc_free(xr);
574}
static int const char char buffer[256]
Definition acutest.h:576
va_list args
Definition acutest.h:770
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:560
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:113
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
Definition debug.h:249
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:189
#define MEM(x)
Definition debug.h:38
#define ERROR(fmt,...)
Definition dhcpclient.c:40
static fr_slen_t in
Definition dict.h:882
talloc_free(hp)
#define DEBUG3(_fmt,...)
Definition log.h:271
fr_type_t
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_OCTETS
Raw octets.
long int ssize_t
static size_t used
fr_cmp_ret_t
Result of an ordering comparison.
Definition misc.h:50
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
#define fr_assert(_expr)
Definition rad_assert.h:37
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
Definition radiusd.c:139
static int thread_instantiate(TALLOC_CTX *ctx, fr_event_list_t *el, UNUSED void *uctx)
Create module and xlat per-thread instances.
Definition radiusd.c:127
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition rb.c:807
int fr_rb_find(void **found, fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:586
void * fr_rb_iter_init_inorder(fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Initialise an in-order iterator.
Definition rb.c:850
void fr_rb_iter_delete_inorder(fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
Definition rb.c:925
int fr_rb_replace(void **old, fr_rb_tree_t *tree, void const *data)
Replace old data with new data, OR insert if there is no old.
Definition rb.c:656
int fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition rb.c:767
void * fr_rb_iter_next_inorder(UNUSED fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:876
#define fr_rb_inline_talloc_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition rb.h:244
Iterator structure for in-order traversal of an rbtree.
Definition rb.h:319
The main red black tree structure.
Definition rb.h:71
static char const * name
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static SBUFF_CHAR_CLASS], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
Definition sbuff.c:1867
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
char const * name
Instance name e.g. user_database.
Definition module.h:357
Module instance data.
Definition module.h:287
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
Definition talloc.c:168
#define talloc_strdup(_ctx, _str)
Definition talloc.h:149
fr_type_t type
Type to cast argument to.
Definition xlat.h:156
int(* xlat_thread_detach_t)(xlat_thread_inst_ctx_t const *xctx)
xlat thread detach callback
Definition xlat.h:292
int(* xlat_detach_t)(xlat_inst_ctx_t const *xctx)
xlat detach callback
Definition xlat.h:277
unsigned int pure
has no external side effects, true for BOX, LITERAL, and some functions
Definition xlat.h:110
void * uctx
Argument to pass to escape callback.
Definition xlat.h:160
xlat_escape_func_t func
Function to handle tainted values.
Definition xlat.h:157
unsigned int impure_func
xlat contains an impure function
Definition xlat.h:111
unsigned int concat
Concat boxes together.
Definition xlat.h:148
xlat_arg_parser_variadic_t variadic
All additional boxes should be processed using this definition.
Definition xlat.h:154
struct xlat_s xlat_t
Definition xlat.h:103
xlat_action_t(* xlat_func_t)(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
xlat callback function
Definition xlat.h:233
unsigned int always_escape
Pass all arguments to escape function not just tainted ones.
Definition xlat.h:152
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:147
unsigned int use_module_status
use the module thread status to force early failure.
Definition xlat.h:116
int(* xlat_thread_instantiate_t)(xlat_thread_inst_ctx_t const *xctx)
Allocate new thread instance data for an xlat instance.
Definition xlat.h:263
unsigned int single
Argument must only contain a single box.
Definition xlat.h:149
int(* xlat_instantiate_t)(xlat_inst_ctx_t const *xctx)
Allocate new instance data for an xlat instance.
Definition xlat.h:254
Definition for a single argument consumed by an xlat function.
Definition xlat.h:146
@ FR_TYPE_PAIR_CURSOR
cursor over a fr_pair_t
Definition types.h:90
#define FR_TYPE_LEAF
Definition types.h:317
static size_t char fr_sbuff_t size_t inlen
Definition value.h:1030
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:162
static int _xlat_func_talloc_free(xlat_t *xlat)
Remove an xlat function from the function tree.
Definition xlat_func.c:104
void xlat_purify_func_set(xlat_t *xlat, xlat_purify_t func)
Set a resolve routine for an xlat function.
Definition xlat_func.c:434
void xlat_func_free(void)
Definition xlat_func.c:566
static fr_cmp_ret_t xlat_name_cmp(void const *one, void const *two)
Compare two xlat_t by the registered name.
Definition xlat_func.c:42
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
Definition xlat_func.c:401
void xlat_func_resolve_set(xlat_t *xlat, xlat_resolve_t func)
Set a resolve routine for an xlat function.
Definition xlat_func.c:424
fr_cmp_ret_t xlat_func_cmp(void const *one, void const *two)
Compare two xlat_t by the underlying function.
Definition xlat_func.c:67
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:374
void xlat_func_call_env_set(xlat_t *x, call_env_method_t const *env_method)
Register call environment of an xlat.
Definition xlat_func.c:391
void xlat_func_unregister_module(module_instance_t const *inst)
Definition xlat_func.c:533
static fr_rb_tree_t * xlat_root
Definition xlat_func.c:31
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.
Definition xlat_func.c:225
int xlat_func_init(void)
Definition xlat_func.c:550
void xlat_func_print_set(xlat_t *xlat, xlat_print_t func)
Set a print routine for an xlat function.
Definition xlat_func.c:414
void _xlat_func_safe_for_set(xlat_t *xlat, fr_value_box_safe_for_t safe_for)
Set the escaped values for output boxes.
Definition xlat_func.c:444
xlat_t * xlat_func_find(char const *in, ssize_t inlen)
Definition xlat_func.c:77
void xlat_mctx_set(xlat_t *x, module_inst_ctx_t const *mctx)
Associate a module calling ctx with the xlat.
Definition xlat_func.c:307
static int xlat_arg_parser_validate(xlat_t *x, xlat_arg_parser_t const *arg, bool last)
Verify xlat arg specifications are valid.
Definition xlat_func.c:323
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:519
void _xlat_func_thread_instantiate_set(xlat_t const *xlat, xlat_thread_instantiate_t thread_instantiate, char const *thread_inst_type, size_t thread_inst_size, xlat_thread_detach_t thread_detach, void *uctx)
Register an async xlat.
Definition xlat_func.c:489
xlat_t * xlat_func_find_module(module_inst_ctx_t const *mctx, char const *name)
Definition xlat_func.c:186
void _xlat_func_instantiate_set(xlat_t const *xlat, xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size, xlat_detach_t detach, void *uctx)
Set global instantiation/detach callbacks.
Definition xlat_func.c:461
static void _xlat_func_tree_free(void *xlat)
Callback for the rbtree to clear out any xlats still registered.
Definition xlat_func.c:118
int(* xlat_purify_t)(xlat_exp_t *xlat, void *inst, request_t *request)
Custom function purify the result of an xlat function.
Definition xlat_func.h:54
int(* xlat_resolve_t)(xlat_exp_t *xlat, void *inst, xlat_res_rules_t const *xr_rules)
Custom function to perform resolution of arguments.
Definition xlat_func.h:50
fr_slen_t(* xlat_print_t)(fr_sbuff_t *in, xlat_exp_t const *self, void *inst, fr_sbuff_escape_rules_t const *e_rules)
Custom function to print xlat debug.
Definition xlat_func.h:46
xlat_func_flags_t
Definition xlat_func.h:36
@ XLAT_FUNC_FLAG_PURE
Definition xlat_func.h:38
@ XLAT_FUNC_FLAG_MODULE_STATUS
Definition xlat_func.h:40
@ XLAT_FUNC_FLAG_INTERNAL
Definition xlat_func.h:39
char const * name
Name of xlat function.
Definition xlat_priv.h:64
char const * thread_inst_type
C type of thread instance structure.
Definition xlat_priv.h:84
module_inst_ctx_t * mctx
Original module instantiation ctx if this xlat was registered by a module.
Definition xlat_priv.h:72
bool internal
If true, cannot be redefined.
Definition xlat_priv.h:67
xlat_func_t func
async xlat function (async unsafe).
Definition xlat_priv.h:65
xlat_instantiate_t instantiate
Instantiation function.
Definition xlat_priv.h:75
size_t thread_inst_size
Size of the thread instance data to pre-allocate.
Definition xlat_priv.h:85
xlat_detach_t detach
Destructor for when xlat instances are freed.
Definition xlat_priv.h:76
void * thread_uctx
uctx to pass to instantiation functions.
Definition xlat_priv.h:86
call_env_method_t const * call_env_method
Optional tmpl expansions performed before calling the xlat.
Definition xlat_priv.h:96
size_t inst_size
Size of instance data to pre-allocate.
Definition xlat_priv.h:78
xlat_arg_parser_t const * args
Definition of args consumed.
Definition xlat_priv.h:94
xlat_resolve_t resolve
function to call when resolving
Definition xlat_priv.h:89
bool const xlat_func_chars[SBUFF_CHAR_CLASS]
xlat_thread_instantiate_t thread_instantiate
Thread instantiation function.
Definition xlat_priv.h:81
char const * inst_type
C type of instance structure.
Definition xlat_priv.h:77
fr_value_box_safe_for_t return_safe_for
Escaped value to set in output boxes.
Definition xlat_priv.h:100
xlat_thread_detach_t thread_detach
Destructor for when xlat thread instance data is freed.
Definition xlat_priv.h:82
xlat_purify_t purify
function to call when purifying the node.
Definition xlat_priv.h:90
xlat_flags_t flags
various flags
Definition xlat_priv.h:92
xlat_print_t print
function to call when printing
Definition xlat_priv.h:88
void * uctx
uctx to pass to instantiation functions.
Definition xlat_priv.h:79