]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Start of relative dcusor init
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 3 Aug 2022 04:53:20 +0000 (12:53 +0800)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 3 Aug 2022 04:53:20 +0000 (12:53 +0800)
src/lib/server/tmpl_dcursor.c
src/lib/server/tmpl_dcursor.h

index cef2d13f81f23adc9eb9f92b0b22634b290fcf74..163e10d2502f2f24819a1ba481021ae97bd44ad0 100644 (file)
@@ -288,7 +288,7 @@ static void *_tmpl_cursor_next(fr_dlist_head_t *list, void *curr, void *uctx)
        return NULL;
 }
 
-/** Initialise a #fr_dcursor_t to the #fr_pair_t specified by a #tmpl_t
+/** Initialise a #fr_dcursor_t at the specified point in a pair tree
  *
  * This makes iterating over the one or more #fr_pair_t specified by a #tmpl_t
  * significantly easier.
@@ -304,7 +304,9 @@ static void *_tmpl_cursor_next(fr_dlist_head_t *list, void *curr, void *uctx)
  *                             Must be explicitly cleared with tmpl_cursor_state_clear
  *                             otherwise we will leak memory.
  * @param[in] cursor           to store iterator position.
- * @param[in] request          The current #request_t.
+ * @param[in] request          the current request.
+ * @param[in] list             a nested list to start evaluating from.
+ *                             May be the child list of a pair in the request's pair tree.
  * @param[in] vpt              specifying the #fr_pair_t type or list to iterate over.
  * @return
  *     - First #fr_pair_t specified by the #tmpl_t.
@@ -312,43 +314,14 @@ static void *_tmpl_cursor_next(fr_dlist_head_t *list, void *curr, void *uctx)
  *
  * @see tmpl_cursor_next
  */
-fr_pair_t *tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
-                            fr_dcursor_t *cursor, request_t *request, tmpl_t const *vpt)
+fr_pair_t *tmpl_dcursor_init_relative(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
+                                     fr_dcursor_t *cursor,
+                                     request_t *request, fr_pair_t *list, tmpl_t const *vpt)
 {
        fr_pair_t               *vp = NULL;
-       fr_pair_t               *list;
 
        TMPL_VERIFY(vpt);
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
-
-       if (err) *err = 0;
-
-       /*
-        *      Navigate to the correct request context
-        */
-       if (tmpl_request_ptr(&request, tmpl_request(vpt)) < 0) {
-               if (err) *err = -3;
-       error:
-               memset(cc, 0, sizeof(*cc));     /* so tmpl_dursor_clear doesn't explode */
-               return NULL;
-       }
-
-       /*
-        *      Get the right list in the specified context
-        */
-       if (!vpt->rules.attr.list_as_attr) {
-               list = tmpl_get_list(request, vpt);
-               if (!list) {
-                       fr_strerror_printf("List \"%s\" not available in this context",
-                                          fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
-                       if (err) *err = -2;
-                       goto error;
-               }
-       } else {
-               list = request->pair_root;
-       }
-
        /*
         *      Initialise the temporary cursor context
         */
@@ -396,6 +369,67 @@ fr_pair_t *tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
        return vp;
 }
 
+/** Initialise a #fr_dcursor_t to the #fr_pair_t specified by a #tmpl_t
+ *
+ * This makes iterating over the one or more #fr_pair_t specified by a #tmpl_t
+ * significantly easier.
+ *
+ * @param[out] err             May be NULL if no error code is required.
+ *                             Will be set to:
+ *                             - 0 on success.
+ *                             - -1 if no matching #fr_pair_t could be found.
+ *                             - -2 if list could not be found (doesn't exist in current #request_t).
+ *                             - -3 if context could not be found (no parent #request_t available).
+ * @param[in] ctx              to make temporary allocations under.
+ * @param[in] cc               to initialise.  Tracks evaluation state.
+ *                             Must be explicitly cleared with tmpl_cursor_state_clear
+ *                             otherwise we will leak memory.
+ * @param[in] cursor           to store iterator position.
+ * @param[in] request          The current #request_t.
+ * @param[in] vpt              specifying the #fr_pair_t type or list to iterate over.
+ * @return
+ *     - First #fr_pair_t specified by the #tmpl_t.
+ *     - NULL if no matching #fr_pair_t found, and NULL on error.
+ *
+ * @see tmpl_cursor_next
+ */
+fr_pair_t *tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
+                            fr_dcursor_t *cursor, request_t *request, tmpl_t const *vpt)
+{
+       fr_pair_t               *list;
+
+       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+
+       if (err) *err = 0;
+
+       /*
+        *      Navigate to the correct request context
+        */
+       if (tmpl_request_ptr(&request, tmpl_request(vpt)) < 0) {
+               if (err) *err = -3;
+       error:
+               memset(cc, 0, sizeof(*cc));     /* so tmpl_dursor_clear doesn't explode */
+               return NULL;
+       }
+
+       /*
+        *      Get the right list in the specified context
+        */
+       if (!vpt->rules.attr.list_as_attr) {
+               list = tmpl_get_list(request, vpt);
+               if (!list) {
+                       fr_strerror_printf("List \"%s\" not available in this context",
+                                          fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
+                       if (err) *err = -2;
+                       goto error;
+               }
+       } else {
+               list = request->pair_root;
+       }
+
+       return tmpl_dcursor_init_relative(err, ctx, cc, cursor, request, list, vpt);
+}
+
 /** Clear any temporary state allocations
  *
  */
index a5dcb149ee3de1cc140b4c24573790ffd9a3cd71..6e798a6094ea59a864e8d1add3981bcbe60dff0a 100644 (file)
@@ -82,6 +82,10 @@ struct tmpl_dcursor_ctx_s {
                                                ///< allocate it later.
 };
 
+fr_pair_t              *tmpl_dcursor_init_relative(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
+                                                   fr_dcursor_t *cursor,
+                                                   request_t *request, fr_pair_t *list, tmpl_t const *vpt);
+
 fr_pair_t              *tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
                                           fr_dcursor_t *cursor, request_t *request,
                                           tmpl_t const *vpt);