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