]> git.sur5r.net Git - openldap/blob - libraries/liblber/bprint.c
e88f072a78b70ca98065d8284add6be02443e6c3
[openldap] / libraries / liblber / bprint.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/ctype.h>
12 #include <ac/stdarg.h>
13 #include <ac/string.h>
14
15 #include "lber-int.h"
16
17 /*
18  * We don't just set ber_pvt_err_file to stderr here, because in NT,
19  * stderr is a symbol imported from a DLL. As such, the compiler
20  * doesn't recognize the symbol as having a constant address. Thus
21  * we set ber_pvt_err_file to stderr later, when it first gets
22  * referenced.
23  */
24 FILE *ber_pvt_err_file;
25
26 /*
27  * ber errno
28  */
29 BER_ERRNO_FN ber_int_errno_fn;
30
31 int * ber_errno_addr(void)
32 {
33         static int ber_int_errno = LBER_ERROR_NONE;
34
35         if( ber_int_errno_fn ) {
36                 return (*ber_int_errno_fn)();
37         }
38
39         return &ber_int_errno;
40 }
41
42 /*
43  * Print stuff
44  */
45 void ber_error_print( LDAP_CONST char *data )
46 {
47         assert( data != NULL );
48
49         if (!ber_pvt_err_file) ber_pvt_err_file = stderr;
50
51         fputs( data, ber_pvt_err_file );
52
53         /* Print to both streams */
54         if (ber_pvt_err_file != stderr) {
55                 fputs( data, stderr );
56                 fflush( stderr );
57         }
58
59         fflush( ber_pvt_err_file );
60 }
61
62 BER_LOG_PRINT_FN ber_pvt_log_print = ber_error_print;
63
64 /*
65  * lber log 
66  */
67
68 static int ber_log_check( int errlvl, int loglvl )
69 {
70         return errlvl & loglvl ? 1 : 0;
71 }
72
73 int ber_pvt_log_printf( int errlvl, int loglvl, const char *fmt, ... )
74 {
75         char buf[ 1024 ];
76         va_list ap;
77
78         assert( fmt != NULL );
79
80         if ( !ber_log_check( errlvl, loglvl )) {
81                 return 0;
82         }
83
84         va_start( ap, fmt );
85
86 #ifdef HAVE_VSNPRINTF
87         buf[sizeof(buf) - 1] = '\0';
88         vsnprintf( buf, sizeof(buf)-1, fmt, ap );
89 #elif HAVE_VSPRINTF
90         vsprintf( buf, fmt, ap ); /* hope it's not too long */
91 #else
92         /* use doprnt() */
93 #error "vsprintf() required."
94 #endif
95
96         va_end(ap);
97
98         (*ber_pvt_log_print)( buf );
99         return 1;
100 }
101 #if 0
102 static int ber_log_puts(int errlvl, int loglvl, char *buf)
103 {
104         assert( buf != NULL );
105
106         if ( !ber_log_check( errlvl, loglvl )) {
107                 return 0;
108         }
109
110         (*ber_pvt_log_print)( buf );
111         return 1;
112 }
113 #endif
114 /*
115  * Print arbitrary stuff, for debugging.
116  */
117
118 int
119 ber_log_bprint(int errlvl,
120         int loglvl,
121         const char *data,
122         ber_len_t len )
123 {
124         assert( data != NULL );
125
126         if ( !ber_log_check( errlvl, loglvl )) {
127                 return 0;
128         }
129
130         ber_bprint(data, len);
131         return 1;
132 }
133
134 void
135 ber_bprint(
136         LDAP_CONST char *data,
137         ber_len_t len )
138 {
139         static const char       hexdig[] = "0123456789abcdef";
140 #define BP_OFFSET 8
141 #define BP_GRAPH 60
142 #define BP_LEN  80
143         char    line[ BP_LEN ];
144         ber_len_t i;
145
146         assert( data != NULL );
147
148         /* in case len is zero */
149         line[0] = '\n';
150         line[1] = '\0';
151         
152         for ( i = 0 ; i < len ; i++ ) {
153                 int n = i % 16;
154                 int off;
155
156                 if( !n ) {
157                         if( i ) (*ber_pvt_log_print)( line );
158                         memset( line, ' ', sizeof(line)-2 );
159                         line[sizeof(line)-2] = '\n';
160                         line[sizeof(line)-1] = '\0';
161
162                         off = i % 0x0ffffU;
163
164                         line[ 2 ] = hexdig[ ( off & 0xf000U ) >> 12 ];
165                         line[ 3 ] = hexdig[ ( off & 0x0f00U ) >>  8 ];
166                         line[ 4 ] = hexdig[ ( off & 0x00f0U ) >>  4 ];
167                         line[ 5 ] = hexdig[ ( off & 0x000fU ) ];
168                         line[ 6 ] = ':';
169                 }
170
171                 off = BP_OFFSET + n*3;
172                 line[ off   ] = hexdig[ ( data[i] & 0xf0U ) >> 4 ];
173                 line[ off+1 ] = hexdig[ data[i] & 0x0fU ];
174                 
175                 off = BP_GRAPH + n;
176
177                 if ( isprint( data[i] )) {
178                         line[ BP_GRAPH + n ] = data[i];
179                 } else {
180                         line[ BP_GRAPH + n ] = '.';
181                 }
182         }
183
184         (*ber_pvt_log_print)( line );
185 }
186
187 int
188 ber_log_dump(
189         int errlvl,
190         int loglvl,
191         BerElement *ber,
192         int inout )
193 {
194         assert( ber != NULL );
195         assert( BER_VALID( ber ) );
196
197         if ( !ber_log_check( errlvl, loglvl )) {
198                 return 0;
199         }
200
201         ber_dump(ber, inout);
202         return 1;
203 }
204
205 void
206 ber_dump(
207         BerElement *ber,
208         int inout )
209 {
210         char buf[132];
211         ber_len_t len;
212
213         assert( ber != NULL );
214         assert( BER_VALID( ber ) );
215
216         if ( inout == 1 ) {
217                 len = ber_pvt_ber_remaining(ber);
218         } else {
219                 len = ber_pvt_ber_write(ber);
220         }
221
222         sprintf( buf, "ber_dump: buf=0x%08lx ptr=0x%08lx end=0x%08lx len=%ld\n",
223             (long) ber->ber_buf,
224                 (long) ber->ber_ptr,
225                 (long) ber->ber_end,
226                 (long) len );
227
228         (*ber_pvt_log_print)( buf );
229
230         ber_bprint( ber->ber_ptr, len );
231 }
232
233 int
234 ber_log_sos_dump(
235         int errlvl,
236         int loglvl,
237         Seqorset *sos )
238 {
239         assert( sos != NULL );
240
241         if ( !ber_log_check( errlvl, loglvl )) {
242                 return 0;
243         }
244
245         ber_sos_dump( sos );
246         return 1;
247 }
248
249 void
250 ber_sos_dump(
251         Seqorset *sos )
252 {
253         char buf[132];
254
255         assert( sos != NULL );
256
257         (*ber_pvt_log_print)( "*** sos dump ***\n" );
258
259         while ( sos != NULL ) {
260                 sprintf( buf, "ber_sos_dump: clen %ld first 0x%lx ptr 0x%lx\n",
261                     (long) sos->sos_clen,
262                         (long) sos->sos_first,
263                         (long) sos->sos_ptr );
264                 (*ber_pvt_log_print)( buf );
265
266                 sprintf( buf, "              current len %ld contents:\n",
267                     (long) (sos->sos_ptr - sos->sos_first) );
268                 (*ber_pvt_log_print)( buf );
269
270                 ber_bprint( sos->sos_first, sos->sos_ptr - sos->sos_first );
271
272                 sos = sos->sos_next;
273         }
274
275         (*ber_pvt_log_print)( "*** end dump ***\n" );
276 }