]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add dict_attr_acopy_children()
authorAlan T. DeKok <aland@freeradius.org>
Thu, 3 Dec 2020 20:50:08 +0000 (15:50 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 3 Dec 2020 21:09:05 +0000 (16:09 -0500)
which does a recursive copy of the child from "src" to "dst"

src/lib/util/dict_priv.h
src/lib/util/dict_util.c

index ebfe1ce164a56dcbb640b7b125b1d03f40565f67..9b8e2aa8d641589c89b7e5a999798219d2a7ba6f 100644 (file)
@@ -146,6 +146,8 @@ fr_dict_attr_t              *dict_attr_alloc(TALLOC_CTX *ctx,
 
 fr_dict_attr_t         *dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in, char const *new_name);
 
+int                    dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_t const *src);
+
 int                    dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child);
 
 int                    dict_protocol_add(fr_dict_t *dict);
index fe07f0c5971a5b2852d6a659d79cc3ecf8295430..9fb4e07c4af341d3d4304179fbe70ef8c93e65d4 100644 (file)
@@ -714,6 +714,49 @@ fr_dict_attr_t *dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in, char
        return n;
 }
 
+/** Copy the children of an existing attribute
+ *
+ * @param[in] dict             to allocate the children in
+ * @param[in] dst              where to copy the children to
+ * @param[in] src              where to copy the children from
+ * @return
+ *     - 0 on success
+ *     - <0 on error
+ */
+int dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_t const *src)
+{
+       fr_dict_attr_t const *child = NULL;
+       fr_dict_attr_t *copy;
+
+       if (dst->type != FR_TYPE_TLV) return -1;
+
+       fr_assert(fr_dict_attr_has_ext(dst, FR_DICT_ATTR_EXT_CHILDREN));
+
+       for (child = fr_dict_attr_iterate_children(src, &child);
+            child != NULL;
+            child = fr_dict_attr_iterate_children(src, &child)) {
+               copy = dict_attr_acopy(dict->pool, child, NULL);
+               if (!copy) {
+                       fr_strerror_printf("Failed cloning child %s", child->name);
+                       return -1;
+               }
+
+               copy->parent = dst;
+
+               if (dict_attr_child_add(dst, copy) < 0) return -1;
+
+               if (dict_attr_add_to_namespace(dict, dst, copy) < 0) return -1;
+               
+               if (!dict_attr_children(child)) continue;
+
+               if (dict_attr_acopy_children(dict, copy, child) < 0) return -1;
+       }
+
+       return 0;
+}
+
+
+
 /** Add a protocol to the global protocol table
  *
  * Inserts a protocol into the global protocol table.  Uses the root attributes