]> git.sur5r.net Git - openldap/blob - libraries/liblutil/debug.c
remove lint
[openldap] / libraries / liblutil / debug.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 #include <stdlib.h>
11
12 #include <ac/stdarg.h>
13 #include <ac/string.h>
14 #include <ac/time.h>
15
16 #include "ldap_log.h"
17 #include "ldap_defaults.h"
18 #include "lber.h"
19
20 struct M2S
21 {
22         char *mnemonic;
23         int  subsys;
24 };
25
26 struct DEBUGLEVEL
27 {
28         char *subsystem;
29         int  level;
30 };
31
32 static struct DEBUGLEVEL **levelArray;
33 static long   numLevels = 0;
34
35 static FILE *log_file = NULL;
36 static int global_level = 0;
37
38 #if 0
39 #ifdef LDAP_SYSLOG
40 static int use_syslog = 0;
41
42 static int debug2syslog(int l) {
43         switch (l) {
44         /* insert mapping cases here */
45         default:
46         }
47         return LOG_DEBUG
48 }
49 #endif
50 #endif
51
52 static char *lutil_levels[] = {"emergency", "alert", "critical",
53                            "error", "warning", "notice",
54                            "information", "entry", "args",
55                            "results", "detail1", "detail2",
56                            NULL};
57
58 int lutil_mnem2level( char *level )
59 {
60     int i;
61     for( i = 0; lutil_levels[i] != NULL; i++ )
62     {
63         if ( !strcasecmp( level, lutil_levels[i] ) )
64         {
65             return i;
66         }
67     }
68     return 0;
69 }
70
71 static void addSubsys( const char *subsys, int level )
72 {
73         int i, j;
74         for( i = 0; i < numLevels; i++ )
75         {
76                 if ( levelArray[i] == NULL )
77                 {
78                         levelArray[i] = (struct DEBUGLEVEL*)ber_memalloc( sizeof( struct DEBUGLEVEL ) );
79                         levelArray[i]->subsystem = (char*)ber_memalloc( strlen( subsys ) + 1 );
80                         strcpy ( levelArray[i]->subsystem, subsys );
81                         levelArray[i]->level = level;
82                         return;
83                 }
84                 if( !strcasecmp( subsys, levelArray[i]->subsystem ) )
85                 {
86                         levelArray[i]->level = level;
87                         return;
88                 }
89         }
90         levelArray = (struct DEBUGLEVEL**)ber_memrealloc( levelArray, sizeof( struct DEBUGLEVEL* ) * (numLevels + 10) );
91         for( j = numLevels; j < (numLevels + 10); j++ )
92         {
93                 levelArray[j] = NULL;
94         }
95         numLevels += 10;
96         levelArray[i] = (struct DEBUGLEVEL*)ber_memalloc( sizeof( struct DEBUGLEVEL ) );
97         levelArray[i]->subsystem = (char*)ber_memalloc( strlen( subsys ) + 1 );
98         strcpy( levelArray[i]->subsystem, subsys );
99         levelArray[i]->level = level;
100         return;
101 }
102
103 void lutil_set_debug_level( char* subsys, int level )
104 {
105         addSubsys( subsys, level );
106 }
107
108 int lutil_debug_file( FILE *file )
109 {
110         log_file = file;
111         ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file );
112
113         return 0;
114 }
115
116 void lutil_log_int(FILE* file, char *subsys, int level, const char *fmt, va_list vl )
117 {
118         char buffer[4096];
119         time_t now;
120         struct tm *today;
121         int i;
122
123         if ( levelArray == NULL ) return; /* logging isn't set up */
124
125         /*
126          * Look for the subsystem in the level array.  When we find it,
127          * break out of the loop.
128          */
129         for( i = 0; i < numLevels; i++ ) {
130                 if ( levelArray[i] == NULL ) return; 
131                 if ( ! strcasecmp( levelArray[i]->subsystem, subsys ) ) break;
132         }
133
134         /*
135          * If we didn't find the subsystem, or the set level is less than
136          * the requested output level, don't output it.
137          */
138         if ( (level > global_level) &&
139                 ((i > numLevels ) || ( level > levelArray[i]->level )) )
140         {
141                 return;
142         }
143
144 #ifdef HAVE_WINSOCK
145 #define BUFOFFSET 18
146         /*
147          * Stick the time in the buffer to output when using Winsock
148          * as NT can't pipe to a timestamp program like Unix can.
149          * This, of course, makes some logs hard to read.
150      */
151         time( &now );
152         today = localtime( &now );
153         sprintf( buffer, "%4d%02d%02d:%02d:%02d:%02d ",
154                 today->tm_year + 1900, today->tm_mon + 1,
155                 today->tm_mday, today->tm_hour,
156                 today->tm_min, today->tm_sec );
157 #else
158 #define BUFOFFSET 0
159 #endif
160
161         /*
162          * format the output data.
163          */
164 #ifdef HAVE_VSNPRINTF
165         vsnprintf( &buffer[BUFOFFSET], sizeof(buffer)-BUFOFFSET, fmt, vl );
166 #else
167         vsprintf( &buffer[BUFOFFSET], fmt, vl );
168 #endif
169         buffer[sizeof(buffer)-1] = '\0';
170
171 #if 0
172 #ifdef LDAP_SYSLOG
173         /* we're configured to use syslog */
174         if( use_syslog ) {
175                 syslog( debug2syslog(level), buffer );
176                 return;
177         }
178 #endif
179 #endif
180
181 #if 0
182 #ifdef HAVE_WINSOCK
183         if( log_file == NULL ) {
184                 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
185
186                 if ( log_file == NULL )
187                         log_file = fopen( "openldap.log", "w" );
188
189                 if ( log_file == NULL )
190                         return;
191
192                 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
193         }
194 #endif
195 #endif
196
197         if( file != NULL ) {
198                 /*
199                  * Use stderr unless file was specified via:
200                  *   ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file)
201                  */
202                 file = stderr;
203         }
204
205     fputs( buffer, file );
206 }
207
208 /*
209  * The primary logging routine.  Takes the subsystem being logged from, the
210  * level of the log output and the format and data.  Send this on to the
211  * internal routine with the print file, if any.
212  */
213 void lutil_log( char *subsys, int level, const char *fmt, ... )
214 {
215         FILE* outfile = NULL;
216         va_list vl;
217         va_start( vl, fmt );
218         ber_get_option( NULL, LBER_OPT_LOG_PRINT_FILE, &outfile );
219         lutil_log_int( outfile, subsys, level, fmt, vl );
220         va_end( vl );
221 }
222
223 void lutil_log_initialize(int argc, char **argv)
224 {
225     int i;
226     /*
227      * Start by setting the hook for the libraries to use this logging
228      * routine.
229      */
230     ber_set_option( NULL, LBER_OPT_LOG_PROC, (void*)lutil_log_int );
231
232     if ( argc == 0 ) return;
233     /*
234      * Now go through the command line options to set the debugging
235      * levels
236      */
237     for( i = 0; i < argc; i++ )
238     {
239         char *next = argv[i];
240         if ( i < argc-1 && next[0] == '-' && next[1] == 'd' )
241         {
242             char subsys[64];
243             int level;
244             char *optarg = argv[i+1];
245             char *index = strchr( optarg, '=' );
246             if ( index != NULL )
247             {
248                 *index = 0;
249                 strcpy ( subsys, optarg );
250                 level = atoi( index+1 );
251                 if ( level <= 0 ) level = lutil_mnem2level( index + 1 );
252                 lutil_set_debug_level( subsys, level );
253                 *index = '=';
254             }
255             else
256             {
257                 global_level = atoi( optarg );
258             }
259         }
260     }
261 }
262
263 void (lutil_debug)( int debug, int level, const char *fmt, ... )
264 {
265         char buffer[4096];
266         va_list vl;
267
268         if ( !(level & debug ) )
269                 return;
270
271 #ifdef HAVE_WINSOCK
272         if( log_file == NULL ) {
273                 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
274
275                 if ( log_file == NULL )
276                         log_file = fopen( "openldap.log", "w" );
277
278                 if ( log_file == NULL )
279                         return;
280
281                 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
282         }
283 #endif
284         va_start( vl, fmt );
285
286 #ifdef HAVE_VSNPRINTF
287         vsnprintf( buffer, sizeof(buffer), fmt, vl );
288 #else
289         vsprintf( buffer, fmt, vl );
290 #endif
291         buffer[sizeof(buffer)-1] = '\0';
292
293         if( log_file != NULL ) {
294                 fputs( buffer, log_file );
295                 fflush( log_file );
296         }
297
298     fputs( buffer, stderr );
299         va_end( vl );
300 }