TALLOC_CTX *xlat_ctx = talloc_init_const("xlat");
xlat_exp_head_t *head = NULL;
fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double };
+ tmpl_rules_t t_rules = (tmpl_rules_t) {
+ .attr = {
+ .dict_def = dict_protocol,
+ .list_def = request_attr_request,
+ .allow_unresolved = true,
+ },
+ .xlat = {
+ .runtime_el = el,
+ },
+ .at_runtime = true,
+ };
+
- slen = xlat_tokenize_ephemeral(xlat_ctx, &head, el, &line, &p_rules, NULL);
+ slen = xlat_tokenize(xlat_ctx, &head, &line, &p_rules, &t_rules);
if (slen <= 0) {
talloc_free(xlat_ctx);
fr_sbuff_in_sprintf(&out, "ERROR offset %d '%s'", (int) -slen, fr_strerror());
xlat_exp_head_t *head = NULL;
vpt = tmpl_alloc_null(ctx);
- if (!t_rules->at_runtime) {
- slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
- } else {
- slen = xlat_tokenize_ephemeral(vpt, &head,
- t_rules->xlat.runtime_el, &our_in,
- p_rules, t_rules);
- }
-
+ slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
if (slen <= 0) FR_SBUFF_ERROR_RETURN(&our_in);
if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
vpt = tmpl_alloc_null(ctx);
- if (!t_rules->at_runtime) {
- slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
- } else {
- slen = xlat_tokenize_ephemeral(vpt, &head, t_rules->xlat.runtime_el,
- &our_in, p_rules, t_rules);
- }
+ slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
if (slen < 0) FR_SBUFF_ERROR_RETURN(&our_in);
/*
vpt = tmpl_alloc_null(ctx);
- if (!t_rules->at_runtime) {
- slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
- } else {
- slen = xlat_tokenize_ephemeral(vpt, &head,
- t_rules->xlat.runtime_el, &our_in,
- p_rules, t_rules);
- }
-
+ slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
if (slen < 0) FR_SBUFF_ERROR_RETURN(&our_in);
/*
fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-fr_slen_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head,
- fr_event_list_t *el, fr_sbuff_t *in,
- fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-
fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool comma, bool allow_attr);
/*
* Parse the input as a literal expansion
*/
- if (xlat_tokenize_ephemeral(rctx,
- &rctx->ex, unlang_interpret_event_list(request),
- &FR_SBUFF_IN(arg->vb_strvalue, arg->vb_length),
- &(fr_sbuff_parse_rules_t){
- .escapes = &escape_rules
- },
- &(tmpl_rules_t){
- .attr = {
- .dict_def = request->dict,
- .list_def = request_attr_request,
- .allow_unknown = false,
- .allow_unresolved = false,
- .allow_foreign = false,
+ if (xlat_tokenize(rctx,
+ &rctx->ex,
+ &FR_SBUFF_IN(arg->vb_strvalue, arg->vb_length),
+ &(fr_sbuff_parse_rules_t){
+ .escapes = &escape_rules
+ },
+ &(tmpl_rules_t){
+ .attr = {
+ .dict_def = request->dict,
+ .list_def = request_attr_request,
+ .allow_unknown = false,
+ .allow_unresolved = false,
+ .allow_foreign = false,
},
- .at_runtime = true
- }) < 0) {
+ .xlat = {
+ .runtime_el = unlang_interpret_event_list(request),
+ },
+ .at_runtime = true
+ }) < 0) {
RPEDEBUG("Failed parsing expansion");
error:
talloc_free(rctx);
/*
* Give better errors than the old code.
*/
- len = xlat_tokenize_ephemeral(ctx, &head, unlang_interpret_event_list(request),
- &FR_SBUFF_IN(fmt, strlen(fmt)),
- NULL,
- &(tmpl_rules_t){
- .attr = {
- .dict_def = request->dict,
- .list_def = request_attr_request,
- }
- });
+ len = xlat_tokenize(ctx, &head,
+ &FR_SBUFF_IN(fmt, strlen(fmt)),
+ NULL,
+ &(tmpl_rules_t){
+ .attr = {
+ .dict_def = request->dict,
+ .list_def = request_attr_request,
+ },
+ .xlat = {
+ .runtime_el = unlang_interpret_event_list(request),
+ },
+ .at_runtime = true,
+ });
if (len == 0) {
if (*out) {
**out = '\0';
}
-/** Tokenize an xlat expansion at runtime
- *
- * This is used for runtime parsing of xlat expansions, such as those we receive from datastores
- * like LDAP or SQL.
- *
- * @param[in] ctx to allocate dynamic buffers in.
- * @param[out] out the head of the xlat list / tree structure.
- * @param[in] el for registering any I/O handlers.
- * @param[in] in the format string to expand.
- * @param[in] p_rules from the encompassing grammar.
- * @param[in] t_rules controlling how attribute references are parsed.
- * @return
- * - >0 on success.
- * - 0 and *head == NULL - Parse failure on first char.
- * - 0 and *head != NULL - Zero length expansion
- * - <0 the negative offset of the parse failure.
- */
-fr_slen_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out,
- fr_event_list_t *el, fr_sbuff_t *in,
- fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
-{
- fr_sbuff_t our_in = FR_SBUFF(in);
- tmpl_rules_t our_t_rules = {};
- xlat_exp_head_t *head;
-
- MEM(head = xlat_exp_head_alloc(ctx));
-
- if (t_rules) {
- head->dict = t_rules->attr.dict_def;
- our_t_rules = *t_rules;
- }
-
- our_t_rules.xlat.runtime_el = el;
-
- fr_strerror_clear(); /* Clear error buffer */
- if (xlat_tokenize_input(head, &our_in, p_rules, &our_t_rules) < 0) {
- talloc_free(head);
- FR_SBUFF_ERROR_RETURN(&our_in);
- }
-
- /*
- * Zero length expansion, return a zero length node.
- */
- if (!xlat_exp_head(head)) {
- *out = head;
- return 0;
- }
-
- /*
- * Create ephemeral instance data for the xlat
- */
- if (xlat_instantiate_ephemeral(head, el) < 0) {
- fr_strerror_const("Failed performing ephemeral instantiation for xlat");
- talloc_free(head);
- return 0;
- }
-
- *out = head;
-
- FR_SBUFF_SET_RETURN(in, &our_in);
-}
-
/** Tokenize an xlat expansion into a series of XLAT_TYPE_CHILD arguments
*
* @param[in] ctx to allocate nodes in. Note: All nodes will be
fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
{
+ int rcode;
fr_sbuff_t our_in = FR_SBUFF(in);
xlat_exp_head_t *head;
* Add nodes that need to be bootstrapped to
* the registry.
*/
- if (xlat_exp_head(head) && (xlat_bootstrap(head) < 0)) {
+ if (!t_rules || !t_rules->xlat.runtime_el) {
+ rcode = xlat_bootstrap(head);
+ } else {
+ rcode = xlat_instantiate_ephemeral(head, t_rules->xlat.runtime_el);
+ }
+ if (rcode < 0) {
talloc_free(head);
return 0;
}