return talloc_zero(ctx, map_t);
}
-/** re-parse a map where the lhs is an unknown attribute.
- *
- *
- * @param map to process.
- * @param rhs_quote quotation type around rhs.
- * @param rhs string to re-parse.
- */
-bool map_cast_from_hex(map_t *map, fr_token_t rhs_quote, char const *rhs)
-{
- size_t len;
- uint8_t *ptr;
- char const *p;
- pair_list_t list;
-
- fr_dict_attr_t const *da;
- fr_pair_t *vp = NULL;
- tmpl_t *vpt;
- fr_value_box_t cast;
-
- fr_assert(map != NULL);
-
- fr_assert(map->lhs != NULL);
- fr_assert(tmpl_is_attr(map->lhs));
-
- fr_assert(map->rhs == NULL);
- fr_assert(rhs != NULL);
-
- MAP_VERIFY(map);
-
- /*
- * If the attribute is still unknown, go parse the RHS.
- */
- if (tmpl_da(map->lhs)->flags.is_raw) {
- da = fr_dict_attr_child_by_num(tmpl_da(map->lhs)->parent,
- tmpl_da(map->lhs)->attr);
- if (!da || da->flags.is_raw) return false;
- } else {
- da = tmpl_da(map->lhs);
- }
-
- /*
- * If the RHS is something OTHER than an octet
- * string, go parse it as that.
- */
- if (rhs_quote != T_BARE_WORD) return false;
- if ((rhs[0] != '0') || (tolower((int)rhs[1]) != 'x')) return false;
- if (!rhs[2]) return false;
-
- len = strlen(rhs + 2);
- ptr = talloc_array(map, uint8_t, len >> 1);
- if (!ptr) return false;
-
- fr_hex2bin(NULL, &FR_DBUFF_TMP(ptr, len >> 1), &FR_SBUFF_IN(rhs + 2, len), false);
-
- /*
- * Convert to da->type (if possible);
- */
- if (fr_value_box_cast(map, &cast, da->type, da, fr_box_octets_buffer(ptr)) < 0) {
- talloc_free(ptr);
- return false;
- }
-
- /*
- * Package the #fr_value_box_t as a #tmpl_t
- */
- if (tmpl_afrom_value_box(map, &map->rhs, &cast, true) < 0) {
- talloc_free(ptr);
- return false;
- }
-
- talloc_free(ptr);
-
- /*
- * Set the LHS to the REAL attribute name.
- *
- * @fixme Is this even necessary? It looks like it goes
- * through a lot of work in order to set the name to
- * (drum roll) exactly the same thing it was before.
- */
- vpt = tmpl_alloc(map, TMPL_TYPE_ATTR, T_BARE_WORD, NULL, 0);
- tmpl_attr_copy(vpt, map->lhs);
- tmpl_attr_set_leaf_da(vpt, da);
-
- /*
- * Be sure to keep the "&control." or "control." prefix.
- * If it's there, we re-generate it from whatever was in
- * the original name, including the '&'.
- *
- * If we don't have a prefix, ensure that the attribute
- * name is prefixed with '&'.
- */
- p = map->lhs->name;
- if (*p == '&') p++;
- len = radius_list_name(&list, p, PAIR_LIST_UNKNOWN);
-
- if (list != PAIR_LIST_UNKNOWN) {
- tmpl_set_name_printf(vpt, T_BARE_WORD, "%.*s:%s", (int) len, map->lhs->name, tmpl_da(map->lhs)->name);
- } else {
- tmpl_set_name_printf(vpt, T_BARE_WORD, "&%s", tmpl_da(map->lhs)->name);
- }
- talloc_free(map->lhs);
- map->lhs = vpt;
-
- fr_pair_list_free(&vp);
-
- MAP_VERIFY(map);
-
- return true;
-}
-
/** Convert CONFIG_PAIR (which may contain refs) to map_t.
*
* Treats the left operand as an attribute reference