26 RCSID(
"$Id: b85edbafb1d0895524878007a184188a285aaa91 $")
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/util/debug.h>
32 #include <freeradius-devel/unlang/xlat_priv.h>
52 fr_value_box_list_t
out;
160 ev->
inst = state->
exp->call.inst;
197 static unlang_t xlat_instruction = {
200 .debug_name =
"xlat",
237 if (node)
switch (node->
type) {
255 fr_value_box_list_init(&state->
out);
311 state->
exp->call.inst->call_env);
338 fr_value_box_list_talloc_free(&state->
out);
352 RWDEBUG(
"Missing call to unlang_xlat_yield()");
403 fr_value_box_list_talloc_free(&state->
out);
417 RWDEBUG(
"Missing call to unlang_xlat_yield()");
460 if (action == FR_SIGNAL_CANCEL) {
521 fr_value_box_list_talloc_free(&state->
out);
625 fr_value_box_list_t list;
632 fr_value_box_list_init(&list);
643 src = fr_value_box_list_head(&list);
647 fr_value_box_list_talloc_free(&list);
652 fr_value_box_list_talloc_free(&list);
663 if (fr_value_box_list_empty(&list)) {
687 .debug_braces =
false,
689 .frame_state_type =
"unlang_frame_state_xlat_t",
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_STOP_PROCESSING
Break out of processing the current request (unwind).
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *env_result, void **env_data, call_env_t const *call_env)
Initialise the expansion of a call environment.
#define fr_dcursor_init(_cursor, _head)
Initialise a cursor.
fr_dcursor_eval_t void const * uctx
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
#define fr_event_timer_at(...)
rlm_rcode_t unlang_interpret(request_t *request)
Run the interpreter for a current request.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame)
Push a new frame onto the stack.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RINDENT_SAVE(_x, _request)
Save indentation for later restoral.
#define RINDENT_RESTORE(_request, _x)
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
void unlang_register(int type, unlang_op_t *op)
Register an operation with the interpreter.
int fr_event_timer_delete(fr_event_timer_t const **ev_p)
Delete a timer event from the event list.
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Stores all information relating to an event list.
static char * stack[MAX_STACK]
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_OCTETS
Raw octets.
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_INVALID
The module considers the request invalid.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOTFOUND
User not found.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
#define tmpl_is_data(vpt)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
#define talloc_get_type_abort_const
static fr_event_list_t * el
int unlang_xlat_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat)
Evaluate a "pure" (or not impure) xlat.
static int unlang_xlat_push_internal(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat, xlat_exp_t *node, bool top_frame)
Push a pre-compiled xlat onto the stack for evaluation.
xlat_exp_head_t const * head
of the xlat list
TALLOC_CTX * ctx
to allocate boxes and values in.
fr_unlang_xlat_fd_event_t fd_read
Function to call when FD is readable.
int unlang_xlat_eval_type(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t type, fr_dict_attr_t const *enumv, request_t *request, xlat_exp_head_t const *xlat)
Evaluate a "pure" (or not impure) xlat.
TALLOC_CTX * event_ctx
for temporary events
xlat_func_signal_t signal
called on signal
fr_event_timer_t const * ev
Event in this worker's event heap.
static void unlang_xlat_event_timeout_handler(UNUSED fr_event_list_t *el, fr_time_t now, void *uctx)
Call the callback registered for a timeout event.
static unlang_action_t unlang_xlat_resume(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Called when we're ready to resume processing the request.
static int _unlang_xlat_event_free(unlang_xlat_event_t *ev)
Frees an unlang event, removing it from the request's event loop.
void * rctx
for resume / signal
fr_dcursor_t values
Values aggregated so far.
fr_value_box_list_t out
Head of the result of a nested expansion.
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
xlat_func_t resume
called on resume
request_t * request
Request this event pertains to.
bool * success
If set, where to record the result of the execution.
int fd
File descriptor to wait on.
fr_unlang_xlat_timeout_t timeout
Function to call on timeout.
int unlang_xlat_push_node(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out, request_t *request, xlat_exp_t *node)
Push a pre-compiled xlat onto the stack for evaluation.
xlat_inst_t * inst
xlat instance data.
static unlang_action_t unlang_xlat(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
Stub function for calling the xlat interpreter.
fr_unlang_xlat_fd_event_t fd_write
Function to call when FD is writable.
fr_signal_t sigmask
Signals to block.
int unlang_xlat_timeout_add(request_t *request, fr_unlang_xlat_timeout_t callback, void const *rctx, fr_time_t when)
Add a timeout for an xlat handler.
rindent_t indent
indentation
int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
Push a pre-compiled xlat onto the stack for evaluation.
void * env_data
Expanded per call environment tmpls.
void const * rctx
rctx data to pass to callbacks.
static void unlang_xlat_signal(request_t *request, unlang_stack_frame_t *frame, fr_signal_t action)
Send a signal (usually stop) to a request that's running an xlat expansions.
static unlang_action_t unlang_xlat_repeat(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
void unlang_xlat_init(void)
Register xlat operation with the interpreter.
xlat_exp_t const * exp
current one we're evaluating
fr_unlang_xlat_fd_event_t fd_error
Function to call when FD has errored.
xlat_thread_inst_t * thread
Thread specific xlat instance.
State of an xlat expansion.
Wrap an fr_event_timer_t providing data needed for unlang events.
void * data
Thread specific instance data.
void(* fr_unlang_xlat_fd_event_t)(xlat_ctx_t const *xctx, request_t *request, int fd)
A callback when the FD is ready for reading.
xlat_thread_inst_t * xlat_thread_instance_find(xlat_exp_t const *node)
Retrieve xlat/thread specific instance data.
void(* xlat_func_signal_t)(xlat_ctx_t const *xctx, request_t *request, fr_signal_t action)
A callback when the request gets a fr_signal_t.
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
void * data
xlat node specific instance data.
void(* fr_unlang_xlat_timeout_t)(xlat_ctx_t const *xctx, request_t *request, fr_time_t fired)
A callback when the the timeout occurs.
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_YIELD
An xlat function pushed a resume frame onto the stack.
@ XLAT_ACTION_PUSH_UNLANG
An xlat function pushed an unlang frame onto the unlang stack.
@ XLAT_ACTION_PUSH_CHILD
A deeper level of nesting needs to be evaluated.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
bool impure_func
xlat contains an impure function
module_ctx_t const * mctx
A synthesised module calling ctx containing module global and thread instance data.
Instance data for an xlat expansion node.
Thread specific instance data for xlat expansion node.
Private interpreter structures and functions.
void * state
Stack frame specialisations.
@ UNLANG_TYPE_XLAT
Represents one level of an xlat expansion.
static void frame_repeat(unlang_stack_frame_t *frame, unlang_process_t process)
Mark the current stack frame up for repeat, and set a new process function.
unlang_t const * instruction
The unlang node we're evaluating.
static void repeatable_set(unlang_stack_frame_t *frame)
unlang_process_t process
function to call for interpreting this stack frame
unlang_type_t type
The specialisation of this node.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
#define fr_strerror_const(_msg)
#define fr_type_is_structural(_x)
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
@ FR_VALUE_BOX_LIST_FREE_BOX
Free each processed box.
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
static size_t char ** out
#define XLAT_CTX(_inst, _thread, _mctx, _env_data, _rctx)
Wrapper to create a xlat_ctx_t as a compound literal.
xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_t const **child, request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in, void *env_data, fr_value_box_list_t *result)
Process the result of a previous nested expansion.
void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp, request_t *request, void *rctx, fr_signal_t action)
Signal an xlat function.
xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_t const **child, request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in, fr_value_box_list_t *result, xlat_func_t resume, void *rctx)
Call an xlat's resumption method.
xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_t const **child, request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in)
Converts xlat nodes to value boxes.
xlat_flags_t flags
Flags that control resolution and evaluation.
@ XLAT_TMPL
xlat attribute
@ XLAT_GROUP
encapsulated string of xlats
static xlat_exp_t * xlat_exp_head(xlat_exp_head_t const *head)
char const *_CONST fmt
The original format string (a talloced buffer).
xlat_type_t _CONST type
type of this expansion.