r21868: Remove check_log_size from the central smbd processing loop. This can be...
[samba.git] / source3 / lib / debug.c
1 /*
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Elrond               2002
6    Copyright (C) Simo Sorce           2002
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 /* -------------------------------------------------------------------------- **
26  * Defines...
27  *
28  *  FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
29  *                    format_bufr[FORMAT_BUFR_MAX] should always be reserved
30  *                    for a terminating null byte.
31  */
32
33 #define FORMAT_BUFR_MAX ( sizeof( format_bufr ) - 1 )
34
35 /* -------------------------------------------------------------------------- **
36  * This module implements Samba's debugging utility.
37  *
38  * The syntax of a debugging log file is represented as:
39  *
40  *  <debugfile> :== { <debugmsg> }
41  *
42  *  <debugmsg>  :== <debughdr> '\n' <debugtext>
43  *
44  *  <debughdr>  :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
45  *
46  *  <debugtext> :== { <debugline> }
47  *
48  *  <debugline> :== TEXT '\n'
49  *
50  * TEXT     is a string of characters excluding the newline character.
51  * LEVEL    is the DEBUG level of the message (an integer in the range 0..10).
52  * TIME     is a timestamp.
53  * FILENAME is the name of the file from which the debug message was generated.
54  * FUNCTION is the function from which the debug message was generated.
55  *
56  * Basically, what that all means is:
57  *
58  * - A debugging log file is made up of debug messages.
59  *
60  * - Each debug message is made up of a header and text.  The header is
61  *   separated from the text by a newline.
62  *
63  * - The header begins with the timestamp and debug level of the message
64  *   enclosed in brackets.  The filename and function from which the
65  *   message was generated may follow.  The filename is terminated by a
66  *   colon, and the function name is terminated by parenthesis.
67  *
68  * - The message text is made up of zero or more lines, each terminated by
69  *   a newline.
70  */
71
72 /* -------------------------------------------------------------------------- **
73  * External variables.
74  *
75  *  dbf           - Global debug file handle.
76  *  debugf        - Debug file name.
77  *  DEBUGLEVEL    - System-wide debug message limit.  Messages with message-
78  *                  levels higher than DEBUGLEVEL will not be processed.
79  */
80
81 XFILE   *dbf        = NULL;
82 pstring debugf     = "";
83 BOOL    debug_warn_unknown_class = True;
84 BOOL    debug_auto_add_unknown_class = True;
85 BOOL    AllowDebugChange = True;
86
87 /* 
88    used to check if the user specified a 
89    logfile on the command line 
90 */
91 BOOL    override_logfile;               
92
93
94 /*
95  * This is to allow assignment to DEBUGLEVEL before the debug
96  * system has been initialised.
97  */
98 static int debug_all_class_hack = 1;
99 static BOOL debug_all_class_isset_hack = True;
100
101 static int debug_num_classes = 0;
102 int     *DEBUGLEVEL_CLASS = &debug_all_class_hack;
103 BOOL    *DEBUGLEVEL_CLASS_ISSET = &debug_all_class_isset_hack;
104
105 /* DEBUGLEVEL is #defined to *debug_level */
106 int     DEBUGLEVEL = &debug_all_class_hack;
107
108
109 /* -------------------------------------------------------------------------- **
110  * Internal variables.
111  *
112  *  stdout_logging  - Default False, if set to True then dbf will be set to
113  *                    stdout and debug output will go to dbf only, and not
114  *                    to syslog.  Set in setup_logging() and read in Debug1().
115  *
116  *  debug_count     - Number of debug messages that have been output.
117  *                    Used to check log size.
118  *
119  *  syslog_level    - Internal copy of the message debug level.  Written by
120  *                    dbghdr() and read by Debug1().
121  *
122  *  format_bufr     - Used to format debug messages.  The dbgtext() function
123  *                    prints debug messages to a string, and then passes the
124  *                    string to format_debug_text(), which uses format_bufr
125  *                    to build the formatted output.
126  *
127  *  format_pos      - Marks the first free byte of the format_bufr.
128  * 
129  *
130  *  log_overflow    - When this variable is True, never attempt to check the
131  *                    size of the log. This is a hack, so that we can write
132  *                    a message using DEBUG, from open_logs() when we
133  *                    are unable to open a new log file for some reason.
134  */
135
136 static BOOL    stdout_logging = False;
137 static int     debug_count    = 0;
138 #ifdef WITH_SYSLOG
139 static int     syslog_level   = 0;
140 #endif
141 static pstring format_bufr    = { '\0' };
142 static size_t     format_pos     = 0;
143 static BOOL    log_overflow   = False;
144
145 /*
146  * Define all the debug class selection names here. Names *MUST NOT* contain 
147  * white space. There must be one name for each DBGC_<class name>, and they 
148  * must be in the table in the order of DBGC_<class name>.. 
149  */
150 static const char *default_classname_table[] = {
151         "all",               /* DBGC_ALL; index refs traditional DEBUGLEVEL */
152         "tdb",               /* DBGC_TDB          */
153         "printdrivers",      /* DBGC_PRINTDRIVERS */
154         "lanman",            /* DBGC_LANMAN       */
155         "smb",               /* DBGC_SMB          */
156         "rpc_parse",         /* DBGC_RPC_PARSE    */
157         "rpc_srv",           /* DBGC_RPC_SRV      */
158         "rpc_cli",           /* DBGC_RPC_CLI      */
159         "passdb",            /* DBGC_PASSDB       */
160         "sam",               /* DBGC_SAM          */
161         "auth",              /* DBGC_AUTH         */
162         "winbind",           /* DBGC_WINBIND      */
163         "vfs",               /* DBGC_VFS          */
164         "idmap",             /* DBGC_IDMAP        */
165         "quota",             /* DBGC_QUOTA        */
166         "acls",              /* DBGC_ACLS         */
167         "locking",           /* DBGC_LOCKING      */
168         "msdfs",             /* DBGC_MSDFS        */
169         "dmapi",             /* DBGC_DMAPI        */
170         NULL
171 };
172
173 static char **classname_table = NULL;
174
175
176 /* -------------------------------------------------------------------------- **
177  * Functions...
178  */
179
180 /***************************************************************************
181  Free memory pointed to by global pointers.
182 ****************************************************************************/
183
184 void gfree_debugsyms(void)
185 {
186         int i;
187
188         if ( classname_table ) {
189                 for ( i = 0; i < debug_num_classes; i++ ) {
190                         SAFE_FREE( classname_table[i] );
191                 }
192                 SAFE_FREE( classname_table );
193         }
194
195         if ( DEBUGLEVEL_CLASS != &debug_all_class_hack )
196                 SAFE_FREE( DEBUGLEVEL_CLASS );
197
198         if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack )
199                 SAFE_FREE( DEBUGLEVEL_CLASS_ISSET );
200 }
201
202 /****************************************************************************
203 utility lists registered debug class names's
204 ****************************************************************************/
205
206 #define MAX_CLASS_NAME_SIZE 1024
207
208 static char *debug_list_class_names_and_levels(void)
209 {
210         int i, dim;
211         char **list;
212         char *buf = NULL;
213         char *b;
214         BOOL err = False;
215
216         if (DEBUGLEVEL_CLASS == &debug_all_class_hack) {
217                 return NULL;
218         }
219
220         list = SMB_CALLOC_ARRAY(char *, debug_num_classes + 1);
221         if (!list) {
222                 return NULL;
223         }
224
225         /* prepare strings */
226         for (i = 0, dim = 0; i < debug_num_classes; i++) {
227                 int l = asprintf(&list[i],
228                                 "%s:%d ",
229                                 classname_table[i],
230                                 DEBUGLEVEL_CLASS_ISSET[i]?DEBUGLEVEL_CLASS[i]:DEBUGLEVEL);
231                 if (l < 0 || l > MAX_CLASS_NAME_SIZE) {
232                         err = True;
233                         goto done;
234                 }
235                 dim += l;
236         }
237
238         /* create single string list - add space for newline */
239         b = buf = (char *)SMB_MALLOC(dim+1);
240         if (!buf) {
241                 err = True;
242                 goto done;
243         }
244         for (i = 0; i < debug_num_classes; i++) {
245                 int l = strlen(list[i]);
246                 strncpy(b, list[i], l);
247                 b = b + l;
248         }
249         b[-1] = '\n'; /* replace last space with newline */
250         b[0] = '\0';  /* null terminate string */
251
252 done:
253         /* free strings list */
254         for (i = 0; i < debug_num_classes; i++) {
255                 SAFE_FREE(list[i]);
256         }
257         SAFE_FREE(list);
258
259         if (err) {
260                 return NULL;
261         } else {
262                 return buf;
263         }
264 }
265
266 /****************************************************************************
267  Utility access to debug class names's.
268 ****************************************************************************/
269
270 const char *debug_classname_from_index(int ndx)
271 {
272         if (ndx < 0 || ndx >= debug_num_classes)
273                 return NULL;
274         else
275                 return classname_table[ndx];
276 }
277
278 /****************************************************************************
279  Utility to translate names to debug class index's (internal version).
280 ****************************************************************************/
281
282 static int debug_lookup_classname_int(const char* classname)
283 {
284         int i;
285
286         if (!classname) return -1;
287
288         for (i=0; i < debug_num_classes; i++) {
289                 if (strcmp(classname, classname_table[i])==0)
290                         return i;
291         }
292         return -1;
293 }
294
295 /****************************************************************************
296  Add a new debug class to the system.
297 ****************************************************************************/
298
299 int debug_add_class(const char *classname)
300 {
301         int ndx;
302         void *new_ptr;
303
304         if (!classname)
305                 return -1;
306
307         /* check the init has yet been called */
308         debug_init();
309
310         ndx = debug_lookup_classname_int(classname);
311         if (ndx >= 0)
312                 return ndx;
313         ndx = debug_num_classes;
314
315         new_ptr = DEBUGLEVEL_CLASS;
316         if (DEBUGLEVEL_CLASS == &debug_all_class_hack) {
317                 /* Initial loading... */
318                 new_ptr = NULL;
319         }
320         new_ptr = SMB_REALLOC_ARRAY(new_ptr, int, debug_num_classes + 1);
321         if (!new_ptr)
322                 return -1;
323         DEBUGLEVEL_CLASS = (int *)new_ptr;
324         DEBUGLEVEL_CLASS[ndx] = 0;
325
326         /* debug_level is the pointer used for the DEBUGLEVEL-thingy */
327         if (ndx==0) {
328                 /* Transfer the initial level from debug_all_class_hack */
329                 DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL;
330         }
331         debug_level = DEBUGLEVEL_CLASS;
332
333         new_ptr = DEBUGLEVEL_CLASS_ISSET;
334         if (new_ptr == &debug_all_class_isset_hack) {
335                 new_ptr = NULL;
336         }
337         new_ptr = SMB_REALLOC_ARRAY(new_ptr, BOOL, debug_num_classes + 1);
338         if (!new_ptr)
339                 return -1;
340         DEBUGLEVEL_CLASS_ISSET = (int *)new_ptr;
341         DEBUGLEVEL_CLASS_ISSET[ndx] = False;
342
343         new_ptr = SMB_REALLOC_ARRAY(classname_table, char *, debug_num_classes + 1);
344         if (!new_ptr)
345                 return -1;
346         classname_table = (char **)new_ptr;
347
348         classname_table[ndx] = SMB_STRDUP(classname);
349         if (! classname_table[ndx])
350                 return -1;
351         
352         debug_num_classes++;
353
354         return ndx;
355 }
356
357 /****************************************************************************
358  Utility to translate names to debug class index's (public version).
359 ****************************************************************************/
360
361 int debug_lookup_classname(const char *classname)
362 {
363         int ndx;
364        
365         if (!classname || !*classname)
366                 return -1;
367
368         ndx = debug_lookup_classname_int(classname);
369
370         if (ndx != -1)
371                 return ndx;
372
373         if (debug_warn_unknown_class) {
374                 DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
375                           classname));
376         }
377         if (debug_auto_add_unknown_class) {
378                 return debug_add_class(classname);
379         }
380         return -1;
381 }
382
383 /****************************************************************************
384  Dump the current registered debug levels.
385 ****************************************************************************/
386
387 static void debug_dump_status(int level)
388 {
389         int q;
390
391         DEBUG(level, ("INFO: Current debug levels:\n"));
392         for (q = 0; q < debug_num_classes; q++) {
393                 DEBUGADD(level, ("  %s: %s/%d\n",
394                                  classname_table[q],
395                                  (DEBUGLEVEL_CLASS_ISSET[q]
396                                   ? "True" : "False"),
397                                  DEBUGLEVEL_CLASS[q]));
398         }
399 }
400
401 /****************************************************************************
402  parse the debug levels from smbcontrol. Example debug level parameter:
403  printdrivers:7
404 ****************************************************************************/
405
406 static BOOL debug_parse_params(char **params)
407 {
408         int   i, ndx;
409         char *class_name;
410         char *class_level;
411
412         if (!params)
413                 return False;
414
415         /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"  
416          * v.s. "all:10", this is the traditional way to set DEBUGLEVEL 
417          */
418         if (isdigit((int)params[0][0])) {
419                 DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
420                 DEBUGLEVEL_CLASS_ISSET[DBGC_ALL] = True;
421                 i = 1; /* start processing at the next params */
422         } else {
423                 i = 0; /* DBGC_ALL not specified OR class name was included */
424         }
425
426         /* Fill in new debug class levels */
427         for (; i < debug_num_classes && params[i]; i++) {
428                 if ((class_name=strtok(params[i],":")) &&
429                         (class_level=strtok(NULL, "\0")) &&
430             ((ndx = debug_lookup_classname(class_name)) != -1)) {
431                                 DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
432                                 DEBUGLEVEL_CLASS_ISSET[ndx] = True;
433                 } else {
434                         DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
435                         return False;
436                 }
437         }
438
439         return True;
440 }
441
442 /****************************************************************************
443  Parse the debug levels from smb.conf. Example debug level string:
444   3 tdb:5 printdrivers:7
445  Note: the 1st param has no "name:" preceeding it.
446 ****************************************************************************/
447
448 BOOL debug_parse_levels(const char *params_str)
449 {
450         char **params;
451
452         /* Just in case */
453         debug_init();
454
455         if (AllowDebugChange == False)
456                 return True;
457
458         params = str_list_make(params_str, NULL);
459
460         if (debug_parse_params(params)) {
461                 debug_dump_status(5);
462                 str_list_free(&params);
463                 return True;
464         } else {
465                 str_list_free(&params);
466                 return False;
467         }
468 }
469
470 /****************************************************************************
471  Receive a "set debug level" message.
472 ****************************************************************************/
473
474 static void debug_message(int msg_type, struct process_id src,
475                           void *buf, size_t len, void *private_data)
476 {
477         const char *params_str = (const char *)buf;
478
479         /* Check, it's a proper string! */
480         if (params_str[len-1] != '\0') {
481                 DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
482                           (unsigned int)procid_to_pid(&src),
483                           (unsigned int)getpid()));
484                 return;
485         }
486
487         DEBUG(3, ("INFO: Remote set of debug to `%s'  (pid %u from pid %u)\n",
488                   params_str, (unsigned int)getpid(),
489                   (unsigned int)procid_to_pid(&src)));
490
491         debug_parse_levels(params_str);
492 }
493
494 /****************************************************************************
495  Send a "set debug level" message.
496 ****************************************************************************/
497
498 void debug_message_send(pid_t pid, const char *params_str)
499 {
500         if (!params_str)
501                 return;
502         message_send_pid(pid_to_procid(pid), MSG_DEBUG,
503                          params_str, strlen(params_str) + 1,
504                          False);
505 }
506
507 /****************************************************************************
508  Return current debug level.
509 ****************************************************************************/
510
511 static void debuglevel_message(int msg_type, struct process_id src,
512                                void *buf, size_t len, void *private_data)
513 {
514         char *message = debug_list_class_names_and_levels();
515
516         if (!message) {
517                 DEBUG(0,("debuglevel_message - debug_list_class_names_and_levels returned NULL\n"));
518                 return;
519         }
520
521         DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",
522                  (unsigned int)procid_to_pid(&src)));
523         message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
524
525         SAFE_FREE(message);
526 }
527
528 /****************************************************************************
529 Init debugging (one time stuff)
530 ****************************************************************************/
531
532 void debug_init(void)
533 {
534         static BOOL initialised = False;
535         const char **p;
536
537         if (initialised)
538                 return;
539
540         initialised = True;
541
542         message_register(MSG_DEBUG, debug_message, NULL);
543         message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message, NULL);
544
545         for(p = default_classname_table; *p; p++) {
546                 debug_add_class(*p);
547         }
548 }
549
550 /***************************************************************************
551  Get ready for syslog stuff
552 **************************************************************************/
553
554 void setup_logging(const char *pname, BOOL interactive)
555 {
556         debug_init();
557
558         /* reset to allow multiple setup calls, going from interactive to
559            non-interactive */
560         stdout_logging = False;
561         if (dbf) {
562                 x_fflush(dbf);
563                 (void) x_fclose(dbf);
564         }
565
566         dbf = NULL;
567
568         if (interactive) {
569                 stdout_logging = True;
570                 dbf = x_stdout;
571                 x_setbuf( x_stdout, NULL );
572         }
573 #ifdef WITH_SYSLOG
574         else {
575                 const char *p = strrchr_m( pname,'/' );
576                 if (p)
577                         pname = p + 1;
578 #ifdef LOG_DAEMON
579                 openlog( pname, LOG_PID, SYSLOG_FACILITY );
580 #else
581                 /* for old systems that have no facility codes. */
582                 openlog( pname, LOG_PID );
583 #endif
584         }
585 #endif
586 }
587
588 /**************************************************************************
589  reopen the log files
590  note that we now do this unconditionally
591  We attempt to open the new debug fp before closing the old. This means
592  if we run out of fd's we just keep using the old fd rather than aborting.
593  Fix from dgibson@linuxcare.com.
594 **************************************************************************/
595
596 BOOL reopen_logs( void )
597 {
598         pstring fname;
599         mode_t oldumask;
600         XFILE *new_dbf = NULL;
601         XFILE *old_dbf = NULL;
602         BOOL ret = True;
603
604         if (stdout_logging)
605                 return True;
606
607         oldumask = umask( 022 );
608   
609         pstrcpy(fname, debugf );
610         debugf[0] = '\0';
611
612         if (lp_loaded()) {
613                 char *logfname;
614
615                 logfname = lp_logfile();
616                 if (*logfname)
617                         pstrcpy(fname, logfname);
618         }
619
620         pstrcpy( debugf, fname );
621         new_dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644);
622
623         if (!new_dbf) {
624                 log_overflow = True;
625                 DEBUG(0, ("Unable to open new log file %s: %s\n", debugf, strerror(errno)));
626                 log_overflow = False;
627                 if (dbf)
628                         x_fflush(dbf);
629                 ret = False;
630         } else {
631                 x_setbuf(new_dbf, NULL);
632                 old_dbf = dbf;
633                 dbf = new_dbf;
634                 if (old_dbf)
635                         (void) x_fclose(old_dbf);
636         }
637
638         /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
639          * to fix problem where smbd's that generate less
640          * than 100 messages keep growing the log.
641          */
642         force_check_log_size();
643         (void)umask(oldumask);
644
645         /* Take over stderr to catch ouput into logs */
646         if (dbf && sys_dup2(x_fileno(dbf), 2) == -1) {
647                 close_low_fds(True); /* Close stderr too, if dup2 can't point it
648                                         at the logfile */
649         }
650
651         return ret;
652 }
653
654 /**************************************************************************
655  Force a check of the log size.
656  ***************************************************************************/
657
658 void force_check_log_size( void )
659 {
660         debug_count = 100;
661 }
662
663 /***************************************************************************
664  Check to see if there is any need to check if the logfile has grown too big.
665 **************************************************************************/
666
667 BOOL need_to_check_log_size( void )
668 {
669         int maxlog;
670
671         if( debug_count < 100 )
672                 return( False );
673
674         maxlog = lp_max_log_size() * 1024;
675         if( !dbf || maxlog <= 0 ) {
676                 debug_count = 0;
677                 return(False);
678         }
679         return( True );
680 }
681
682 /**************************************************************************
683  Check to see if the log has grown to be too big.
684  **************************************************************************/
685
686 void check_log_size( void )
687 {
688         int         maxlog;
689         SMB_STRUCT_STAT st;
690
691         if(log_overflow || !need_to_check_log_size() )
692                 return;
693
694         maxlog = lp_max_log_size() * 1024;
695
696         if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
697
698                 become_root_uid_only();
699
700                 (void)reopen_logs();
701                 if( dbf && get_file_size( debugf ) > maxlog ) {
702                         pstring name;
703
704                         slprintf( name, sizeof(name)-1, "%s.old", debugf );
705                         (void)rename( debugf, name );
706       
707                         if (!reopen_logs()) {
708                                 /* We failed to reopen a log - continue using the old name. */
709                                 (void)rename(name, debugf);
710                         }
711                 }
712
713                 unbecome_root_uid_only();
714         }
715
716         /*
717          * Here's where we need to panic if dbf == NULL..
718          */
719
720         if(dbf == NULL) {
721                 /* This code should only be reached in very strange
722                  * circumstances. If we merely fail to open the new log we
723                  * should stick with the old one. ergo this should only be
724                  * reached when opening the logs for the first time: at
725                  * startup or when the log level is increased from zero.
726                  * -dwg 6 June 2000
727                  */
728                 dbf = x_fopen( "/dev/console", O_WRONLY, 0);
729                 if(dbf) {
730                         DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
731                                         debugf ));
732                 } else {
733                         /*
734                          * We cannot continue without a debug file handle.
735                          */
736                         abort();
737                 }
738         }
739         debug_count = 0;
740 }
741
742 /*************************************************************************
743  Write an debug message on the debugfile.
744  This is called by dbghdr() and format_debug_text().
745 ************************************************************************/
746
747  int Debug1( const char *format_str, ... )
748 {
749         va_list ap;  
750         int old_errno = errno;
751
752         debug_count++;
753
754         if( stdout_logging ) {
755                 va_start( ap, format_str );
756                 if(dbf)
757                         (void)x_vfprintf( dbf, format_str, ap );
758                 va_end( ap );
759                 errno = old_errno;
760                 return( 0 );
761         }
762
763         /* prevent recursion by checking if reopen_logs() has temporaily
764            set the debugf string to "" */
765         if( debugf[0] == '\0')
766                 return( 0 );
767
768 #ifdef WITH_SYSLOG
769         if( !lp_syslog_only() )
770 #endif
771         {
772                 if( !dbf ) {
773                         mode_t oldumask = umask( 022 );
774
775                         dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
776                         (void)umask( oldumask );
777                         if( dbf ) {
778                                 x_setbuf( dbf, NULL );
779                         } else {
780                                 errno = old_errno;
781                                 return(0);
782                         }
783                 }
784         }
785
786 #ifdef WITH_SYSLOG
787         if( syslog_level < lp_syslog() ) {
788                 /* map debug levels to syslog() priorities
789                  * note that not all DEBUG(0, ...) calls are
790                  * necessarily errors */
791                 static int priority_map[] = { 
792                         LOG_ERR,     /* 0 */
793                         LOG_WARNING, /* 1 */
794                         LOG_NOTICE,  /* 2 */
795                         LOG_INFO,    /* 3 */
796                 };
797                 int     priority;
798                 pstring msgbuf;
799
800                 if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) ) || syslog_level < 0)
801                         priority = LOG_DEBUG;
802                 else
803                         priority = priority_map[syslog_level];
804
805                 va_start( ap, format_str );
806                 vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
807                 va_end( ap );
808
809                 msgbuf[255] = '\0';
810                 syslog( priority, "%s", msgbuf );
811         }
812 #endif
813   
814         check_log_size();
815
816 #ifdef WITH_SYSLOG
817         if( !lp_syslog_only() )
818 #endif
819         {
820                 va_start( ap, format_str );
821                 if(dbf)
822                         (void)x_vfprintf( dbf, format_str, ap );
823                 va_end( ap );
824                 if(dbf)
825                         (void)x_fflush( dbf );
826         }
827
828         errno = old_errno;
829
830         return( 0 );
831 }
832
833
834 /**************************************************************************
835  Print the buffer content via Debug1(), then reset the buffer.
836  Input:  none
837  Output: none
838 ****************************************************************************/
839
840 static void bufr_print( void )
841 {
842         format_bufr[format_pos] = '\0';
843         (void)Debug1( "%s", format_bufr );
844         format_pos = 0;
845 }
846
847 /***************************************************************************
848  Format the debug message text.
849
850  Input:  msg - Text to be added to the "current" debug message text.
851
852  Output: none.
853
854  Notes:  The purpose of this is two-fold.  First, each call to syslog()
855          (used by Debug1(), see above) generates a new line of syslog
856          output.  This is fixed by storing the partial lines until the
857          newline character is encountered.  Second, printing the debug
858          message lines when a newline is encountered allows us to add
859          spaces, thus indenting the body of the message and making it
860          more readable.
861 **************************************************************************/
862
863 static void format_debug_text( const char *msg )
864 {
865         size_t i;
866         BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() || !(lp_loaded())));
867
868         for( i = 0; msg[i]; i++ ) {
869                 /* Indent two spaces at each new line. */
870                 if(timestamp && 0 == format_pos) {
871                         format_bufr[0] = format_bufr[1] = ' ';
872                         format_pos = 2;
873                 }
874
875                 /* If there's room, copy the character to the format buffer. */
876                 if( format_pos < FORMAT_BUFR_MAX )
877                         format_bufr[format_pos++] = msg[i];
878
879                 /* If a newline is encountered, print & restart. */
880                 if( '\n' == msg[i] )
881                         bufr_print();
882
883                 /* If the buffer is full dump it out, reset it, and put out a line
884                  * continuation indicator.
885                  */
886                 if( format_pos >= FORMAT_BUFR_MAX ) {
887                         bufr_print();
888                         (void)Debug1( " +>\n" );
889                 }
890         }
891
892         /* Just to be safe... */
893         format_bufr[format_pos] = '\0';
894 }
895
896 /***************************************************************************
897  Flush debug output, including the format buffer content.
898
899  Input:  none
900  Output: none
901 ***************************************************************************/
902
903 void dbgflush( void )
904 {
905         bufr_print();
906         if(dbf)
907                 (void)x_fflush( dbf );
908 }
909
910 /***************************************************************************
911  Print a Debug Header.
912
913  Input:  level - Debug level of the message (not the system-wide debug
914                   level. )
915           file  - Pointer to a string containing the name of the file
916                   from which this function was called, or an empty string
917                   if the __FILE__ macro is not implemented.
918           func  - Pointer to a string containing the name of the function
919                   from which this function was called, or an empty string
920                   if the __FUNCTION__ macro is not implemented.
921          line  - line number of the call to dbghdr, assuming __LINE__
922                  works.
923
924   Output: Always True.  This makes it easy to fudge a call to dbghdr()
925           in a macro, since the function can be called as part of a test.
926           Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
927
928   Notes:  This function takes care of setting syslog_level.
929
930 ****************************************************************************/
931
932 BOOL dbghdr( int level, const char *file, const char *func, int line )
933 {
934         /* Ensure we don't lose any real errno value. */
935         int old_errno = errno;
936
937         if( format_pos ) {
938                 /* This is a fudge.  If there is stuff sitting in the format_bufr, then
939                  * the *right* thing to do is to call
940                  *   format_debug_text( "\n" );
941                  * to write the remainder, and then proceed with the new header.
942                  * Unfortunately, there are several places in the code at which
943                  * the DEBUG() macro is used to build partial lines.  That in mind,
944                  * we'll work under the assumption that an incomplete line indicates
945                  * that a new header is *not* desired.
946                  */
947                 return( True );
948         }
949
950 #ifdef WITH_SYSLOG
951         /* Set syslog_level. */
952         syslog_level = level;
953 #endif
954
955         /* Don't print a header if we're logging to stdout. */
956         if( stdout_logging )
957                 return( True );
958
959         /* Print the header if timestamps are turned on.  If parameters are
960          * not yet loaded, then default to timestamps on.
961          */
962         if( lp_timestamp_logs() || lp_debug_prefix_timestamp() || !(lp_loaded()) ) {
963                 char header_str[200];
964
965                 header_str[0] = '\0';
966
967                 if( lp_debug_pid())
968                         slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)sys_getpid());
969
970                 if( lp_debug_uid()) {
971                         size_t hs_len = strlen(header_str);
972                         slprintf(header_str + hs_len,
973                         sizeof(header_str) - 1 - hs_len,
974                                 ", effective(%u, %u), real(%u, %u)",
975                                 (unsigned int)geteuid(), (unsigned int)getegid(),
976                                 (unsigned int)getuid(), (unsigned int)getgid()); 
977                 }
978   
979                 /* Print it all out at once to prevent split syslog output. */
980                 if( lp_debug_prefix_timestamp() ) {
981                     (void)Debug1( "[%s, %d%s] ",
982                         current_timestring(lp_debug_hires_timestamp()), level,
983                         header_str);
984                 } else {
985                     (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
986                         current_timestring(lp_debug_hires_timestamp()), level,
987                         header_str, file, func, line );
988                 }
989         }
990
991         errno = old_errno;
992         return( True );
993 }
994
995 /***************************************************************************
996  Add text to the body of the "current" debug message via the format buffer.
997
998   Input:  format_str  - Format string, as used in printf(), et. al.
999           ...         - Variable argument list.
1000
1001   ..or..  va_alist    - Old style variable parameter list starting point.
1002
1003   Output: Always True.  See dbghdr() for more info, though this is not
1004           likely to be used in the same way.
1005
1006 ***************************************************************************/
1007
1008  BOOL dbgtext( const char *format_str, ... )
1009 {
1010         va_list ap;
1011         pstring msgbuf;
1012
1013         va_start( ap, format_str ); 
1014         vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
1015         va_end( ap );
1016
1017         format_debug_text( msgbuf );
1018
1019   return( True );
1020 }