From: Alan T. DeKok Date: Thu, 3 Dec 2020 20:50:08 +0000 (-0500) Subject: add dict_attr_acopy_children() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=18cfaec63c69b0cc6e25b2bb4caac24df365140c;p=thirdparty%2Ffreeradius-server.git add dict_attr_acopy_children() which does a recursive copy of the child from "src" to "dst" --- diff --git a/src/lib/util/dict_priv.h b/src/lib/util/dict_priv.h index ebfe1ce164a..9b8e2aa8d64 100644 --- a/src/lib/util/dict_priv.h +++ b/src/lib/util/dict_priv.h @@ -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); diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index fe07f0c5971..9fb4e07c4af 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -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