]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
framework for adding XLAT_TYPE_CHILD
authorAlan T. DeKok <aland@freeradius.org>
Sun, 22 Mar 2020 15:44:05 +0000 (11:44 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 23 Mar 2020 13:01:29 +0000 (09:01 -0400)
src/lib/server/xlat_eval.c
src/lib/server/xlat_priv.h
src/lib/server/xlat_tokenize.c

index 5664919fb352615ce9e803e03affa54a97df8720..aa355b4a383b5a8a2e5e4919c00efeef889dbe59 100644 (file)
@@ -126,6 +126,7 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node)
 {
        switch (node->type) {
        case XLAT_LITERAL:
+       case XLAT_CHILD:
                return talloc_asprintf(ctx, "%s", node->fmt);
 
        case XLAT_ONE_LETTER:
@@ -184,6 +185,7 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node)
 
                return result;
        }
+
        default:
                return NULL;
        }
@@ -1068,6 +1070,18 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons
                        *child = node->child;
                        xa = XLAT_ACTION_PUSH_CHILD;
                        goto finish;
+
+               case XLAT_CHILD:
+                       XLAT_DEBUG("** [%i] %s(child) - %%{%s:...}", unlang_interpret_stack_depth(request), __FUNCTION__,
+                                  node->fmt);
+
+                       /*
+                        *      Hand back the child node to the caller
+                        *      for evaluation.
+                        */
+                       *child = node->child;
+                       xa = XLAT_ACTION_PUSH_CHILD;
+                       goto finish;
                }
        }
 
@@ -1103,6 +1117,10 @@ static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * c
                XLAT_DEBUG("%.*sxlat_aprint LITERAL", lvl, xlat_spaces);
                return talloc_typed_strdup(ctx, node->fmt);
 
+       case XLAT_CHILD:
+               XLAT_DEBUG("%.*sxlat_aprint CHILD", lvl, xlat_spaces);
+               return talloc_typed_strdup(ctx, node->fmt);
+
                /*
                 *      Do a one-character expansion.
                 */
@@ -1686,6 +1704,19 @@ int xlat_eval_walk(xlat_exp_t *exp, xlat_walker_t walker, xlat_type_t type, void
                        if (ret < 0) return ret;
                        break;
 
+               case XLAT_CHILD:
+                       if (!type || (type & XLAT_CHILD)) {
+                               ret = walker(node, uctx);
+                               if (ret < 0) return ret;
+                       }
+
+                       /*
+                        *      Evaluate the child.
+                        */
+                       ret = xlat_eval_walk(node->child, walker, type, uctx);
+                       if (ret < 0) return ret;
+                       break;
+
                default:
                        if (!type || (type & node->type)) {
                                ret = walker(node, uctx);
index 414d5185be70eb3cc66c5f9fb53495e8034e9123..70581cbcb943a1683f1f6844933ec493c51d9d2c 100644 (file)
@@ -88,6 +88,7 @@ typedef enum {
        XLAT_REGEX              = 0x20,         //!< regex reference
 #endif
        XLAT_ALTERNATE          = 0x40,         //!< xlat conditional syntax :-
+       XLAT_CHILD              = 0x80          //!< encapsulated string of xlats
 } xlat_type_t;
 
 /** An xlat expansion node
index d8324e733a08aedd6f93943f4920bfbfb0f06cf6..07497aa164ca1efcf9a29f0bbdf65ff2ff4291f4 100644 (file)
@@ -749,6 +749,15 @@ static void xlat_tokenize_debug(REQUEST *request, xlat_exp_t const *node)
                        RDEBUG3("literal --> %s", node->fmt);
                        break;
 
+               case XLAT_CHILD:
+                       RDEBUG3("child --> %s", node->fmt);
+                       RDEBUG3("{");
+                       RINDENT();
+                       xlat_tokenize_debug(request, node->child);
+                       REXDENT();
+                       RDEBUG3("}");
+                       break;
+
                case XLAT_ONE_LETTER:
                        RDEBUG3("percent --> %c", node->fmt[0]);
                        break;
@@ -831,7 +840,7 @@ size_t xlat_snprint(char *out, size_t outlen, xlat_exp_t const *node)
 #define CHECK_SPACE(_p, _end) if (_p >= _end) goto oob
 
        while (node) {
-               if (node->type == XLAT_LITERAL) {
+               if ((node->type == XLAT_LITERAL) || (node->type == XLAT_CHILD)) {
                        p += strlcpy(p, node->fmt, end - p);
                        CHECK_SPACE(p, end);
                        goto next;