2 * print.c Routines to print stuff.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000,2006 The FreeRADIUS server project
23 #include <freeradius-devel/ident.h>
26 #include <freeradius-devel/autoconf.h>
30 #include <sys/types.h>
34 #include <freeradius-devel/missing.h>
35 #include <freeradius-devel/libradius.h>
38 * Convert a string to something printable.
39 * The output string has to be _at least_ 4x the size
40 * of the input string!
42 void librad_safeprint(char *in, int inlen, char *out, int outlen)
44 unsigned char *str = (unsigned char *)in;
48 if (inlen < 0) inlen = strlen(in);
50 while (inlen-- > 0 && (done + 3) < outlen) {
52 * Hack: never print trailing zero.
53 * Some clients send strings with an off-by-one
54 * length (confused with strings in C).
56 if (inlen == 0 && *str == 0)
78 if (*str < 32 || (*str >= 128)){
79 snprintf(out, outlen, "\\%03o", *str);
102 * Print one value into a string.
103 * delimitst will define if strings and dates will be delimited by '"'
105 int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
109 const char *a = NULL;
119 if ((delimitst == 1) && vp->flags.has_tag) {
120 /* Tagged attribute: print delimter and ignore tag */
122 librad_safeprint((char *)(vp->vp_strvalue),
123 vp->length, buf + 1, sizeof(buf) - 2);
125 } else if (delimitst == 1) {
126 /* Non-tagged attribute: print delimter */
128 librad_safeprint((char *)vp->vp_strvalue,
129 vp->length, buf + 1, sizeof(buf) - 2);
132 } else if (delimitst < 0) {
133 strlcpy(out, vp->vp_strvalue, outlen);
137 /* Non-tagged attribute: no delimiter */
138 librad_safeprint((char *)vp->vp_strvalue,
139 vp->length, buf, sizeof(buf));
143 case PW_TYPE_INTEGER:
144 if ( vp->flags.has_tag ) {
145 /* Attribute value has a tag, need to ignore it */
146 if ((v = dict_valbyattr(vp->attribute, (vp->lvalue & 0xffffff)))
150 snprintf(buf, sizeof(buf), "%u", (vp->lvalue & 0xffffff));
156 /* Normal, non-tagged attribute */
157 if ((v = dict_valbyattr(vp->attribute, vp->lvalue))
161 snprintf(buf, sizeof(buf), "%u", vp->lvalue);
169 len = strftime(buf, sizeof(buf), "\"%b %e %Y %H:%M:%S %Z\"",
170 localtime_r(&t, &s_tm));
172 len = strftime(buf, sizeof(buf), "%b %e %Y %H:%M:%S %Z",
173 localtime_r(&t, &s_tm));
175 if (len > 0) a = buf;
178 a = inet_ntop(AF_INET, &(vp->lvalue),
181 case PW_TYPE_ABINARY:
184 print_abinary(vp, buf, sizeof(buf));
190 if (outlen <= (2 * (vp->length + 1))) return 0;
194 lrad_bin2hex(vp->vp_octets, buf + 2, vp->length);
199 a = ifid_ntoa(buf, sizeof(buf), vp->vp_octets);
202 case PW_TYPE_IPV6ADDR:
203 a = inet_ntop(AF_INET6,
204 (const struct in6_addr *) vp->vp_strvalue,
208 case PW_TYPE_IPV6PREFIX:
210 struct in6_addr addr;
215 memcpy(&addr, vp->vp_strvalue + 2, sizeof(addr));
217 a = inet_ntop(AF_INET6, &addr, buf, sizeof(buf));
219 char *p = buf + strlen(buf);
220 sprintf(p, "/%u", (unsigned int) vp->vp_strvalue[1]);
230 if (a != NULL) strlcpy(out, a, outlen);
236 * This is a hack, and has to be kept in sync with tokens.h
238 static const char *vp_tokens[] = {
239 "?", /* T_OP_INVALID */
270 * Print one attribute and value into a string.
272 int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
275 const char *token = NULL;
283 DICT_ATTR *da = dict_attrbyvalue(vp->attribute);
289 if (strlen(name) + 3 > (size_t)outlen) {
293 if ((vp->operator > T_OP_INVALID) &&
294 (vp->operator < T_TOKEN_LAST)) {
295 token = vp_tokens[vp->operator];
297 token = "<INVALID-TOKEN>";
300 if( vp->flags.has_tag ) {
302 snprintf(out, outlen, "%s:%d %s ", name, vp->flags.tag,
306 vp_prints_value(out + len, outlen - len, vp, 1);
310 snprintf(out, outlen, "%s %s ", name, token);
312 vp_prints_value(out + len, outlen - len, vp, 1);
321 * Print one attribute and value.
323 void vp_print(FILE *fp, VALUE_PAIR *vp)
327 vp_prints(buf, sizeof(buf), vp);
333 * Print a whole list of attributes, indented by a TAB
334 * and with a newline at the end.
336 void vp_printlist(FILE *fp, VALUE_PAIR *vp)
338 for (; vp; vp = vp->next) {