The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: c3c8b0442b3bf2fd10f0d1eadda070b4ac1a7153 $
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: c3c8b0442b3bf2fd10f0d1eadda070b4ac1a7153 $")
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 int8_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 */
67int8_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
81 if (!xlat_root) return NULL;
82
83 if (inlen < 0) return fr_rb_find(xlat_root, &(xlat_t){ .name = in });
84
85 if ((size_t) inlen >= sizeof(buffer)) return NULL;
86
87 memcpy(buffer, in, inlen);
88 buffer[inlen] = '\0';
89
90 return fr_rb_find(xlat_root, &(xlat_t){ .name = buffer });
91}
92
93/** Remove an xlat function from the function tree
94 *
95 * @param[in] xlat to free.
96 * @return 0
97 */
99{
100 if (!xlat_root) return 0;
101
102 fr_rb_delete(xlat_root, xlat);
103 if (fr_rb_num_elements(xlat_root) == 0) TALLOC_FREE(xlat_root);
104
105 return 0;
106}
107
108
109/** Callback for the rbtree to clear out any xlats still registered
110 *
111 */
112static void _xlat_func_tree_free(void *xlat)
113{
114 talloc_free(xlat);
115}
116
117#if 0
118/** Compare two argument entries to see if they're equivalent
119 *
120 * @note Does not check escape function or uctx pointers.
121 *
122 * @param[in] a First argument structure.
123 * @param[in] b Second argument structure.
124 * @return
125 * - 1 if a > b
126 * - 0 if a == b
127 * - -1 if a < b
128 */
129static int xlat_arg_cmp_no_escape(xlat_arg_parser_t const *a, xlat_arg_parser_t const *b)
130{
131 int8_t ret;
132
133 ret = CMP(a->required, b->required);
134 if (ret != 0) return ret;
135
136 ret = CMP(a->concat, b->concat);
137 if (ret != 0) return ret;
138
139 ret = CMP(a->single, b->single);
140 if (ret != 0) return ret;
141
142 ret = CMP(a->variadic, b->variadic);
143 if (ret != 0) return ret;
144
145 ret = CMP(a->always_escape, b->always_escape);
146 if (ret != 0) return ret;
147
148 return CMP(a->type, b->type);
149}
150
151/** Compare two argument lists to see if they're equivalent
152 *
153 * @note Does not check escape function or uctx pointers.
154 *
155 * @param[in] a First argument structure.
156 * @param[in] b Second argument structure.
157 * @return
158 * - 1 if a > b
159 * - 0 if a == b
160 * - -1 if a < b
161 */
162static int xlat_arg_cmp_list_no_escape(xlat_arg_parser_t const a[], xlat_arg_parser_t const b[])
163{
164 xlat_arg_parser_t const *arg_a_p;
165 xlat_arg_parser_t const *arg_b_p;
166
167 for (arg_a_p = a, arg_b_p = b;
168 (arg_a_p->type != FR_TYPE_NULL) && (arg_b_p->type != FR_TYPE_NULL);
169 arg_a_p++, arg_b_p++) {
170 int8_t ret;
171
172 ret = xlat_arg_cmp_no_escape(arg_a_p, arg_b_p);
173 if (ret != 0) return ret;
174 }
175
176 return CMP(arg_a_p, arg_b_p); /* Check we ended at the same point */
177}
178#endif
179
181{
182 char inst_name[256];
183
185
186 if (!*name) {
187 ERROR("%s: Invalid xlat name", __FUNCTION__);
188 return NULL;
189 }
190
191 /*
192 * Name xlats other than those which are just the module instance
193 * as <instance name>.<function name>
194 */
195 if (mctx && name != mctx->mi->name) {
196 snprintf(inst_name, sizeof(inst_name), "%s.%s", mctx->mi->name, name);
197 name = inst_name;
198 }
199
200 /*
201 * If it already exists, replace the instance.
202 */
203 return fr_rb_find(xlat_root, &(xlat_t){ .name = name });
204}
205
206/** Register an xlat function
207 *
208 * @param[in] ctx Used to automate deregistration of the xlat function.
209 * @param[in] name of the xlat.
210 * @param[in] func to register.
211 * @param[in] return_type what type of output the xlat function will produce.
212 * @return
213 * - A handle for the newly registered xlat function on success.
214 * - NULL on failure.
215 */
216xlat_t *xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
217{
218 xlat_t *c;
220 size_t len, used;
221
223
224 if (!*name) {
225 invalid_name:
226 ERROR("%s: Invalid xlat name", __FUNCTION__);
227 return NULL;
228 }
229
230 len = strlen(name);
231 if ((len == 1) && (strchr("InscCdDeGHlmMStTY", *name) != NULL)) goto invalid_name;
232
233 in = FR_SBUFF_IN(name, len);
236
237 if (used < len) {
238 ERROR("%s: Invalid character '%c' in dynamic expansion name '%s'", __FUNCTION__, name[used], name);
239 return NULL;
240 }
241
242 /*
243 * If it already exists, replace the instance.
244 */
245 c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
246 if (c) {
247 if (c->internal) {
248 ERROR("%s: Cannot re-define internal expansion %s", __FUNCTION__, name);
249 return NULL;
250 }
251
252 if (c->func != func) {
253 ERROR("%s: Cannot change callback function for %s", __FUNCTION__, name);
254 return NULL;
255 }
256
257 return c;
258 }
259
260 /*
261 * Doesn't exist. Create it.
262 */
263 MEM(c = talloc(NULL, xlat_t));
264 *c = (xlat_t){
266 .func = func,
267 .return_type = return_type,
268 };
269
270 /*
271 * Don't allocate directly in the parent ctx, it might be mprotected
272 * later, and that'll cause segfaults if any of the xlat_t are still
273 * protected when we start shuffling the contents of the rbtree.
274 */
275 if (ctx) talloc_link_ctx(c, ctx);
276
277 talloc_set_destructor(c, _xlat_func_talloc_free);
278 DEBUG3("%s: %s", __FUNCTION__, c->name);
279
280 if (fr_rb_replace(NULL, xlat_root, c) < 0) {
281 ERROR("%s: Failed inserting xlat registration for %s", __FUNCTION__, c->name);
282 talloc_free(c);
283 return NULL;
284 }
285
286 return c;
287}
288
289/** Associate a module calling ctx with the xlat
290 *
291 * @note Intended to be called from the module_rlm
292 *
293 * @param[in] x to set the mctx for.
294 * @param[in] mctx Is duplicated and about to the lifetime of the xlat.
295 */
297{
298 module_inst_ctx_t *our_mctx = NULL;
299
300 TALLOC_FREE(x->mctx);
301 MEM(our_mctx = talloc_zero(x, module_inst_ctx_t)); /* Original won't stick around */
302 memcpy(our_mctx, mctx, sizeof(*our_mctx));
303 x->mctx = our_mctx;
304}
305
306/** Verify xlat arg specifications are valid
307 *
308 * @param[in] x we're setting arguments for.
309 * @param[in] arg specification to validate.
310 * @param[in] last Is this the last argument in the list.
311 */
312static inline int xlat_arg_parser_validate(xlat_t *x, xlat_arg_parser_t const *arg, bool last)
313{
314 if (arg->concat) {
315 if (!fr_cond_assert_msg((arg->type == FR_TYPE_STRING) || (arg->type == FR_TYPE_OCTETS),
316 "%s - concat type must be string or octets", x->name)) return -1;
317
318 if (!fr_cond_assert_msg(!arg->single, "%s - concat and single are mutually exclusive", x->name)) return -1;
319 }
320
321 if (arg->single) {
322 if (!fr_cond_assert_msg(!arg->concat, "%s - single and concat are mutually exclusive", x->name)) return -1;
323 }
324
325 if (arg->variadic) {
326 if (!fr_cond_assert_msg(last, "%s - variadic can only be set on the last argument", x->name)) return -1;
327 if (!fr_cond_assert_msg(!arg->required, "%s - required can't be set on a variadic argument. "
328 "Set required in the preceding entry", x->name)) return -1;
329 }
330
331 if (arg->always_escape) {
332 if (!fr_cond_assert_msg(arg->func, "%s - always_escape requires an escape func", x->name)) return -1;
333 }
334
335 if (arg->uctx) {
336 if (!fr_cond_assert_msg(arg->func, "%s - uctx requires an escape func", x->name)) return -1;
337 }
338
339 switch (arg->type) {
340 case FR_TYPE_LEAF:
341 case FR_TYPE_VOID:
343 break;
344
345 default:
346 fr_assert_fail("%s - type must be a leaf box type", x->name);
347 return -1;
348 }
349
350 return 0;
351}
352
353/** Register the arguments of an xlat
354 *
355 * For xlats that take multiple arguments
356 *
357 * @param[in,out] x to have it's arguments registered
358 * @param[in] args to be registered
359 * @return
360 * - 0 on success.
361 * - < 0 on failure.
362 */
364{
365 xlat_arg_parser_t const *arg_p = args;
366 bool seen_optional = false;
367
368 for (arg_p = args; arg_p->type != FR_TYPE_NULL; arg_p++) {
369 if (xlat_arg_parser_validate(x, arg_p, (arg_p + 1)->type == FR_TYPE_NULL) < 0) return -1;
370
371 if (arg_p->required) {
372 if (!fr_cond_assert_msg(!seen_optional,
373 "required arguments must be at the "
374 "start of the argument list")) return -1;
375 } else {
376 seen_optional = true;
377 }
378 }
379 x->args = args;
380
381 return 0;
382}
383
384/** Register call environment of an xlat
385 *
386 * @param[in,out] x to have it's module method env registered.
387 * @param[in] env_method to be registered.
388 */
390{
391 x->call_env_method = env_method;
392}
393
394/** Specify flags that alter the xlat's behaviour
395 *
396 * @param[in] x xlat to set flags for.
397 * @param[in] flags to set.
398 */
400{
401 x->flags.pure = flags & XLAT_FUNC_FLAG_PURE;
403 x->flags.impure_func = !x->flags.pure;
404}
405
406/** Set a print routine for an xlat function.
407 *
408 * @param[in] xlat to set
409 * @param[in] func for printing
410 */
412{
413 xlat->print = func;
414}
415
416/** Set a resolve routine for an xlat function.
417 *
418 * @param[in] xlat to set
419 * @param[in] func to resolve xlat.
420 */
422{
423 xlat->resolve = func;
424}
425
426/** Set a resolve routine for an xlat function.
427 *
428 * @param[in] xlat to set
429 * @param[in] func to purify xlat
430 */
432{
433 xlat->purify = func;
434}
435
436/** Set the escaped values for output boxes
437 *
438 * @param[in] xlat function to set the escaped value for (as returned by xlat_register).
439 * @param[in] safe_for escaped value to write to output boxes.
440 */
442{
443 xlat->return_safe_for = safe_for;
444}
445
446/** Set global instantiation/detach callbacks
447 *
448 * @param[in] xlat to set instantiation callbacks for.
449 * @param[in] instantiate Instantiation function. Called whenever a xlat is
450 * compiled.
451 * @param[in] inst_type Name of the instance structure.
452 * @param[in] inst_size The size of the instance struct.
453 * Pre-allocated for use by the instantiate function.
454 * If 0, no memory will be allocated.
455 * @param[in] detach Called when an xlat_exp_t is freed.
456 * @param[in] uctx Passed to the instantiation function.
457 */
459 xlat_instantiate_t instantiate, char const *inst_type, size_t inst_size,
460 xlat_detach_t detach,
461 void *uctx)
462{
463 xlat_t *c = UNCONST(xlat_t *, xlat);
464
466 c->inst_type = inst_type;
467 c->inst_size = inst_size;
468 c->detach = detach;
469 c->uctx = uctx;
470}
471
472/** Register an async xlat
473 *
474 * All functions registered must be !pure
475 *
476 * @param[in] xlat to set instantiation callbacks for.
477 * @param[in] thread_instantiate Instantiation function. Called for every compiled xlat
478 * every time a thread is started.
479 * @param[in] thread_inst_type Name of the thread instance structure.
480 * @param[in] thread_inst_size The size of the thread instance struct.
481 * Pre-allocated for use by the instantiate function.
482 * If 0, no memory will be allocated.
483 * @param[in] thread_detach Called when the thread is freed.
484 * @param[in] uctx Passed to the thread instantiate function.
485 */
488 char const *thread_inst_type, size_t thread_inst_size,
490 void *uctx)
491{
492 xlat_t *c = UNCONST(xlat_t *, xlat);
493
494 /*
495 * Pure functions can't use any thread-local
496 * variables. They MUST operate only on constant
497 * instantiation data, and on their (possibly constant)
498 * inputs.
499 */
500 fr_assert(!c->flags.pure);
501
503 c->thread_inst_type = thread_inst_type;
504 c->thread_inst_size = thread_inst_size;
506 c->thread_uctx = uctx;
507}
508
509/** Unregister an xlat function
510 *
511 * We can only have one function to call per name, so the passing of "func"
512 * here is extraneous.
513 *
514 * @param[in] name xlat to unregister.
515 */
516void xlat_func_unregister(char const *name)
517{
518 xlat_t *c;
519
520 if (!name || !xlat_root) return;
521
522 c = fr_rb_find(xlat_root, &(xlat_t){ .name = name });
523 if (!c) return;
524
525 (void) talloc_get_type_abort(c, xlat_t);
526
527 talloc_free(c); /* Should also remove from tree */
528}
529
531{
532 xlat_t *c;
534
535 if (!xlat_root) return; /* All xlats have already been freed */
536
537 for (c = fr_rb_iter_init_inorder(&iter, xlat_root);
538 c;
539 c = fr_rb_iter_next_inorder(&iter)) {
540 if (!c->mctx) continue;
541 if (c->mctx->mi != inst) continue;
542
544 }
545}
546
548{
549 if (xlat_root) return 0;
550
551 /*
552 * Create the function tree
553 */
555 if (!xlat_root) {
556 ERROR("%s: Failed to create tree", __FUNCTION__);
557 return -1;
558 }
559
560 return 0;
561}
562
564{
565 fr_rb_tree_t *xr = xlat_root; /* Make sure the tree can't be freed multiple times */
566
567 if (!xr) return;
568
569 xlat_root = NULL;
570 talloc_free(xr);
571}
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:167
#define RCSID(id)
Definition build.h:485
#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:112
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
Definition debug.h:216
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:156
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
static fr_slen_t in
Definition dict.h:840
#define DEBUG3(_fmt,...)
Definition log.h:266
talloc_free(reap)
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
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:38
static void thread_detach(UNUSED void *uctx)
Explicitly cleanup module/xlat resources.
Definition radiusd.c:150
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:133
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition rb.c:781
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
Definition rb.c:824
void fr_rb_iter_delete_inorder(fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
Definition rb.c:898
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:647
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:850
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:577
bool 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:741
#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:246
Iterator structure for in-order traversal of an rbtree.
Definition rb.h:321
The main red black tree structure.
Definition rb.h:73
static char const * name
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1313
size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX+1], fr_sbuff_term_t const *tt)
Wind position past characters in the allowed set.
Definition sbuff.c:1779
#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:336
Module instance data.
Definition module.h:266
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:167
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:467
fr_type_t type
Type to cast argument to.
Definition xlat.h:154
int(* xlat_thread_detach_t)(xlat_thread_inst_ctx_t const *xctx)
xlat thread detach callback
Definition xlat.h:290
uint8_t single
Argument must only contain a single box.
Definition xlat.h:147
int(* xlat_detach_t)(xlat_inst_ctx_t const *xctx)
xlat detach callback
Definition xlat.h:275
void * uctx
Argument to pass to escape callback.
Definition xlat.h:158
xlat_escape_func_t func
Function to handle tainted values.
Definition xlat.h:155
uint8_t always_escape
Pass all arguments to escape function not just tainted ones.
Definition xlat.h:150
xlat_arg_parser_variadic_t variadic
All additional boxes should be processed using this definition.
Definition xlat.h:152
struct xlat_s xlat_t
Definition xlat.h:102
uint8_t required
Argument must be present, and non-empty.
Definition xlat.h:145
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:231
uint8_t concat
Concat boxes together.
Definition xlat.h:146
uint8_t pure
has no external side effects, true for BOX, LITERAL, and some functions
Definition xlat.h:109
int(* xlat_thread_instantiate_t)(xlat_thread_inst_ctx_t const *xctx)
Allocate new thread instance data for an xlat instance.
Definition xlat.h:261
uint8_t impure_func
xlat contains an impure function
Definition xlat.h:110
int(* xlat_instantiate_t)(xlat_inst_ctx_t const *xctx)
Allocate new instance data for an xlat instance.
Definition xlat.h:252
Definition for a single argument consumend by an xlat function.
Definition xlat.h:144
@ FR_TYPE_PAIR_CURSOR
cursor over a fr_pair_t
Definition types.h:89
#define FR_TYPE_LEAF
Definition types.h:313
static size_t char fr_sbuff_t size_t inlen
Definition value.h:1020
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:160
static int _xlat_func_talloc_free(xlat_t *xlat)
Remove an xlat function from the function tree.
Definition xlat_func.c:98
void xlat_purify_func_set(xlat_t *xlat, xlat_purify_t func)
Set a resolve routine for an xlat function.
Definition xlat_func.c:431
void xlat_func_free(void)
Definition xlat_func.c:563
static int8_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:399
void xlat_func_resolve_set(xlat_t *xlat, xlat_resolve_t func)
Set a resolve routine for an xlat function.
Definition xlat_func.c:421
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:363
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:389
void xlat_func_unregister_module(module_instance_t const *inst)
Definition xlat_func.c:530
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:216
int xlat_func_init(void)
Definition xlat_func.c:547
void xlat_func_print_set(xlat_t *xlat, xlat_print_t func)
Set a print routine for an xlat function.
Definition xlat_func.c:411
int8_t xlat_func_cmp(void const *one, void const *two)
Compare two xlat_t by the underlying function.
Definition xlat_func.c:67
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:441
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:296
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:312
void xlat_func_unregister(char const *name)
Unregister an xlat function.
Definition xlat_func.c:516
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:486
xlat_t * xlat_func_find_module(module_inst_ctx_t const *mctx, char const *name)
Definition xlat_func.c:180
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:458
static void _xlat_func_tree_free(void *xlat)
Callback for the rbtree to clear out any xlats still registered.
Definition xlat_func.c:112
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:53
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:49
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:45
xlat_func_flags_t
Definition xlat_func.h:36
@ XLAT_FUNC_FLAG_PURE
Definition xlat_func.h:38
@ 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 const xlat_func_chars[UINT8_MAX+1]
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
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