3 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright (c) 1996, 1998 by Internet Software Consortium.
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 #include <ac/stdarg.h>
28 #include <ac/string.h>
32 #include "ldap_defaults.h"
35 static FILE *log_file;
49 static struct DEBUGLEVEL **levelArray;
50 static long numLevels = 0;
54 static char *lutil_levels[] = {"emergency", "alert", "critical",
55 "error", "warning", "notice",
56 "information", "entry", "args",
57 "results", "detail1", "detail2",
60 int lutil_mnem2level( char *level )
63 for( i = 0; lutil_levels[i] != NULL; i++ )
65 if ( !strcasecmp( level, lutil_levels[i] ) )
73 static void addSubsys( const char *subsys, int level )
76 for( i = 0; i < numLevels; i++ )
78 if ( levelArray[i] == NULL )
80 levelArray[i] = (struct DEBUGLEVEL*)ber_memalloc( sizeof( struct DEBUGLEVEL ) );
81 levelArray[i]->subsystem = (char*)ber_memalloc( strlen( subsys ) + 1 );
82 strcpy ( levelArray[i]->subsystem, subsys );
83 levelArray[i]->level = level;
86 if( !strcasecmp( subsys, levelArray[i]->subsystem ) )
88 levelArray[i]->level = level;
92 levelArray = (struct DEBUGLEVEL**)ber_memrealloc( levelArray, sizeof( struct DEBUGLEVEL* ) * (numLevels + 10) );
93 for( j = numLevels; j < (numLevels + 10); j++ )
98 levelArray[i] = (struct DEBUGLEVEL*)ber_memalloc( sizeof( struct DEBUGLEVEL ) );
99 levelArray[i]->subsystem = (char*)ber_memalloc( strlen( subsys ) + 1 );
100 strcpy( levelArray[i]->subsystem, subsys );
101 levelArray[i]->level = level;
105 void lutil_set_debug_level( char* subsys, int level )
107 addSubsys( subsys, level );
110 int lutil_debug_file( FILE *file )
113 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file );
118 void lutil_log_int(FILE* file, char *subsys, int level, const char *fmt, va_list vl )
125 if ( levelArray == NULL ) return; /* logging isn't set up */
127 * Look for the subsystem in the level array. When we find it, break out of the
130 for( i = 0; i < numLevels; i++ )
132 if ( levelArray[i] == NULL ) return;
133 if ( ! strcasecmp( levelArray[i]->subsystem, subsys ) ) break;
137 * If we didn't find the subsystem, or the set level is less than
138 * the requested output level, don't output it.
140 if ( (level > global_level) &&
141 ((i > numLevels ) || ( level > levelArray[i]->level )) )
146 if( log_file == NULL ) {
147 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
149 if ( log_file == NULL )
150 log_file = fopen( "openldap.log", "w" );
152 if ( log_file == NULL )
155 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
161 * Stick the time in the buffer to output. Kurt doesn't like
162 * doing this here, but NT can't pipe to a timestamp program
163 * like Unix can, and I don't think it costs much.
166 today = localtime( &now );
167 sprintf( buffer, "%4d%02d%02d:%02d:%02d:%02d ",
168 today->tm_year + 1900, today->tm_mon + 1,
169 today->tm_mday, today->tm_hour,
170 today->tm_min, today->tm_sec );
173 * format the output data.
175 #ifdef HAVE_VSNPRINTF
176 vsnprintf( &buffer[18], sizeof(buffer)-18, fmt, vl );
178 vsprintf( &buffer[18], fmt, vl );
180 buffer[sizeof(buffer)-1] = '\0';
183 * If the user set up a file using
184 * ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file), use
185 * it. Otherwise, just output to stderr.
188 fputs( buffer, file );
193 fputs( buffer, stderr );
197 * Kurt or someone needs to decide what to do about this. This
198 * code will log to syslog if the level is less than a normal
199 * debug level (meaning a warning or error of some kind). However,
200 * having the code here means that ldap_syslog has to be defined.
204 if ( level < LDAP_LEVEL_ENTRY && level >= ldap_syslog )
206 syslog( level, buffer );
213 * The primary logging routine. Takes the subsystem being logged from, the
214 * level of the log output and the format and data. Send this on to the
215 * internal routine with the print file, if any.
217 void lutil_log( char *subsys, int level, const char *fmt, ... )
219 FILE* outfile = NULL;
222 ber_get_option( NULL, LBER_OPT_LOG_PRINT_FILE, &outfile );
223 lutil_log_int( outfile, subsys, level, fmt, vl );
227 void lutil_log_initialize(int argc, char **argv)
231 * Start by setting the hook for the libraries to use this logging
234 ber_set_option( NULL, LBER_OPT_LOG_PROC, (void*)lutil_log_int );
236 if ( argc == 0 ) return;
238 * Now go through the command line options to set the debugging
241 for( i = 0; i < argc; i++ )
243 char *next = argv[i];
244 if ( i < argc-1 && next[0] == '-' && next[1] == 'd' )
248 char *optarg = argv[i+1];
249 char *index = strchr( optarg, '=' );
253 strcpy ( subsys, optarg );
254 level = atoi( index+1 );
255 if ( level <= 0 ) level = lutil_mnem2level( index + 1 );
256 lutil_set_debug_level( subsys, level );
261 global_level = atoi( optarg );
267 void (lutil_debug)( int debug, int level, const char *fmt, ... )
272 if ( !(level & debug ) )
276 if( log_file == NULL ) {
277 log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
279 if ( log_file == NULL )
280 log_file = fopen( "openldap.log", "w" );
282 if ( log_file == NULL )
285 ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
290 #ifdef HAVE_VSNPRINTF
291 vsnprintf( buffer, sizeof(buffer), fmt, vl );
293 vsprintf( buffer, fmt, vl );
295 buffer[sizeof(buffer)-1] = '\0';
297 if( log_file != NULL ) {
298 fputs( buffer, log_file );
302 fputs( buffer, stderr );