fr_dcursor_t *cursor, request_t *request, tmpl_t const *vpt)
{
fr_pair_t *vp = NULL;
- fr_pair_list_t *list_head;
+ fr_pair_list_t *list_head = NULL;
tmpl_request_t *rr = NULL;
TALLOC_CTX *list_ctx;
}
/*
- * Get the right list in the specified context
+ * If the rules say "return the list as an attribute",
+ * then check for that. But if the first da isn't a
+ * list, then default to whatever list ref is given.
+ *
+ * @todo - for the future, have the tokenizer (or
+ * whatever) always add the list head to the list of
+ * attribute references.
*/
- list_head = tmpl_list_head(request, tmpl_list(vpt));
+ if (vpt->rules.list_as_attr) {
+ tmpl_attr_t const *ar;
+
+ ar = fr_dlist_head(&vpt->data.attribute.ar);
+ fr_assert(ar != NULL);
+
+ if ((ar->ar_da == request_attr_request) ||
+ (ar->ar_da == request_attr_reply) ||
+ (ar->ar_da == request_attr_control) ||
+ (ar->ar_da == request_attr_state)) {
+ list_head = &request->pair_root->vp_group;
+ list_ctx = request->pair_root;
+ }
+ }
+
if (!list_head) {
- if (err) {
- *err = -2;
- fr_strerror_printf("List \"%s\" not available in this context",
- fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
+ /*
+ * Get the right list in the specified context
+ */
+ list_head = tmpl_list_head(request, tmpl_list(vpt));
+ if (!list_head) {
+ if (err) {
+ *err = -2;
+ fr_strerror_printf("List \"%s\" not available in this context",
+ fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
+ }
+ goto error;
}
- goto error;
+ list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
}
- list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
/*
* Initialise the temporary cursor context
tmpl_rules_t const *t_rules)
{
int ret;
- size_t list_len;
+ size_t list_len = 0;
tmpl_t *vpt;
fr_sbuff_t our_name = FR_SBUFF(name); /* Take a local copy in case we need to back track */
bool ref_prefix = false;
fr_sbuff_marker(&m_l, &our_name);
- /*
- * Parse the list reference
- *
- * This code should be removed when lists
- * are integrated into attribute references.
- */
- fr_sbuff_out_by_longest_prefix(&list_len, &vpt->data.attribute.list, pair_list_table,
- &our_name, t_rules->list_def);
+ if (!t_rules->list_as_attr) {
+ /*
+ * Parse the list reference
+ *
+ * This code should be removed when lists
+ * are integrated into attribute references.
+ */
+ fr_sbuff_out_by_longest_prefix(&list_len, &vpt->data.attribute.list, pair_list_table,
+ &our_name, t_rules->list_def);
- /*
- * Check if we need to backtrack
- *
- * Lists can be followed by a '.', '[', or the end of the attribute reference
- *
- * If we don't find any of those things it wasn't an actual list match
- * but one of the list identifiers matched part of an attribute reference.
- *
- * i.e. reply with reply-message.
- */
- if ((list_len > 0) && !fr_sbuff_is_char(&our_name, '.') &&
- !fr_sbuff_is_char(&our_name, '[') && !tmpl_substr_terminal_check(&our_name, p_rules)) {
- fr_sbuff_set(&our_name, &m_l);
- list_len = 0;
- vpt->data.attribute.list = t_rules->list_def;
- }
+ /*
+ * Check if we need to backtrack
+ *
+ * Lists can be followed by a '.', '[', or the end of the attribute reference
+ *
+ * If we don't find any of those things it wasn't an actual list match
+ * but one of the list identifiers matched part of an attribute reference.
+ *
+ * i.e. reply with reply-message.
+ */
+ if ((list_len > 0) && !fr_sbuff_is_char(&our_name, '.') &&
+ !fr_sbuff_is_char(&our_name, '[') && !tmpl_substr_terminal_check(&our_name, p_rules)) {
+ fr_sbuff_set(&our_name, &m_l);
+ list_len = 0;
+ vpt->data.attribute.list = t_rules->list_def;
+ }
- if ((t_rules->attr_parent || t_rules->disallow_qualifiers) && (list_len > 0)) {
- fr_strerror_const("It is not permitted to specify a pair list here");
- if (err) *err = TMPL_ATTR_ERROR_INVALID_LIST_QUALIFIER;
- talloc_free(vpt);
- FR_SBUFF_ERROR_RETURN(&our_name);
+ if ((t_rules->attr_parent || t_rules->disallow_qualifiers) && (list_len > 0)) {
+ fr_strerror_const("It is not permitted to specify a pair list here");
+ if (err) *err = TMPL_ATTR_ERROR_INVALID_LIST_QUALIFIER;
+ talloc_free(vpt);
+ FR_SBUFF_ERROR_RETURN(&our_name);
+ }
}
/*