The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
catch.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: d2673ba3b6cedded9b57cd6c6755229a41ed3791 $
19 *
20 * @file unlang/catch.c
21 * @brief Unlang "catch" keyword evaluation.
22 *
23 * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
24 */
25RCSID("$Id: d2673ba3b6cedded9b57cd6c6755229a41ed3791 $")
26
27#include <freeradius-devel/server/rcode.h>
28#include "unlang_priv.h"
29#include "try_priv.h"
30
35
36
37/*
38 * Sanity checks have already been done by compile_try().
39 */
40static void catch_argv(unlang_try_t *gext, char const *name, unlang_t *c)
41{
42 rlm_rcode_t rcode;
43
46 fr_assert(!gext->catch[rcode]);
47
48 gext->catch[rcode] = c;
49}
50
52{
55 unlang_t *c;
56 unlang_try_t *gext;
57 char const *name;
58
60 fr_assert(g != NULL);
61
62 /*
63 * "catch" is NOT inserted into the normal child list.
64 * It's an exception, and is run only if the "try" says
65 * to run it.
66 */
67 c = unlang_list_tail(&g->children);
68 if (!c || c->type != UNLANG_TYPE_TRY) {
69 cf_log_err(cs, "Found 'catch' section with no previous 'try'");
70 cf_log_err(ci, DOC_KEYWORD_REF(catch));
71 return NULL;
72 }
73
74 gext = talloc_get_type_abort(c, unlang_try_t);
75 fr_assert(gext != NULL);
76
78 if (!g) return NULL;
79
81
82 /*
83 * Want to log what we caught
84 */
86
87 /*
88 * catch { ... } has to be the last one, and will catch _all_ rcodes that weren't mentioned
89 * before.
90 */
91 if (!cf_section_name2(cs)) {
92 int i;
93
94 for (i = 0; i < RLM_MODULE_NUMCODES; i++) {
95 if (gext->catch[i]) continue;
96
97 gext->catch[i] = c;
98 }
99
100 } else {
101 int i;
102
104
105 catch_argv(gext, name, c);
106
107 for (i = 0; (name = cf_section_argv(cs, i)) != NULL; i++) {
108 catch_argv(gext, name, c);
109 }
110 }
111
112 /*
113 * Compile our children.
114 */
116 return NULL;
117 }
118
119 /*
120 * The "catch" section isn't in the parent list. It's just associated with "try".
121 */
122 (void) talloc_steal(gext, c);
123 c->parent = &gext->group.self;
124 c->list = NULL;
125
126 /*
127 * Don't insert it unto the normal list of children.
128 */
129 return UNLANG_IGNORE;
130}
131
133{
135 .name = "catch",
136 .type = UNLANG_TYPE_CATCH,
138
139 .compile = unlang_compile_catch,
140 .interpret = unlang_catch,
141
142 .unlang_size = sizeof(unlang_group_t),
143 .unlang_name = "unlang_group_t",
144 });
145}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define RCSID(id)
Definition build.h:485
#define UNUSED
Definition build.h:317
static void catch_argv(unlang_try_t *gext, char const *name, unlang_t *c)
Definition catch.c:40
static unlang_action_t unlang_catch(UNUSED unlang_result_t *p_result, request_t *request, UNUSED unlang_stack_frame_t *frame)
Definition catch.c:31
void unlang_catch_init(void)
Definition catch.c:132
static unlang_t * unlang_compile_catch(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
Definition catch.c:51
Common header for all CONF_* types.
Definition cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1184
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1170
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:683
char const * cf_section_argv(CONF_SECTION const *cs, int argc)
Return variadic argument at the specified index.
Definition cf_util.c:1212
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
unlang_t * unlang_compile_children(unlang_group_t *g, unlang_compile_ctx_t *unlang_ctx_in)
Definition compile.c:1288
unlang_group_t * unlang_group_allocate(unlang_t *parent, CONF_SECTION *cs, unlang_type_t type)
Definition compile.c:447
fr_table_num_sorted_t const mod_rcode_table[]
Definition compile.c:75
unlang_action_t unlang_interpret_push_children(unlang_result_t *p_result, request_t *request, rlm_rcode_t default_rcode, bool do_next_sibling)
Push the children of the current frame onto a new frame onto the stack.
Definition interpret.c:384
static TALLOC_CTX * unlang_ctx
Definition base.c:71
void unlang_register(unlang_op_t *op)
Register an operation with the interpreter.
Definition base.c:56
#define fr_assert(_expr)
Definition rad_assert.h:38
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
Definition rcode.h:41
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
Definition rcode.h:53
static char const * name
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:514
Declaration for unlang try.
unlang_group_t group
Definition try_priv.h:33
unlang_t * catch[RLM_MODULE_NUMCODES]
Definition try_priv.h:35
Private interpreter structures and functions.
#define UNLANG_NEXT_SIBLING
char const * debug_name
Printed in log messages when the node is executed.
unlang_t * parent
Previous node.
static unlang_t * unlang_group_to_generic(unlang_group_t const *p)
#define UNLANG_IGNORE
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
unlang_list_t children
char const * name
Unknown...
@ UNLANG_TYPE_TRY
try / catch blocks
Definition unlang_priv.h:77
@ UNLANG_TYPE_CATCH
catch a previous try
Definition unlang_priv.h:78
@ UNLANG_OP_FLAG_DEBUG_BRACES
Print debug braces.
unlang_type_t type
The specialisation of this node.
unlang_list_t * list
so we have fewer run-time dereferences
Generic representation of a grouping.
An unlang operation.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
static fr_slen_t parent
Definition pair.h:841
#define DOC_KEYWORD_REF(_x)
Definition version.h:89