3 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/stdarg.h>
13 #include <ac/string.h>
17 #include "ldap_defaults.h"
32 static struct DEBUGLEVEL **levelArray;
33 static long numLevels = 0;
35 static FILE *log_file = NULL;
36 static int global_level = 0;
40 static int use_syslog = 0;
42 static int debug2syslog(int l) {
44 /* insert mapping cases here */
52 static char *lutil_levels[] = {"emergency", "alert", "critical",
53 "error", "warning", "notice",
54 "information", "entry", "args",
55 "results", "detail1", "detail2",
58 int lutil_mnem2level( char *level )
61 for( i = 0; lutil_levels[i] != NULL; i++ )
63 if ( !strcasecmp( level, lutil_levels[i] ) )
71 static void addSubsys( const char *subsys, int level )
74 for( i = 0; i < numLevels; i++ )
76 if ( levelArray[i] == NULL )
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;
84 if( !strcasecmp( subsys, levelArray[i]->subsystem ) )
86 levelArray[i]->level = level;
90 levelArray = (struct DEBUGLEVEL**)ber_memrealloc( levelArray, sizeof( struct DEBUGLEVEL* ) * (numLevels + 10) );
91 for( j = numLevels; j < (numLevels + 10); j++ )
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;
103 void lutil_set_debug_level( char* subsys, int level )
105 addSubsys( subsys, level );
108 int lutil_debug_file( FILE *file )
111 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file );
116 void lutil_log_int(FILE* file, char *subsys, int level, const char *fmt, va_list vl )
123 if ( levelArray == NULL ) return; /* logging isn't set up */
126 * Look for the subsystem in the level array. When we find it,
127 * break out of the loop.
129 for( i = 0; i < numLevels; i++ ) {
130 if ( levelArray[i] == NULL ) return;
131 if ( ! strcasecmp( levelArray[i]->subsystem, subsys ) ) break;
135 * If we didn't find the subsystem, or the set level is less than
136 * the requested output level, don't output it.
138 if ( (level > global_level) &&
139 ((i > numLevels ) || ( level > levelArray[i]->level )) )
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.
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 );
162 * format the output data.
164 #ifdef HAVE_VSNPRINTF
165 vsnprintf( &buffer[BUFOFFSET], sizeof(buffer)-BUFOFFSET, fmt, vl );
167 vsprintf( &buffer[BUFOFFSET], fmt, vl );
169 buffer[sizeof(buffer)-1] = '\0';
173 /* we're configured to use syslog */
175 syslog( debug2syslog(level), buffer );
183 if( log_file == NULL ) {
184 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
186 if ( log_file == NULL )
187 log_file = fopen( "openldap.log", "w" );
189 if ( log_file == NULL )
192 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
199 * Use stderr unless file was specified via:
200 * ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file)
205 fputs( buffer, file );
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.
213 void lutil_log( char *subsys, int level, const char *fmt, ... )
215 FILE* outfile = NULL;
218 ber_get_option( NULL, LBER_OPT_LOG_PRINT_FILE, &outfile );
219 lutil_log_int( outfile, subsys, level, fmt, vl );
223 void lutil_log_initialize(int argc, char **argv)
227 * Start by setting the hook for the libraries to use this logging
230 ber_set_option( NULL, LBER_OPT_LOG_PROC, (void*)lutil_log_int );
232 if ( argc == 0 ) return;
234 * Now go through the command line options to set the debugging
237 for( i = 0; i < argc; i++ )
239 char *next = argv[i];
240 if ( i < argc-1 && next[0] == '-' && next[1] == 'd' )
244 char *optarg = argv[i+1];
245 char *index = strchr( optarg, '=' );
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 );
257 global_level = atoi( optarg );
263 void (lutil_debug)( int debug, int level, const char *fmt, ... )
268 if ( !(level & debug ) )
272 if( log_file == NULL ) {
273 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
275 if ( log_file == NULL )
276 log_file = fopen( "openldap.log", "w" );
278 if ( log_file == NULL )
281 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
286 #ifdef HAVE_VSNPRINTF
287 vsnprintf( buffer, sizeof(buffer), fmt, vl );
289 vsprintf( buffer, fmt, vl );
291 buffer[sizeof(buffer)-1] = '\0';
293 if( log_file != NULL ) {
294 fputs( buffer, log_file );
298 fputs( buffer, stderr );