]> git.sur5r.net Git - openldap/blob - libraries/liblber/bprint.c
Changes from HEAD for beta
[openldap] / libraries / liblber / bprint.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2003 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 #define ber_log_check(errlvl, loglvl)   ((errlvl) & (loglvl))
18
19 BER_LOG_FN ber_int_log_proc = NULL;
20
21 /*
22  * We don't just set ber_pvt_err_file to stderr here, because in NT,
23  * stderr is a symbol imported from a DLL. As such, the compiler
24  * doesn't recognize the symbol as having a constant address. Thus
25  * we set ber_pvt_err_file to stderr later, when it first gets
26  * referenced.
27  */
28 FILE *ber_pvt_err_file = NULL;
29
30 /*
31  * ber errno
32  */
33 BER_ERRNO_FN ber_int_errno_fn = NULL;
34
35 int * ber_errno_addr(void)
36 {
37         static int ber_int_errno = LBER_ERROR_NONE;
38
39         if( ber_int_errno_fn ) {
40                 return (*ber_int_errno_fn)();
41         }
42
43         return &ber_int_errno;
44 }
45
46 /*
47  * Print stuff
48  */
49 void ber_error_print( LDAP_CONST char *data )
50 {
51         assert( data != NULL );
52
53         if (!ber_pvt_err_file) ber_pvt_err_file = stderr;
54
55         fputs( data, ber_pvt_err_file );
56
57         /* Print to both streams */
58         if (ber_pvt_err_file != stderr) {
59                 fputs( data, stderr );
60                 fflush( stderr );
61         }
62
63         fflush( ber_pvt_err_file );
64 }
65
66 BER_LOG_PRINT_FN ber_pvt_log_print = ber_error_print;
67
68 /*
69  * lber log 
70  */
71
72 int ber_pvt_log_output(
73         const char *subsystem,
74         int level,
75         const char *fmt,
76         ... )
77 {
78         char buf[1024];
79         va_list vl;
80         va_start( vl, fmt );
81
82         if ( ber_int_log_proc != NULL ) {
83                 ber_int_log_proc( ber_pvt_err_file, subsystem, level, fmt, vl );
84
85         } else {
86                 int level;
87                 ber_get_option( NULL, LBER_OPT_BER_DEBUG, &level );
88                 buf[sizeof(buf) - 1] = '\0';
89                 vsnprintf( buf, sizeof(buf)-1, fmt, vl );
90                 if ( ber_log_check( LDAP_DEBUG_BER, level ) ) {
91                         (*ber_pvt_log_print)( buf );
92                 }
93         }
94
95         va_end(vl);
96         return 1;
97 }
98         
99 int ber_pvt_log_printf( int errlvl, int loglvl, const char *fmt, ... )
100 {
101         char buf[1024];
102         va_list ap;
103
104         assert( fmt != NULL );
105
106         if ( !ber_log_check( errlvl, loglvl )) {
107                 return 0;
108         }
109
110         va_start( ap, fmt );
111
112         buf[sizeof(buf) - 1] = '\0';
113         vsnprintf( buf, sizeof(buf)-1, fmt, ap );
114
115         va_end(ap);
116
117         (*ber_pvt_log_print)( buf );
118         return 1;
119 }
120
121 #if 0
122 static int ber_log_puts(int errlvl, int loglvl, char *buf)
123 {
124         assert( buf != NULL );
125
126         if ( !ber_log_check( errlvl, loglvl )) {
127                 return 0;
128         }
129
130         (*ber_pvt_log_print)( buf );
131         return 1;
132 }
133 #endif
134
135 /*
136  * Print arbitrary stuff, for debugging.
137  */
138
139 int
140 ber_log_bprint(int errlvl,
141         int loglvl,
142         const char *data,
143         ber_len_t len )
144 {
145         assert( data != NULL );
146
147         if ( !ber_log_check( errlvl, loglvl )) {
148                 return 0;
149         }
150
151         ber_bprint(data, len);
152         return 1;
153 }
154
155 void
156 ber_bprint(
157         LDAP_CONST char *data,
158         ber_len_t len )
159 {
160         static const char hexdig[] = "0123456789abcdef";
161 #define BP_OFFSET 9
162 #define BP_GRAPH 60
163 #define BP_LEN  80
164         char    line[BP_LEN];
165         ber_len_t i;
166
167         assert( data != NULL );
168
169         /* in case len is zero */
170         line[0] = '\n';
171         line[1] = '\0';
172         
173         for ( i = 0 ; i < len ; i++ ) {
174                 int n = i % 16;
175                 unsigned off;
176
177                 if( !n ) {
178                         if( i ) (*ber_pvt_log_print)( line );
179                         memset( line, ' ', sizeof(line)-2 );
180                         line[sizeof(line)-2] = '\n';
181                         line[sizeof(line)-1] = '\0';
182
183                         off = i % 0x0ffffU;
184
185                         line[2] = hexdig[0x0f & (off >> 12)];
186                         line[3] = hexdig[0x0f & (off >>  8)];
187                         line[4] = hexdig[0x0f & (off >>  4)];
188                         line[5] = hexdig[0x0f & off];
189                         line[6] = ':';
190                 }
191
192                 off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
193                 line[off] = hexdig[0x0f & ( data[i] >> 4 )];
194                 line[off+1] = hexdig[0x0f & data[i]];
195                 
196                 off = BP_GRAPH + n + ((n >= 8)?1:0);
197
198                 if ( isprint( (unsigned char) data[i] )) {
199                         line[BP_GRAPH + n] = data[i];
200                 } else {
201                         line[BP_GRAPH + n] = '.';
202                 }
203         }
204
205         (*ber_pvt_log_print)( line );
206 }
207
208 #ifdef NEW_LOGGING
209 int ber_output_dump(
210         const char *subsys,
211         int level,
212         BerElement *ber,
213         int inout )
214 {
215     static const char   hexdig[] = "0123456789abcdef";
216     char buf[132];
217     ber_len_t len;
218     char        line[ BP_LEN ];
219     ber_len_t i;
220     char *data = ber->ber_ptr;
221
222     if ( inout == 1 ) {
223         len = ber_pvt_ber_remaining(ber);
224     } else {
225         len = ber_pvt_ber_write(ber);
226     }
227
228     sprintf( buf, "ber_dump: buf=0x%08lx ptr=0x%08lx end=0x%08lx len=%ld\n",
229              (long) ber->ber_buf,
230              (long) ber->ber_ptr,
231              (long) ber->ber_end,
232              (long) len );
233
234     (void) ber_pvt_log_output( subsys, level, "%s", buf );
235
236 #define BP_OFFSET 9
237 #define BP_GRAPH 60
238 #define BP_LEN  80
239
240     assert( data != NULL );
241         
242     /* in case len is zero */
243     line[0] = '\n';
244     line[1] = '\0';
245         
246     for ( i = 0 ; i < len ; i++ ) {
247         int n = i % 16;
248         unsigned off;
249         
250         if( !n ) {
251             if( i ) {
252                                 (void) ber_pvt_log_output( subsys, level, "%s", line );
253                         }
254             memset( line, ' ', sizeof(line)-2 );
255             line[sizeof(line)-2] = '\n';
256             line[sizeof(line)-1] = '\0';
257             
258             off = i % 0x0ffffU;
259
260             line[2] = hexdig[0x0f & (off >> 12)];
261             line[3] = hexdig[0x0f & (off >>  8)];
262             line[4] = hexdig[0x0f & (off >>  4)];
263             line[5] = hexdig[0x0f & off ];
264             line[6] = ':';
265         }
266
267         off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
268         line[off] = hexdig[ 0x0f & ( data[i] >> 4 ) ];
269         line[off+1] = hexdig[ 0x0f & data[i] ];
270         
271         off = BP_GRAPH + n + ((n >= 8)?1:0);
272         
273         if ( isprint( (unsigned char) data[i] )) {
274             line[BP_GRAPH + n] = data[i];
275         } else {
276             line[BP_GRAPH + n] = '.';
277         }
278     }
279
280     return ber_pvt_log_output( subsys, level, "%s", line );
281 }
282 #endif
283
284 int
285 ber_log_dump(
286         int errlvl,
287         int loglvl,
288         BerElement *ber,
289         int inout )
290 {
291         assert( ber != NULL );
292         assert( LBER_VALID( ber ) );
293
294         if ( !ber_log_check( errlvl, loglvl )) {
295                 return 0;
296         }
297
298         ber_dump(ber, inout);
299         return 1;
300 }
301
302 void
303 ber_dump(
304         BerElement *ber,
305         int inout )
306 {
307         char buf[132];
308         ber_len_t len;
309
310         assert( ber != NULL );
311         assert( LBER_VALID( ber ) );
312
313         if ( inout == 1 ) {
314                 len = ber_pvt_ber_remaining(ber);
315         } else {
316                 len = ber_pvt_ber_write(ber);
317         }
318
319         sprintf( buf, "ber_dump: buf=0x%08lx ptr=0x%08lx end=0x%08lx len=%ld\n",
320             (long) ber->ber_buf,
321                 (long) ber->ber_ptr,
322                 (long) ber->ber_end,
323                 (long) len );
324
325         (void) (*ber_pvt_log_print)( buf );
326
327         ber_bprint( ber->ber_ptr, len );
328 }
329
330 int
331 ber_log_sos_dump(
332         int errlvl,
333         int loglvl,
334         Seqorset *sos )
335 {
336         assert( sos != NULL );
337
338         if ( !ber_log_check( errlvl, loglvl )) {
339                 return 0;
340         }
341
342         ber_sos_dump( sos );
343         return 1;
344 }
345
346 void
347 ber_sos_dump(
348         Seqorset *sos )
349 {
350         char buf[132];
351
352         assert( sos != NULL );
353
354         (*ber_pvt_log_print)( "*** sos dump ***\n" );
355
356         while ( sos != NULL ) {
357                 sprintf( buf, "ber_sos_dump: clen %ld first 0x%lx ptr 0x%lx\n",
358                     (long) sos->sos_clen,
359                         (long) sos->sos_first,
360                         (long) sos->sos_ptr );
361                 (*ber_pvt_log_print)( buf );
362
363                 sprintf( buf, "              current len %ld contents:\n",
364                     (long) (sos->sos_ptr - sos->sos_first) );
365                 (*ber_pvt_log_print)( buf );
366
367                 ber_bprint( sos->sos_first, sos->sos_ptr - sos->sos_first );
368
369                 sos = sos->sos_next;
370         }
371
372         (*ber_pvt_log_print)( "*** end dump ***\n" );
373 }