Initial revision
[freeradius.git] / src / lib / print.c
1 /*
2  * print.c      Routines to print stuff.
3  *
4  * Version:     @(#)print.c  1.00  26-Oct-1998  miquels@cistron.nl
5  *
6  */
7
8 #include        "autoconf.h"
9
10 #include        <stdio.h>
11 #include        <stdlib.h>
12 #include        <sys/types.h>
13 #include        <time.h>
14 #include        <pwd.h>
15 #include        <ctype.h>
16 #include        <string.h>
17
18 #include        "libradius.h"
19
20 /*
21  *      Convert a string to something printable.
22  *      The output string has to be _at least_ 4x the size
23  *      of the input string!
24  */
25 static void librad_safeprint(char *in, int inlen, char *out, int outlen)
26 {
27         unsigned char   *str = (unsigned char *)in;
28         int             done = 0;
29         int             sp = 0;
30
31         if (inlen < 0) inlen = strlen(str);
32
33         while (inlen-- > 0 && (done + 3) < outlen) {
34                 /*
35                  *      Hack: never print trailing zero.
36                  *      Some clients send strings with an off-by-one
37                  *      length (confused with strings in C).
38                  */
39                 if (inlen == 0 && *str == 0)
40                         break;
41
42                 sp = 0;
43
44                 switch (*str) {
45                         case '\\':
46                                 sp = '\\';
47                                 break;
48                         case '\r':
49                                 sp = 'r';
50                                 break;
51                         case '\n':
52                                 sp = 'n';
53                                 break;
54                         case '\t':
55                                 sp = 't';
56                                 break;
57                         default:
58                                 if (*str < 32 || (*str >= 128 && *str <= 160)){
59                                         sprintf(out, "\\%03o", *str);
60                                         done += 4;
61                                         out  += 4;
62                                 } else {
63                                         *out++ = *str;
64                                         done++;
65                                 }
66                 }
67                 if (sp) {
68                         *out++ = '\\';
69                         *out++ = sp;
70                         done += 2;
71                 }
72                 str++;
73         }
74         *out = 0;
75 }
76
77
78 /*
79  *      Print one attribute and value into a string.
80  */
81 void vp_prints(char *out, int outlen, VALUE_PAIR *vp)
82 {
83         DICT_VALUE      *v;
84         char            buf[1024];
85         char            *a;
86         time_t          t;
87         int             len;
88
89         out[0] = 0;
90         if (strlen(vp->name) + 3 > outlen)
91                 return;
92
93         sprintf(out, "%s = ", vp->name);
94         len = strlen(out);
95         outlen -= len;
96         out += len;
97
98         switch (vp->type) {
99                 case PW_TYPE_STRING:
100                         if (vp->attribute == PW_NAS_PORT_ID)
101                                 a = vp->strvalue;
102                         else {
103                                 buf[0] = '"';
104                                 librad_safeprint(vp->strvalue, vp->length,
105                                         buf + 1, sizeof(buf) - 2);
106                                 strcat(buf, "\"");
107                                 a = buf;
108                         }
109                         break;
110                 case PW_TYPE_INTEGER:
111                         if ((v = dict_valbyattr(vp->attribute, vp->lvalue))
112                             != NULL)
113                                 a = v->name;
114                         else {
115                                 sprintf(buf, "%d", vp->lvalue);
116                                 a = buf;
117                         }
118                         break;
119                 case PW_TYPE_DATE:
120                         t = vp->lvalue;
121                         strftime(buf, sizeof(buf), "\"%b %e %Y\"",
122                                 gmtime(&t));
123                         a = buf;
124                         break;
125                 case PW_TYPE_IPADDR:
126                         if (vp->strvalue[0])
127                                 a = vp->strvalue;
128                         else
129                                 a = ip_ntoa(NULL, vp->lvalue);
130                         break;
131                 default:
132                         a = "UNKNOWN";
133                         break;
134         }
135         strncpy(out, a, outlen);
136         out[outlen - 1] = 0;
137 }
138
139
140 /*
141  *      Print one attribute and value.
142  */
143 void vp_print(FILE *fp, VALUE_PAIR *vp)
144 {
145         char    buf[1024];
146
147         vp_prints(buf, sizeof(buf), vp);
148         fputs(buf, fp);
149 }
150
151
152 /*
153  *      Print a whole list of attributes, indented by a TAB
154  *      and with a newline at the end.
155  */
156 void vp_printlist(FILE *fp, VALUE_PAIR *vp)
157 {
158         for (; vp; vp = vp->next) {
159                 fprintf(fp, "\t");
160                 vp_print(fp, vp);
161                 fprintf(fp, "\n");
162         }
163 }
164