25RCSID(
"$Id: df8ab6fc5eab1bad272382342149ab64cbf6c8f4 $")
27#include <freeradius-devel/server/rcode.h>
88 request, switch_gext->
vpt);
89 if (slen < 0)
goto find_null_case;
152 cf_log_err(cs,
"\"case\" statements may only appear within a \"switch\" section");
188 if (da->flags.has_value) t_rules.
enumv = da;
208 cf_log_err(cs,
"arguments to 'case' statements MUST NOT be attribute references.");
213 cf_log_err(cs,
"arguments to 'case' statements MUST be static data.");
243 case_gext->
vpt = talloc_steal(case_gext,
vpt);
255static int8_t
case_cmp(
void const *one,
void const *two)
282 char const *name1, *name2;
283 char const *type_name;
305 cf_log_err(cs,
"You must specify a variable to switch over for 'switch'");
360 cf_log_err(cs,
"Cannot use list for 'switch' statement");
367 cf_log_err(cs,
"Cannot use regular expression for 'switch' statement");
372 cf_log_err(cs,
"Cannot use constant data for 'switch' statement");
380 cf_log_err(cs,
"Cannot use constant data for 'switch' statement");
387 cf_log_err(cs,
"Cannot resolve key for 'switch' statement");
421 cf_log_err(cs,
"Invalid data type '%s' used for 'switch' statement",
432 cf_log_err(cs,
"Failed initializing internal data structures");
451 cf_log_err(subci,
"\"switch\" sections can only have \"case\" subsections");
458 if (strcmp(name1,
"case") != 0) {
462 if (strcmp(name1,
"default") == 0) {
464 cf_log_err(subci,
"\"default\" sections cannot have a match argument");
470 cf_log_err(subci,
"\"switch\" sections can only have \"case\" subsections");
478 cf_log_err(subci,
"Cannot have two 'default' case statements");
487 if (!single)
goto error;
496 if (!case_gext->
vpt) {
505 cf_log_err(subci,
"Failed inserting 'case' statement. Is there a duplicate?");
512 unlang_list_insert_tail(&g->
children, single);
529 .unlang_name =
"unlang_switch_t",
545 .unlang_name =
"unlang_case_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_EXECUTE_NEXT
Execute the next unlang_t.
@ UNLANG_ACTION_STOP_PROCESSING
Break out of processing the current request (unwind).
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
#define RULES_VERIFY(_cs, _rules)
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
bool cf_item_is_pair(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_ITEM * cf_section_to_item(CONF_SECTION const *cs)
Cast a CONF_SECTION to a CONF_ITEM.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
bool cf_item_is_section(CONF_ITEM const *ci)
Determine if CONF_ITEM is a CONF_SECTION.
char const * cf_section_argv(CONF_SECTION const *cs, int argc)
Return variadic argument at the specified index.
fr_token_t cf_section_name2_quote(CONF_SECTION const *cs)
Return the quoting of the name2 identifier.
#define cf_log_err(_cf, _fmt,...)
#define cf_canonicalize_error(_ci, _slen, _msg, _str)
#define cf_item_next(_parent, _curr)
#define cf_log_perr(_cf, _fmt,...)
unlang_t * unlang_compile_section(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_SECTION *cs, unlang_type_t type)
bool pass2_fixup_tmpl(UNUSED TALLOC_CTX *ctx, tmpl_t **vpt_p, CONF_ITEM const *ci, fr_dict_t const *dict)
unlang_group_t * unlang_group_allocate(unlang_t *parent, CONF_SECTION *cs, unlang_type_t type)
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
unlang_action_t unlang_group(UNUSED unlang_result_t *p_result, request_t *request, UNUSED unlang_stack_frame_t *frame)
Declarations for the "group" keyword.
uint32_t(* fr_hash_t)(void const *)
fr_htrie_t * fr_htrie_alloc(TALLOC_CTX *ctx, fr_htrie_type_t type, fr_hash_t hash_data, fr_cmp_t cmp_data, fr_trie_key_t get_key, fr_free_t free_data)
An abstraction over our internal hashes, rb trees, and prefix tries.
static fr_htrie_type_t fr_htrie_hint(fr_type_t type)
static bool fr_htrie_insert(fr_htrie_t *ht, void const *data)
Insert data into a htrie.
static void * fr_htrie_find(fr_htrie_t *ht, void const *data)
Find data in a htrie.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
int unlang_interpret_push(unlang_result_t *p_result, request_t *request, unlang_t const *instruction, unlang_frame_conf_t const *conf, bool do_next_sibling)
Push a new frame onto the stack.
#define FRAME_CONF(_default_rcode, _top_frame)
static TALLOC_CTX * unlang_ctx
void unlang_register(unlang_op_t *op)
Register an operation with the interpreter.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_VALUE_BOX
A boxed value.
int8_t(* fr_cmp_t)(void const *a, void const *b)
@ MOD_ACTION_RETURN
stop processing the section, and return the rcode with unset priority
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
#define RETURN_UNLANG_NOOP
#define FR_SBUFF_IN_STR(_start)
int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt))
Returns the first VP matching a tmpl_t.
static char const * tmpl_type_to_str(tmpl_type_t type)
Return a static string containing the type name.
#define tmpl_is_xlat(vpt)
#define tmpl_is_attr_unresolved(vpt)
#define tmpl_value(_tmpl)
#define tmpl_contains_regex(vpt)
#define tmpl_is_attr(vpt)
#define tmpl_is_exec(vpt)
fr_dict_attr_t const * enumv
Enumeration attribute used to resolve enum values.
@ TMPL_TYPE_DATA
Value in native boxed format.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
fr_type_t tmpl_data_type(tmpl_t const *vpt)
static bool tmpl_is_list(tmpl_t const *vpt)
ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Parse a string into a TMPL_TYPE_ATTR_* type tmpl_t.
#define tmpl_is_data(vpt)
#define tmpl_aexpand_type(_ctx, _out, _type, _request, _vpt)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
#define TMPL_POOL_DEF_HEADERS
Define manipulation functions for the attribute reference list.
#define tmpl_value_type(_tmpl)
#define tmpl_is_data_unresolved(vpt)
fr_type_t cast
Whether there was an explicit cast.
#define TMPL_POOL_DEF_LEN
How many additional bytes to allocate in a pool for a tmpl_t.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
#define tmpl_needs_resolving(vpt)
int tmpl_cast_set(tmpl_t *vpt, fr_type_t type)
Set a cast for a tmpl.
fr_type_t tmpl_expanded_type(tmpl_t const *vpt)
Return the native data type of the expression.
Optional arguments passed to vp_tmpl functions.
fr_aka_sim_id_type_t type
uint8_t allow_unknown
Allow unknown attributes i.e.
Stores an attribute, a value and various bits of other data.
static unlang_action_t unlang_case(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
void unlang_switch_init(void)
static uint32_t case_hash(void const *data)
static unlang_t * unlang_compile_switch(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
static int case_to_key(uint8_t **out, size_t *outlen, void const *data)
static unlang_t * unlang_compile_case(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
static int8_t case_cmp(void const *one, void const *two)
static unlang_action_t unlang_switch(UNUSED unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
static unlang_switch_t * unlang_group_to_switch(unlang_group_t *g)
Cast a group structure to the switch keyword extension.
static unlang_case_t * unlang_group_to_case(unlang_group_t *g)
Cast a group structure to the case keyword extension.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
int(* fr_trie_key_t)(uint8_t **out, size_t *outlen, void const *data)
uint8_t pure
has no external side effects, true for BOX, LITERAL, and some functions
uint8_t constant
xlat is just tmpl_attr_tail_data, or XLAT_BOX
char const * debug_name
Printed in log messages when the node is executed.
unlang_mod_actions_t actions
Priorities, etc. for the various return codes.
static unlang_t * unlang_group_to_generic(unlang_group_t const *p)
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
char const * name
Unknown...
@ UNLANG_TYPE_SWITCH
Switch section.
@ UNLANG_TYPE_CASE
Case section (within a UNLANG_TYPE_SWITCH).
unlang_t const * instruction
The unlang node we're evaluating.
@ UNLANG_OP_FLAG_DEBUG_BRACES
Print debug braces.
@ UNLANG_OP_FLAG_BREAK_POINT
Break point.
unlang_type_t type
The specialisation of this node.
Generic representation of a grouping.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define DOC_KEYWORD_REF(_x)
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
Perform a shallow copy of a value_box.
int fr_value_box_to_key(uint8_t **out, size_t *outlen, fr_value_box_t const *value)
Get a key from a value box.
static size_t char ** out
String expansion ("translation").
xlat_flags_t flags
Flags that control resolution and evaluation.