radcli_avp_concat_str(3)

πŸ“¦ version 2.0.1, in arch rolling

πŸ’… radcli_avp_concat_str β€” from the radcli manual, section 3

okay so bestie, buckle up, because this one is literally the "grab every copy of an attribute and smoosh them into one string" function, and it ATE. it's radcli_avp_concat_str(3) and it's about to make your reply-parsing life so much easier 🫢


✨ SYNOPSIS ✨

#include <radcli/>

int radcli_avp_concat_str(
    char                   *buf,
    size_t                  buflen,
    const radcli_avp_list  *list,
    const radcli_attr_def  *def,
    const char             *sep
);

🌸 DESCRIPTION 🌸

so basically this generalizes the one little convenience thing that legacy radcli.h's rc_aaa() used to fold right into its own call signature β€” you know, its msg parameter, the one that "will contain the concatenation of any PW_REPLY_MESSAGE received" (lib/buildreq.c) πŸ’« β€” except now it works for any attribute, not just Reply-Message. because the pattern "walk every occurrence of one attribute in a reply, join as text" was never actually specific to Reply-Message, and everyone knew it. so if you're a caller who just wants rc_aaa()'s old convenience? you no longer have to hand-roll the whole radcli_avp_get()-in-a-loop thing that this function replaces. no cap, that loop can retire πŸ’…

if there's no occurrence of def present in list, buf gets set to an empty string and 0 is returned β€” and that is not a failure, okay? it's the exact same energy as rc_aaa()'s msg starting out as '' and just... staying that way when no Reply-Message ever showed up. iconic, honestly. and an attribute whose value contains an embedded NUL byte, or (for a RADCLI_TYPE_TEXT attribute) invalid UTF-8, gets skipped β€” that's radcli_avp_get_cstr()'s policy β€” and it's also not treated as a failure. no drama, just vibes 🌈

it follows snprintf()'s buffer-sizing contract exactly, and when I say exactly I mean it:

  • buf may be NULL and/or buflen may be 0 so you can size a buffer before you allocate one (in that case nothing gets written, periodt)
  • the return value is always the number of bytes the joined result would occupy, whether or not it actually fit
  • so a return >= buflen means the result was truncated, and buf (if it's non-NULL and buflen > 0) then holds only a valid NUL-terminated prefix of whatever fits β€” never garbage, never unterminated πŸ™ˆ

πŸŽ€ PARAMETERS πŸŽ€

  • buf β€” the destination buffer, or NULL if you only want to compute the needed size. it's always left NUL-terminated on return (truncation included, holding whatever fit) whenever buf is non-NULL and buflen > 0 πŸ¦‹
  • buflen β€” size of buf, in bytes. may be 0.
  • list β€” the list you're searching. your scavenger hunt ✨
  • def β€” the attribute you want to concatenate occurrences of.
  • sep β€” the separator inserted between occurrences. NULL or "" for none. (yes, both work, live your truth)

πŸ‘‘ RETURN VALUE πŸ‘‘

the number of bytes the joined result occupies (excluding the NUL terminator), whether or not it fit in buf β€” or -1 if def is NULL. that's it, that's the deal πŸ”₯


πŸ’œ SEE ALSO πŸ’œ

your reading list, bestie, and yes you're gonna read all of them:


friendly reminder from your local Unix bestie: buf may be NULL and buflen may be 0 β€” that's the size-only mode, nothing is written, don't panic πŸ’€

okay that's the whole page, mwah πŸ’‹ this came out of the radcli source, dated 2026-10-10, and the page itself is radcli_avp_concat_str(3) β€” go forth and concatenate, you absolute main character 🌟

πŸ“¦ where this page comes from