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