}
static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, UNUSED void *proc_inst, UNUSED request_t *request,
- UNUSED fr_value_box_t **src, UNUSED fr_map_list_t const *maps)
+ UNUSED fr_value_box_list_t *src, UNUSED fr_map_list_t const *maps)
{
return RLM_MODULE_FAIL;
}
size_t fr_jpath_escape_func(UNUSED request_t *request, char *out, size_t outlen,
char const *in, UNUSED void *arg);
-int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_t **out,
+int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_list_t *out,
fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
json_object *root, fr_jpath_node_t const *jpath);
/** Recursive function for jpath_expr_evaluate
*
* @param[in,out] ctx to allocate fr_value_box_t in.
- * @param[out] tail Where to write fr_value_box_t (**).
+ * @param[out] tail Where to write fr_value_box_t.
* @param[in] dst_type FreeRADIUS type to convert to.
* @param[in] dst_enumv Enumeration values to allow string to integer conversions.
* @param[in] object current node in the json tree.
* - 0 on no match.
* - -1 on error.
*/
-static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail,
+static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_list_t *tail,
fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
json_object *object, fr_jpath_node_t const *jpath)
{
return -1;
}
- **tail = value;
- *tail = &(**tail)->next;
+ fr_dlist_insert_tail(tail, value);
return 1;
}
* - 0 on no match.
* - -1 on error.
*/
-int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_t **out,
+int fr_jpath_evaluate_leaf(TALLOC_CTX *ctx, fr_value_box_list_t *out,
fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
json_object *root, fr_jpath_node_t const *jpath)
{
- fr_value_box_t **tail = out;
-
- *tail = NULL;
-
if (!root) return -1;
switch (jpath->selector->type) {
return -1;
}
- return jpath_evaluate(ctx, &tail, dst_type, dst_enumv, root, jpath->next);
+ return jpath_evaluate(ctx, out, dst_type, dst_enumv, root, jpath->next);
}
/** Print a node list to a string for debugging
/** Execute a program without waiting for the program to finish.
*
* @param request the request
- * @param vb as returned by xlat_frame_eval()
+ * @param vb_list as returned by xlat_frame_eval()
* @param env_pairs VPs to put into into the environment. May be NULL.
* @return
* - <0 on error
* would allow finer-grained control over the attributes to put into
* the environment.
*/
-int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs)
+int fr_exec_nowait(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs)
{
int argc;
char **envp;
/*
* Ensure that we don't do anything stupid.
*/
- first = fr_value_box_list_get(vb, 0);
- if (first->type == FR_TYPE_GROUP) first = first->vb_group;
+ first = fr_dlist_head(vb_list);
+ if (first->type == FR_TYPE_GROUP) first = fr_dlist_head(&first->vb_group);
if (first->tainted) {
fr_strerror_printf("Program to run comes from tainted source - %pV", first);
return -1;
envp[0] = NULL;
}
- argc = fr_value_box_list_flatten_argv(request, &argv, vb);
+ argc = fr_value_box_list_flatten_argv(request, &argv, vb_list);
if (argc < 0) {
talloc_free(envp);
return -1;
* and closing it.
*
* @param request the request
- * @param vb as returned by xlat_frame_eval()
+ * @param vb_list as returned by xlat_frame_eval()
* @param env_pairs VPs to put into into the environment. May be NULL.
* @param[out] pid_p The PID of the child
* @param[out] input_fd The stdin FD of the child
* would allow finer-grained control over the attributes to put into
* the environment.
*/
-int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd)
+int fr_exec_wait_start(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd)
{
int argc;
char **envp;
/*
* Ensure that we don't do anything stupid.
*/
- first = fr_value_box_list_get(vb, 0);
- if (first->type == FR_TYPE_GROUP) first = first->vb_group;
+ first = fr_dlist_head(vb_list);
+ if (first->type == FR_TYPE_GROUP) first = fr_dlist_head(&first->vb_group);
if (first->tainted) {
fr_strerror_printf("Program to run comes from tainted source - %pV", first);
return -1;
envp[0] = NULL;
}
- argc = fr_value_box_list_flatten_argv(request, &argv, vb);
+ argc = fr_value_box_list_flatten_argv(request, &argv, vb_list);
if (argc < 0) {
error:
talloc_free(envp);
request_t *request, char const *cmd, fr_pair_list_t *input_pairs,
bool exec_wait, bool shell_escape, fr_time_delta_t timeout) CC_HINT(nonnull (5, 6));
-int fr_exec_nowait(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs);
+int fr_exec_nowait(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs);
-int fr_exec_wait_start(request_t *request, fr_value_box_t *vb, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd);
+int fr_exec_wait_start(request_t *request, fr_value_box_list_t *vb_list, fr_pair_list_t *env_pairs, pid_t *pid_p, int *input_fd, int *output_fd);
void fr_exec_waitpid(pid_t pid);
int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
request_t *request, map_t const *map,
- fr_value_box_t **lhs_result, fr_value_box_t **rhs_result);
+ fr_value_box_list_t *lhs_result, fr_value_box_list_t *rhs_result);
int map_to_request(request_t *request, map_t const *map,
radius_map_getvalue_t func, void *ctx);
*/
int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
request_t *request, map_t const *original,
- fr_value_box_t **lhs_result, fr_value_box_t **rhs_result)
+ fr_value_box_list_t *lhs_result, fr_value_box_list_t *rhs_result)
{
vp_list_mod_t *n = NULL;
- map_t map_tmp;
+ map_t map_tmp;
map_t const *mutated = original;
- fr_cursor_t values;
- fr_value_box_t *head = NULL;
-
+ fr_dcursor_t values;
+ fr_value_box_list_t head;
TALLOC_CTX *tmp_ctx = NULL;
MAP_VERIFY(original);
tmpl_is_xlat(original->lhs));
*out = NULL;
+ fr_value_box_list_init(&head);
/*
* Preprocessing of the LHS of the map.
case TMPL_TYPE_XLAT:
{
ssize_t slen;
+ fr_value_box_t *lhs_result_head = fr_dlist_head(lhs_result);
/*
* Get our own mutable copy of the original so we can
tmp_ctx = talloc_new(NULL);
- fr_assert(lhs_result && *lhs_result);
+ fr_assert(!fr_dlist_empty(lhs_result));
/*
* This should always be a noop, but included
* here for robustness.
*/
- if (fr_value_box_list_concat(*lhs_result, *lhs_result, lhs_result, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(lhs_result_head, lhs_result_head, lhs_result, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Left side expansion failed");
- TALLOC_FREE(*lhs_result);
+ fr_dlist_talloc_free(lhs_result);
goto error;
}
- slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, (*lhs_result)->vb_strvalue,
+ slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, lhs_result_head->vb_strvalue,
&(tmpl_rules_t){
.dict_def = request->dict,
.prefix = TMPL_ATTR_REF_PREFIX_NO
});
if (slen <= 0) {
RPEDEBUG("Left side expansion result \"%s\" is not an attribute reference",
- (*lhs_result)->vb_strvalue);
- TALLOC_FREE(*lhs_result);
+ lhs_result_head->vb_strvalue);
+ fr_dlist_talloc_free(lhs_result);
goto error;
}
fr_assert(tmpl_is_attr(mutated->lhs) || tmpl_is_list(mutated->lhs));
n = list_mod_generic_afrom_map(ctx, original, mutated);
if (!n) goto error;
- fr_cursor_init(&values, &head);
+ fr_dcursor_init(&values, &head);
if (fr_value_box_from_str(fr_dlist_head(&n->mod),
tmpl_value(fr_map_list_head(&n->mod)->rhs), &type,
*/
if (!map_check_src_or_dst(request, mutated, mutated->lhs)) goto error;
- (void)fr_cursor_init(&values, &head);
+ (void)fr_dcursor_init(&values, &head);
switch (mutated->rhs->type) {
case TMPL_TYPE_XLAT:
{
fr_assert(tmpl_xlat(mutated->rhs) != NULL);
- fr_cursor_t from;
+ fr_dcursor_t from;
fr_value_box_t *vb, *n_vb;
assign_values:
* happens. This is only for XLATs and in future
* EXECs.
*/
- if (!rhs_result || !*rhs_result) {
+ if (fr_dlist_empty(rhs_result)) {
n = list_mod_empty_string_afrom_map(ctx, original, mutated);
if (!n) {
RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name);
xlat_error:
- fr_cursor_head(&values);
- fr_cursor_free_list(&values);
+ fr_dcursor_head(&values);
+ fr_dcursor_free_list(&values);
goto error;
}
goto finish;
n = list_mod_generic_afrom_map(ctx, original, mutated);
if (!n) goto error;
- (void)fr_cursor_init(&from, rhs_result);
- while ((vb = fr_cursor_remove(&from))) {
+ (void)fr_dcursor_init(&from, rhs_result);
+ while ((vb = fr_dcursor_remove(&from))) {
if (vb->type != tmpl_da(mutated->lhs)->type) {
n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs);
if (!n_vb) {
- fr_cursor_head(&from);
- fr_cursor_free_list(&from);
+ fr_dcursor_head(&from);
+ fr_dcursor_free_list(&from);
goto xlat_error;
}
tmpl_da(mutated->lhs), vb) < 0) {
RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name);
- fr_cursor_head(&from);
- fr_cursor_free_list(&from);
+ fr_dcursor_head(&from);
+ fr_dcursor_free_list(&from);
goto xlat_error;
}
talloc_free(vb);
} else {
n_vb = talloc_steal(n, vb); /* Should already be in ctx of n's parent */
}
- fr_cursor_append(&values, n_vb);
+ fr_dcursor_append(&values, n_vb);
}
}
break;
fr_value_box_t *n_vb;
int err;
- fr_assert(!rhs_result || !*rhs_result);
+ fr_assert(fr_dlist_empty(rhs_result));
fr_assert((tmpl_is_attr(mutated->lhs) && tmpl_da(mutated->lhs)) ||
(tmpl_is_list(mutated->lhs) && !tmpl_da(mutated->lhs)));
n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs);
if (!n_vb) {
attr_error:
- fr_cursor_head(&values);
- fr_cursor_free_list(&values);
+ fr_dcursor_head(&values);
+ fr_dcursor_free_list(&values);
tmpl_cursor_clear(&cc_attr);
goto error;
}
} else {
fr_value_box_copy(n_vb, n_vb, &vp->data);
}
- fr_cursor_append(&values, n_vb);
+ fr_dcursor_append(&values, n_vb);
} while ((vp = fr_dcursor_next(&from)));
tmpl_cursor_clear(&cc_attr);
case TMPL_TYPE_DATA:
{
- fr_cursor_t from;
- fr_value_box_t *vb, *vb_head, *n_vb;
+ /*
+ * Commented out lines below are due to fr_value_box_t
+ * now being in a dlist - so value box entries in a fr_tmpl_t
+ * can no-longer be treated as the head of a list
+ */
+ fr_value_box_t *vb, *n_vb;
+// fr_value_box_t *vb_head;
- fr_assert(!rhs_result || !*rhs_result);
+ fr_assert(fr_dlist_empty(rhs_result));
fr_assert(tmpl_da(mutated->lhs));
fr_assert(tmpl_is_attr(mutated->lhs));
n = list_mod_generic_afrom_map(ctx, original, mutated);
if (!n) goto error;
- vb_head = tmpl_value(mutated->rhs);
+ vb = tmpl_value(mutated->rhs);
- for (vb = fr_cursor_init(&from, &vb_head);
- vb;
- vb = fr_cursor_next(&from)) {
+// while ((vb = fr_dlist_next(vb_head, vb))) {
n_vb = fr_value_box_alloc_null(fr_map_list_head(&n->mod)->rhs);
if (!n_vb) {
data_error:
- fr_cursor_head(&values);
- fr_cursor_free_list(&values);
+ fr_dcursor_head(&values);
+ fr_dcursor_free_list(&values);
goto error;
}
/*
*/
if (fr_value_box_copy(n_vb, n_vb, vb) < 0) goto data_error;
}
- fr_cursor_append(&values, n_vb);
- }
+ fr_dcursor_append(&values, n_vb);
+// }
}
break;
fr_dcursor_t from;
fr_pair_list_t vp_head;
fr_pair_t *vp;
+ fr_value_box_t *rhs_result_head = fr_dlist_head(rhs_result);
fr_pair_list_init(&vp_head);
/*
* happens. This is only for XLATs and in future
* EXECs.
*/
- if (!rhs_result || !*rhs_result) {
+ if (fr_dlist_empty(rhs_result)) {
RPEDEBUG("Cannot assign empty value to \"%s\"", mutated->lhs->name);
goto error;
}
* This should always be a noop, but included
* here for robustness.
*/
- if (fr_value_box_list_concat(*rhs_result, *rhs_result, rhs_result, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(rhs_result_head, rhs_result_head, rhs_result, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Right side expansion failed");
- TALLOC_FREE(*rhs_result);
+ fr_dlist_talloc_free(rhs_result);
goto error;
}
/*
* Parse the VPs from the RHS.
*/
- fr_pair_list_afrom_box(ctx, &vp_head, request->dict, *rhs_result);
+ fr_pair_list_afrom_box(ctx, &vp_head, request->dict, rhs_result_head);
if (fr_pair_list_empty(&vp_head)) {
talloc_free(n);
RDEBUG2("No pairs returned by exec");
goto error;
}
- fr_assert(head || !n);
+ fr_assert(!fr_dlist_empty(&head) || !n);
/*
* FIXME: This is only required because
* If tmpl_value were a pointer we could
* assign values directly.
*/
- fr_value_box_copy(fr_map_list_head(&n->mod)->rhs, tmpl_value(fr_map_list_head(&n->mod)->rhs), head);
- tmpl_value(fr_map_list_head(&n->mod)->rhs)->next = head->next;
- talloc_free(head);
+ fr_value_box_copy(fr_map_list_head(&n->mod)->rhs, tmpl_value(fr_map_list_head(&n->mod)->rhs), fr_dlist_head(&head));
+ /*
+ * value boxes in tmpls cannot now be the head of a list
+ *
+ *tmpl_value(fr_map_list_head(&n->mod)->rhs)->next = head->next;
+ */
+ fr_dlist_talloc_free(&head);
finish:
if (n) {
* Fast path...
*/
mod = fr_dlist_head(&vlm->mod);
- if ((vlm->mod.num_elements == 1) && !tmpl_value(mod->rhs)->next) {
+ if (vlm->mod.num_elements == 1) {
fr_pair_t *vp;
vp = map_list_mod_to_vp(ctx, mod->lhs, tmpl_value(mod->rhs));
fr_pair_add(list, vp);
for (;
mod;
mod = fr_dlist_next(&vlm->mod, mod)) {
- fr_value_box_t *vb;
+ /*
+ * Commented out lines due to fr_value_box_t lists now
+ * being dlists
+ */
+// fr_value_box_t *vb;
fr_pair_t *vp;
- for (vb = tmpl_value(mod->rhs);
- vb;
- vb = vb->next) {
- vp = map_list_mod_to_vp(ctx, mod->lhs, vb);
+// for (vb = tmpl_value(mod->rhs);
+// vb;
+// vb = vb->next) {
+ vp = map_list_mod_to_vp(ctx, mod->lhs, tmpl_value(mod->rhs));
if (!vp) {
fr_pair_list_free(list);
}
fr_pair_add(list, vp);
- }
+// }
}
}
* map_list_mod_debug()
*/
if (RDEBUG_ENABLED2) {
- for (vb = tmpl_value(mod->rhs);
- vb;
- vb = vb->next) {
+ vb = tmpl_value(mod->rhs);
+ /*
+ * Commented out lines due to fr_value_box_t lists now
+ * being dlists
+ */
+// for (vb = tmpl_value(mod->rhs);
+// vb;
+// vb = vb->next) {
map_list_mod_debug(request, map, mod, vb->type != FR_TYPE_INVALID ? vb : NULL);
- }
+// }
}
}
mod = fr_dlist_head(&vlm->mod); /* Reset */
*/
if (tmpl_num(map->lhs) != NUM_ALL) {
fr_value_box_t *vb = tmpl_value(fr_map_list_head(&vlm->mod)->rhs);
-
- do {
+ /*
+ * Commented out loop due to fr_value_box_t now being
+ * in dlists
+ */
+// do {
if (fr_value_box_cmp(vb, &found->data) == 0) {
fr_dcursor_free_item(&list);
goto finish;
}
- } while ((vb = vb->next));
+// } while ((vb = vb->next));
goto finish; /* Wasn't found */
}
*/
do {
fr_value_box_t *vb = tmpl_value(fr_map_list_head(&vlm->mod)->rhs);
-
- do {
+ /*
+ * Commented out loop due to fr_value_box_t now being
+ * in dlists
+ */
+// do {
if (fr_value_box_cmp(vb, &found->data) == 0) {
fr_dcursor_free_item(&list);
break;
}
- } while ((vb = vb->next));
+// } while ((vb = vb->next));
} while ((found = fr_dcursor_next(&list)));
}
goto finish;
fr_value_box_t *vb = tmpl_value(mod->rhs);
bool remove = true;
- do {
+ /*
+ * Commented out loop due to fr_value_box_t now being
+ * in dlists
+ */
+// do {
if (fr_value_box_cmp_op(mod->op, &found->data, vb) == 1) remove = false;
- } while ((vb = vb->next));
+// } while ((vb = vb->next));
if (remove) fr_dcursor_free_item(&list);
goto finish;
fr_value_box_t *vb = tmpl_value(mod->rhs);
bool remove = true;
- do {
+ /*
+ * Commented out loop due to fr_value_box_t now being
+ * in dlists
+ */
+// do {
if (fr_value_box_cmp_op(mod->op, &found->data, vb) == 1) remove = false;
- } while ((vb = vb->next));
+// } while ((vb = vb->next));
if (remove) {
fr_dcursor_free_item(&list);
* @param[in,out] result Result of expanding the map input. May be consumed
* by the map processor.
*/
-rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_t **result)
+rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *result)
{
return inst->proc->evaluate(inst->proc->mod_inst, inst->data, request, result, inst->maps);
}
* - #RLM_MODULE_FAIL - If an error occurred performing the mapping.
*/
typedef rlm_rcode_t (*map_proc_func_t)(void *mod_inst, void *proc_inst, request_t *request,
- fr_value_box_t **result, fr_map_list_t const *maps);
+ fr_value_box_list_t *result, fr_map_list_t const *maps);
/** Allocate new instance data for a map processor
*
map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc,
CONF_SECTION *cs, tmpl_t const *src, fr_map_list_t const *maps);
-rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_t **src);
+rlm_rcode_t map_proc(request_t *request, map_proc_inst_t const *inst, fr_value_box_list_t *src);
#ifdef __cplusplus
}
}
typedef struct {
- char *name;
- xlat_exp_t *xlat;
- fr_pair_list_t vps;
- fr_value_box_t *box;
- bool expanded;
+ char *name;
+ xlat_exp_t *xlat;
+ fr_pair_list_t vps;
+ fr_value_box_list_t box;
+ bool expanded;
} fr_trigger_t;
static unlang_action_t trigger_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
*/
}
- if (!ctx->box) {
+ if (fr_dlist_empty(&ctx->box)) {
RERROR("Failed trigger %s - did not expand to anything", ctx->name);
RETURN_MODULE_FAIL;
}
/*
* Execute the program without waiting for results.
*/
- if (fr_exec_nowait(request, ctx->box, NULL) < 0) {
+ if (fr_exec_nowait(request, &ctx->box, NULL) < 0) {
RPERROR("Failed trigger %s", ctx->name);
RETURN_MODULE_FAIL;
}
MEM(ctx = talloc_zero(fake, fr_trigger_t));
fr_pair_list_init(&ctx->vps);
+ fr_value_box_list_init(&ctx->box);
ctx->name = talloc_strdup(ctx, value);
if (request && !fr_pair_list_empty(&request->request_pairs)) {
vp_list_mod_t **vlm_next;
vp_list_mod_t *vlm_head; //!< First VP List Mod.
- fr_value_box_t *lhs_result; //!< Result of expanding the LHS
- fr_value_box_t *rhs_result; //!< Result of expanding the RHS.
+ fr_value_box_list_t lhs_result; //!< Result of expanding the LHS
+ fr_value_box_list_t rhs_result; //!< Result of expanding the RHS.
unlang_update_state_t state; //!< What we're currently doing.
} unlang_frame_state_update_t;
*
*/
typedef struct {
- fr_value_box_t *src_result; //!< Result of expanding the map source.
+ fr_value_box_list_t src_result; //!< Result of expanding the map source.
} unlang_frame_state_map_proc_t;
/** Apply a list of modifications on one or more fr_pair_t lists.
case UNLANG_UPDATE_MAP_INIT:
update_state->state = UNLANG_UPDATE_MAP_EXPANDED_LHS;
- fr_assert(!update_state->lhs_result); /* Should have been consumed */
- fr_assert(!update_state->rhs_result); /* Should have been consumed */
+ fr_assert(fr_dlist_empty(&update_state->lhs_result)); /* Should have been consumed */
+ fr_assert(fr_dlist_empty(&update_state->rhs_result)); /* Should have been consumed */
switch (map->lhs->type) {
default:
/*
* Concat the top level results together
*/
- if (update_state->rhs_result &&
- (fr_value_box_list_concat(update_state, update_state->rhs_result, &update_state->rhs_result,
+ if (!fr_dlist_empty(&update_state->rhs_result) &&
+ (fr_value_box_list_concat(update_state, fr_dlist_head(&update_state->rhs_result), &update_state->rhs_result,
FR_TYPE_STRING, true) < 0)) {
RPEDEBUG("Failed concatenating RHS expansion results");
goto error;
request, map,
&update_state->lhs_result, &update_state->rhs_result) < 0) goto error;
- talloc_list_free(&update_state->rhs_result);
+ fr_dlist_talloc_free(&update_state->rhs_result);
next:
update_state->state = UNLANG_UPDATE_MAP_INIT;
- talloc_list_free(&update_state->lhs_result);
+ fr_dlist_talloc_free(&update_state->lhs_result);
/*
* Wind to the end...
g->num_children)); /* 128 is for string buffers */
fr_dcursor_init(&update_state->maps, &gext->map);
+ fr_value_box_list_init(&update_state->lhs_result);
+ fr_value_box_list_init(&update_state->rhs_result);
update_state->vlm_next = &update_state->vlm_head;
repeatable_set(frame);
map_proc_inst_t *inst = gext->proc_inst;
unlang_frame_state_map_proc_t *map_proc_state = talloc_get_type_abort(frame->state, unlang_frame_state_map_proc_t);
- RDEBUG2("MAP %s \"%pM\"", inst->proc->name, map_proc_state->src_result);
+ RDEBUG2("MAP %s \"%pM\"", inst->proc->name, &map_proc_state->src_result);
/*
* FIXME - We don't yet support async LHS/RHS expansions for map procs
*/
#ifndef NDEBUG
- if (map_proc_state->src_result) talloc_list_get_type_abort(map_proc_state->src_result, fr_value_box_t);
+ if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result);
#endif
*p_result = map_proc(request, gext->proc_inst, &map_proc_state->src_result);
#ifndef NDEBUG
- if (map_proc_state->src_result) talloc_list_get_type_abort(map_proc_state->src_result, fr_value_box_t);
+ if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result);
#endif
return *p_result == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT;
*/
repeatable_set(frame);
+ fr_value_box_list_init(&map_proc_state->src_result);
/*
* Set this BEFORE doing anything else, as we will be
* called again after unlang_xlat_push() returns.
*/
if (inst->src) switch (inst->src->type) {
default:
- if (tmpl_aexpand(frame->state, &map_proc_state->src_result,
+ {
+ fr_value_box_t *src_result = NULL;
+ if (tmpl_aexpand(frame->state, &src_result,
request, inst->src, NULL, NULL) < 0) {
REDEBUG("Failed expanding map src");
error:
*p_result = RLM_MODULE_FAIL;
return UNLANG_ACTION_CALCULATE_RESULT;
}
+ fr_dlist_insert_head(&map_proc_state->src_result, src_result);
break;
-
+ }
case TMPL_TYPE_EXEC:
if (unlang_tmpl_push(map_proc_state, &map_proc_state->src_result,
request, inst->src, NULL, NULL) < 0) {
* @return
* - UNLANG_ACTION_YIELD
*/
-unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_t **out,
+unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_list_t *out,
request_t *request, xlat_exp_t const *exp,
unlang_module_resume_t resume,
unlang_module_signal_t signal, void *rctx)
* @return
* - UNLANG_ACTION_YIELD
*/
-unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_t **out, int *status,
+unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, int *status,
request_t *request, tmpl_t const *vpt,
fr_pair_list_t *vps,
unlang_module_resume_t resume,
unlang_module_resume_t resume,
unlang_module_signal_t signal, void *rctx);
-unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_t **out,
+unlang_action_t unlang_module_yield_to_xlat(TALLOC_CTX *ctx, fr_value_box_list_t *out,
request_t *request, xlat_exp_t const *xlat,
unlang_module_resume_t resume,
unlang_module_signal_t signal, void *rctx);
-unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_t **out, int *status,
+unlang_action_t unlang_module_yield_to_tmpl(TALLOC_CTX *ctx, fr_value_box_list_t *out, int *status,
request_t *request, tmpl_t const *exp,
fr_pair_list_t *vps,
unlang_module_resume_t resume,
* @param[in] vps the input VPs. May be NULL. Used only for #TMPL_TYPE_EXEC
* @param[out] status where the status of exited programs will be stored.
*/
-int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_t **out, request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status)
+int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status)
{
unlang_stack_t *stack = request->stack;
unlang_stack_frame_t *frame;
.status_p = status
};
+ fr_value_box_list_init(&state->box);
+
return 0;
}
unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state,
unlang_frame_state_tmpl_t);
- if (state->out) *state->out = state->box;
+ if (state->out) fr_dlist_move(state->out, &state->box);
if (state->resume) {
rlm_rcode_t rcode;
* care about output, and we don't care about the programs exit status.
*/
if (state->failed) {
- TALLOC_FREE(state->box);
+ fr_dlist_talloc_free(&state->box);
goto resume;
}
state->status = -state->status;
}
- fr_assert(state->box == NULL);
+ fr_assert(fr_dlist_empty(&state->box));
goto resume;
}
*/
if (state->out) {
fr_type_t type = FR_TYPE_STRING;
+ fr_value_box_t *box;
/*
* Remove any trailing LF / CR
state->ptr = p;
}
- MEM(state->box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true));
- if (fr_value_box_from_str(state->box, state->box, &type, NULL,
+ fr_value_box_list_init(&state->box);
+ MEM(box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true));
+ if (fr_value_box_from_str(state->ctx, box, &type, NULL,
state->buffer, state->ptr - state->buffer, 0, true) < 0) {
- talloc_free(state->box);
+ talloc_free(box);
*p_result = RLM_MODULE_FAIL;
return UNLANG_ACTION_CALCULATE_RESULT;
}
+ fr_dlist_insert_head(&state->box, box);
}
/*
state->fd = -1;
if (state->out) fd_p = &state->fd;
- if (fr_exec_wait_start(request, state->box, state->vps, &pid, NULL, fd_p) < 0) {
+ if (fr_exec_wait_start(request, &state->box, state->vps, &pid, NULL, fd_p) < 0) {
RPEDEBUG("Failed executing program");
fail:
*p_result = RLM_MODULE_FAIL;
return UNLANG_ACTION_CALCULATE_RESULT;
}
- TALLOC_FREE(state->box); /* this is the xlat expansion, and not the output string we want */
+ fr_dlist_talloc_free(&state->box); /* this is the xlat expansion, and not the output string we want */
state->pid = pid;
state->status = -1; /* default to program didn't work */
unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state,
unlang_frame_state_tmpl_t);
- if (fr_exec_nowait(request, state->box, state->vps) < 0) {
+ if (fr_exec_nowait(request, &state->box, state->vps) < 0) {
RPEDEBUG("Failed executing program");
*p_result = RLM_MODULE_FAIL;
/*
* If we're not called from unlang_tmpl_push(), then
- * ensure that we clean up the resulting value boxes.
+ * ensure that we clean up the resulting value boxes
+ * and that the list to write the boxes in is initialised.
*/
- if (!state->ctx) state->ctx = state;
+ if (!state->ctx) {
+ state->ctx = state;
+ fr_value_box_list_init(&state->box);
+ }
if (!tmpl_async_required(ut->tmpl)) {
if (!ut->inline_exec) {
*/
typedef rlm_rcode_t (*fr_unlang_tmpl_resume_t)(request_t *request, void *rctx);
-int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_t **out,
+int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out,
request_t *request, tmpl_t const *tmpl, fr_pair_list_t *vps, int *status)
CC_HINT(warn_unused_result);
*/
typedef struct {
TALLOC_CTX *ctx; //!< for allocating value boxes
- fr_value_box_t **out; //!< where the expansion is stored
- fr_value_box_t *box; //!< where the expansion is stored
+ fr_value_box_list_t *out; //!< where the expansion is stored
+ fr_value_box_list_t box; //!< where the expansion is stored
void *rctx; //!< for resume
fr_unlang_tmpl_resume_t resume; //!< resumption handler
TALLOC_CTX *ctx; //!< to allocate boxes and values in.
TALLOC_CTX *event_ctx; //!< for temporary events
xlat_exp_t const *exp;
- fr_cursor_t values; //!< Values aggregated so far.
+ fr_dcursor_t values; //!< Values aggregated so far.
/*
* For func and alternate
*/
- fr_value_box_t *rhead; //!< Head of the result of a nested
+ fr_value_box_list_t rhead; //!< Head of the result of a nested
///< expansion.
bool alternate; //!< record which alternate branch we
///< previously took.
* - 0 on success.
* - -1 on failure.
*/
-int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_t **out,
+int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_list_t *out,
request_t *request, xlat_exp_t const *exp, bool top_frame)
{
MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_xlat_t));
state->exp = talloc_get_type_abort_const(exp, xlat_exp_t); /* Ensure the node is valid */
- fr_cursor_talloc_init(&state->values, out, fr_value_box_t);
+ fr_dcursor_talloc_init(&state->values, out, fr_value_box_t);
+ fr_value_box_list_init(&state->rhead);
state->ctx = ctx;
* at this level. A frame may be used to evaluate
* multiple sibling nodes.
*/
- talloc_list_free(&state->rhead);
+ fr_dlist_talloc_free(&state->rhead);
if (unlang_xlat_push(state->ctx, &state->rhead, request, child, false) < 0) {
*p_result = RLM_MODULE_FAIL;
return UNLANG_ACTION_STOP_PROCESSING;
* mean it turned a result.
* - XLAT_ACTION_FAIL the xlat function failed.
*/
-typedef xlat_action_t (*xlat_func_t)(TALLOC_CTX *ctx, fr_cursor_t *out,
+typedef xlat_action_t (*xlat_func_t)(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in);
+ fr_value_box_list_t *in);
/** xlat callback resumption function
*
* mean it turned a result.
* - XLAT_ACTION_FAIL the xlat function failed.
*/
-typedef xlat_action_t (*xlat_func_resume_t)(TALLOC_CTX *ctx, fr_cursor_t *out,
+typedef xlat_action_t (*xlat_func_resume_t)(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in, void *rctx);
+ fr_value_box_list_t *in, void *rctx);
/** A callback when the request gets a fr_state_signal_t.
*
int unlang_xlat_event_timeout_add(request_t *request, fr_unlang_xlat_timeout_t callback,
void const *ctx, fr_time_t when);
-int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_t **out,
+int unlang_xlat_push(TALLOC_CTX *ctx, fr_value_box_list_t *out,
request_t *request, xlat_exp_t const *exp, bool top_frame)
CC_HINT(warn_unused_result);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_base64_encode(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
size_t alen;
ssize_t elen;
char *buff;
fr_value_box_t *vb;
+ fr_value_box_t *in_head;
/*
* If there's no input, there's no output
*/
- if (!in) return XLAT_ACTION_DONE;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_DONE;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ in_head = fr_dlist_head(in);
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- alen = FR_BASE64_ENC_LENGTH((*in)->vb_length);
+ alen = FR_BASE64_ENC_LENGTH(in_head->vb_length);
MEM(vb = fr_value_box_alloc_null(ctx));
if (fr_value_box_bstr_alloc(vb, &buff, vb, NULL, alen, false) < 0) {
return XLAT_ACTION_FAIL;
}
- elen = fr_base64_encode(buff, alen + 1, (*in)->vb_octets, (*in)->vb_length);
+ elen = fr_base64_encode(buff, alen + 1, in_head->vb_octets, in_head->vb_length);
if (elen < 0) {
RPEDEBUG("Base64 encoding failed");
talloc_free(buff);
}
fr_assert((size_t)elen <= alen);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_base64_decode(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
size_t alen;
ssize_t declen;
uint8_t *decbuf;
fr_value_box_t *vb;
+ fr_value_box_t *in_head;
/*
* If there's no input, there's no output
*/
- if (!in) return XLAT_ACTION_DONE;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_DONE;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ in_head = fr_dlist_head(in);
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- alen = FR_BASE64_DEC_LENGTH((*in)->vb_length);
+ alen = FR_BASE64_DEC_LENGTH(in_head->vb_length);
MEM(vb = fr_value_box_alloc_null(ctx));
- MEM(fr_value_box_mem_alloc(vb, &decbuf, vb, NULL, alen, (*in)->tainted) == 0);
- declen = fr_base64_decode(decbuf, alen, (*in)->vb_strvalue, (*in)->vb_length);
+ MEM(fr_value_box_mem_alloc(vb, &decbuf, vb, NULL, alen, in_head->tainted) == 0);
+ declen = fr_base64_decode(decbuf, alen, in_head->vb_strvalue, in_head->vb_length);
if (declen < 0) {
talloc_free(vb);
REDEBUG("Base64 string invalid");
return XLAT_ACTION_FAIL;
}
MEM(fr_value_box_mem_realloc(vb, NULL, vb, declen) == 0);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
fr_value_box_t *result;
char *buff = NULL, *p, *end;
/*
* If there's no input, there's no output
*/
- if (!*in) return XLAT_ACTION_DONE;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_DONE;
- buff = fr_value_box_list_aprint(NULL, *in, NULL, NULL);
+ buff = fr_value_box_list_aprint(NULL, in, NULL, NULL);
if (!buff) return XLAT_ACTION_FAIL;
len = talloc_array_length(buff) - 1;
outlen = len / 2;
MEM(result = fr_value_box_alloc_null(ctx));
- MEM(fr_value_box_mem_alloc(result, &bin, result, NULL, outlen, fr_value_box_list_tainted(*in)) == 0);
+ MEM(fr_value_box_mem_alloc(result, &bin, result, NULL, outlen, fr_value_box_list_tainted(in)) == 0);
fr_hex2bin(&err, &FR_DBUFF_TMP(bin, outlen), &FR_SBUFF_IN(p, end - p), true);
if (err) {
REDEBUG2("Invalid hex string");
return XLAT_ACTION_FAIL;
}
- fr_cursor_append(out, result);
+ fr_dcursor_append(out, result);
finish:
talloc_free(buff);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_concat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
fr_value_box_t *result;
fr_value_box_t *separator;
/*
* If there's no input, there's no output
*/
- if (!in) return XLAT_ACTION_DONE;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_DONE;
/*
* Separator is first value box
*/
- separator = *in;
+ separator = fr_dlist_pop_head(in);
if (!separator) {
REDEBUG("Missing separator for concat xlat");
return XLAT_ACTION_FAIL;
}
- buff = fr_value_box_list_aprint(result, (*in)->next, sep, NULL);
+ buff = fr_value_box_list_aprint(result, in, sep, NULL);
if (!buff) goto error;
- fr_value_box_bstrdup_buffer_shallow(NULL, result, NULL, buff, fr_value_box_list_tainted((*in)->next));
+ fr_value_box_bstrdup_buffer_shallow(NULL, result, NULL, buff, fr_value_box_list_tainted(in));
- fr_cursor_append(out, result);
+ /*
+ * Return separator to the start of the vb list
+ */
+ fr_dlist_insert_head(in, separator);
+
+ fr_dcursor_append(out, result);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
char *p;
fr_value_box_t* vb;
+ fr_value_box_t* in_head;
/*
* If there's no input, there's no output
*/
- if (!*in) return XLAT_ACTION_DONE;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_DONE;
+ in_head = fr_dlist_head(in);
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
- vb->vb_length = ((*in)->vb_length * 2);
+ vb->vb_length = (in_head->vb_length * 2);
vb->vb_strvalue = p = talloc_zero_array(vb, char, vb->vb_length + 1);
- if ((*in)->vb_length) {
- fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP((*in)->vb_octets, (*in)->vb_length), SIZE_MAX);
+ if (in_head->vb_length) {
+ fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP(in_head->vb_octets, in_head->vb_length), SIZE_MAX);
}
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
HMAC_SHA1
} hmac_type;
-static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_hmac(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in, uint8_t *digest, int digest_len, hmac_type type)
+ fr_value_box_list_t *in, uint8_t *digest, int digest_len, hmac_type type)
{
uint8_t const *data_p, *key_p;
size_t data_len, key_len;
fr_value_box_t *vb, *vb_data, *vb_sep, *vb_key;
- if (!in) return XLAT_ACTION_FAIL;
+ if (fr_dlist_empty(in)) return XLAT_ACTION_FAIL;
- vb_data = fr_value_box_list_get(*in, 0);
- vb_sep = fr_value_box_list_get(*in, 1);
- vb_key = fr_value_box_list_get(*in, 2);
+ vb_data = fr_dlist_head(in);
+ vb_sep = fr_dlist_next(in, vb_data);
+ vb_key = fr_dlist_next(in, vb_sep);
if (!vb_data || !vb_sep || !vb_key ||
vb_sep->vb_length != 1 ||
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, digest, digest_len, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_hmac_md5(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t digest[MD5_DIGEST_LENGTH];
return xlat_hmac(ctx, out, request, xlat_inst, xlat_thread_inst, in, digest, MD5_DIGEST_LENGTH, HMAC_MD5);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_hmac_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t digest[SHA1_DIGEST_LENGTH];
return xlat_hmac(ctx, out, request, xlat_inst, xlat_thread_inst, in, digest, SHA1_DIGEST_LENGTH, HMAC_SHA1);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_length(TALLOC_CTX *ctx, fr_dcursor_t *out,
UNUSED request_t *request, UNUSED void const *xlat_inst,
- UNUSED void *xlat_thread_inst, fr_value_box_t **in)
+ UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
{
fr_value_box_t *vb;
- fr_cursor_t cursor;
+ fr_dcursor_t cursor;
- for (vb = fr_cursor_talloc_init(&cursor, in, fr_value_box_t);
+ for (vb = fr_dcursor_talloc_init(&cursor, in, fr_value_box_t);
vb;
- vb = fr_cursor_next(&cursor)) {
+ vb = fr_dcursor_next(&cursor)) {
fr_value_box_t *my;
MEM(my = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false));
my->vb_size = fr_value_box_network_length(vb);
- fr_cursor_append(out, my);
+ fr_dcursor_append(out, my);
}
return XLAT_ACTION_DONE;
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_md4(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t digest[MD5_DIGEST_LENGTH];
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Concatenate all input if there is some
*/
- if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- if (*in) {
- fr_md4_calc(digest, (*in)->vb_octets, (*in)->vb_length);
+ if (in_head) {
+ fr_md4_calc(digest, in_head->vb_octets, in_head->vb_length);
} else {
/* Digest of empty string */
fr_md4_calc(digest, NULL, 0);
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t digest[MD5_DIGEST_LENGTH];
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Concatenate all input if there is some
*/
- if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- if (*in) {
- fr_md5_calc(digest, (*in)->vb_octets, (*in)->vb_length);
+ if (in_head) {
+ fr_md5_calc(digest, in_head->vb_octets, in_head->vb_length);
} else {
/* Digest of empty string */
fr_md5_calc(digest, NULL, 0);
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- UNUSED fr_value_box_t **in)
+ UNUSED fr_value_box_list_t *in)
{
fr_value_box_t *vb = NULL;
return XLAT_ACTION_FAIL;
}
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
fr_value_box_t *vb, *in_vb;
- fr_cursor_t cursor;
- if (!*in) {
+ if (fr_dlist_empty(in)) {
REDEBUG("Missing input boxes");
return XLAT_ACTION_FAIL;
}
/*
* Loop over the input boxes, packing them together.
*/
- for (in_vb = fr_cursor_init(&cursor, in);
+ for (in_vb = fr_dlist_head(in);
in_vb;
- in_vb = fr_cursor_next(&cursor)) {
+ in_vb = fr_dlist_next(in, in_vb)) {
fr_value_box_t *cast, box;
if (in_vb->type != FR_TYPE_OCTETS) {
fr_assert(vb->vb_octets != NULL);
}
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
tmpl_t *vpt = NULL;
fr_dcursor_t cursor;
tmpl_cursor_ctx_t cc;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* If there's no input, there's no output
*/
- if (!in) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
fr_pair_t *vp;
- if (tmpl_afrom_attr_str(ctx, NULL, &vpt, (*in)->vb_strvalue,
+ if (tmpl_afrom_attr_str(ctx, NULL, &vpt, in_head->vb_strvalue,
&(tmpl_rules_t){
.dict_def = request->dict,
.prefix = TMPL_ATTR_REF_PREFIX_AUTO
vb->vb_strvalue = buff;
vb->vb_length = talloc_array_length(buff) - 1;
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
}
tmpl_cursor_clear(&cc);
talloc_free(vpt);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_rand(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
int64_t result;
- fr_value_box_t* vb;
+ fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/* Make sure input can be converted to an unsigned 32 bit integer */
- if (fr_value_box_cast_in_place(ctx, (*in), FR_TYPE_UINT32, NULL) < 0) {
+ if (fr_value_box_cast_in_place(ctx, in_head, FR_TYPE_UINT32, NULL) < 0) {
RPEDEBUG("Failed converting input to uint32");
return XLAT_ACTION_FAIL;
}
- result = (*in)->vb_uint32;
+ result = in_head->vb_uint32;
/* Make sure it isn't too big */
if (result > (1 << 30)) result = (1 << 30);
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_UINT64, NULL, false));
vb->vb_uint64 = result;
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
@endverbatim
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_randstr(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
/*
* Lookup tables for randstr char classes
unsigned int reps;
size_t outlen = 0;
fr_value_box_t* vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/** Max repetitions of a single character class
*
/*
* Nothing to do if input is empty
*/
- if (!(*in)) return XLAT_ACTION_DONE;
-
+ if (!in_head) return XLAT_ACTION_DONE;
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- start = p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ start = p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
/*
* Calculate size of output
*buff_p++ = '\0';
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_regex(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Return the complete capture if no other capture is specified
*/
- if (!(*in)) {
+ if (!in_head) {
fr_value_box_t *vb;
char *p;
fr_assert(p);
fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
- switch ((*in)->type) {
+ switch (in_head->type) {
/*
* If the input is an integer value then get an
* arbitrary subcapture index.
fr_value_box_t *vb;
char *p;
- if ((*in)->next) {
+ if (fr_dlist_next(in, in_head)) {
REDEBUG("Only one subcapture argument allowed");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_cast(NULL, &idx, FR_TYPE_UINT32, NULL, *in) < 0) {
+ if (fr_value_box_cast(NULL, &idx, FR_TYPE_UINT32, NULL, in_head) < 0) {
RPEDEBUG("Bad subcapture index");
return XLAT_ACTION_FAIL;
}
}
fr_assert(p);
fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
MEM(vb = fr_value_box_alloc_null(ctx));
- if (regex_request_to_sub_named(vb, &p, request, (*in)->vb_strvalue) < 0) {
+ if (regex_request_to_sub_named(vb, &p, request, in_head->vb_strvalue) < 0) {
REDEBUG2("No previous named regex capture group");
talloc_free(vb);
return XLAT_ACTION_FAIL;
fr_assert(p);
fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, p, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_sha1(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t digest[SHA1_DIGEST_LENGTH];
fr_sha1_ctx sha1_ctx;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Concatenate all input if there is some
*/
- if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
fr_sha1_init(&sha1_ctx);
- if (*in) {
- fr_sha1_update(&sha1_ctx, (*in)->vb_octets, (*in)->vb_length);
+ if (in_head) {
+ fr_sha1_update(&sha1_ctx, in_head->vb_octets, in_head->vb_length);
} else {
/* sha1 of empty string */
fr_sha1_update(&sha1_ctx, NULL, 0);
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
* @ingroup xlat_functions
*/
#ifdef HAVE_OPENSSL_EVP_H
-static xlat_action_t xlat_evp_md(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_evp_md(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in, EVP_MD const *md)
+ fr_value_box_list_t *in, EVP_MD const *md)
{
uint8_t digest[EVP_MAX_MD_SIZE];
unsigned int digestlen;
EVP_MD_CTX *md_ctx;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Concatenate all input if there is some
*/
- if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (in_head && fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
md_ctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(md_ctx, md, NULL);
- if (*in) {
- EVP_DigestUpdate(md_ctx, (*in)->vb_octets, (*in)->vb_length);
+ if (in_head) {
+ EVP_DigestUpdate(md_ctx, in_head->vb_octets, in_head->vb_length);
} else {
EVP_DigestUpdate(md_ctx, NULL, 0);
}
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, digest, digestlen, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
# define EVP_MD_XLAT(_md, _md_func) \
-static xlat_action_t xlat_func_##_md(TALLOC_CTX *ctx, fr_cursor_t *out,\
+static xlat_action_t xlat_func_##_md(TALLOC_CTX *ctx, fr_dcursor_t *out,\
request_t *request, void const *xlat_inst, void *xlat_thread_inst,\
- fr_value_box_t **in)\
+ fr_value_box_list_t *in)\
{\
return xlat_evp_md(ctx, out, request, xlat_inst, xlat_thread_inst, in, EVP_##_md_func());\
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_string(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_string(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
- if (!*in) return XLAT_ACTION_DONE;
+ fr_value_box_t *in_head = fr_dlist_head(in);
+ if (!in_head) return XLAT_ACTION_DONE;
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- fr_cursor_append(out, *in);
- *in = NULL; /* Let the caller know this was consumed */
+ fr_dlist_remove(in, in_head); /* Let the caller know this was consumed */
+ fr_dcursor_append(out, in_head);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_strlen(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst,
- UNUSED void *xlat_thread_inst, fr_value_box_t **in)
+ UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
{
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false));
vb->vb_size = 0;
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_SIZE, NULL, false));
- vb->vb_size = strlen((*in)->vb_strvalue);
- fr_cursor_append(out, vb);
+ vb->vb_size = strlen(in_head->vb_strvalue);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_sub_regex(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
char const *p, *q, *end;
char const *regex, *rep, *subject;
regex_t *pattern;
fr_regex_flags_t flags;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* If there's no input, there's no output
*/
- if (!*in) {
+ if (!in_head) {
REDEBUG("No input arguments");
return XLAT_ACTION_FAIL;
}
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
if (p == end) {
REDEBUG("Regex must not be empty");
talloc_free(pattern);
return XLAT_ACTION_FAIL;
}
- fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, buff, (*in)->tainted);
+ fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, buff, in_head->tainted);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
talloc_free(pattern);
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_sub(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request,
#ifdef HAVE_REGEX_PCRE2
void const *xlat_inst, void *xlat_thread_inst,
#else
UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
#endif
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
char const *p, *q, *end;
char *vb_str;
size_t pattern_len, rep_len;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* If there's no input, there's no output
*/
- if (!*in) {
+ if (!in_head) {
REDEBUG("No input arguments");
return XLAT_ACTION_FAIL;
}
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
if (p == end) {
REDEBUG("Substitution arguments must not be empty");
p = q + pattern_len;
}
- if (fr_value_box_bstrdup_buffer_shallow(vb, vb, NULL, vb_str, (*in)->vb_strvalue) < 0) {
+ if (fr_value_box_bstrdup_buffer_shallow(vb, vb, NULL, vb_str, in_head->vb_strvalue) < 0) {
RPEDEBUG("Failed creating output box");
talloc_free(vb);
return XLAT_ACTION_FAIL;
}
fr_assert(vb && (vb->type != FR_TYPE_INVALID));
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* If upper is true, change to uppercase, otherwise, change to lowercase
*/
-static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_cursor_t *out,
- request_t *request, fr_value_box_t **in, bool upper)
+static xlat_action_t xlat_change_case(TALLOC_CTX *ctx, fr_dcursor_t *out,
+ request_t *request, fr_value_box_list_t *in, bool upper)
{
char *buff_p;
char const *p, *end;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* If there's no input, there's no output
*/
- if (!*in) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
- MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, (*in)->vb_length, (*in)->tainted) == 0);
+ MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, in_head->vb_length, in_head->tainted) == 0);
while (p < end) {
*(buff_p++) = upper ? toupper ((int) *(p++)) : tolower((int) *(p++));
*buff_p = '\0';
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_tolower(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
return xlat_change_case(ctx, out, request, in, false);
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_toupper(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
return xlat_change_case(ctx, out, request, in, true);
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_urlquote(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
char const *p, *end;
char *buff_p;
size_t outlen = 0;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Nothing to do if input is empty
*/
- if (!(*in)) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
/*
* Calculate size of output
MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, outlen, false) == 0);
/* Reset p to start position */
- p = (*in)->vb_strvalue;
+ p = in_head->vb_strvalue;
while (p < end) {
if (isalnum(*p)) {
*buff_p = '\0';
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_urlunquote(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
char const *p, *end;
char *buff_p;
char *c1, *c2;
size_t outlen = 0;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* Nothing to do if input is empty
*/
- if (!*in) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
/*
* Concatenate all input
*/
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
- end = p + (*in)->vb_length;
+ p = in_head->vb_strvalue;
+ end = p + in_head->vb_length;
/*
* Calculate size of output
MEM(fr_value_box_bstr_alloc(vb, &buff_p, vb, NULL, outlen, false) == 0);
/* Reset p to start position */
- p = (*in)->vb_strvalue;
+ p = in_head->vb_strvalue;
while (p < end) {
if (*p != '%') {
/* Don't need \0 check, as it won't be in the hextab */
if (!(c1 = memchr(hextab, tolower(*++p), 16)) ||
!(c2 = memchr(hextab, tolower(*++p), 16))) {
- REMARKER((*in)->vb_strvalue, p - (*in)->vb_strvalue, "Non-hex char in %% sequence");
+ REMARKER(in_head->vb_strvalue, p - in_head->vb_strvalue, "Non-hex char in %% sequence");
talloc_free(vb);
return XLAT_ACTION_FAIL;
}
*buff_p = '\0';
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
* @param[in] node Being processed.
* @param[in] args from previous expansion.
*/
-static inline void xlat_debug_log_expansion(request_t *request, xlat_exp_t const *node, fr_value_box_t const *args)
+static inline void xlat_debug_log_expansion(request_t *request, xlat_exp_t const *node, fr_value_box_list_t const *args)
{
char *str;
talloc_free(str);
}
+/** Output the list result of an expansion
+ *
+ * @param[in] request The current request.
+ * @param[in] result of the expansion.
+ */
+static inline void xlat_debug_log_list_result(request_t *request, fr_value_box_list_t const *result)
+{
+ if (!RDEBUG_ENABLED2) return;
+
+ RDEBUG2(" --> %pM", result);
+}
+
/** Output the result of an expansion
*
* @param[in] request The current request.
{
if (!RDEBUG_ENABLED2) return;
- RDEBUG2(" --> %pM", result);
+ RDEBUG2(" --> %pV", result);
}
/** One letter expansions
* - #XLAT_ACTION_DONE if we're done processing this node.
*
*/
-static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, char letter)
+static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, char letter)
{
char buffer[64];
return XLAT_ACTION_FAIL;
}
- fr_cursor_append(out, value);
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out); /* Advance to our first value */
return XLAT_ACTION_DONE;
}
* - #XLAT_ACTION_FAIL on memory allocation errors.
* - #XLAT_ACTION_DONE if we're done processing this node.
*/
-static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, tmpl_t const *vpt)
+static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt)
{
fr_radius_packet_t *packet = NULL;
fr_value_box_t *value;
}
done:
- fr_cursor_append(out, value);
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out); /* Advance to our first value */
return XLAT_ACTION_DONE;
}
* - #XLAT_ACTION_FAIL we failed getting a value for the attribute.
* - #XLAT_ACTION_DONE we successfully evaluated the xlat.
*/
-static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request, tmpl_t const *vpt)
+static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt)
{
fr_pair_t *vp = NULL;
fr_value_box_t *value;
goto done;
}
value->datum.int32 = 0;
- fr_cursor_append(out, value);
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out); /* Advance to our first value */
} /* Fall through to being done */
goto done;
value = fr_value_box_alloc(ctx, FR_TYPE_UINT32, NULL, false);
value->datum.uint32 = count;
- fr_cursor_append(out, value);
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out); /* Advance to our first value */
break;
}
vp = fr_dcursor_next(&cursor)) {
value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted);
fr_value_box_copy(value, value, &vp->data);
- fr_cursor_append(out, value);
+ fr_dcursor_append(out, value);
}
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_next(out); /* Advance to our first value */
break;
default:
if (!value) goto oom;
fr_value_box_copy(value, value, &vp->data); /* Also dups taint */
- fr_cursor_append(out, value);
- fr_cursor_next(out); /* Advance to our first value */
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out); /* Advance to our first value */
break;
}
* @param[in] rctx Opaque (to us), resume ctx provided by xlat function
* when it yielded.
*/
-xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
+xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
xlat_func_resume_t resume, xlat_exp_t const *exp,
- request_t *request, fr_value_box_t **result, void *rctx)
+ request_t *request, fr_value_box_list_t *result, void *rctx)
{
xlat_thread_inst_t *thread_inst = xlat_thread_instance_find(exp);
xlat_action_t xa;
* to debug problems if they free or change elements
* and don't remove them from the list.
*/
- if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t);
+ if (!fr_dlist_empty(result)) { fr_dlist_verify(result); }
xa = resume(ctx, out, request, exp->call.inst, thread_inst->data, result, rctx);
- if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t);
+ if (!fr_dlist_empty(result)) { fr_dlist_verify(result); }
RDEBUG2("EXPAND %%{%s:...}", exp->call.func->name);
switch (xa) {
break;
case XLAT_ACTION_DONE:
- fr_cursor_next(out); /* Wind to the start of this functions output */
- RDEBUG2(" --> %pM", fr_cursor_current(out));
+ fr_dcursor_next(out); /* Wind to the start of this functions output */
+ RDEBUG2(" --> %pV", fr_dcursor_current(out));
break;
case XLAT_ACTION_FAIL:
* additional #xlat_exp_t.
* @param[in] result of a previous nested evaluation.
*/
-xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out,
+xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
xlat_exp_t const **child, bool *alternate,
request_t *request, xlat_exp_t const **in,
- fr_value_box_t **result)
+ fr_value_box_list_t *result)
{
xlat_exp_t const *node = *in;
- fr_cursor_tail(out); /* Needed for reentrant behaviour and debugging */
+ fr_dcursor_tail(out); /* Needed for reentrant behaviour and debugging */
switch (node->type) {
case XLAT_FUNC:
char *result_str = NULL;
ssize_t slen;
- if (*result) {
- (void) talloc_list_get_type_abort(*result, fr_value_box_t);
- result_str = fr_value_box_list_aprint(NULL, *result, NULL, NULL);
+ if (!fr_dlist_empty(result)) {
+ fr_dlist_verify(result);
+ result_str = fr_value_box_list_aprint(NULL, result, NULL, NULL);
if (!result_str) return XLAT_ACTION_FAIL;
} else {
result_str = talloc_typed_strdup(NULL, "");
slen = node->call.func->func.sync(value, &str, node->call.func->buf_len,
node->call.func->mod_inst, NULL, request, result_str);
- xlat_debug_log_expansion(request, *in, *result);
+ xlat_debug_log_expansion(request, *in, result);
if (slen < 0) {
talloc_free(value);
talloc_free(result_str);
fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
}
- fr_cursor_append(out, value); /* Append the result of the expansion */
+ fr_dcursor_append(out, value); /* Append the result of the expansion */
talloc_free(result_str);
xlat_debug_log_result(request, value);
}
{
xlat_action_t xa;
xlat_thread_inst_t *thread_inst;
- fr_value_box_t *result_copy = NULL;
+ fr_value_box_list_t result_copy;
+ fr_value_box_list_init(&result_copy);
thread_inst = xlat_thread_instance_find(node);
XLAT_DEBUG("** [%i] %s(func-async) - %%{%s:%pM}", unlang_interpret_stack_depth(request), __FUNCTION__,
- node->fmt, *result);
+ node->fmt, result);
/*
* Need to copy the input list in case
* the async function mucks with it.
*/
- if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, *result);
+ if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, result);
- if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t);
+ if (!fr_dlist_empty(result)) { fr_dlist_verify(result); }
xa = node->call.func->func.async(ctx, out, request, node->call.inst->data, thread_inst->data, result);
- if (*result) (void) talloc_list_get_type_abort(*result, fr_value_box_t);
-
+ if (!fr_dlist_empty(result)) { fr_dlist_verify(result); }
if (RDEBUG_ENABLED2) {
- xlat_debug_log_expansion(request, *in, result_copy);
- talloc_list_free(&result_copy);
+ xlat_debug_log_expansion(request, *in, &result_copy);
+ fr_dlist_talloc_free(&result_copy);
}
switch (xa) {
case XLAT_ACTION_FAIL:
return xa;
case XLAT_ACTION_DONE: /* Process the result */
- fr_cursor_next(out);
- xlat_debug_log_result(request, fr_cursor_current(out));
+ fr_dcursor_next(out);
+ xlat_debug_log_result(request, fr_dcursor_current(out));
break;
}
break;
case XLAT_ALTERNATE:
{
- fr_cursor_t from;
+ fr_dcursor_t from;
fr_assert(alternate);
/*
* No result from the first child, try the alternate
*/
- if (!*result) {
+ if (fr_dlist_empty(result)) {
/*
* Already tried the alternate
*/
*alternate = false; /* Reset */
xlat_debug_log_expansion(request, *in, NULL);
- xlat_debug_log_result(request, *result);
+ xlat_debug_log_list_result(request, result);
- (void) talloc_list_get_type_abort(*result, fr_value_box_t);
- fr_cursor_init(&from, result);
- fr_cursor_merge(out, &from);
- fr_assert(!*result);
+ fr_dlist_verify(result);
+ fr_dcursor_init(&from, result);
+ fr_dcursor_merge(out, &from);
+ fr_assert(fr_dlist_empty(result));
}
break;
case XLAT_GROUP:
{
fr_value_box_t *value;
- fr_cursor_t from;
XLAT_DEBUG("** [%i] %s(child) - continuing %%{%s ...}", unlang_interpret_stack_depth(request), __FUNCTION__,
node->fmt);
- fr_assert(*result != NULL);
- (void) talloc_list_get_type_abort(*result, fr_value_box_t);
+ fr_assert(!fr_dlist_empty(result));
+ fr_dlist_verify(result);
/*
* If the input is a series of xlat expansions,
MEM(value = fr_value_box_alloc_null(ctx));
- if (*result) {
- (void) talloc_list_get_type_abort(*result, fr_value_box_t);
- str = fr_value_box_list_aprint(value, *result, NULL, NULL);
+ if (!fr_dlist_empty(result)) {
+ fr_dlist_verify(result);
+ str = fr_value_box_list_aprint(value, result, NULL, NULL);
if (!str) return XLAT_ACTION_FAIL;
} else {
str = talloc_typed_strdup(value, "");
}
- fr_value_box_strdup_shallow(value, NULL, str, fr_value_box_list_tainted(*result));
- talloc_free(*result);
- *result = value;
+ fr_value_box_strdup_shallow(value, NULL, str, fr_value_box_list_tainted(result));
+ fr_dlist_talloc_free(result);
+ fr_dlist_insert_head(result, value);
}
MEM(value = fr_value_box_alloc(ctx, FR_TYPE_GROUP, NULL, false));
- value->vb_group = *result;
- *result = NULL;
+ fr_dlist_move(&value->vb_group, result);
xlat_debug_log_expansion(request, *in, NULL);
xlat_debug_log_result(request, value);
- fr_cursor_init(&from, &value);
- fr_cursor_merge(out, &from);
- fr_assert(!value);
+ fr_dcursor_insert(out, value);
}
break;
* - XLAT_ACTION_DONE we're done, pop the frame.
* - XLAT_ACTION_FAIL an xlat module failed.
*/
-xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t const **child,
+xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child,
request_t *request, xlat_exp_t const **in)
{
xlat_exp_t const *node = *in;
for (node = *in; node; node = (*in)->next) {
*in = node; /* Update node in our caller */
- fr_cursor_tail(out); /* Needed for debugging */
+ fr_dcursor_tail(out); /* Needed for debugging */
switch (node->type) {
case XLAT_LITERAL:
*/
MEM(value = fr_value_box_alloc_null(ctx));
fr_value_box_bstrdup_buffer(value, value, NULL, node->fmt, false);
- fr_cursor_append(out, value);
+ fr_dcursor_append(out, value);
continue;
case XLAT_ONE_LETTER:
xlat_debug_log_expansion(request, node, NULL);
if (xlat_eval_one_letter(ctx, out, request, node->fmt[0]) == XLAT_ACTION_FAIL) {
fail:
- fr_cursor_free_list(out); /* Only frees what we've added during this call */
+ fr_dcursor_free_list(out); /* Only frees what we've added during this call */
xa = XLAT_ACTION_FAIL;
goto finish;
}
- xlat_debug_log_result(request, fr_cursor_current(out));
+ xlat_debug_log_result(request, fr_dcursor_current(out));
continue;
case XLAT_ATTRIBUTE:
xlat_debug_log_expansion(request, node, NULL);
if (xlat_eval_pair_real(ctx, out, request, node->attr) == XLAT_ACTION_FAIL) goto fail;
- xlat_debug_log_result(request, fr_cursor_current(out));
+ xlat_debug_log_result(request, fr_dcursor_current(out));
continue;
case XLAT_VIRTUAL:
if (slen == 0) continue;
fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
- fr_cursor_append(out, value);
- fr_cursor_next(out);
+ fr_dcursor_append(out, value);
+ fr_dcursor_next(out);
- xlat_debug_log_result(request, fr_cursor_current(out));
+ xlat_debug_log_result(request, fr_dcursor_current(out));
}
continue;
case XLAT_FUNC:
{
- fr_value_box_t *result = NULL;
+ fr_value_box_list_t result;
+ fr_value_box_list_init(&result);
XLAT_DEBUG("** [%i] %s(func) - %%{%s:...}", unlang_interpret_stack_depth(request), __FUNCTION__,
node->fmt);
continue;
}
fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
- fr_cursor_append(out, value);
+ fr_dcursor_append(out, value);
}
continue;
#endif
ssize_t slen;
char *str = NULL, *child;
char const *p;
- fr_value_box_t *head = NULL, string, *value;
- fr_cursor_t cursor;
+ fr_value_box_t string, *value;
+ fr_value_box_list_t head;
+ fr_dcursor_t cursor;
- fr_cursor_talloc_init(&cursor, &head, fr_value_box_t);
+ fr_value_box_list_init(&head);
+ fr_dcursor_talloc_init(&cursor, &head, fr_value_box_t);
XLAT_DEBUG("%.*sxlat aprint %d %s", lvl, xlat_spaces, node->type, node->fmt);
* cast to a string until we're actually doing
* the concatenation.
*/
- if (fr_value_box_cast(ctx, &string, FR_TYPE_STRING, NULL, head) < 0) {
+ if (fr_value_box_cast(ctx, &string, FR_TYPE_STRING, NULL, fr_dlist_head(&head)) < 0) {
RPERROR("Casting one letter expansion to string failed");
- fr_cursor_free_list(&cursor);
+ fr_dcursor_free_list(&cursor);
return NULL;
}
memcpy(&str, &string.vb_strvalue, sizeof(str));
- fr_cursor_free_list(&cursor);
+ fr_dcursor_free_list(&cursor);
break;
case XLAT_ATTRIBUTE:
XLAT_DEBUG("xlat_sync_eval ATTR");
if (xlat_eval_pair_real(ctx, &cursor, request, node->attr) == XLAT_ACTION_FAIL) return NULL;
- value = fr_cursor_head(&cursor);
+ value = fr_dcursor_head(&cursor);
if (!value) return NULL;
/*
if (!str) {
attr_error:
RPERROR("Printing box to string failed");
- fr_cursor_free_list(&cursor);
+ fr_dcursor_free_list(&cursor);
return NULL;
}
* temporarily until we do aggregation with
* value boxes.
*/
- while ((value = fr_cursor_next(&cursor))) {
+ while ((value = fr_dcursor_next(&cursor))) {
char *more;
fr_value_box_aprint(ctx, &more, value, &fr_value_escape_double);
str = talloc_strdup_append_buffer(str, more);
talloc_free(more);
}
- fr_cursor_free_list(&cursor);
+ fr_dcursor_free_list(&cursor);
break;
case XLAT_VIRTUAL:
* Will not handle yields.
*/
if (node->call.func->type == XLAT_FUNC_NORMAL) {
- fr_value_box_t *result = NULL;
+ fr_value_box_list_t result;
TALLOC_CTX *pool = talloc_new(NULL);
-
+ fr_value_box_list_init(&result);
/*
* Use the unlang stack to evaluate
* the async xlat up until the point
return NULL;
}
- if (result) {
- str = fr_value_box_list_aprint(ctx, result, NULL, &fr_value_escape_double);
+ if (!fr_dlist_empty(&result)) {
+ str = fr_value_box_list_aprint(ctx, &result, NULL, &fr_value_escape_double);
if (!str) {
RPEDEBUG("Failed concatenating xlat result string");
talloc_free(pool);
void xlat_signal(xlat_func_signal_t signal, xlat_exp_t const *exp,
request_t *request, void *rctx, fr_state_signal_t action);
-xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
+xlat_action_t xlat_frame_eval_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
xlat_func_resume_t resume, xlat_exp_t const *exp,
- request_t *request, fr_value_box_t **result, void *rctx);
+ request_t *request, fr_value_box_list_t *result, void *rctx);
-xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out,
+xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
xlat_exp_t const **child, bool *alternate,
request_t *request, xlat_exp_t const **in,
- fr_value_box_t **result) CC_HINT(nonnull(1,2,3,5,6));
+ fr_value_box_list_t *result) CC_HINT(nonnull(1,2,3,5,6));
-xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t const **child,
+xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child,
request_t *request, xlat_exp_t const **in);
int xlat_eval_walk(xlat_exp_t *exp, xlat_walker_t walker, xlat_type_t type, void *uctx);
#include <freeradius-devel/util/ascend.h>
#include <freeradius-devel/util/base64.h>
#include <freeradius-devel/util/conf.h>
-#include <freeradius-devel/util/cursor.h>
#include <freeradius-devel/util/dcursor.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/dict.h>
case 'M':
{
- fr_value_box_t const *in = va_arg(ap_q, fr_value_box_t const *);
+ fr_value_box_list_t const *in = va_arg(ap_q, fr_value_box_list_t const *);
if (!in) {
subst = talloc_strdup(NULL, "(null)");
#undef _VALUE_PRIVATE
#include <freeradius-devel/util/ascend.h>
-#include <freeradius-devel/util/cursor.h>
+#include <freeradius-devel/util/dcursor.h>
#include <freeradius-devel/util/dbuff.h>
#include <freeradius-devel/util/hash.h>
#include <freeradius-devel/util/hex.h>
dst->enumv = src->enumv;
dst->type = src->type;
dst->tainted = src->tainted;
- dst->next = NULL; /* copy one */
+ fr_dlist_entry_init(&dst->entry);
}
/** Compare two values
case FR_TYPE_GROUP:
{
- fr_cursor_t cursor;
- fr_value_box_t *vb;
+ fr_value_box_t *vb = NULL;
/*
* Initialise an empty buffer we can
*/
if (fr_value_box_bstrndup(ctx, dst, dst_enumv, NULL, 0, src->tainted) < 0) return -1;
- for (vb = fr_cursor_init(&cursor, &src->vb_group);
- vb;
- vb = fr_cursor_next(&cursor)) {
+ while ((vb = fr_dlist_next(&src->vb_group, vb))) {
/*
* Attempt to cast to a string so
* we can append.
case FR_TYPE_GROUP:
{
- fr_cursor_t cursor;
- fr_value_box_t *vb;
+ fr_value_box_t *vb = NULL;
/*
* Initialise an empty buffer we can
*/
if (fr_value_box_memdup(ctx, dst, dst_enumv, NULL, 0, src->tainted) < 0) return -1;
- for (vb = fr_cursor_init(&cursor, &src->vb_group);
- vb;
- vb = fr_cursor_next(&cursor)) {
+ while ((vb = fr_dlist_next(&src->vb_group, vb))) {
/*
* Attempt to cast to octets so
* we can append;
fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
{
fr_value_box_t tmp;
+ /*
+ * Store list poiters to restore later - fr_value_box_cast clears them
+ */
+ fr_dlist_t entry = {
+ .next = vb->entry.next,
+ .prev = vb->entry.prev
+ };
/*
* Simple case, destination type and current
fr_value_box_clear(&tmp); /* Clear out any old buffers */
+ /*
+ * Restore list pointers
+ */
+ vb->entry.next = entry.next;
+ vb->entry.prev = entry.prev;
+
return 0;
}
* This ensures orderly freeing, regardless
* of talloc hierarchy.
*/
- switch (data->datum.children.type) {
- case FR_VALUE_BOX_LIST_SINGLE:
- {
- fr_cursor_t cursor;
- fr_value_box_t *vb;
-
- for (vb = fr_cursor_init(&cursor, &data->datum.children.slist);
- vb;
- vb = fr_cursor_next(&cursor)) {
- fr_value_box_clear_value(vb);
- talloc_free(vb);
- }
- }
- break;
-
- case FR_VALUE_BOX_LIST_DOUBLE:
{
fr_value_box_t *vb = NULL;
- while ((vb = fr_dlist_next(&data->datum.children.dlist, vb))) {
+ while ((vb = fr_dlist_next(&data->datum.children, vb))) {
fr_value_box_clear_value(vb);
talloc_free(vb);
}
- }
- break;
}
return;
* Fixup enumvs
*/
dst->enumv = dst_enumv;
- dst->next = NULL;
+ fr_dlist_entry_init(&dst->entry);
return 0;
}
/*
* Be lazy by just converting it to a string, and then printing the string.
*/
- if (fr_value_box_cast_to_strvalue(NULL, &vb, FR_TYPE_STRING, NULL, data->vb_group) < 0) return 0;
+ if (fr_value_box_cast_to_strvalue(NULL, &vb, FR_TYPE_STRING, NULL, data) < 0) return 0;
slen = fr_value_box_print(&our_out, &vb, e_rules);
fr_value_box_clear(&vb);
* - -1 on failure.
*/
int fr_value_box_list_concat(TALLOC_CTX *ctx,
- fr_value_box_t *out, fr_value_box_t **list, fr_type_t type, bool free_input)
+ fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, bool free_input)
{
TALLOC_CTX *pool;
- fr_cursor_t cursor;
+ fr_dcursor_t cursor;
fr_value_box_t const *vb;
+ fr_value_box_t *head_vb;
- if (!list || !*list) {
+ if (!list || fr_dlist_empty(list)) {
fr_strerror_const("Invalid arguments. List was NULL");
return -1;
}
return -1;
}
- fr_cursor_init(&cursor, list);
+ head_vb = fr_dlist_head(list);
+ fr_dcursor_init(&cursor, list);
/*
* Allow concatenating in place
*/
- if (out == *list) {
- if ((*list)->type != type) {
+ if (out == head_vb) {
+ if (head_vb->type != type) {
fr_value_box_t from_cast;
- fr_value_box_t *next = out->next;
+ fr_dlist_t entry = {
+ .next = out->entry.next,
+ .prev = out->entry.prev
+ };
/*
* Two phase, as the casting code doesn't
*/
if (fr_value_box_cast(ctx, &from_cast, type, NULL, out) < 0) return -1;
if (fr_value_box_copy(ctx, out, &from_cast) < 0) return -1;
- out->next = next; /* Restore the next pointer */
+
+ out->entry.next = entry.next; /* Restore the list pointers */
+ out->entry.prev = entry.prev;
+
}
- fr_cursor_next(&cursor);
+ fr_dcursor_next(&cursor);
} else {
- if (fr_value_box_cast(ctx, out, type, NULL, *list) < 0) return -1; /* Decomposes to copy */
+ if (fr_value_box_cast(ctx, out, type, NULL, head_vb) < 0) return -1; /* Decomposes to copy */
if (free_input) {
- fr_cursor_free_item(&cursor); /* Advances cursor */
+ fr_dcursor_free_item(&cursor); /* Advances cursor */
} else {
- fr_cursor_next(&cursor);
+ fr_dcursor_next(&cursor);
}
}
/*
* Imploding a one element list.
*/
- if (!fr_cursor_current(&cursor)) return 0;
+ if (!fr_dcursor_current(&cursor)) return 0;
pool = talloc_pool(NULL, 255); /* To absorb the temporary strings */
/*
* Join the remaining values
*/
- while ((vb = fr_cursor_current(&cursor))) {
+ while ((vb = fr_dcursor_current(&cursor))) {
fr_value_box_t from_cast;
fr_value_box_t const *n;
}
if (free_input) {
- fr_cursor_free_item(&cursor); /* Advances cursor */
+ fr_dcursor_free_item(&cursor); /* Advances cursor */
} else {
- fr_cursor_next(&cursor);
+ fr_dcursor_next(&cursor);
}
}
/** Concatenate the string representations of a list of value boxes together
*
* @param[in] ctx to allocate the buffer in.
- * @param[in] head of the list of value boxes.
+ * @param[in] list of value boxes.
* @param[in] delim to insert between value box values.
* @param[in] e_rules to control escaping of the concatenated elements.
* @return
* - NULL on error.
* - The concatenation of the string values of the value box list on success.
*/
-char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_t const *head, char const *delim,
+char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim,
fr_sbuff_escape_rules_t const *e_rules)
{
- fr_value_box_t const *vb = head;
+ fr_value_box_t const *vb = fr_dlist_head(list);
char *aggr, *td = NULL;
TALLOC_CTX *pool = NULL;
- if (!head) return NULL;
+ if (!vb) return NULL;
fr_value_box_aprint(ctx, &aggr, vb, e_rules);
if (!aggr) return NULL;
- if (!vb->next) return aggr;
+ if (!fr_dlist_next(list, vb)) return aggr;
/*
* If we're aggregating more values,
pool = talloc_pool(NULL, 255);
if (delim) td = talloc_typed_strdup(pool, delim);
- while ((vb = vb->next)) {
+ while ((vb = fr_dlist_next(list, vb))) {
char *str, *new_aggr;
fr_value_box_aprint(pool, &str, vb, e_rules);
* - >= 0 number of array elements in argv
* - <0 on error
*/
-int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_t const *in)
+int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in)
{
int i, argc;
char **argv;
+ fr_value_box_t *head = fr_dlist_head(in);
- if (in->type != FR_TYPE_GROUP) {
+ if (head->type != FR_TYPE_GROUP) {
argc = 1;
} else {
argv = talloc_zero_array(ctx, char *, argc + 1);
if (!argv) return -1;
- if (in->type != FR_TYPE_GROUP) {
- fr_value_box_aprint(argv, &argv[0], in, NULL);
+ if (head->type != FR_TYPE_GROUP) {
+ fr_value_box_aprint(argv, &argv[0], head, NULL);
} else {
fr_value_box_t const *in_p;
/*
* Print the children of each group into the argv array.
*/
- for (in_p = in, i = 0;
+ for (in_p = head, i = 0;
in_p;
- in_p = in_p->next) {
- if (!in_p->vb_group) {
+ in_p = fr_dlist_next(in, in_p)) {
+ if (fr_dlist_empty(&in_p->vb_group)) {
argv[i] = talloc_typed_strdup(argv, "");
} else {
- fr_value_box_aprint(argv, &argv[i], in_p->vb_group, NULL);
+ fr_value_box_aprint(argv, &argv[i], in_p, NULL);
}
if (!argv[i]) {
talloc_free(argv);
* - A duplicate list of value boxes, allocated in the context of 'ctx'
* - NULL on error, or empty input list.
*/
-int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_t **out, fr_value_box_t const *in)
+int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_value_box_list_t const *in)
{
- fr_value_box_t const *in_p;
- fr_cursor_t cursor;
-
- *out = NULL;
-
- fr_cursor_init(&cursor, out);
+ fr_value_box_t const *in_p = NULL;
- for (in_p = in;
- in_p;
- in_p = in_p->next) {
+ while ((in_p = fr_dlist_next(in, in_p))) {
fr_value_box_t *n = NULL;
n = fr_value_box_alloc_null(ctx);
if (!n) {
error:
- fr_cursor_head(&cursor);
- fr_cursor_free_list(&cursor);
+ fr_dlist_talloc_free(out);
return -1;
}
if (fr_value_box_copy(n, n, in_p) < 0) goto error;
- fr_cursor_append(&cursor, n);
+ fr_dlist_insert_tail(out, n);
}
return 0;
* - true if a list member is tainted.
* - false if no list members are tainted.
*/
-bool fr_value_box_list_tainted(fr_value_box_t const *head)
+bool fr_value_box_list_tainted(fr_value_box_list_t const *head)
{
- if (!head) return false;
-
- do {
- if (head->tainted) return true;
- } while ((head = head->next));
-
- return false;
-}
+ fr_value_box_t *vb = NULL;
-/** Get list member at a given index
- *
- * @param[in] head of list.
- * @param[in] index of member to return.
- * @return
- * - NULL if there is no member at given index
- * - member if it exists
- */
-fr_value_box_t *fr_value_box_list_get(fr_value_box_t *head, int index)
-{
- int i = 0;
+ if (fr_dlist_empty(head)) return false;
- while (i < index && head) {
- head = head->next;
- i++;
+ while ((vb = fr_dlist_next(head, vb))) {
+ if (vb->tainted) return true;
}
- return head;
+ return false;
}
extern fr_sbuff_escape_rules_t fr_value_escape_backtick;
extern fr_sbuff_escape_rules_t *fr_value_escape_by_quote[T_TOKEN_LAST];
-typedef enum {
- FR_VALUE_BOX_LIST_SINGLE = 0, //!< Singly linked list.
- FR_VALUE_BOX_LIST_DOUBLE, //!< Doubly linked list.
-} fr_value_box_list_type_t;
-
-/** Placeholder structure to represent lists of value boxes
+/** Lists of value boxes
*
- * Should have additional fields added later.
+ * Specifically define a type for lists of value_box_t to aid type checking
*/
-typedef struct {
- union {
- fr_value_box_t *slist; //!< The head of the list.
- fr_dlist_head_t dlist; //!< Doubly linked list head.
- };
- fr_value_box_list_type_t type; //!< What type of list this is.
-} fr_value_box_list_t;
+typedef fr_dlist_head_t fr_value_box_list_t;
/** Union containing all data types supported by the server
*
fr_dict_attr_t const *enumv; //!< Enumeration values.
- fr_value_box_t *next; //!< Next in a series of value_box.
+ fr_dlist_t entry; //!< Doubly linked list entry.
};
/** @name Field accessors for #fr_value_box_t
*/
#define vb_strvalue datum.strvalue
#define vb_octets datum.octets
-#define vb_group datum.children.slist
+#define vb_group datum.children
#define vb_ip datum.ip
/** Returns the number of boxes in a list of value boxes
*
- * @param[in] head of the value box list.
+ * @param[in] list of value boxes.
* @return Number of boxes in the list.
*/
-static inline size_t fr_value_box_list_len(fr_value_box_t const *head)
+static inline size_t fr_value_box_list_len(fr_value_box_list_t const *list)
{
- size_t i;
-
- for (i = 0; head; head = head->next, i++);
-
- return i;
+ return fr_dlist_num_elements(list);
}
/** Determines whether a list contains the number of boxes required
*
- * @note More efficient than fr_value_box_list_len for argument validation as it
- * doesn't walk the entire list.
- *
- * @param[in] head of the list of value boxes.
+ * @param[in] list of value boxes.
* @param[in] min The number of boxes required to return true.
* @return
* - true if the list has at least min boxes.
* - false if the list has fewer than min boxes.
*/
-static inline bool fr_value_box_list_len_min(fr_value_box_t const *head, size_t min)
+static inline bool fr_value_box_list_len_min(fr_value_box_list_t const *list, size_t min)
{
- size_t i;
+ size_t i = fr_dlist_num_elements(list);
- for (i = 0; head && i < min; head = head->next, i++);
+ return (i >= min);
+}
- return (i == min);
+/** Initialise a list of fr_value_box_t
+ *
+ * @param[in,out] list to initialise
+ */
+static inline void fr_value_box_list_init(fr_value_box_list_t *list)
+{
+ fr_dlist_talloc_init(list, fr_value_box_t, entry);
}
/** @} */
.enumv = enumv,
.tainted = tainted
}, sizeof(*vb));
+ fr_dlist_entry_init(&vb->entry);
+ if (type == FR_TYPE_GROUP) fr_value_box_list_init(&vb->vb_group);
}
/** Initialise an empty/null box that will be filled later
* @{
*/
int fr_value_box_list_concat(TALLOC_CTX *ctx,
- fr_value_box_t *out, fr_value_box_t **list,
+ fr_value_box_t *out, fr_value_box_list_t *list,
fr_type_t type, bool free_input);
-char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_t const *head, char const *delim,
+char *fr_value_box_list_aprint(TALLOC_CTX *ctx, fr_value_box_list_t const *list, char const *delim,
fr_sbuff_escape_rules_t const *e_rules);
-int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_t **out, fr_value_box_t const *in);
-
-bool fr_value_box_list_tainted(fr_value_box_t const *head);
+int fr_value_box_list_acopy(TALLOC_CTX *ctx, fr_value_box_list_t *out, fr_value_box_list_t const *in);
-fr_value_box_t* fr_value_box_list_get(fr_value_box_t *head, int index);
+bool fr_value_box_list_tainted(fr_value_box_list_t const *head);
-int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_t const *in);
+int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in);
/** @} */
/*
*
* Example: "%{db_status:fail}"
*/
-static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t always_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_always_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),rlm_always_t);
module_instance_t *mi;
char const *status;
char const *p;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
mi = module_by_name(NULL, inst->xlat_name);
if (!mi) {
p = fr_table_str_by_value(rcode_table, mi->code, "<invalid>");
}
- if (!(*in) || (*in)->vb_length == 0) goto done;
- status = (*in)->vb_strvalue;
+ if (!in_head || in_head->vb_length == 0) goto done;
+ status = in_head->vb_strvalue;
/*
* Set the module status
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_strdup(vb, vb, NULL, p, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
uint8_t chap_password[1 + RADIUS_CHAP_CHALLENGE_LENGTH];
fr_value_box_t *vb;
fr_pair_t *challenge;
uint8_t const *vector;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/*
* If there's no input, there's no output
*/
- if (!*in) {
+ if (!in_head) {
REDEBUG("chap requires a password as input");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
vector = request->packet->vector;
}
fr_radius_encode_chap_password(chap_password, (uint8_t)(fr_rand() & 0xff), vector,
- (*in)->vb_strvalue, (*in)->vb_length);
+ in_head->vb_strvalue, in_head->vb_length);
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(vb, vb, NULL, chap_password, sizeof(chap_password), false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_cipher_rsa_thread_inst_t *xt = talloc_get_type_abort(*((void **)xlat_thread_inst),
rlm_cipher_rsa_thread_inst_t);
size_t ciphertext_len;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
REDEBUG("encrypt requires one or arguments (<plaintext>...)");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
fr_tls_log_error(request, "Failed concatenating arguments to form plaintext");
return XLAT_ACTION_FAIL;
}
- plaintext = (*in)->vb_strvalue;
- plaintext_len = (*in)->vb_length;
+ plaintext = in_head->vb_strvalue;
+ plaintext_len = in_head->vb_length;
/*
* Figure out the buffer we need
}
RHEXDUMP3(ciphertext, ciphertext_len, "Ciphertext (%zu bytes)", ciphertext_len);
MEM(fr_value_box_mem_realloc(vb, NULL, vb, ciphertext_len) == 0);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_cipher_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),
rlm_cipher_t);
unsigned int digest_len = 0;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
REDEBUG("sign requires one or arguments (<plaintext>...)");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating arguments to form plaintext");
return XLAT_ACTION_FAIL;
}
- msg = (*in)->vb_strvalue;
- msg_len = (*in)->vb_length;
+ msg = in_head->vb_strvalue;
+ msg_len = in_head->vb_length;
/*
* First produce a digest of the message
return XLAT_ACTION_FAIL;
}
MEM(fr_value_box_mem_realloc(vb, NULL, vb, sig_len) == 0);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_cipher_rsa_thread_inst_t *xt = talloc_get_type_abort(*((void **)xlat_thread_inst),
rlm_cipher_rsa_thread_inst_t);
size_t plaintext_len;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
REDEBUG("decrypt requires one or more arguments (<ciphertext>...)");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_OCTETS, true) < 0) {
REDEBUG("Failed concatenating arguments to form plaintext");
return XLAT_ACTION_FAIL;
}
- ciphertext = (*in)->vb_octets;
- ciphertext_len = (*in)->vb_length;
+ ciphertext = in_head->vb_octets;
+ ciphertext_len = in_head->vb_length;
/*
* Decrypt the ciphertext
}
RHEXDUMP3((uint8_t const *)plaintext, plaintext_len, "Plaintext (%zu bytes)", plaintext_len);
MEM(fr_value_box_bstr_realloc(vb, NULL, vb, plaintext_len) == 0);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_cipher_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),
rlm_cipher_t);
unsigned int digest_len = 0;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_pop_head(in);
+ fr_value_box_t *args;
- if (!*in) {
+ if (!in_head) {
REDEBUG("verification requires two or more arguments (<signature>, <message>...)");
return XLAT_ACTION_FAIL;
}
/*
* Check we have at least two boxed values
*/
- if (!(*in)->next) {
+ if (fr_dlist_empty(in)) {
REDEBUG("Missing message data arg or message data was (null)");
return XLAT_ACTION_FAIL;
}
* isn't already in that form.
* It could be hexits or base64 or some other encoding.
*/
- if ((*in)->type != FR_TYPE_OCTETS) {
+ if (in_head->type != FR_TYPE_OCTETS) {
REDEBUG("Signature argument wrong type, expected %s, got %s. "
"Use %%{base64_decode:<text>} or %%{hex_decode:<text>} if signature is armoured",
fr_table_str_by_value(fr_value_box_type_table, FR_TYPE_OCTETS, "?Unknown?"),
- fr_table_str_by_value(fr_value_box_type_table, (*in)->type, "?Unknown?"));
+ fr_table_str_by_value(fr_value_box_type_table, in_head->type, "?Unknown?"));
return XLAT_ACTION_FAIL;
}
- sig = (*in)->vb_octets;
- sig_len = (*in)->vb_length;
+ sig = in_head->vb_octets;
+ sig_len = in_head->vb_length;
/*
* Concat (...) args to get message data
*/
- if (fr_value_box_list_concat(ctx, (*in)->next, &((*in)->next), FR_TYPE_STRING, true) < 0) {
+ args = fr_dlist_head(in);
+ if (fr_value_box_list_concat(ctx, args, in, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating arguments to form plaintext");
return XLAT_ACTION_FAIL;
}
- msg = (*in)->next->vb_strvalue;
- msg_len = (*in)->next->vb_length;
+ msg = args->vb_strvalue;
+ msg_len = args->vb_length;
+
+ /*
+ * Return the first entry to the "in" vb list
+ */
+ fr_dlist_insert_head(in, in_head);
/*
* The argument separator also gets rolled into
case 1: /* success (signature valid) */
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, false));
vb->vb_bool = true;
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
break;
case 0: /* failure (signature not valid) */
MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL, false));
vb->vb_bool = false;
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
break;
default:
* - #RLM_MODULE_FAIL if an error occurred.
*/
static rlm_rcode_t map_proc_client(UNUSED void *mod_inst, UNUSED void *proc_inst, request_t *request,
- fr_value_box_t **client_override, fr_map_list_t const *maps)
+ fr_value_box_list_t *client_override, fr_map_list_t const *maps)
{
rlm_rcode_t rcode = RLM_MODULE_OK;
map_t const *map = NULL;
RADCLIENT *client;
client_get_vp_ctx_t uctx;
- if (*client_override) {
+ if (!fr_dlist_empty(client_override)) {
fr_ipaddr_t ip;
char const *client_str;
+ fr_value_box_t *client_override_head = fr_dlist_head(client_override);
/*
* Concat don't asprint, as this becomes a noop
* in the vast majority of cases.
*/
- if (fr_value_box_list_concat(request, *client_override, client_override, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(request, client_override_head, client_override, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating input data");
return RLM_MODULE_FAIL;
}
- client_str = (*client_override)->vb_strvalue;
+ client_str = client_override_head->vb_strvalue;
if (fr_inet_pton(&ip, client_str, -1, AF_UNSPEC, false, true) < 0) {
REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", client_str);
#include <freeradius-devel/server/map_proc.h>
static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request,
- fr_value_box_t **key, fr_map_list_t const *maps);
+ fr_value_box_list_t *key, fr_map_list_t const *maps);
/*
* Define a structure for our module configuration.
* - #RLM_MODULE_FAIL if an error occurred.
*/
static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request,
- fr_value_box_t **key, fr_map_list_t const *maps)
+ fr_value_box_list_t *key, fr_map_list_t const *maps)
{
rlm_csv_t *inst = talloc_get_type_abort(mod_inst, rlm_csv_t);
+ fr_value_box_t *key_head = fr_dlist_head(key);
- if (!*key) {
+ if (!key_head) {
REDEBUG("CSV key cannot be (null)");
return RLM_MODULE_FAIL;
}
if ((inst->key_data_type == FR_TYPE_OCTETS) || (inst->key_data_type == FR_TYPE_STRING)) {
- if (fr_value_box_list_concat(request, *key, key, inst->key_data_type, true) < 0) {
+ if (fr_value_box_list_concat(request, key_head, key, inst->key_data_type, true) < 0) {
REDEBUG("Failed parsing key");
return RLM_MODULE_FAIL;
}
}
- return mod_map_apply(inst, request, *key, maps);
+ return mod_map_apply(inst, request, key_head, maps);
}
return unlang_module_yield(request, mod_delay_return, mod_delay_cancel, yielded_at);
}
-static xlat_action_t xlat_delay_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_delay_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request,
UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- UNUSED fr_value_box_t **in, void *rctx)
+ UNUSED fr_value_box_list_t *in, void *rctx)
{
fr_time_t *yielded_at = talloc_get_type_abort(rctx, fr_time_t);
fr_time_t delayed;
RDEBUG3("Request delayed by %pVs", vb);
- fr_cursor_insert(out, vb);
+ fr_dcursor_insert(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out,
+static xlat_action_t xlat_delay(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out,
request_t *request, void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_delay_t const *inst;
void *instance;
fr_time_delta_t delay;
fr_time_t resume_at, *yielded_at;
+ fr_value_box_t *in_head = fr_dlist_head(in);
memcpy(&instance, xlat_inst, sizeof(instance)); /* Stupid const issues */
* immediately re-enqueue the request.
* This is very useful for testing.
*/
- if (!*in) {
+ if (!in_head) {
if (!fr_cond_assert(delay_add(request, &resume_at, *yielded_at, 0, true, true) == 0)) {
return XLAT_ACTION_FAIL;
}
goto yield;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
talloc_free(yielded_at);
return XLAT_ACTION_FAIL;
}
- if (fr_time_delta_from_str(&delay, (*in)->vb_strvalue, FR_TIME_RES_SEC) < 0) {
+ if (fr_time_delta_from_str(&delay, in_head->vb_strvalue, FR_TIME_RES_SEC) < 0) {
RPEDEBUG("Failed parsing delay time");
talloc_free(yielded_at);
return XLAT_ACTION_FAIL;
*
* @ingroup xlat_functions
*/
-static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t dhcpv4_decode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
- fr_cursor_t in_cursor;
+ fr_dcursor_t in_cursor;
fr_value_box_t *vb, *vb_decoded;
fr_pair_t *vp;
fr_pair_list_t head;
fr_pair_list_init(&head);
- for (vb = fr_cursor_talloc_init(&in_cursor, in, fr_value_box_t);
+ for (vb = fr_dcursor_talloc_init(&in_cursor, in, fr_value_box_t);
vb;
- vb = fr_cursor_next(&in_cursor)) {
+ vb = fr_dcursor_next(&in_cursor)) {
uint8_t const *p, *end;
ssize_t len;
fr_pair_list_t vps;
/* create a value box to hold the decoded count */
MEM(vb_decoded = fr_value_box_alloc(ctx, FR_TYPE_UINT16, NULL, false));
vb_decoded->vb_uint16 = decoded;
- fr_cursor_append(out, vb_decoded);
+ fr_dcursor_append(out, vb_decoded);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t dhcpv4_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
fr_dcursor_t *cursor;
bool tainted = false;
uint8_t binbuf[2048];
uint8_t *p = binbuf, *end = p + sizeof(binbuf);
ssize_t len = 0;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input string for attribute reference");
return XLAT_ACTION_FAIL;
}
- if (xlat_fmt_to_cursor(NULL, &cursor, &tainted, request, (*in)->vb_strvalue) < 0) return XLAT_ACTION_FAIL;
+ if (xlat_fmt_to_cursor(NULL, &cursor, &tainted, request, in_head->vb_strvalue) < 0) return XLAT_ACTION_FAIL;
if (!fr_dcursor_head(cursor)) return XLAT_ACTION_DONE; /* Nothing to encode */
*/
MEM(encoded = fr_value_box_alloc_null(ctx));
fr_value_box_memdup(encoded, encoded, NULL, binbuf, (size_t)len, tainted);
- fr_cursor_append(out, encoded);
+ fr_dcursor_append(out, encoded);
return XLAT_ACTION_DONE;
}
request_t *request, void *rctx)
{
rlm_exec_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_exec_t);
- fr_value_box_t *box = talloc_get_type_abort(rctx, fr_value_box_t);
+ fr_value_box_list_t *box = talloc_get_type_abort(rctx, fr_value_box_list_t);
fr_pair_list_t env_pairs;
fr_pair_list_init(&env_pairs);
}
typedef struct {
- fr_value_box_t *box;
- int status;
+ fr_value_box_list_t box;
+ int status;
} rlm_exec_ctx_t;
static const rlm_rcode_t status2rcode[] = {
rlm_exec_ctx_t *m = talloc_get_type_abort(rctx, rlm_exec_ctx_t);
rlm_exec_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_exec_t);
- if (inst->output && m->box) {
+ if (inst->output && !fr_dlist_empty(&m->box)) {
TALLOC_CTX *ctx;
fr_pair_list_t vps, *output_pairs;
+ fr_value_box_t *box = fr_dlist_head(&m->box);
- RDEBUG("EXEC GOT -- %pV", m->box);
+ RDEBUG("EXEC GOT -- %pV", box);
fr_pair_list_init(&vps);
output_pairs = tmpl_list_head(request, inst->output_list);
ctx = tmpl_list_ctx(request, inst->output_list);
- fr_pair_list_afrom_box(ctx, &vps, request->dict, m->box);
+ fr_pair_list_afrom_box(ctx, &vps, request->dict, box);
if (!fr_pair_list_empty(&vps)) fr_pair_list_move(output_pairs, &vps);
- m->box = NULL; /* has been consumed */
+ fr_dlist_talloc_free(&m->box); /* has been consumed */
}
status = m->status;
* The status rcodes aren't quite the same as the rcode
* enumeration.
*/
- RETURN_MODULE_RCODE(rlm_exec_status2rcode(request, m->box, status));
+ RETURN_MODULE_RCODE(rlm_exec_status2rcode(request, fr_dlist_head(&m->box), status));
}
/*
* Do the asynchronous xlat expansion.
*/
if (!inst->wait) {
- fr_value_box_t *box;
+ fr_value_box_list_t *box = talloc_zero(ctx, fr_value_box_list_t);
- MEM(box = talloc_zero(ctx, fr_value_box_t));
+ fr_value_box_list_init(box);
- return unlang_module_yield_to_xlat(request, &box, request, tmpl_xlat(inst->tmpl), mod_exec_nowait_resume, NULL, box);
+ return unlang_module_yield_to_xlat(request, box, request, tmpl_xlat(inst->tmpl), mod_exec_nowait_resume, NULL, &box);
}
/*
}
m = talloc_zero(ctx, rlm_exec_ctx_t);
+ fr_value_box_list_init(&m->box);
return unlang_module_yield_to_tmpl(m, &m->box, &m->status, request, inst->tmpl, &env_pairs, mod_exec_wait_resume, NULL, m);
}
CONF_PARSER_TERMINATOR
};
-static xlat_action_t xlat_icmp_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t xlat_icmp_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
UNUSED request_t *request,
UNUSED void const *xlat_inst, void *xlat_thread_inst,
- UNUSED fr_value_box_t **in, void *rctx)
+ UNUSED fr_value_box_list_t *in, void *rctx)
{
rlm_icmp_echo_t *echo = talloc_get_type_abort(rctx, rlm_icmp_echo_t);
xlat_icmp_thread_inst_t *thread = talloc_get_type_abort(xlat_thread_inst, xlat_icmp_thread_inst_t);
(void) rbtree_deletebydata(thread->t->tree, echo);
talloc_free(echo);
- fr_cursor_insert(out, vb);
+ fr_dcursor_insert(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out,
+static xlat_action_t xlat_icmp(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out,
request_t *request, void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
void *instance;
rlm_icmp_t const *inst;
ssize_t rcode;
socklen_t salen;
struct sockaddr_storage dst;
+ fr_value_box_t *in_head = fr_dlist_head(in);
memcpy(&instance, xlat_inst, sizeof(instance)); /* Stupid const issues */
/*
* If there's no input, do we can't ping anything.
*/
- if (!*in) return XLAT_ACTION_FAIL;
+ if (!in_head) return XLAT_ACTION_FAIL;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_cast_in_place(ctx, *in, thread->t->ipaddr_type, NULL) < 0) {
+ if (fr_value_box_cast_in_place(ctx, in_head, thread->t->ipaddr_type, NULL) < 0) {
RPEDEBUG("Failed casting result to IP address");
return XLAT_ACTION_FAIL;
}
MEM(echo = talloc_zero(ctx, rlm_icmp_echo_t));
- echo->ip = *in;
+ echo->ip = in_head;
echo->request = request;
echo->counter = thread->t->counter++;
* @param in list of value boxes as input
* @return XLAT_ACTION_DONE or XLAT_ACTION_FAIL
*/
-static xlat_action_t json_quote_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request,
+static xlat_action_t json_quote_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
char *tmp;
- if (!*in) return XLAT_ACTION_DONE;
+ if (!in_head) return XLAT_ACTION_DONE;
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
MEM(vb = fr_value_box_alloc_null(ctx));
- if (!(tmp = fr_json_from_string(vb, (*in)->vb_strvalue, false))) {
+ if (!(tmp = fr_json_from_string(vb, in_head->vb_strvalue, false))) {
REDEBUG("Unable to JSON-quote string");
talloc_free(vb);
return XLAT_ACTION_FAIL;
}
fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, tmp, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
* @param in list of value boxes as input
* @return XLAT_ACTION_DONE or XLAT_ACTION_FAIL
*/
-static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request_t *request,
+static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
void const *xlat_inst, UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_json_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),
rlm_json_t);
char *json_str = NULL;
fr_value_box_t *vb;
fr_sbuff_t sbuff;
+ fr_value_box_t *in_head = fr_dlist_head(in);
fr_pair_list_init(&json_vps);
fr_pair_list_init(&vps);
- if (!*in) {
+ if (!in_head) {
REDEBUG("Missing attribute(s)");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- sbuff = FR_SBUFF_IN((*in)->vb_strvalue, (*in)->vb_length);
+ sbuff = FR_SBUFF_IN(in_head->vb_strvalue, in_head->vb_length);
fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL);
/*
}
fr_value_box_bstrdup_buffer_shallow(NULL, vb, NULL, json_str, false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
fr_pair_list_free(&json_vps);
return XLAT_ACTION_DONE;
{
fr_pair_t *vp;
rlm_json_jpath_to_eval_t *to_eval = uctx;
- fr_value_box_t *head, *value;
+ fr_value_box_t *value;
+ fr_value_box_list_t head;
int ret;
fr_pair_list_free(out);
+ fr_value_box_list_init(&head);
ret = fr_jpath_evaluate_leaf(request, &head, tmpl_da(map->lhs)->type, tmpl_da(map->lhs),
to_eval->root, to_eval->jpath);
return -1;
}
if (ret == 0) return 0;
- fr_assert(head);
+ fr_assert(!fr_dlist_empty(&head));
- for (value = head;
+ for (value = fr_dlist_head(&head);
value;
- fr_pair_add(out, vp), value = value->next) {
+ fr_pair_add(out, vp), value = fr_dlist_next(&head, value)) {
MEM(vp = fr_pair_afrom_da(ctx, tmpl_da(map->lhs)));
vp->op = map->op;
* - #RLM_MODULE_FAIL if a fault occurred.
*/
static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, void *proc_inst, request_t *request,
- fr_value_box_t **json, fr_map_list_t const *maps)
+ fr_value_box_list_t *json, fr_map_list_t const *maps)
{
rlm_rcode_t rcode = RLM_MODULE_UPDATED;
struct json_tokener *tok;
rlm_json_jpath_to_eval_t to_eval;
char const *json_str = NULL;
+ fr_value_box_t *json_head = fr_dlist_head(json);
- if (!*json) {
+ if (!json_head) {
REDEBUG("JSON map input cannot be (null)");
return RLM_MODULE_FAIL;
}
- if (fr_value_box_list_concat(request, *json, json, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(request, json_head, json, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating input");
return RLM_MODULE_FAIL;
}
- json_str = (*json)->vb_strvalue;
+ json_str = json_head->vb_strvalue;
if ((talloc_array_length(json_str) - 1) == 0) {
REDEBUG("JSON map input length must be > 0");
* - #RLM_MODULE_FAIL if an error occurred.
*/
static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request,
- fr_value_box_t **url, fr_map_list_t const *maps)
+ fr_value_box_list_t *url, fr_map_list_t const *maps)
{
rlm_rcode_t rcode = RLM_MODULE_UPDATED;
rlm_ldap_t *inst = talloc_get_type_abort(mod_inst, rlm_ldap_t);
LDAPControl *server_ctrls[] = { NULL, NULL };
fr_ldap_map_exp_t expanded; /* faster than allocing every time */
+ fr_value_box_t *url_head = fr_dlist_head(url);
/*
* FIXME - Maybe it can be NULL?
*/
- if (!*url) {
+ if (!url_head) {
REDEBUG("LDAP URL cannot be (null)");
return RLM_MODULE_FAIL;
}
- if (fr_value_box_list_concat(request, *url, url, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(request, url_head, url, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating input");
return RLM_MODULE_FAIL;
}
- url_str = (*url)->vb_strvalue;
+ url_str = url_head->vb_strvalue;
if (!ldap_is_ldap_url(url_str)) {
REDEBUG("Map query string does not look like a valid LDAP URI");
*
* @ingroup xlat_functions
*/
-static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_redis_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),
rlm_redis_t);
fr_redis_conn_t *conn;
fr_redis_cluster_rcode_t rcode;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
REDEBUG("Missing key");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- if (fr_inet_pton_port(&node_addr.inet.dst_ipaddr, &node_addr.inet.dst_port, (*in)->vb_strvalue, (*in)->vb_length,
+ if (fr_inet_pton_port(&node_addr.inet.dst_ipaddr, &node_addr.inet.dst_port, in_head->vb_strvalue, in_head->vb_length,
AF_UNSPEC, true, true) < 0) {
RPEDEBUG("Failed parsing node address");
return XLAT_ACTION_FAIL;
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_strdup(vb, vb, NULL, fr_table_str_by_value(fr_redis_cluster_rcodes_table, rcode, "<INVALID>"), false);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
*
* @ingroup xlat_functions
*/
-static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, void const *xlat_inst,
UNUSED void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rlm_redis_t const *inst = talloc_get_type_abort_const(*((void const * const *)xlat_inst),
rlm_redis_t);
size_t key_len;
unsigned long idx = 0;
fr_value_box_t *vb;
+ fr_value_box_t *in_head = fr_dlist_head(in);
- if (!*in) {
+ if (!in_head) {
REDEBUG("Missing key");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input");
return XLAT_ACTION_FAIL;
}
- key = p = (*in)->vb_strvalue;
+ key = p = in_head->vb_strvalue;
p = strchr(p, ' '); /* Look for index */
if (p) {
key_len = p - key;
return XLAT_ACTION_FAIL;
}
} else {
- key_len = (*in)->vb_length;
+ key_len = in_head->vb_length;
}
key_slot = fr_redis_cluster_slot_by_key(inst->cluster, request, (uint8_t const *)key, key_len);
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_asprintf(vb, vb, NULL, false, "%pV:%u", fr_box_ipaddr(ipaddr), port);
- fr_cursor_append(out, vb);
+ fr_dcursor_append(out, vb);
return XLAT_ACTION_DONE;
}
return 0;
}
-static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_cursor_t *out,
+static xlat_action_t rest_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst,
- UNUSED fr_value_box_t **in, void *rctx)
+ UNUSED fr_value_box_list_t *in, void *rctx)
{
rest_xlat_thread_inst_t *xti = talloc_get_type_abort(xlat_thread_inst, rest_xlat_thread_inst_t);
rlm_rest_t const *mod_inst = xti->inst;
MEM(vb = fr_value_box_alloc_null(ctx));
fr_value_box_bstrndup(vb, vb, NULL, body, len, true);
- fr_cursor_insert(out, vb);
+ fr_dcursor_insert(out, vb);
}
finish:
*
* @ingroup xlat_functions
*/
-static xlat_action_t rest_xlat(TALLOC_CTX *ctx, UNUSED fr_cursor_t *out,
+static xlat_action_t rest_xlat(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out,
request_t *request, UNUSED void const *xlat_inst, void *xlat_thread_inst,
- fr_value_box_t **in)
+ fr_value_box_list_t *in)
{
rest_xlat_thread_inst_t *xti = talloc_get_type_abort(xlat_thread_inst, rest_xlat_thread_inst_t);
rlm_rest_t const *mod_inst = xti->inst;
char *uri = NULL;
char const *p = NULL, *q;
http_method_t method;
+ fr_value_box_t *in_head = fr_dlist_head(in);
/* There are no configurable parameters other than the URI */
rlm_rest_xlat_rctx_t *rctx;
rlm_rest_section_t *section;
- if (!*in) {
+ if (!in_head) {
REDEBUG("Got empty URL string");
return XLAT_ACTION_FAIL;
}
- if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(ctx, in_head, in, FR_TYPE_STRING, true) < 0) {
REDEBUG("Failed concatenating arguments into URL string");
return XLAT_ACTION_FAIL;
}
- p = (*in)->vb_strvalue;
+ p = in_head->vb_strvalue;
MEM(rctx = talloc(request, rlm_rest_xlat_rctx_t));
section = &rctx->section;
* - #RLM_MODULE_FAIL if a fault occurred.
*/
static rlm_rcode_t mod_map_proc(void *mod_inst, UNUSED void *proc_inst, request_t *request,
- fr_value_box_t **query, fr_map_list_t const *maps)
+ fr_value_box_list_t *query, fr_map_list_t const *maps)
{
rlm_sql_t *inst = talloc_get_type_abort(mod_inst, rlm_sql_t);
rlm_sql_handle_t *handle = NULL;
char map_rhs_buff[128];
char const *query_str = NULL;
+ fr_value_box_t *query_head = fr_dlist_head(query);
#define MAX_SQL_FIELD_INDEX (64)
fr_assert(inst->driver->sql_fields); /* Should have been caught during validation... */
- if (!*query) {
+ if (!query_head) {
REDEBUG("Query cannot be (null)");
return RLM_MODULE_FAIL;
}
- if (fr_value_box_list_concat(request, *query, query, FR_TYPE_STRING, true) < 0) {
+ if (fr_value_box_list_concat(request, query_head, query, FR_TYPE_STRING, true) < 0) {
RPEDEBUG("Failed concatenating input string");
return RLM_MODULE_FAIL;
}
- query_str = (*query)->vb_strvalue;
+ query_str = query_head->vb_strvalue;
for (i = 0; i < MAX_SQL_FIELD_INDEX; i++) field_index[i] = -1;