/** Print the value of an attribute to a string * * @param[out] out Where to write the string. * @param[in] outlen Size of outlen (must be at least 3 bytes). * @param[in] vp to print. * @param[in] quote Char to add before and after printed value, if 0 no char will be added, if < 0 * raw string will be added. * @return * - Length of data written to out. * - Value >= outlen on truncation. */ size_t vp_prints_value(char *out, size_t outlen, VALUE_PAIR const *vp, char quote) { VERIFY_VP(vp); if (vp->type == VT_XLAT) { return snprintf(out, outlen, "%c%s%c", quote, vp->xlat, quote); } return value_data_prints(out, outlen, vp->da->type, vp->da, &vp->data, quote); }
static ssize_t cache_xlat(void *instance, REQUEST *request, char const *fmt, char *out, size_t freespace) { rlm_cache_entry_t *c = NULL; rlm_cache_t *inst = instance; rlm_cache_handle_t *handle = NULL; size_t slen; ssize_t ret = 0; vp_tmpl_t target; vp_map_t *map = NULL; slen = tmpl_from_attr_substr(&target, fmt, REQUEST_CURRENT, PAIR_LIST_REQUEST, false, false); if (slen <= 0) { REDEBUG("%s", fr_strerror()); return -1; } if (cache_acquire(&handle, inst, request) < 0) return -1; switch (cache_find(&c, inst, request, handle, fmt)) { case RLM_MODULE_OK: /* found */ break; case RLM_MODULE_NOTFOUND: /* not found */ *out = '\0'; return 0; default: return -1; } for (map = c->maps; map; map = map->next) { if ((map->lhs->tmpl_da != target.tmpl_da) || (map->lhs->tmpl_tag != target.tmpl_tag) || (map->lhs->tmpl_list != target.tmpl_list)) continue; ret = value_data_prints(out, freespace, map->rhs->tmpl_data_type, map->lhs->tmpl_da, &map->rhs->tmpl_data_value, '\0'); if (is_truncated(slen, freespace)) { REDEBUG("Insufficient buffer space to write cached value"); ret = -1; goto finish; } break; } /* * Check if we found a matching map */ if (!map) { *out = '\0'; return 0; } finish: cache_free(inst, &c); cache_release(inst, request, &handle); return ret; }