configure: Changes for extra headers.
[ira/wip.git] / source3 / lib / debug.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /* -------------------------------------------------------------------------- **
25  * This module implements Samba's debugging utility.
26  *
27  * The syntax of a debugging log file is represented as:
28  *
29  *  <debugfile> :== { <debugmsg> }
30  *
31  *  <debugmsg>  :== <debughdr> '\n' <debugtext>
32  *
33  *  <debughdr>  :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
34  *
35  *  <debugtext> :== { <debugline> }
36  *
37  *  <debugline> :== TEXT '\n'
38  *
39  * TEXT     is a string of characters excluding the newline character.
40  * LEVEL    is the DEBUG level of the message (an integer in the range 0..10).
41  * TIME     is a timestamp.
42  * FILENAME is the name of the file from which the debug message was generated.
43  * FUNCTION is the function from which the debug message was generated.
44  *
45  * Basically, what that all means is:
46  *
47  * - A debugging log file is made up of debug messages.
48  *
49  * - Each debug message is made up of a header and text.  The header is
50  *   separated from the text by a newline.
51  *
52  * - The header begins with the timestamp and debug level of the message
53  *   enclosed in brackets.  The filename and function from which the
54  *   message was generated may follow.  The filename is terminated by a
55  *   colon, and the function name is terminated by parenthesis.
56  *
57  * - The message text is made up of zero or more lines, each terminated by
58  *   a newline.
59  */
60
61 /* -------------------------------------------------------------------------- **
62  * External variables.
63  *
64  *  dbf           - Global debug file handle.
65  *  debugf        - Debug file name.
66  *  append_log    - If True, then the output file will be opened in append
67  *                  mode.
68  *  DEBUGLEVEL    - System-wide debug message limit.  Messages with message-
69  *                  levels higher than DEBUGLEVEL will not be processed.
70  */
71
72 FILE   *dbf        = NULL;
73 pstring debugf     = "";
74 BOOL    append_log = False;
75 int     DEBUGLEVEL = 1;
76
77
78 /* -------------------------------------------------------------------------- **
79  * Internal variables.
80  *
81  *  stdout_logging  - Default False, if set to True then dbf will be set to
82  *                    stdout and debug output will go to dbf only, and not
83  *                    to syslog.  Set in setup_logging() and read in Debug1().
84  *
85  *  debug_count     - Number of debug messages that have been output.
86  *                    Used to check log size.
87  *
88  *  syslog_level    - Internal copy of the message debug level.  Written by
89  *                    dbghdr() and read by Debug1().
90  *
91  *  format_bufr     - Used to format debug messages.  The dbgtext() function
92  *                    prints debug messages to a string, and then passes the
93  *                    string to format_debug_text(), which uses format_bufr
94  *                    to build the formatted output.
95  *
96  *  format_pos      - Marks the first free byte of the format_bufr.
97  */
98
99 static BOOL    stdout_logging = False;
100 static int     debug_count    = 0;
101 static int     syslog_level   = 0;
102 static pstring format_bufr    = { '\0' };
103 static int     format_pos     = 0;
104
105
106 /* -------------------------------------------------------------------------- **
107  * Functions...
108  */
109
110 #if defined(SIGUSR2)
111 /* ************************************************************************** **
112  * catch a sigusr2 - decrease the debug log level.
113  * ************************************************************************** **
114  */
115 void sig_usr2( int sig )
116   {
117   BlockSignals( True, SIGUSR2 );
118
119   DEBUGLEVEL--;
120   if( DEBUGLEVEL < 0 )
121     DEBUGLEVEL = 0;
122
123   DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) );
124
125   BlockSignals( False, SIGUSR2 );
126   CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
127
128   } /* sig_usr2 */
129 #endif /* SIGUSR2 */
130
131 #if defined(SIGUSR1)
132 /* ************************************************************************** **
133  * catch a sigusr1 - increase the debug log level. 
134  * ************************************************************************** **
135  */
136 void sig_usr1( int sig )
137   {
138   BlockSignals( True, SIGUSR1 );
139
140   DEBUGLEVEL++;
141
142   if( DEBUGLEVEL > 10 )
143     DEBUGLEVEL = 10;
144
145   DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
146
147   BlockSignals( False, SIGUSR1 );
148   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
149
150   } /* sig_usr1 */
151 #endif /* SIGUSR1 */
152
153
154 /* ************************************************************************** **
155  * get ready for syslog stuff
156  * ************************************************************************** **
157  */
158 void setup_logging( char *pname, BOOL interactive )
159   {
160   if( interactive )
161     {
162     stdout_logging = True;
163     dbf = stdout;
164     }
165 #ifdef WITH_SYSLOG
166   else
167     {
168     char *p = strrchr( pname,'/' );
169
170     if( p )
171       pname = p + 1;
172 #ifdef LOG_DAEMON
173     openlog( pname, LOG_PID, SYSLOG_FACILITY );
174 #else /* for old systems that have no facility codes. */
175     openlog( pname, LOG_PID );
176 #endif
177     }
178 #endif
179   } /* setup_logging */
180
181 /* ************************************************************************** **
182  * reopen the log files
183  * ************************************************************************** **
184  */
185 void reopen_logs( void )
186   {
187   pstring fname;
188   
189   if( DEBUGLEVEL > 0 )
190     {
191     pstrcpy( fname, debugf );
192     if( lp_loaded() && (*lp_logfile()) )
193       pstrcpy( fname, lp_logfile() );
194
195     if( !strcsequal( fname, debugf ) || !dbf || !file_exist( debugf, NULL ) )
196       {
197       int oldumask = umask( 022 );
198
199       pstrcpy( debugf, fname );
200       if( dbf )
201         (void)fclose( dbf );
202       if( append_log )
203         dbf = fopen( debugf, "a" );
204       else
205         dbf = fopen( debugf, "w" );
206       /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
207        * to fix problem where smbd's that generate less
208        * than 100 messages keep growing the log.
209        */
210       force_check_log_size();
211       if( dbf )
212         setbuf( dbf, NULL );
213       (void)umask( oldumask );
214       }
215     }
216   else
217     {
218     if( dbf )
219       {
220       (void)fclose( dbf );
221       dbf = NULL;
222       }
223     }
224   } /* reopen_logs */
225
226 /* ************************************************************************** **
227  * Force a check of the log size.
228  * ************************************************************************** **
229  */
230 void force_check_log_size( void )
231   {
232   debug_count = 100;
233   } /* force_check_log_size */
234
235 /* ************************************************************************** **
236  * Check to see if the log has grown to be too big.
237  * ************************************************************************** **
238  */
239 static void check_log_size( void )
240   {
241   int         maxlog;
242   struct stat st;
243
244   if( debug_count++ < 100 || getuid() != 0 )
245     return;
246
247   maxlog = lp_max_log_size() * 1024;
248   if( !dbf || maxlog <= 0 )
249     return;
250
251   if( fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog )
252     {
253     (void)fclose( dbf );
254     dbf = NULL;
255     reopen_logs();
256     if( dbf && file_size( debugf ) > maxlog )
257       {
258       pstring name;
259
260       (void)fclose( dbf );
261       dbf = NULL;
262       slprintf( name, sizeof(name)-1, "%s.old", debugf );
263       (void)rename( debugf, name );
264       reopen_logs();
265       }
266     }
267   debug_count = 0;
268   } /* check_log_size */
269
270 /* ************************************************************************** **
271  * Write an debug message on the debugfile.
272  * This is called by dbghdr() and format_debug_text().
273  * ************************************************************************** **
274  */
275 #ifdef HAVE_STDARG_H
276  int Debug1( char *format_str, ... )
277 {
278 #else
279  int Debug1(va_alist)
280 va_dcl
281 {  
282   char *format_str;
283 #endif
284   va_list ap;  
285   int old_errno = errno;
286
287   if( stdout_logging )
288     {
289 #ifdef HAVE_STDARG_H
290     va_start( ap, format_str );
291 #else
292     va_start( ap );
293     format_str = va_arg( ap, char * );
294 #endif
295     (void)vfprintf( dbf, format_str, ap );
296     va_end( ap );
297     errno = old_errno;
298     return( 0 );
299     }
300   
301 #ifdef WITH_SYSLOG
302   if( !lp_syslog_only() )
303 #endif
304     {
305     if( !dbf )
306       {
307       int oldumask = umask( 022 );
308
309       if( append_log )
310         dbf = fopen( debugf, "a" );
311       else
312         dbf = fopen( debugf, "w" );
313       (void)umask( oldumask );
314       if( dbf )
315         {
316         setbuf( dbf, NULL );
317         }
318       else
319         {
320         errno = old_errno;
321         return(0);
322         }
323       }
324     }
325
326 #ifdef WITH_SYSLOG
327   if( syslog_level < lp_syslog() )
328     {
329     /* map debug levels to syslog() priorities
330      * note that not all DEBUG(0, ...) calls are
331      * necessarily errors
332      */
333     static int priority_map[] = { 
334       LOG_ERR,     /* 0 */
335       LOG_WARNING, /* 1 */
336       LOG_NOTICE,  /* 2 */
337       LOG_INFO,    /* 3 */
338       };
339     int     priority;
340     pstring msgbuf;
341
342     if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) )
343      || syslog_level < 0)
344       priority = LOG_DEBUG;
345     else
346       priority = priority_map[syslog_level];
347       
348 #ifdef HAVE_STDARG_H
349     va_start( ap, format_str );
350 #else
351     va_start( ap );
352     format_str = va_arg( ap, char * );
353 #endif
354     vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
355     va_end( ap );
356       
357     msgbuf[255] = '\0';
358     syslog( priority, "%s", msgbuf );
359     }
360 #endif
361   
362 #ifdef WITH_SYSLOG
363   if( !lp_syslog_only() )
364 #endif
365     {
366 #ifdef HAVE_STDARG_H
367     va_start( ap, format_str );
368 #else
369     va_start( ap );
370     format_str = va_arg( ap, char * );
371 #endif
372     (void)vfprintf( dbf, format_str, ap );
373     va_end( ap );
374     (void)fflush( dbf );
375     }
376
377   check_log_size();
378
379   errno = old_errno;
380
381   return( 0 );
382   } /* Debug1 */
383
384
385 /* ************************************************************************** **
386  * Print the buffer content via Debug1(), then reset the buffer.
387  *
388  *  Input:  none
389  *  Output: none
390  *
391  * ************************************************************************** **
392  */
393 static void bufr_print( void )
394   {
395   format_bufr[format_pos] = '\0';
396   (void)Debug1( "%s", format_bufr );
397   format_pos = 0;
398   } /* bufr_print */
399
400 /* ************************************************************************** **
401  * Format the debug message text.
402  *
403  *  Input:  msg - Text to be added to the "current" debug message text.
404  *
405  *  Output: none.
406  *
407  *  Notes:  The purpose of this is two-fold.  First, each call to syslog()
408  *          (used by Debug1(), see above) generates a new line of syslog
409  *          output.  This is fixed by storing the partial lines until the
410  *          newline character is encountered.  Second, printing the debug
411  *          message lines when a newline is encountered allows us to add
412  *          spaces, thus indenting the body of the message and making it
413  *          more readable.
414  *
415  * ************************************************************************** **
416  */
417 static void format_debug_text( char *msg )
418   {
419   int max = sizeof( format_bufr ) - 1;
420   int i;
421
422   for( i = 0; msg[i]; i++ )
423     {
424     /* Indent two spaces at each new line. */
425     if( 0 == format_pos )
426       {
427       format_bufr[0] = format_bufr[1] = ' ';
428       format_pos = 2;
429       }
430
431     /* If there's room, copy the character to the format buffer. */
432     if( format_pos < max )
433       format_bufr[format_pos++] = msg[i];
434
435     /* If a newline is encountered, print & restart. */
436     if( '\n' == msg[i] )
437       bufr_print();
438     }
439
440   /* Just to be safe... */
441   format_bufr[format_pos] = '\0';
442   } /* format_debug_text */
443
444 /* ************************************************************************** **
445  * Flush debug output, including the format buffer content.
446  *
447  *  Input:  none
448  *  Output: none
449  *
450  * ************************************************************************** **
451  */
452 void dbgflush( void )
453   {
454   bufr_print();
455   (void)fflush( dbf );
456   } /* dbgflush */
457
458 /* ************************************************************************** **
459  * Print a Debug Header.
460  *
461  *  Input:  level - Debug level of the message (not the system-wide debug
462  *                  level.
463  *          file  - Pointer to a string containing the name of the file
464  *                  from which this function was called, or an empty string
465  *                  if the __FILE__ macro is not implemented.
466  *          func  - Pointer to a string containing the name of the function
467  *                  from which this function was called, or an empty string
468  *                  if the __FUNCTION__ macro is not implemented.
469  *          line  - line number of the call to dbghdr, assuming __LINE__
470  *                  works.
471  *
472  *  Output: Always True.  This makes it easy to fudge a call to dbghdr()
473  *          in a macro, since the function can be called as part of a test.
474  *          Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
475  *
476  *  Notes:  This function takes care of setting syslog_level.
477  *
478  * ************************************************************************** **
479  */
480 BOOL dbghdr( int level, char *file, char *func, int line )
481   {
482   if( format_pos )
483     {
484     /* This is a fudge.  If there is stuff sitting in the format_bufr, then
485      * the *right* thing to do is to call
486      *   format_debug_text( "\n" );
487      * to write the remainder, and then proceed with the new header.
488      * Unfortunately, there are several places in the code at which
489      * the DEBUG() macro is used to build partial lines.  That in mind,
490      * we'll work under the assumption that an incomplete line indicates
491      * that a new header is *not* desired.
492      */
493     return( True );
494     }
495
496   /* Set syslog_level. */
497   syslog_level = level;
498
499   /* Don't print a header if we're logging to stdout. */
500   if( stdout_logging )
501     return( True );
502
503   /* Print the header if timestamps are turned on.  If parameters are
504    * not yet loaded, then default to timestamps on.
505    */
506   if( lp_timestamp_logs() || !(lp_loaded()) )
507     {
508     /* Print it all out at once to prevent split syslog output. */
509     (void)Debug1( "[%s, %d] %s:%s(%d)\n",
510                   timestring(), level, file, func, line );
511     }
512
513   return( True );
514   } /* dbghdr */
515
516 /* ************************************************************************** **
517  * Add text to the body of the "current" debug message via the format buffer.
518  *
519  *  Input:  format_str  - Format string, as used in printf(), et. al.
520  *          ...         - Variable argument list.
521  *
522  *  ..or..  va_alist    - Old style variable parameter list starting point.
523  *
524  *  Output: Always True.  See dbghdr() for more info, though this is not
525  *          likely to be used in the same way.
526  *
527  * ************************************************************************** **
528  */
529 #ifdef HAVE_STDARG_H
530  BOOL dbgtext( char *format_str, ... )
531   {
532   va_list ap;
533   pstring msgbuf;
534
535   va_start( ap, format_str ); 
536   vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
537   va_end( ap );
538
539   format_debug_text( msgbuf );
540
541   return( True );
542   } /* dbgtext */
543
544 #else
545  BOOL dbgtext( va_alist )
546  va_dcl
547   {
548   char *format_str;
549   va_list ap;
550   pstring msgbuf;
551
552   va_start( ap );
553   format_str = va_arg( ap, char * );
554   vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
555   va_end( ap );
556
557   format_debug_text( msgbuf );
558
559   return( True );
560   } /* dbgtext */
561
562 #endif
563
564 /* ************************************************************************** */