typedef struct {
fr_value_box_list_t out; //!< Head of the result of a nested
///< expansion.
- bool success; //!< If set, where to record the result
- ///< of the execution.
+ unlang_result_t result; //!< Store the result of unlang expressions.
} unlang_frame_state_cond_t;
static unlang_action_t unlang_if_resume(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
fr_value_box_list_init(&state->out);
- if (unlang_xlat_push(state, &state->success, &state->out,
+ if (unlang_xlat_push(state, &state->result, &state->out,
request, gext->head, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
return UNLANG_ACTION_PUSHED_CHILD;
uint32_t index; //!< for xlat results
char *buffer; //!< for key values
- bool success; //!< for xlat expansion
+ unlang_result_t exp_result; //!< for xlat expansion
fr_value_box_list_t list; //!< value box list for looping over xlats
tmpl_dcursor_ctx_t cc; //!< tmpl cursor state
unlang_frame_state_foreach_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_foreach_t);
fr_value_box_t *box;
- if (!state->success) {
+ if (!XLAT_RESULT_SUCCESS(&state->exp_result)) {
RDEBUG("Failed expanding 'foreach' list");
RETURN_UNLANG_FAIL;
}
{
fr_value_box_list_init(&state->list);
- if (unlang_xlat_push(state, &state->success, &state->list, request, tmpl_xlat(state->vpt), false) < 0) {
+ if (unlang_xlat_push(state, &state->exp_result, &state->list, request, tmpl_xlat(state->vpt), false) < 0) {
REDEBUG("Failed starting expansion of %s", state->vpt->name);
RETURN_UNLANG_FAIL;
}
* will then call the module resumption frame, allowing the module to continue execution.
*
* @param[in] ctx To allocate talloc value boxes and values in.
- * @param[out] p_success Whether xlat evaluation was successful.
+ * @param[out] p_result Whether xlat evaluation was successful.
* @param[out] out Where to write the result of the expansion.
* @param[in] request The current request.
* @param[in] exp XLAT expansion to evaluate.
* @return
* - UNLANG_ACTION_PUSHED_CHILD
*/
-unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_head_t const *exp,
module_method_t resume,
unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
/*
* Push the xlat function
*/
- if (unlang_xlat_push(ctx, p_success, out, request, exp, false) < 0) return UNLANG_ACTION_STOP_PROCESSING;
+ if (unlang_xlat_push(ctx, p_result, out, request, exp, false) < 0) return UNLANG_ACTION_STOP_PROCESSING;
return UNLANG_ACTION_PUSHED_CHILD;
}
module_method_t resume,
unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx);
-unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_head_t const *xlat,
module_method_t resume,
unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx);
*/
typedef struct {
fr_edit_list_t *el; //!< my edit list
+ unlang_result_t result;
} unlang_frame_state_transaction_t;
/** Cast a group structure to the transaction keyword extension
#include <freeradius-devel/server/base.h>
#include <ctype.h>
+#include <freeradius-devel/unlang/mod_action.h>
#include <freeradius-devel/unlang/xlat_priv.h>
#include <freeradius-devel/util/debug.h>
#include "unlang_priv.h" /* Fixme - Should create a proper semi-public interface for the interpret */
fr_signal_t sigmask; //!< Signals to block
void *rctx; //!< for resume / signal
- bool *success; //!< If set, where to record the result
+ unlang_result_t *p_result; //!< If set, where to record the result
///< of the execution.
} unlang_frame_state_xlat_t;
/** Push a pre-compiled xlat onto the stack for evaluation
*
* @param[in] ctx To allocate value boxes and values in.
- * @param[out] p_success If set, and execution succeeds, true will be written
- * here. If execution fails, false will be written.
+ * @param[out] p_result If set, rcodes and priorities will be written here and
+ * not evaluated by the unlang interpreter.
* @param[out] out Where to write the result of the expansion.
* @param[in] request to push xlat onto.
* @param[in] xlat head of list
* - 0 on success.
* - -1 on failure.
*/
-static int unlang_xlat_push_internal(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+static int unlang_xlat_push_internal(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_head_t const *xlat, xlat_exp_t *node, bool top_frame)
{
/** Static instruction for performing xlat evaluations
/*
* Push a new xlat eval frame onto the stack
*/
- if (unlang_interpret_push(NULL, request, &xlat_instruction,
+ if (unlang_interpret_push(p_result, request, &xlat_instruction,
FRAME_CONF(RLM_MODULE_NOT_SET, top_frame), UNLANG_NEXT_STOP) < 0) return -1;
frame = &stack->frame[stack->depth];
MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_xlat_t));
state->head = xlat;
state->exp = node;
- state->success = p_success;
+ state->p_result = p_result;
state->ctx = ctx;
if (node) switch (node->type) {
/** Push a pre-compiled xlat onto the stack for evaluation
*
* @param[in] ctx To allocate value boxes and values in.
- * @param[out] p_success If set, and execution succeeds, true will be written
- * here. If execution fails, false will be written.
* @param[out] out Where to write the result of the expansion.
* @param[in] request to push xlat onto.
* @param[in] xlat to evaluate.
* - 0 on success.
* - -1 on failure.
*/
-int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+int unlang_xlat_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
{
(void) talloc_get_type_abort_const(xlat, xlat_exp_head_t);
- return unlang_xlat_push_internal(ctx, p_success, out, request, xlat, xlat_exp_head(xlat), top_frame);
+ return unlang_xlat_push_internal(ctx, p_result, out, request, xlat, xlat_exp_head(xlat), top_frame);
}
/** Push a pre-compiled xlat onto the stack for evaluation
*
* @param[in] ctx To allocate value boxes and values in.
- * @param[out] p_success If set, and execution succeeds, true will be written
+ * @param[out] p_result If set, and execution succeeds, true will be written
* here. If execution fails, false will be written.
* @param[out] out Where to write the result of the expansion.
* @param[in] request to push xlat onto.
* - 0 on success.
* - -1 on failure.
*/
-int unlang_xlat_push_node(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+int unlang_xlat_push_node(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_t *node)
{
- return unlang_xlat_push_internal(ctx, p_success, out, request, NULL, node, UNLANG_TOP_FRAME);
+ return unlang_xlat_push_internal(ctx, p_result, out, request, NULL, node, UNLANG_TOP_FRAME);
}
static unlang_action_t unlang_xlat_repeat(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
* multiple sibling nodes.
*/
fr_value_box_list_talloc_free(&state->out);
- if (unlang_xlat_push(state->ctx, state->success, &state->out, request, child, false) < 0) {
+ if (unlang_xlat_push(state->ctx, p_result, &state->out, request, child, false) < 0) {
REXDENT();
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_YIELD;
case XLAT_ACTION_DONE:
- if (state->success) *state->success = true;
p_result->rcode = RLM_MODULE_OK;
REXDENT();
return UNLANG_ACTION_CALCULATE_RESULT;
case XLAT_ACTION_FAIL:
fail:
- if (state->success) *state->success = false;
p_result->rcode = RLM_MODULE_FAIL;
REXDENT();
return UNLANG_ACTION_CALCULATE_RESULT;
* Calls the xlat interpreter and translates its wants and needs into
* unlang_action_t codes.
*/
-static unlang_action_t unlang_xlat(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
+static unlang_action_t unlang_xlat(UNUSED unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
{
unlang_frame_state_xlat_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t);
xlat_action_t xa;
* multiple sibling nodes.
*/
fr_value_box_list_talloc_free(&state->out);
- if (unlang_xlat_push(state->ctx, state->success, &state->out, request, child, false) < 0) {
+ if (unlang_xlat_push(state->ctx, NULL, &state->out, request, child, false) < 0) {
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_YIELD;
case XLAT_ACTION_DONE:
- if (state->success) *state->success = true;
p_result->rcode = RLM_MODULE_OK;
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_CALCULATE_RESULT;
case XLAT_ACTION_FAIL:
fail:
- if (state->success) *state->success = false;
p_result->rcode = RLM_MODULE_FAIL;
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_CALCULATE_RESULT;
return UNLANG_ACTION_YIELD;
case XLAT_ACTION_DONE:
- if (state->success) *state->success = true;
p_result->rcode = RLM_MODULE_OK;
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_CALCULATE_RESULT;
* multiple sibling nodes.
*/
fr_value_box_list_talloc_free(&state->out);
- if (unlang_xlat_push(state->ctx, state->success, &state->out, request, child, false) < 0) {
+ if (unlang_xlat_push(state->ctx, state->p_result, &state->out, request, child, false) < 0) {
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_PUSHED_CHILD;
case XLAT_ACTION_FAIL:
- if (state->success) *state->success = false;
p_result->rcode = RLM_MODULE_FAIL;
RINDENT_RESTORE(request, state);
return UNLANG_ACTION_CALCULATE_RESULT;
*/
int unlang_xlat_eval(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, xlat_exp_head_t const *xlat)
{
- bool success = false;
+ unlang_result_t result = { .rcode = RLM_MODULE_NOT_SET, .priority = MOD_ACTION_NOT_SET };
if (xlat->flags.impure_func) {
fr_strerror_const("Expansion requires async operations");
return -1;
}
- if (unlang_xlat_push(ctx, &success, out, request, xlat, UNLANG_TOP_FRAME) < 0) return -1;
+ if (unlang_xlat_push(ctx, &result, out, request, xlat, UNLANG_TOP_FRAME) < 0) return -1;
(void) unlang_interpret(request, UNLANG_REQUEST_RUNNING);
- if (!success) return -1;
+ if (!XLAT_RESULT_SUCCESS(&result)) return -1;
return 0;
}
#include <freeradius-devel/unlang/call_env.h>
#include <freeradius-devel/unlang/xlat_ctx.h>
+#include <freeradius-devel/unlang/interpret.h>
/** Instance data for an xlat expansion node
*
int unlang_xlat_timeout_add(request_t *request, fr_unlang_xlat_timeout_t callback,
void const *rctx, fr_time_t when);
-int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+#define XLAT_RESULT_SUCCESS(_p_result) ((_p_result)->rcode == RLM_MODULE_OK)
+
+int unlang_xlat_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_head_t const *head, bool top_frame)
CC_HINT(warn_unused_result);
}
typedef struct {
- bool last_success;
+ unlang_result_t last_result;
xlat_exp_head_t *ex;
} xlat_eval_rctx_t;
UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
{
xlat_eval_rctx_t *rctx = talloc_get_type_abort(xctx->rctx, xlat_eval_rctx_t);
- xlat_action_t xa = rctx->last_success ? XLAT_ACTION_DONE : XLAT_ACTION_FAIL;
+ xlat_action_t xa = XLAT_RESULT_SUCCESS(&rctx->last_result) ? XLAT_ACTION_DONE : XLAT_ACTION_FAIL;
talloc_free(rctx);
if (unlang_xlat_yield(request, xlat_eval_resume, NULL, 0, rctx) != XLAT_ACTION_YIELD) goto error;
- if (unlang_xlat_push(ctx, &rctx->last_success, (fr_value_box_list_t *)out->dlist,
+ if (unlang_xlat_push(ctx, &rctx->last_result, (fr_value_box_list_t *)out->dlist,
request, rctx->ex, UNLANG_SUB_FRAME) < 0) goto error;
return XLAT_ACTION_PUSH_UNLANG;
#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/tmpl_dcursor.h>
+#include <freeradius-devel/server/rcode.h>
+#include <freeradius-devel/unlang/mod_action.h>
#include <freeradius-devel/unlang/xlat_priv.h>
static int instance_count = 0;
xlat_escape_legacy_t escape, void const *escape_ctx)
{
fr_value_box_list_t result;
- bool success = false;
+ unlang_result_t unlang_result = { .rcode = RLM_MODULE_NOT_SET, .priority = MOD_ACTION_NOT_SET };
TALLOC_CTX *pool = talloc_new(NULL);
rlm_rcode_t rcode;
char *str;
/*
* Use the unlang stack to evaluate the xlat.
*/
- if (unlang_xlat_push(pool, &success, &result, request, head, UNLANG_TOP_FRAME) < 0) {
+ if (unlang_xlat_push(pool, &unlang_result, &result, request, head, UNLANG_TOP_FRAME) < 0) {
fail:
talloc_free(pool);
return -1;
switch (rcode) {
default:
- if (!success) goto fail;
+ if (!XLAT_RESULT_SUCCESS(&unlang_result)) goto fail;
break;
case RLM_MODULE_REJECT:
} xlat_regex_inst_t;
typedef struct {
- bool last_success;
+ unlang_result_t last_result;
fr_value_box_list_t list;
} xlat_regex_rctx_t;
/*
* If the expansions fails, then we fail the entire thing.
*/
- if (!rctx->last_success) {
+ if (!XLAT_RESULT_SUCCESS(&rctx->last_result)) {
talloc_free(rctx);
return XLAT_ACTION_FAIL;
}
return XLAT_ACTION_FAIL;
}
- if (unlang_xlat_push(ctx, &rctx->last_success, &rctx->list,
+ if (unlang_xlat_push(ctx, &rctx->last_result, &rctx->list,
request, tmpl_xlat(inst->xlat->vpt), UNLANG_SUB_FRAME) < 0) goto fail;
return XLAT_ACTION_PUSH_UNLANG;
typedef struct {
TALLOC_CTX *ctx;
- bool last_success;
+ unlang_result_t last_result;
fr_value_box_t *box; //!< output value-box
int current;
fr_value_box_list_t list;
return XLAT_ACTION_FAIL;
}
- if (unlang_xlat_push(rctx, &rctx->last_success, &rctx->list,
+ if (unlang_xlat_push(rctx, &rctx->last_result, &rctx->list,
request, inst->argv[rctx->current], UNLANG_SUB_FRAME) < 0) goto fail;
return XLAT_ACTION_PUSH_UNLANG;
void unlang_xlat_init(void);
-int unlang_xlat_push_node(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+int unlang_xlat_push_node(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
request_t *request, xlat_exp_t *node);
int xlat_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out,
RCSID("$Id$")
#include <freeradius-devel/server/base.h>
+#include <freeradius-devel/unlang/mod_action.h>
#include <freeradius-devel/unlang/xlat_priv.h>
#include <freeradius-devel/util/calc.h>
static int xlat_purify_list_internal(xlat_exp_head_t *head, request_t *request, fr_token_t quote)
{
int rcode;
- bool success;
+ unlang_result_t result = { .rcode = RLM_MODULE_NOT_SET, .priority = MOD_ACTION_NOT_SET };
fr_value_box_list_t list;
xlat_flags_t our_flags;
xlat_exp_t *node, *next;
*/
fr_assert(node->flags.pure);
fr_value_box_list_init(&list);
- success = false;
- if (unlang_xlat_push_node(head, &success, &list, request, node) < 0) {
+ result.rcode = RLM_MODULE_NOT_SET;
+ if (unlang_xlat_push_node(head, &result, &list, request, node) < 0) {
return -1;
}
*/
(void) unlang_interpret_synchronous(NULL, request);
- if (!success) return -1;
+ if (!XLAT_RESULT_SUCCESS(&result)) return -1;
/*
* The function call becomes a GROUP of boxes
} xlat_redundant_inst_t;
typedef struct {
- bool last_success; //!< Did the last call succeed?
+ unlang_result_t last_result; //!< Did the last call succeed?
xlat_exp_head_t **first; //!< First function called.
///< Used for redundant-load-balance.
xlat_redundant_rctx_t *rctx = talloc_get_type_abort(xctx->rctx, xlat_redundant_rctx_t);
xlat_action_t xa = XLAT_ACTION_DONE;
- if (rctx->last_success) {
+ if (XLAT_RESULT_SUCCESS(&rctx->last_result)) {
done:
talloc_free(rctx);
return xa;
/*
* Push the next child...
*/
- if (unlang_xlat_push(ctx, &rctx->last_success, (fr_value_box_list_t *)out->dlist,
+ if (unlang_xlat_push(ctx, &rctx->last_result, (fr_value_box_list_t *)out->dlist,
request, *rctx->current, UNLANG_SUB_FRAME) < 0) goto error;
return XLAT_ACTION_PUSH_UNLANG;
UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
{
xlat_redundant_rctx_t *rctx = talloc_get_type_abort(xctx->rctx, xlat_redundant_rctx_t);
- xlat_action_t xa = rctx->last_success ? XLAT_ACTION_DONE : XLAT_ACTION_FAIL;
+ xlat_action_t xa = XLAT_RESULT_SUCCESS(&rctx->last_result) ? XLAT_ACTION_DONE : XLAT_ACTION_FAIL;
talloc_free(rctx);
fr_assert(0);
}
- if (unlang_xlat_push(ctx, &rctx->last_success, (fr_value_box_list_t *)out->dlist,
+ if (unlang_xlat_push(ctx, &rctx->last_result, (fr_value_box_list_t *)out->dlist,
request, *rctx->current, UNLANG_SUB_FRAME) < 0) return XLAT_ACTION_FAIL;
return XLAT_ACTION_PUSH_UNLANG;
}
typedef struct {
- bool last_success;
+ unlang_result_t last_result;
fr_value_box_list_t result;
rlm_sqlcounter_t *inst;
sqlcounter_call_env_t *env;
}
fr_value_box_list_init(&rctx->result);
- if (unlang_xlat_push(rctx, &rctx->last_success, &rctx->result, request, env->query_xlat, UNLANG_SUB_FRAME) < 0) goto error;
+ if (unlang_xlat_push(rctx, &rctx->last_result, &rctx->result, request, env->query_xlat, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}