made ip_hostname() take a buffer pointer, and a buffer size.
[freeradius.git] / src / lib / print.c
1 /*
2  * print.c      Routines to print stuff.
3  *
4  * Version:     $Id$
5  *
6  */
7
8 static const char rcsid[] = "$Id$";
9
10 #include        "autoconf.h"
11
12 #include        <stdio.h>
13 #include        <stdlib.h>
14 #include        <sys/types.h>
15 #include        <time.h>
16 #include        <ctype.h>
17 #include        <string.h>
18
19 #include        "libradius.h"
20
21 /*
22  *      Convert a string to something printable.
23  *      The output string has to be _at least_ 4x the size
24  *      of the input string!
25  */
26 void librad_safeprint(char *in, int inlen, char *out, int outlen)
27 {
28         unsigned char   *str = (unsigned char *)in;
29         int             done = 0;
30         int             sp = 0;
31
32         if (inlen < 0) inlen = strlen(str);
33
34         while (inlen-- > 0 && (done + 3) < outlen) {
35                 /*
36                  *      Hack: never print trailing zero.
37                  *      Some clients send strings with an off-by-one
38                  *      length (confused with strings in C).
39                  */
40                 if (inlen == 0 && *str == 0)
41                         break;
42
43                 sp = 0;
44
45                 switch (*str) {
46                         case '\\':
47                                 sp = '\\';
48                                 break;
49                         case '\r':
50                                 sp = 'r';
51                                 break;
52                         case '\n':
53                                 sp = 'n';
54                                 break;
55                         case '\t':
56                                 sp = 't';
57                                 break;
58                         default:
59                                 if (*str < 32 || (*str >= 128)){
60                                         sprintf(out, "\\%03o", *str);
61                                         done += 4;
62                                         out  += 4;
63                                 } else {
64                                         *out++ = *str;
65                                         done++;
66                                 }
67                 }
68                 if (sp) {
69                         *out++ = '\\';
70                         *out++ = sp;
71                         done += 2;
72                 }
73                 str++;
74         }
75         *out = 0;
76 }
77
78
79 /*
80  *  Print one value into a string.
81  *  delimitst will define if strings and dates will be delimited by '"'
82  */
83 int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
84 {
85         DICT_VALUE  *v;
86         char        buf[1024];
87         char        *a;
88         time_t      t;
89
90         out[0] = 0;
91         if (!vp) return 0;
92
93         switch (vp->type) {
94                 case PW_TYPE_STRING:
95                         if (vp->attribute == PW_NAS_PORT_ID)
96                                 a = vp->strvalue;
97                         else {
98                                 if (delimitst) {
99                                   buf[0] = '"';
100                                   librad_safeprint(vp->strvalue, vp->length,
101                                           buf + 1, sizeof(buf) - 2);
102                                   strcat(buf, "\"");
103                                 } else {
104                                   librad_safeprint(vp->strvalue, vp->length,
105                                           buf, sizeof(buf));
106                                 }
107
108                                 a = buf;
109                         }
110                         break;
111                 case PW_TYPE_INTEGER:
112                         if ((v = dict_valbyattr(vp->attribute, vp->lvalue))
113                                 != NULL)
114                                 a = v->name;
115                         else {
116                                 sprintf(buf, "%d", vp->lvalue);
117                                 a = buf;
118                         }
119                         break;
120                 case PW_TYPE_DATE:
121                         t = vp->lvalue;
122                         if (delimitst) {
123                           strftime(buf, sizeof(buf), "\"%b %e %Y\"", gmtime(&t));
124                         } else {
125                           strftime(buf, sizeof(buf), "%b %e %Y", gmtime(&t));
126                         }
127                         a = buf;
128                         break;
129                 case PW_TYPE_IPADDR:
130                         if (vp->strvalue[0])
131                                 a = vp->strvalue;
132                         else
133                                 a = ip_hostname(vp->strvalue,
134                                                 sizeof(vp->strvalue),
135                                                 vp->lvalue);
136                         break;
137                 case PW_TYPE_ABINARY:
138 #ifdef ASCEND_BINARY
139                   a = buf;
140                   print_abinary(vp, buf, sizeof(buf));
141                   break;
142 #else
143                   /* FALL THROUGH */
144 #endif
145                 case PW_TYPE_OCTETS:
146                   strcpy(buf, "0x");
147                   a = buf + 2;
148                   for (t = 0; t < vp->length; t++) {
149                         sprintf(a, "%02x", vp->strvalue[t]);
150                         a += 2;
151                   }
152                   a = buf;
153                   break;
154
155                 default:
156                         a = "UNKNOWN-TYPE";
157                         break;
158         }
159         strncpy(out, a, outlen);
160         out[outlen - 1] = 0;
161
162         return strlen(out);
163 }
164
165
166 /*
167  *      Print one attribute and value into a string.
168  */
169 int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
170 {
171         int             len;
172
173         out[0] = 0;
174         if (!vp) return 0;
175
176         if (strlen(vp->name) + 3 > outlen) {
177                 return 0;
178         }
179
180         sprintf(out, "%s = ", vp->name);
181         len = strlen(out);
182         vp_prints_value(out + len, outlen - len, vp, 1);
183
184         return strlen(out);
185 }
186
187
188 /*
189  *      Print one attribute and value.
190  */
191 void vp_print(FILE *fp, VALUE_PAIR *vp)
192 {
193         char    buf[1024];
194
195         vp_prints(buf, sizeof(buf), vp);
196         fputs(buf, fp);
197 }
198
199
200 /*
201  *      Print a whole list of attributes, indented by a TAB
202  *      and with a newline at the end.
203  */
204 void vp_printlist(FILE *fp, VALUE_PAIR *vp)
205 {
206         for (; vp; vp = vp->next) {
207                 fprintf(fp, "\t");
208                 vp_print(fp, vp);
209                 fprintf(fp, "\n");
210         }
211 }
212