From: Arran Cudbard-Bell Date: Fri, 15 Sep 2017 08:22:41 +0000 (+0700) Subject: Add iterator for iterating by DA X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8b1dd771cda3bd018bc1af0691efdee0a4d8501;p=thirdparty%2Ffreeradius-server.git Add iterator for iterating by DA --- diff --git a/src/include/pair.h b/src/include/pair.h index 10e1e5fdc1d..7bff1ecf66c 100644 --- a/src/include/pair.h +++ b/src/include/pair.h @@ -26,6 +26,7 @@ RCSIDH(pair_h, "$Id$") #include +#include #ifdef __cplusplus extern "C" { @@ -200,6 +201,8 @@ int fr_pair_to_unknown(VALUE_PAIR *vp); int fr_pair_mark_xlat(VALUE_PAIR *vp, char const *value); /* Searching and list modification */ +VALUE_PAIR *fr_pair_cursor_init_by_da(fr_cursor_t *cursor, VALUE_PAIR **head, fr_dict_attr_t const *da); + VALUE_PAIR *fr_pair_find_by_da(VALUE_PAIR *head, fr_dict_attr_t const *da, int8_t tag); VALUE_PAIR *fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag); diff --git a/src/lib/util/cursor.c b/src/lib/util/cursor.c index b50d76f9fc9..fb21d1fde1c 100644 --- a/src/lib/util/cursor.c +++ b/src/lib/util/cursor.c @@ -64,7 +64,6 @@ static inline void *cursor_next(void **prev, fr_cursor_t *cursor, void *current) } if (!cursor->iter) { - next = *NEXT_PTR(current); /* Fast path without custom iter */ if (prev) *prev = current; diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 594cd2966cd..79bb5fdf5ca 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -607,6 +607,48 @@ int fr_pair_mark_xlat(VALUE_PAIR *vp, char const *value) return 0; } +/** Iterate over pairs with a specified da + * + * @param[in,out] prev The VALUE_PAIR before curr. Will be updated to point to the + * pair before the one returned, or the last pair in the list + * if no matching pairs found. + * @param[in] curr The VALUE_PAIR after cursor->current. Will be checked to + * see if it matches the specified fr_dict_attr_t. + * @param[in] ctx The fr_dict_attr_t to search for. + * @return + * - Next matching VALUE_PAIR. + * - NULL if not more matching VALUE_PAIRs could be found. + */ +static void *_pair_iter_by_da(void **prev, void *curr, void *ctx) +{ + VALUE_PAIR *c, *p; + fr_dict_attr_t *da = ctx; + + if (!curr) return NULL; + + for (p = *prev, c = curr; c; p = c, c = c->next) { + VP_VERIFY(c); + if (c->da == da) break; + } + + *prev = p; + + return c; +} + +/** Create a cursor which will only return pairs with the specified fr_dict_attr_t + * + * @param[in] cursor Usually an #fr_cursor_t struct in stack memory. + * @param[in] head Pointer to the start of the list. + * @param[in] da We're searching for. + * @return + * - The first VALUE_PAIR in the list matching da + */ +VALUE_PAIR *fr_pair_cursor_init_by_da(fr_cursor_t *cursor, VALUE_PAIR **head, fr_dict_attr_t const *da) +{ + return fr_cursor_talloc_iter_init(cursor, head, _pair_iter_by_da, da, VALUE_PAIR); +} + /** Find the pair with the matching DAs * */