I've added a dbgflush() function to debug.c. Calling this will cause the
[sfrench/samba-autobuild/.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 int sig_usr2( void )
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   return( 0 );
129   } /* sig_usr2 */
130 #endif /* SIGUSR2 */
131
132 #if defined(SIGUSR1)
133 /* ************************************************************************** **
134  * catch a sigusr1 - increase the debug log level. 
135  * ************************************************************************** **
136  */
137 int sig_usr1( void )
138   {
139   BlockSignals( True, SIGUSR1 );
140
141   DEBUGLEVEL++;
142
143   if( DEBUGLEVEL > 10 )
144     DEBUGLEVEL = 10;
145
146   DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
147
148   BlockSignals( False, SIGUSR1 );
149   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
150
151   return( 0 );
152   } /* sig_usr1 */
153 #endif /* SIGUSR1 */
154
155
156 /* ************************************************************************** **
157  * get ready for syslog stuff
158  * ************************************************************************** **
159  */
160 void setup_logging( char *pname, BOOL interactive )
161   {
162   if( interactive )
163     {
164     stdout_logging = True;
165     dbf = stdout;
166     }
167 #ifdef WITH_SYSLOG
168   else
169     {
170     char *p = strrchr( pname,'/' );
171
172     if( p )
173       pname = p + 1;
174 #ifdef LOG_DAEMON
175     openlog( pname, LOG_PID, SYSLOG_FACILITY );
176 #else /* for old systems that have no facility codes. */
177     openlog( pname, LOG_PID );
178 #endif
179     }
180 #endif
181   } /* setup_logging */
182
183 /* ************************************************************************** **
184  * reopen the log files
185  * ************************************************************************** **
186  */
187 void reopen_logs( void )
188   {
189   pstring fname;
190   
191   if( DEBUGLEVEL > 0 )
192     {
193     pstrcpy( fname, debugf );
194     if( lp_loaded() && (*lp_logfile()) )
195       pstrcpy( fname, lp_logfile() );
196
197     if( !strcsequal( fname, debugf ) || !dbf || !file_exist( debugf, NULL ) )
198       {
199       int oldumask = umask( 022 );
200
201       pstrcpy( debugf, fname );
202       if( dbf )
203         (void)fclose( dbf );
204       if( append_log )
205         dbf = fopen( debugf, "a" );
206       else
207         dbf = fopen( debugf, "w" );
208       /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
209        * to fix problem where smbd's that generate less
210        * than 100 messages keep growing the log.
211        */
212       force_check_log_size();
213       if( dbf )
214         setbuf( dbf, NULL );
215       (void)umask( oldumask );
216       }
217     }
218   else
219     {
220     if( dbf )
221       {
222       (void)fclose( dbf );
223       dbf = NULL;
224       }
225     }
226   } /* reopen_logs */
227
228 /* ************************************************************************** **
229  * Force a check of the log size.
230  * ************************************************************************** **
231  */
232 void force_check_log_size( void )
233   {
234   debug_count = 100;
235   } /* force_check_log_size */
236
237 /* ************************************************************************** **
238  * Check to see if the log has grown to be too big.
239  * ************************************************************************** **
240  */
241 static void check_log_size( void )
242   {
243   int         maxlog;
244   struct stat st;
245
246   if( debug_count++ < 100 || getuid() != 0 )
247     return;
248
249   maxlog = lp_max_log_size() * 1024;
250   if( !dbf || maxlog <= 0 )
251     return;
252
253   if( fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog )
254     {
255     (void)fclose( dbf );
256     dbf = NULL;
257     reopen_logs();
258     if( dbf && file_size( debugf ) > maxlog )
259       {
260       pstring name;
261
262       (void)fclose( dbf );
263       dbf = NULL;
264       slprintf( name, sizeof(name)-1, "%s.old", debugf );
265       (void)rename( debugf, name );
266       reopen_logs();
267       }
268     }
269   debug_count = 0;
270   } /* check_log_size */
271
272 /* ************************************************************************** **
273  * Write an debug message on the debugfile.
274  * This is called by dbghdr() and format_debug_text().
275  * ************************************************************************** **
276  */
277 #ifdef HAVE_STDARG_H
278  int Debug1( char *format_str, ... )
279 {
280 #else
281  int Debug1(va_alist)
282 va_dcl
283 {  
284   char *format_str;
285 #endif
286   va_list ap;  
287   int old_errno = errno;
288
289   if( stdout_logging )
290     {
291 #ifdef HAVE_STDARG_H
292     va_start( ap, format_str );
293 #else
294     va_start( ap );
295     format_str = va_arg( ap, char * );
296 #endif
297     (void)vfprintf( dbf, format_str, ap );
298     va_end( ap );
299     errno = old_errno;
300     return( 0 );
301     }
302   
303 #ifdef WITH_SYSLOG
304   if( !lp_syslog_only() )
305 #endif
306     {
307     if( !dbf )
308       {
309       int oldumask = umask( 022 );
310
311       if( append_log )
312         dbf = fopen( debugf, "a" );
313       else
314         dbf = fopen( debugf, "w" );
315       (void)umask( oldumask );
316       if( dbf )
317         {
318         setbuf( dbf, NULL );
319         }
320       else
321         {
322         errno = old_errno;
323         return(0);
324         }
325       }
326     }
327
328 #ifdef WITH_SYSLOG
329   if( syslog_level < lp_syslog() )
330     {
331     /* map debug levels to syslog() priorities
332      * note that not all DEBUG(0, ...) calls are
333      * necessarily errors
334      */
335     static int priority_map[] = { 
336       LOG_ERR,     /* 0 */
337       LOG_WARNING, /* 1 */
338       LOG_NOTICE,  /* 2 */
339       LOG_INFO,    /* 3 */
340       };
341     int     priority;
342     pstring msgbuf;
343
344     if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) )
345      || syslog_level < 0)
346       priority = LOG_DEBUG;
347     else
348       priority = priority_map[syslog_level];
349       
350 #ifdef HAVE_STDARG_H
351     va_start( ap, format_str );
352 #else
353     va_start( ap );
354     format_str = va_arg( ap, char * );
355 #endif
356     vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
357     va_end( ap );
358       
359     msgbuf[255] = '\0';
360     syslog( priority, "%s", msgbuf );
361     }
362 #endif
363   
364 #ifdef WITH_SYSLOG
365   if( !lp_syslog_only() )
366 #endif
367     {
368 #ifdef HAVE_STDARG_H
369     va_start( ap, format_str );
370 #else
371     va_start( ap );
372     format_str = va_arg( ap, char * );
373 #endif
374     (void)vfprintf( dbf, format_str, ap );
375     va_end( ap );
376     (void)fflush( dbf );
377     }
378
379   check_log_size();
380
381   errno = old_errno;
382
383   return( 0 );
384   } /* Debug1 */
385
386
387 /* ************************************************************************** **
388  * Print the buffer content via Debug1(), then reset the buffer.
389  *
390  *  Input:  none
391  *  Output: none
392  *
393  * ************************************************************************** **
394  */
395 static void bufr_print( void )
396   {
397   format_bufr[format_pos] = '\0';
398   (void)Debug1( "%s", format_bufr );
399   format_pos = 0;
400   } /* bufr_print */
401
402 /* ************************************************************************** **
403  * Format the debug message text.
404  *
405  *  Input:  msg - Text to be added to the "current" debug message text.
406  *
407  *  Output: none.
408  *
409  *  Notes:  The purpose of this is two-fold.  First, each call to syslog()
410  *          (used by Debug1(), see above) generates a new line of syslog
411  *          output.  This is fixed by storing the partial lines until the
412  *          newline character is encountered.  Second, printing the debug
413  *          message lines when a newline is encountered allows us to add
414  *          spaces, thus indenting the body of the message and making it
415  *          more readable.
416  *
417  * ************************************************************************** **
418  */
419 static void format_debug_text( char *msg )
420   {
421   int max = sizeof( format_bufr ) - 1;
422   int i;
423
424   for( i = 0; msg[i]; i++ )
425     {
426     /* Indent two spaces at each new line. */
427     if( 0 == format_pos )
428       {
429       format_bufr[0] = format_bufr[1] = ' ';
430       format_pos = 2;
431       }
432
433     /* If there's room, copy the character to the format buffer. */
434     if( format_pos < max )
435       format_bufr[format_pos++] = msg[i];
436
437     /* If a newline is encountered, print & restart. */
438     if( '\n' == msg[i] )
439       bufr_print();
440     }
441
442   /* Just to be safe... */
443   format_bufr[format_pos] = '\0';
444   } /* format_debug_text */
445
446 /* ************************************************************************** **
447  * Flush debug output, including the format buffer content.
448  *
449  *  Input:  none
450  *  Output: none
451  *
452  * ************************************************************************** **
453  */
454 void dbgflush( void )
455   {
456   bufr_print();
457   (void)fflush( dbf );
458   } /* dbgflush */
459
460 /* ************************************************************************** **
461  * Print a Debug Header.
462  *
463  *  Input:  level - Debug level of the message (not the system-wide debug
464  *                  level.
465  *          file  - Pointer to a string containing the name of the file
466  *                  from which this function was called, or an empty string
467  *                  if the __FILE__ macro is not implemented.
468  *          func  - Pointer to a string containing the name of the function
469  *                  from which this function was called, or an empty string
470  *                  if the __FUNCTION__ macro is not implemented.
471  *          line  - line number of the call to dbghdr, assuming __LINE__
472  *                  works.
473  *
474  *  Output: Always True.  This makes it easy to fudge a call to dbghdr()
475  *          in a macro, since the function can be called as part of a test.
476  *          Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
477  *
478  *  Notes:  This function takes care of setting syslog_level.
479  *
480  * ************************************************************************** **
481  */
482 BOOL dbghdr( int level, char *file, char *func, int line )
483   {
484   if( format_pos )
485     {
486     /* This is a fudge.  If there is stuff sitting in the format_bufr, then
487      * the *right* thing to do is to call
488      *   format_debug_text( "\n" );
489      * to write the remainder, and then proceed with the new header.
490      * Unfortunately, there are several places in the code at which
491      * the DEBUG() macro is used to build partial lines.  That in mind,
492      * we'll work under the assumption that an incomplete line indicates
493      * that a new header is *not* desired.
494      */
495     return( True );
496     }
497
498   /* Set syslog_level. */
499   syslog_level = level;
500
501   /* Don't print a header if we're logging to stdout. */
502   if( stdout_logging )
503     return( True );
504
505   /* Print the header if timestamps are turned on.  If parameters are
506    * not yet loaded, then default to timestamps on.
507    */
508   if( lp_timestamp_logs() || !(lp_loaded()) )
509     {
510     /* Print it all out at once to prevent split syslog output. */
511     (void)Debug1( "[%s, %d] %s:%s(%d)\n",
512                   timestring(), level, file, func, line );
513     }
514
515   return( True );
516   } /* dbghdr */
517
518 /* ************************************************************************** **
519  * Add text to the body of the "current" debug message via the format buffer.
520  *
521  *  Input:  format_str  - Format string, as used in printf(), et. al.
522  *          ...         - Variable argument list.
523  *
524  *  ..or..  va_alist    - Old style variable parameter list starting point.
525  *
526  *  Output: Always True.  See dbghdr() for more info, though this is not
527  *          likely to be used in the same way.
528  *
529  * ************************************************************************** **
530  */
531 #ifdef HAVE_STDARG_H
532  BOOL dbgtext( char *format_str, ... )
533   {
534   va_list ap;
535   pstring msgbuf;
536
537   va_start( ap, format_str ); 
538   vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
539   va_end( ap );
540
541   format_debug_text( msgbuf );
542
543   return( True );
544   } /* dbgtext */
545
546 #else
547  BOOL dbgtext( va_alist )
548  va_dcl
549   {
550   char *format_str;
551   va_list ap;
552   pstring msgbuf;
553
554   va_start( ap );
555   format_str = va_arg( ap, char * );
556   vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
557   va_end( ap );
558
559   format_debug_text( msgbuf );
560
561   return( True );
562   } /* dbgtext */
563
564 #endif
565
566 /* ************************************************************************** */