r8428: some more old printerdb stuff.
[sfrench/samba-autobuild/.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         NULL
170 };
171
172 static char **classname_table = NULL;
173
174
175 /* -------------------------------------------------------------------------- **
176  * Functions...
177  */
178
179
180 /****************************************************************************
181 utility lists registered debug class names's
182 ****************************************************************************/
183
184 #define MAX_CLASS_NAME_SIZE 1024
185
186 static char *debug_list_class_names_and_levels(void)
187 {
188         int i, dim;
189         char **list;
190         char *buf = NULL;
191         char *b;
192         BOOL err = False;
193
194         if (DEBUGLEVEL_CLASS == &debug_all_class_hack)
195                 return NULL;
196
197         list = SMB_CALLOC_ARRAY(char *, debug_num_classes + 1);
198         if (!list)
199                 return NULL;
200
201         /* prepare strings */
202         for (i = 0, dim = 0; i < debug_num_classes; i++) {
203                 int l = asprintf(&list[i],
204                                 "%s:%d ",
205                                 classname_table[i],
206                                 DEBUGLEVEL_CLASS_ISSET[i]?DEBUGLEVEL_CLASS[i]:DEBUGLEVEL);
207                 if (l < 0 || l > MAX_CLASS_NAME_SIZE) {
208                         err = True;
209                         goto done;
210                 }
211                 dim += l;
212         }
213
214         /* create single string list - add space for newline */
215         b = buf = SMB_MALLOC(dim+1);
216         if (!buf) {
217                 err = True;
218                 goto done;
219         }
220         for (i = 0; i < debug_num_classes; i++) {
221                 int l = strlen(list[i]);
222                 strncpy(b, list[i], l);
223                 b = b + l;
224         }
225         b[-1] = '\n'; /* replace last space with newline */
226         b[0] = '\0';  /* null terminate string */
227
228 done:
229         /* free strings list */
230         for (i = 0; i < debug_num_classes; i++)
231                 if (list[i]) free(list[i]);
232         free(list);
233
234         if (err) {
235                 if (buf)
236                         free(buf);
237                 return NULL;
238         } else {
239                 return buf;
240         }
241 }
242
243 /****************************************************************************
244  Utility access to debug class names's.
245 ****************************************************************************/
246
247 const char *debug_classname_from_index(int ndx)
248 {
249         if (ndx < 0 || ndx >= debug_num_classes)
250                 return NULL;
251         else
252                 return classname_table[ndx];
253 }
254
255 /****************************************************************************
256  Utility to translate names to debug class index's (internal version).
257 ****************************************************************************/
258
259 static int debug_lookup_classname_int(const char* classname)
260 {
261         int i;
262
263         if (!classname) return -1;
264
265         for (i=0; i < debug_num_classes; i++) {
266                 if (strcmp(classname, classname_table[i])==0)
267                         return i;
268         }
269         return -1;
270 }
271
272 /****************************************************************************
273  Add a new debug class to the system.
274 ****************************************************************************/
275
276 int debug_add_class(const char *classname)
277 {
278         int ndx;
279         void *new_ptr;
280
281         if (!classname)
282                 return -1;
283
284         /* check the init has yet been called */
285         debug_init();
286
287         ndx = debug_lookup_classname_int(classname);
288         if (ndx >= 0)
289                 return ndx;
290         ndx = debug_num_classes;
291
292         new_ptr = DEBUGLEVEL_CLASS;
293         if (DEBUGLEVEL_CLASS == &debug_all_class_hack) {
294                 /* Initial loading... */
295                 new_ptr = NULL;
296         }
297         new_ptr = SMB_REALLOC_ARRAY(new_ptr, int, debug_num_classes + 1);
298         if (!new_ptr)
299                 return -1;
300         DEBUGLEVEL_CLASS = new_ptr;
301         DEBUGLEVEL_CLASS[ndx] = 0;
302
303         /* debug_level is the pointer used for the DEBUGLEVEL-thingy */
304         if (ndx==0) {
305                 /* Transfer the initial level from debug_all_class_hack */
306                 DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL;
307         }
308         debug_level = DEBUGLEVEL_CLASS;
309
310         new_ptr = DEBUGLEVEL_CLASS_ISSET;
311         if (new_ptr == &debug_all_class_isset_hack) {
312                 new_ptr = NULL;
313         }
314         new_ptr = SMB_REALLOC_ARRAY(new_ptr, BOOL, debug_num_classes + 1);
315         if (!new_ptr)
316                 return -1;
317         DEBUGLEVEL_CLASS_ISSET = new_ptr;
318         DEBUGLEVEL_CLASS_ISSET[ndx] = False;
319
320         new_ptr = SMB_REALLOC_ARRAY(classname_table, char *, debug_num_classes + 1);
321         if (!new_ptr)
322                 return -1;
323         classname_table = new_ptr;
324
325         classname_table[ndx] = SMB_STRDUP(classname);
326         if (! classname_table[ndx])
327                 return -1;
328         
329         debug_num_classes++;
330
331         return ndx;
332 }
333
334 /****************************************************************************
335  Utility to translate names to debug class index's (public version).
336 ****************************************************************************/
337
338 int debug_lookup_classname(const char *classname)
339 {
340         int ndx;
341        
342         if (!classname || !*classname)
343                 return -1;
344
345         ndx = debug_lookup_classname_int(classname);
346
347         if (ndx != -1)
348                 return ndx;
349
350         if (debug_warn_unknown_class) {
351                 DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
352                           classname));
353         }
354         if (debug_auto_add_unknown_class) {
355                 return debug_add_class(classname);
356         }
357         return -1;
358 }
359
360 /****************************************************************************
361  Dump the current registered debug levels.
362 ****************************************************************************/
363
364 static void debug_dump_status(int level)
365 {
366         int q;
367
368         DEBUG(level, ("INFO: Current debug levels:\n"));
369         for (q = 0; q < debug_num_classes; q++) {
370                 DEBUGADD(level, ("  %s: %s/%d\n",
371                                  classname_table[q],
372                                  (DEBUGLEVEL_CLASS_ISSET[q]
373                                   ? "True" : "False"),
374                                  DEBUGLEVEL_CLASS[q]));
375         }
376 }
377
378 /****************************************************************************
379  parse the debug levels from smbcontrol. Example debug level parameter:
380  printdrivers:7
381 ****************************************************************************/
382
383 static BOOL debug_parse_params(char **params)
384 {
385         int   i, ndx;
386         char *class_name;
387         char *class_level;
388
389         if (!params)
390                 return False;
391
392         /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"  
393          * v.s. "all:10", this is the traditional way to set DEBUGLEVEL 
394          */
395         if (isdigit((int)params[0][0])) {
396                 DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
397                 DEBUGLEVEL_CLASS_ISSET[DBGC_ALL] = True;
398                 i = 1; /* start processing at the next params */
399         } else {
400                 i = 0; /* DBGC_ALL not specified OR class name was included */
401         }
402
403         /* Fill in new debug class levels */
404         for (; i < debug_num_classes && params[i]; i++) {
405                 if ((class_name=strtok(params[i],":")) &&
406                         (class_level=strtok(NULL, "\0")) &&
407             ((ndx = debug_lookup_classname(class_name)) != -1)) {
408                                 DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
409                                 DEBUGLEVEL_CLASS_ISSET[ndx] = True;
410                 } else {
411                         DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
412                         return False;
413                 }
414         }
415
416         return True;
417 }
418
419 /****************************************************************************
420  Parse the debug levels from smb.conf. Example debug level string:
421   3 tdb:5 printdrivers:7
422  Note: the 1st param has no "name:" preceeding it.
423 ****************************************************************************/
424
425 BOOL debug_parse_levels(const char *params_str)
426 {
427         char **params;
428
429         /* Just in case */
430         debug_init();
431
432         if (AllowDebugChange == False)
433                 return True;
434
435         params = str_list_make(params_str, NULL);
436
437         if (debug_parse_params(params)) {
438                 debug_dump_status(5);
439                 str_list_free(&params);
440                 return True;
441         } else {
442                 str_list_free(&params);
443                 return False;
444         }
445 }
446
447 /****************************************************************************
448  Receive a "set debug level" message.
449 ****************************************************************************/
450
451 static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
452 {
453         const char *params_str = buf;
454
455         /* Check, it's a proper string! */
456         if (params_str[len-1] != '\0') {
457                 DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
458                           (unsigned int)src, (unsigned int)getpid()));
459                 return;
460         }
461
462         DEBUG(3, ("INFO: Remote set of debug to `%s'  (pid %u from pid %u)\n",
463                   params_str, (unsigned int)getpid(), (unsigned int)src));
464
465         debug_parse_levels(params_str);
466 }
467
468 /****************************************************************************
469  Send a "set debug level" message.
470 ****************************************************************************/
471
472 void debug_message_send(pid_t pid, const char *params_str)
473 {
474         if (!params_str)
475                 return;
476         message_send_pid(pid, MSG_DEBUG, params_str, strlen(params_str) + 1,
477                          False);
478 }
479
480 /****************************************************************************
481  Return current debug level.
482 ****************************************************************************/
483
484 static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
485 {
486         char *message = debug_list_class_names_and_levels();
487
488         DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
489         message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
490
491         SAFE_FREE(message);
492 }
493
494 /****************************************************************************
495 Init debugging (one time stuff)
496 ****************************************************************************/
497
498 void debug_init(void)
499 {
500         static BOOL initialised = False;
501         const char **p;
502
503         if (initialised)
504                 return;
505         
506         initialised = True;
507
508         message_register(MSG_DEBUG, debug_message);
509         message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message);
510
511         for(p = default_classname_table; *p; p++) {
512                 debug_add_class(*p);
513         }
514 }
515
516 /***************************************************************************
517  Get ready for syslog stuff
518 **************************************************************************/
519
520 void setup_logging(const char *pname, BOOL interactive)
521 {
522         debug_init();
523
524         /* reset to allow multiple setup calls, going from interactive to
525            non-interactive */
526         stdout_logging = False;
527         if (dbf) {
528                 x_fflush(dbf);
529                 (void) x_fclose(dbf);
530         }
531
532         dbf = NULL;
533
534         if (interactive) {
535                 stdout_logging = True;
536                 dbf = x_stdout;
537                 x_setbuf( x_stdout, NULL );
538         }
539 #ifdef WITH_SYSLOG
540         else {
541                 const char *p = strrchr_m( pname,'/' );
542                 if (p)
543                         pname = p + 1;
544 #ifdef LOG_DAEMON
545                 openlog( pname, LOG_PID, SYSLOG_FACILITY );
546 #else
547                 /* for old systems that have no facility codes. */
548                 openlog( pname, LOG_PID );
549 #endif
550         }
551 #endif
552 }
553
554 /**************************************************************************
555  reopen the log files
556  note that we now do this unconditionally
557  We attempt to open the new debug fp before closing the old. This means
558  if we run out of fd's we just keep using the old fd rather than aborting.
559  Fix from dgibson@linuxcare.com.
560 **************************************************************************/
561
562 BOOL reopen_logs( void )
563 {
564         pstring fname;
565         mode_t oldumask;
566         XFILE *new_dbf = NULL;
567         XFILE *old_dbf = NULL;
568         BOOL ret = True;
569
570         if (stdout_logging)
571                 return True;
572
573         oldumask = umask( 022 );
574   
575         pstrcpy(fname, debugf );
576         debugf[0] = '\0';
577
578         if (lp_loaded()) {
579                 char *logfname;
580
581                 logfname = lp_logfile();
582                 if (*logfname)
583                         pstrcpy(fname, logfname);
584         }
585
586         pstrcpy( debugf, fname );
587         new_dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644);
588
589         if (!new_dbf) {
590                 log_overflow = True;
591                 DEBUG(0, ("Unable to open new log file %s: %s\n", debugf, strerror(errno)));
592                 log_overflow = False;
593                 if (dbf)
594                         x_fflush(dbf);
595                 ret = False;
596         } else {
597                 x_setbuf(new_dbf, NULL);
598                 old_dbf = dbf;
599                 dbf = new_dbf;
600                 if (old_dbf)
601                         (void) x_fclose(old_dbf);
602         }
603
604         /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
605          * to fix problem where smbd's that generate less
606          * than 100 messages keep growing the log.
607          */
608         force_check_log_size();
609         (void)umask(oldumask);
610
611         /* Take over stderr to catch ouput into logs */
612         if (dbf && sys_dup2(x_fileno(dbf), 2) == -1) {
613                 close_low_fds(True); /* Close stderr too, if dup2 can't point it
614                                         at the logfile */
615         }
616
617         return ret;
618 }
619
620 /**************************************************************************
621  Force a check of the log size.
622  ***************************************************************************/
623
624 void force_check_log_size( void )
625 {
626         debug_count = 100;
627 }
628
629 /***************************************************************************
630  Check to see if there is any need to check if the logfile has grown too big.
631 **************************************************************************/
632
633 BOOL need_to_check_log_size( void )
634 {
635         int maxlog;
636
637         if( debug_count < 100 )
638                 return( False );
639
640         maxlog = lp_max_log_size() * 1024;
641         if( !dbf || maxlog <= 0 ) {
642                 debug_count = 0;
643                 return(False);
644         }
645         return( True );
646 }
647
648 /**************************************************************************
649  Check to see if the log has grown to be too big.
650  **************************************************************************/
651
652 void check_log_size( void )
653 {
654         int         maxlog;
655         SMB_STRUCT_STAT st;
656
657         /*
658          *  We need to be root to check/change log-file, skip this and let the main
659          *  loop check do a new check as root.
660          */
661
662         if( geteuid() != 0 )
663                 return;
664
665         if(log_overflow || !need_to_check_log_size() )
666                 return;
667
668         maxlog = lp_max_log_size() * 1024;
669
670         if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
671                 (void)reopen_logs();
672                 if( dbf && get_file_size( debugf ) > maxlog ) {
673                         pstring name;
674
675                         slprintf( name, sizeof(name)-1, "%s.old", debugf );
676                         (void)rename( debugf, name );
677       
678                         if (!reopen_logs()) {
679                                 /* We failed to reopen a log - continue using the old name. */
680                                 (void)rename(name, debugf);
681                         }
682                 }
683         }
684
685         /*
686          * Here's where we need to panic if dbf == NULL..
687          */
688
689         if(dbf == NULL) {
690                 /* This code should only be reached in very strange
691                  * circumstances. If we merely fail to open the new log we
692                  * should stick with the old one. ergo this should only be
693                  * reached when opening the logs for the first time: at
694                  * startup or when the log level is increased from zero.
695                  * -dwg 6 June 2000
696                  */
697                 dbf = x_fopen( "/dev/console", O_WRONLY, 0);
698                 if(dbf) {
699                         DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
700                                         debugf ));
701                 } else {
702                         /*
703                          * We cannot continue without a debug file handle.
704                          */
705                         abort();
706                 }
707         }
708         debug_count = 0;
709 }
710
711 /*************************************************************************
712  Write an debug message on the debugfile.
713  This is called by dbghdr() and format_debug_text().
714 ************************************************************************/
715
716  int Debug1( const char *format_str, ... )
717 {
718         va_list ap;  
719         int old_errno = errno;
720
721         debug_count++;
722
723         if( stdout_logging ) {
724                 va_start( ap, format_str );
725                 if(dbf)
726                         (void)x_vfprintf( dbf, format_str, ap );
727                 va_end( ap );
728                 errno = old_errno;
729                 return( 0 );
730         }
731
732         /* prevent recursion by checking if reopen_logs() has temporaily
733            set the debugf string to "" */
734         if( debugf[0] == '\0')
735                 return( 0 );
736
737 #ifdef WITH_SYSLOG
738         if( !lp_syslog_only() )
739 #endif
740         {
741                 if( !dbf ) {
742                         mode_t oldumask = umask( 022 );
743
744                         dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
745                         (void)umask( oldumask );
746                         if( dbf ) {
747                                 x_setbuf( dbf, NULL );
748                         } else {
749                                 errno = old_errno;
750                                 return(0);
751                         }
752                 }
753         }
754
755 #ifdef WITH_SYSLOG
756         if( syslog_level < lp_syslog() ) {
757                 /* map debug levels to syslog() priorities
758                  * note that not all DEBUG(0, ...) calls are
759                  * necessarily errors */
760                 static int priority_map[] = { 
761                         LOG_ERR,     /* 0 */
762                         LOG_WARNING, /* 1 */
763                         LOG_NOTICE,  /* 2 */
764                         LOG_INFO,    /* 3 */
765                 };
766                 int     priority;
767                 pstring msgbuf;
768
769                 if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) ) || syslog_level < 0)
770                         priority = LOG_DEBUG;
771                 else
772                         priority = priority_map[syslog_level];
773
774                 va_start( ap, format_str );
775                 vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
776                 va_end( ap );
777
778                 msgbuf[255] = '\0';
779                 syslog( priority, "%s", msgbuf );
780         }
781 #endif
782   
783         check_log_size();
784
785 #ifdef WITH_SYSLOG
786         if( !lp_syslog_only() )
787 #endif
788         {
789                 va_start( ap, format_str );
790                 if(dbf)
791                         (void)x_vfprintf( dbf, format_str, ap );
792                 va_end( ap );
793                 if(dbf)
794                         (void)x_fflush( dbf );
795         }
796
797         errno = old_errno;
798
799         return( 0 );
800 }
801
802
803 /**************************************************************************
804  Print the buffer content via Debug1(), then reset the buffer.
805  Input:  none
806  Output: none
807 ****************************************************************************/
808
809 static void bufr_print( void )
810 {
811         format_bufr[format_pos] = '\0';
812         (void)Debug1( "%s", format_bufr );
813         format_pos = 0;
814 }
815
816 /***************************************************************************
817  Format the debug message text.
818
819  Input:  msg - Text to be added to the "current" debug message text.
820
821  Output: none.
822
823  Notes:  The purpose of this is two-fold.  First, each call to syslog()
824          (used by Debug1(), see above) generates a new line of syslog
825          output.  This is fixed by storing the partial lines until the
826          newline character is encountered.  Second, printing the debug
827          message lines when a newline is encountered allows us to add
828          spaces, thus indenting the body of the message and making it
829          more readable.
830 **************************************************************************/
831
832 static void format_debug_text( const char *msg )
833 {
834         size_t i;
835         BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() || !(lp_loaded())));
836
837         for( i = 0; msg[i]; i++ ) {
838                 /* Indent two spaces at each new line. */
839                 if(timestamp && 0 == format_pos) {
840                         format_bufr[0] = format_bufr[1] = ' ';
841                         format_pos = 2;
842                 }
843
844                 /* If there's room, copy the character to the format buffer. */
845                 if( format_pos < FORMAT_BUFR_MAX )
846                         format_bufr[format_pos++] = msg[i];
847
848                 /* If a newline is encountered, print & restart. */
849                 if( '\n' == msg[i] )
850                         bufr_print();
851
852                 /* If the buffer is full dump it out, reset it, and put out a line
853                  * continuation indicator.
854                  */
855                 if( format_pos >= FORMAT_BUFR_MAX ) {
856                         bufr_print();
857                         (void)Debug1( " +>\n" );
858                 }
859         }
860
861         /* Just to be safe... */
862         format_bufr[format_pos] = '\0';
863 }
864
865 /***************************************************************************
866  Flush debug output, including the format buffer content.
867
868  Input:  none
869  Output: none
870 ***************************************************************************/
871
872 void dbgflush( void )
873 {
874         bufr_print();
875         if(dbf)
876                 (void)x_fflush( dbf );
877 }
878
879 /***************************************************************************
880  Print a Debug Header.
881
882  Input:  level - Debug level of the message (not the system-wide debug
883                   level. )
884           file  - Pointer to a string containing the name of the file
885                   from which this function was called, or an empty string
886                   if the __FILE__ macro is not implemented.
887           func  - Pointer to a string containing the name of the function
888                   from which this function was called, or an empty string
889                   if the __FUNCTION__ macro is not implemented.
890          line  - line number of the call to dbghdr, assuming __LINE__
891                  works.
892
893   Output: Always True.  This makes it easy to fudge a call to dbghdr()
894           in a macro, since the function can be called as part of a test.
895           Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
896
897   Notes:  This function takes care of setting syslog_level.
898
899 ****************************************************************************/
900
901 BOOL dbghdr( int level, const char *file, const char *func, int line )
902 {
903         /* Ensure we don't lose any real errno value. */
904         int old_errno = errno;
905
906         if( format_pos ) {
907                 /* This is a fudge.  If there is stuff sitting in the format_bufr, then
908                  * the *right* thing to do is to call
909                  *   format_debug_text( "\n" );
910                  * to write the remainder, and then proceed with the new header.
911                  * Unfortunately, there are several places in the code at which
912                  * the DEBUG() macro is used to build partial lines.  That in mind,
913                  * we'll work under the assumption that an incomplete line indicates
914                  * that a new header is *not* desired.
915                  */
916                 return( True );
917         }
918
919 #ifdef WITH_SYSLOG
920         /* Set syslog_level. */
921         syslog_level = level;
922 #endif
923
924         /* Don't print a header if we're logging to stdout. */
925         if( stdout_logging )
926                 return( True );
927
928         /* Print the header if timestamps are turned on.  If parameters are
929          * not yet loaded, then default to timestamps on.
930          */
931         if( lp_timestamp_logs() || !(lp_loaded()) ) {
932                 char header_str[200];
933
934                 header_str[0] = '\0';
935
936                 if( lp_debug_pid())
937                         slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)sys_getpid());
938
939                 if( lp_debug_uid()) {
940                         size_t hs_len = strlen(header_str);
941                         slprintf(header_str + hs_len,
942                         sizeof(header_str) - 1 - hs_len,
943                                 ", effective(%u, %u), real(%u, %u)",
944                                 (unsigned int)geteuid(), (unsigned int)getegid(),
945                                 (unsigned int)getuid(), (unsigned int)getgid()); 
946                 }
947   
948                 /* Print it all out at once to prevent split syslog output. */
949                 (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
950                         timestring(lp_debug_hires_timestamp()), level,
951                         header_str, file, func, line );
952         }
953
954         errno = old_errno;
955         return( True );
956 }
957
958 /***************************************************************************
959  Add text to the body of the "current" debug message via the format buffer.
960
961   Input:  format_str  - Format string, as used in printf(), et. al.
962           ...         - Variable argument list.
963
964   ..or..  va_alist    - Old style variable parameter list starting point.
965
966   Output: Always True.  See dbghdr() for more info, though this is not
967           likely to be used in the same way.
968
969 ***************************************************************************/
970
971  BOOL dbgtext( const char *format_str, ... )
972 {
973         va_list ap;
974         pstring msgbuf;
975
976         va_start( ap, format_str ); 
977         vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
978         va_end( ap );
979
980         format_debug_text( msgbuf );
981
982   return( True );
983 }