]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
remove UNLANG_TYPE_XLAT_INLINE and replace with UNLANG_TYPE_TMPL
authorAlan T. DeKok <aland@freeradius.org>
Fri, 10 Apr 2020 12:44:34 +0000 (08:44 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 10 Apr 2020 12:45:08 +0000 (08:45 -0400)
which has the same functionality, but will also allow for async
template expansions.

src/lib/unlang/compile.c
src/lib/unlang/tmpl.c
src/lib/unlang/tmpl_priv.h
src/lib/unlang/unlang_priv.h
src/lib/unlang/xlat.c

index fac268e021901c561b1eab2f834b35965fa8f54f..b8a5dbea47d648a4aa48050cb420e3117855286f 100644 (file)
@@ -2484,42 +2484,81 @@ static unlang_t *compile_detach(unlang_t *parent, unlang_compile_t *unlang_ctx,
 }
 #endif
 
-static unlang_t *compile_xlat_inline(unlang_t *parent,
-                                    unlang_compile_t *unlang_ctx, CONF_PAIR const *cp)
+static unlang_t *compile_tmpl(unlang_t *parent,
+                             unlang_compile_t *unlang_ctx, CONF_PAIR *cp)
 {
        unlang_t *c;
-       unlang_xlat_inline_t *mx;
+       unlang_tmpl_t *ut;
+       ssize_t slen;
+       FR_TOKEN type;
+       char const *p = cf_pair_attr(cp);
+       size_t len;
+       vp_tmpl_t *vpt;
 
-       mx = talloc_zero(parent, unlang_xlat_inline_t);
+       ut = talloc_zero(parent, unlang_tmpl_t);
 
-       c = unlang_xlat_inline_to_generic(mx);
+       c = unlang_tmpl_to_generic(ut);
        c->parent = parent;
        c->next = NULL;
-       c->name = "expand";
+       c->name = p;
        c->debug_name = c->name;
-       c->type = UNLANG_TYPE_XLAT_INLINE;
+       c->type = UNLANG_TYPE_TMPL;
+
+       if (*p == '`') {
+               type = T_BACK_QUOTED_STRING;
+               p++;
+               len = strlen(p);
+               if (!len || (p[len - 1] != '`')) {
+                       talloc_free(ut);
+                       cf_log_err(cp, "String is missing trailing quotation character");
+                       return NULL;
+               }
+
+               p = talloc_bstrndup(ut, p, len - 1);
+               len--;
+
+       } else {
+               type = T_DOUBLE_QUOTED_STRING;
+               len = strlen(p);
+       }
 
        (void) compile_action_defaults(c, unlang_ctx);
 
-       mx->xlat_name = talloc_typed_strdup(mx, cf_pair_attr(cp));
-       if (mx->xlat_name[0] == '%') {
-               ssize_t         slen;
+       slen = tmpl_afrom_str(ut, &vpt, p, len, type, unlang_ctx->rules, true);
+       if (slen <= 0) {
+               char *spaces, *text;
 
-               slen = xlat_tokenize(mx, &mx->exp, mx->xlat_name, talloc_array_length(mx->xlat_name) - 1, unlang_ctx->rules);
-               if (slen < 0) {
-                       cf_log_err(cp, "%s", fr_strerror());
-                       talloc_free(mx);
-                       return NULL;
+       error:
+               fr_canonicalize_error(cp, &spaces, &text, slen, fr_strerror());
+
+               cf_log_err(cp, "Syntax error");
+               cf_log_err(cp, "%s", p);
+               cf_log_err(cp, "%s^ %s", spaces, text);
+
+               talloc_free(ut);
+               talloc_free(spaces);
+               talloc_free(text);
+
+               return NULL;
+       }
+
+       if (vpt->type == TMPL_TYPE_XLAT) {
+               xlat_exp_t *head;
+
+               /*
+                *      Re-write it to be a pre-parsed XLAT structure.
+                */
+               slen = xlat_tokenize(vpt, &head, vpt->name, talloc_array_length(vpt->name) - 1, unlang_ctx->rules);
+               if (slen <= 0) {
+                       p = vpt->name;
+                       goto error;
                }
-       } else {
-               char *p;
-               mx->exec = true;
 
-               memmove(mx->xlat_name, mx->xlat_name + 1, strlen(mx->xlat_name)); /* including trailing NUL */
-               p = strrchr(mx->xlat_name, '`');
-               if (p) *p = '\0';
+               vpt->type = TMPL_TYPE_XLAT_STRUCT;
+               vpt->tmpl_xlat = head;
        }
 
+       ut->tmpl = vpt; /* const issues */
        return c;
 }
 
@@ -3366,7 +3405,7 @@ static unlang_t *compile_item(unlang_t *parent, unlang_compile_t *unlang_ctx, CO
                 */
                if (((modrefname[0] == '%') && (modrefname[1] == '{')) ||
                    (modrefname[0] == '`')) {
-                       return compile_xlat_inline(parent, unlang_ctx, cp);
+                       return compile_tmpl(parent, unlang_ctx, cp);
                }
        }
 
index cb6f5814cb0c888dd986f21ddbeb727288922148..f36e23bf3d37d85c06995fc0ec4b3157644d83a9 100644 (file)
@@ -41,9 +41,9 @@ void unlang_tmpl_push(fr_value_box_t **out, REQUEST *request, vp_tmpl_t const *t
        unlang_stack_frame_t            *frame = &stack->frame[stack->depth];
        unlang_frame_state_tmpl_t       *state = talloc_get_type_abort(frame->state,
                                                                               unlang_frame_state_tmpl_t);
-       unlang_t                        *instruction;
+       unlang_tmpl_t                   *ut;
 
-       static unlang_t const tmpl_instruction = {
+       static unlang_t tmpl_instruction = {
                .type = UNLANG_TYPE_TMPL,
                .name = "tmpl",
                .debug_name = "tmpl",
@@ -61,14 +61,15 @@ void unlang_tmpl_push(fr_value_box_t **out, REQUEST *request, vp_tmpl_t const *t
        };
 
        state->out = out;
-       state->tmpl = tmpl;
 
-       memcpy(&instruction, &tmpl_instruction, sizeof(instruction)); /* const issues */
+       MEM(ut = talloc(state, unlang_tmpl_t));
+       ut->self = tmpl_instruction;
+       ut->tmpl = tmpl;
 
        /*
         *      Push a new tmpl frame onto the stack
         */
-       unlang_interpret_push(request, instruction, RLM_MODULE_UNKNOWN, UNLANG_NEXT_STOP, false);
+       unlang_interpret_push(request, unlang_tmpl_to_generic(ut), RLM_MODULE_UNKNOWN, UNLANG_NEXT_STOP, false);
 }
 
 /** Wrapper to call a resumption function after a tmpl has been expanded
@@ -98,17 +99,12 @@ rlm_rcode_t unlang_tmpl_yield(REQUEST *request, fr_unlang_tmpl_resume_t resume,
        unlang_stack_frame_t            *frame = &stack->frame[stack->depth];
        unlang_frame_state_tmpl_t       *state = talloc_get_type_abort(frame->state,
                                                                       unlang_frame_state_tmpl_t);
-       if (!tmpl_async_required(state->tmpl)) {
-               if (tmpl_aexpand_type(request, state->out, FR_TYPE_VALUE_BOX, request, state->tmpl, NULL, NULL) < 0) {
-                       return RLM_MODULE_FAIL;
-               }
-
-               return RLM_MODULE_OK;
-       }
 
        state->rctx = rctx;
        state->resume = resume;
 
+       frame->interpret = unlang_tmpl_resume;
+
        /*
         *      We set the repeatable flag here, so that the resume
         *      function is always called going back up the stack.
@@ -120,22 +116,36 @@ rlm_rcode_t unlang_tmpl_yield(REQUEST *request, fr_unlang_tmpl_resume_t resume,
         */
        frame->interpret = unlang_tmpl_resume;
        repeatable_set(frame);
-
-       /*
-        *      Not implemented.
-        */
-       return RLM_MODULE_FAIL;
+       return RLM_MODULE_YIELD;
 }
 
 static unlang_action_t unlang_tmpl(UNUSED REQUEST *request, rlm_rcode_t *presult)
 {
-#if 0
        unlang_stack_t                  *stack = request->stack;
        unlang_stack_frame_t            *frame = &stack->frame[stack->depth];
        unlang_frame_state_tmpl_t       *state = talloc_get_type_abort(frame->state,
                                                                       unlang_frame_state_tmpl_t);
-#endif
+       unlang_tmpl_t                   *ut = unlang_generic_to_tmpl(frame->instruction);
 
+       if (!state->out) {
+               state->out = fr_value_box_alloc(state, FR_TYPE_STRING, NULL, false);
+       }
+
+       if (!tmpl_async_required(ut->tmpl)) {
+               if (tmpl_aexpand_type(request, state->out, FR_TYPE_STRING, request, ut->tmpl, NULL, NULL) < 0) {
+                       REDEBUG("Failed expanding %s - %s", ut->tmpl->name, fr_strerror());
+                       *presult = RLM_MODULE_FAIL;
+               }
+
+               *presult = RLM_MODULE_OK;
+               return UNLANG_ACTION_CALCULATE_RESULT;
+       }
+
+       REDEBUG("Async xlats are not implemented!");
+
+       /*
+        *      Not implemented.
+        */
        *presult = RLM_MODULE_FAIL;
 
        return UNLANG_ACTION_CALCULATE_RESULT;
index 24b370afd0dc8de9133e449f21e055eaaa325d62..f6ad31b7cd68bece89796d8389650c43a03c0dd8 100644 (file)
@@ -34,7 +34,6 @@ extern "C" {
  * Represents a single tmpl
  */
 typedef struct {
-       vp_tmpl_t const                 *tmpl;          //!< the tmpl to expand
        fr_value_box_t                  **out;          //!< where the expansion is stored
        void                            *rctx;          //!< for resume / signal
        fr_unlang_tmpl_resume_t         resume;         //!< resumption handler
index 07dc920772bc9725b04ba7359dce24117918b2db..5db2356e8c5d75f864853e0d56b2c5c25ed3ca34 100644 (file)
@@ -78,7 +78,6 @@ typedef enum {
        UNLANG_TYPE_CALL,                       //!< call another virtual server
 #endif
        UNLANG_TYPE_POLICY,                     //!< Policy section.
-       UNLANG_TYPE_XLAT_INLINE,                //!< xlat statement, inline in "unlang"
        UNLANG_TYPE_XLAT,                       //!< Represents one level of an xlat expansion.
        UNLANG_TYPE_TMPL,                       //!< asynchronously expand a vp_tmpl_t
        UNLANG_TYPE_MAX
@@ -174,10 +173,8 @@ typedef struct {
  */
 typedef struct {
        unlang_t                self;
-       int                     exec;
-       char                    *xlat_name;
-       xlat_exp_t              *exp;                           //!< First xlat node to execute.
-} unlang_xlat_inline_t;
+       vp_tmpl_t const         *tmpl;
+} unlang_tmpl_t;
 
 /** State of a redundant operation
  *
@@ -312,13 +309,13 @@ static inline unlang_t *unlang_group_to_generic(unlang_group_t *p)
        return (unlang_t *)p;
 }
 
-static inline unlang_xlat_inline_t *unlang_generic_to_xlat_inline(unlang_t *p)
+static inline unlang_tmpl_t *unlang_generic_to_tmpl(unlang_t *p)
 {
-       rad_assert(p->type == UNLANG_TYPE_XLAT_INLINE);
-       return talloc_get_type_abort(p, unlang_xlat_inline_t);
+       rad_assert(p->type == UNLANG_TYPE_TMPL);
+       return talloc_get_type_abort(p, unlang_tmpl_t);
 }
 
-static inline unlang_t *unlang_xlat_inline_to_generic(unlang_xlat_inline_t *p)
+static inline unlang_t *unlang_tmpl_to_generic(unlang_tmpl_t *p)
 {
        return (unlang_t *)p;
 }
index ed7c8f863bfa634bbe1b26af78e277fa0963464a..8a6b4d467988c2a83cc0771d030bf4876249b6fa 100644 (file)
@@ -32,14 +32,6 @@ RCSID("$Id$")
 #include <freeradius-devel/unlang/xlat_priv.h>
 #include "unlang_priv.h"       /* Fixme - Should create a proper semi-public interface for the interpret */
 
-/** Hold the result of an inline xlat expansion
- *
- */
-typedef struct {
-       fr_value_box_t          *result;                        //!< Where to store the result of the
-                                                               ///< xlat expansion. This is usually discarded.
-} unlang_frame_state_xlat_inline_t;
-
 /** State of an xlat expansion
  *
  * State of one level of nesting within an xlat expansion.
@@ -392,32 +384,6 @@ xlat_action_t unlang_xlat_yield(REQUEST *request,
        return XLAT_ACTION_YIELD;
 }
 
-/** Evaluates "naked" xlats in the config
- *
- */
-static unlang_action_t unlang_xlat_inline(REQUEST *request, UNUSED rlm_rcode_t *presult)
-{
-       unlang_stack_t          *stack = request->stack;
-       unlang_stack_frame_t    *frame = &stack->frame[stack->depth];
-       unlang_t                *instruction = frame->instruction;
-       unlang_xlat_inline_t    *mx = unlang_generic_to_xlat_inline(instruction);
-
-       if (!mx->exec) {
-               TALLOC_CTX *pool;
-               unlang_frame_state_xlat_inline_t *state;
-
-               MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_xlat_inline_t));
-               MEM(pool = talloc_pool(frame->state, 1024));    /* Pool to absorb some allocs */
-
-               unlang_xlat_push(pool, &state->result, request, mx->exp, false);
-               return UNLANG_ACTION_PUSHED_CHILD;
-       } else {
-               RDEBUG2("`%s`", mx->xlat_name);
-               radius_exec_program(request, NULL, 0, NULL, request, mx->xlat_name, request->packet->vps,
-                                   false, true, fr_time_delta_from_sec(EXEC_TIMEOUT));
-               return UNLANG_ACTION_EXECUTE_NEXT;
-       }
-}
 
 /** Register xlat operation with the interpreter
  *
@@ -433,12 +399,4 @@ void unlang_xlat_init(void)
                                .frame_state_size = sizeof(unlang_frame_state_xlat_t),
                                .frame_state_name = "unlang_frame_state_xlat_t",
                           });
-
-
-       unlang_register(UNLANG_TYPE_XLAT_INLINE,
-                          &(unlang_op_t){
-                               .name = "xlat_inline",
-                               .interpret = unlang_xlat_inline,
-                               .debug_braces = false
-                          });
 }