Fix build with arc4.
[kai/samba.git] / source3 / lib / debug.c
index 72285277eccbd1f4363e05b07cf7d4f6c55d9b29..d835ea7c176e5a824b387a587f21ba94991bf6e5 100644 (file)
@@ -29,7 +29,8 @@
  *                    for a terminating null byte.
  */
 
-#define FORMAT_BUFR_MAX ( sizeof( format_bufr ) - 1 )
+#define FORMAT_BUFR_SIZE 1024
+#define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)
 
 /* -------------------------------------------------------------------------- **
  * This module implements Samba's debugging utility.
  */
 
 XFILE   *dbf        = NULL;
-pstring debugf     = "";
+static char *debugf = NULL;
 bool    debug_warn_unknown_class = True;
 bool    debug_auto_add_unknown_class = True;
 bool    AllowDebugChange = True;
 
-/* 
-   used to check if the user specified a 
-   logfile on the command line 
+/*
+   used to check if the user specified a
+   logfile on the command line
 */
-bool    override_logfile;              
+bool    override_logfile;
 
+static TALLOC_CTX *tmp_debug_ctx;
 
 /*
  * This is to allow assignment to DEBUGLEVEL before the debug
- * system has been initialised.
+ * system has been initialized.
  */
 static int debug_all_class_hack = 1;
 static bool debug_all_class_isset_hack = True;
@@ -137,7 +139,7 @@ static int     debug_count    = 0;
 #ifdef WITH_SYSLOG
 static int     syslog_level   = 0;
 #endif
-static pstring format_bufr    = { '\0' };
+static char *format_bufr = NULL;
 static size_t     format_pos     = 0;
 static bool    log_overflow   = False;
 
@@ -181,6 +183,8 @@ static char **classname_table = NULL;
  Free memory pointed to by global pointers.
 ****************************************************************************/
 
+static bool initialized;
+
 void gfree_debugsyms(void)
 {
        int i;
@@ -192,11 +196,23 @@ void gfree_debugsyms(void)
                SAFE_FREE( classname_table );
        }
 
-       if ( DEBUGLEVEL_CLASS != &debug_all_class_hack )
+       if ( DEBUGLEVEL_CLASS != &debug_all_class_hack ) {
                SAFE_FREE( DEBUGLEVEL_CLASS );
+               DEBUGLEVEL_CLASS = &debug_all_class_hack;
+       }
 
-       if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack )
+       if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack ) {
                SAFE_FREE( DEBUGLEVEL_CLASS_ISSET );
+               DEBUGLEVEL_CLASS_ISSET = &debug_all_class_isset_hack;
+       }
+
+       SAFE_FREE(format_bufr);
+
+       debug_num_classes = 0;
+
+       debug_level = DEBUGLEVEL_CLASS;
+
+       initialized = false;
 }
 
 /****************************************************************************
@@ -425,8 +441,9 @@ static bool debug_parse_params(char **params)
 
        /* Fill in new debug class levels */
        for (; i < debug_num_classes && params[i]; i++) {
-               if ((class_name=strtok(params[i],":")) &&
-                       (class_level=strtok(NULL, "\0")) &&
+               char *saveptr;
+               if ((class_name = strtok_r(params[i],":", &saveptr)) &&
+                       (class_level = strtok_r(NULL, "\0", &saveptr)) &&
             ((ndx = debug_lookup_classname(class_name)) != -1)) {
                                DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
                                DEBUGLEVEL_CLASS_ISSET[ndx] = True;
@@ -455,14 +472,14 @@ bool debug_parse_levels(const char *params_str)
        if (AllowDebugChange == False)
                return True;
 
-       params = str_list_make(params_str, NULL);
+       params = str_list_make(talloc_tos(), params_str, NULL);
 
        if (debug_parse_params(params)) {
                debug_dump_status(5);
-               str_list_free(&params);
+               TALLOC_FREE(params);
                return True;
        } else {
-               str_list_free(&params);
+               TALLOC_FREE(params);
                return False;
        }
 }
@@ -471,7 +488,7 @@ bool debug_parse_levels(const char *params_str)
  Receive a "set debug level" message.
 ****************************************************************************/
 
-static void debug_message(struct messaging_context *msg_ctx,
+void debug_message(struct messaging_context *msg_ctx,
                          void *private_data, 
                          uint32_t msg_type, 
                          struct server_id src,
@@ -525,17 +542,20 @@ Init debugging (one time stuff)
 
 void debug_init(void)
 {
-       static bool initialised = False;
        const char **p;
 
-       if (initialised)
+       if (initialized)
                return;
 
-       initialised = True;
+       initialized = true;
 
        for(p = default_classname_table; *p; p++) {
                debug_add_class(*p);
        }
+       format_bufr = (char *)SMB_MALLOC(FORMAT_BUFR_SIZE);
+       if (!format_bufr) {
+               smb_panic("debug_init: unable to create buffer");
+       }
 }
 
 void debug_register_msgs(struct messaging_context *msg_ctx)
@@ -583,6 +603,16 @@ void setup_logging(const char *pname, bool interactive)
 #endif
 }
 
+/***************************************************************************
+ Set the logfile name.
+**************************************************************************/
+
+void debug_set_logfile(const char *name)
+{
+       SAFE_FREE(debugf);
+       debugf = SMB_STRDUP(name);
+}
+
 /**************************************************************************
  reopen the log files
  note that we now do this unconditionally
@@ -593,7 +623,7 @@ void setup_logging(const char *pname, bool interactive)
 
 bool reopen_logs( void )
 {
-       pstring fname;
+       char *fname = NULL;
        mode_t oldumask;
        XFILE *new_dbf = NULL;
        XFILE *old_dbf = NULL;
@@ -603,19 +633,27 @@ bool reopen_logs( void )
                return True;
 
        oldumask = umask( 022 );
-  
-       pstrcpy(fname, debugf );
-       debugf[0] = '\0';
+
+       fname = debugf;
+       if (!fname) {
+               return false;
+       }
+       debugf = NULL;
 
        if (lp_loaded()) {
                char *logfname;
 
                logfname = lp_logfile();
-               if (*logfname)
-                       pstrcpy(fname, logfname);
+               if (*logfname) {
+                       SAFE_FREE(fname);
+                       fname = SMB_STRDUP(logfname);
+                       if (!fname) {
+                               return false;
+                       }
+               }
        }
 
-       pstrcpy( debugf, fname );
+       debugf = fname;
        new_dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644);
 
        if (!new_dbf) {
@@ -702,15 +740,18 @@ void check_log_size( void )
        if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
                (void)reopen_logs();
                if( dbf && get_file_size( debugf ) > maxlog ) {
-                       pstring name;
+                       char *name = NULL;
+
+                       if (asprintf(&name, "%s.old", debugf ) < 0) {
+                               return;
+                       }
+                       (void)rename(debugf, name);
 
-                       slprintf( name, sizeof(name)-1, "%s.old", debugf );
-                       (void)rename( debugf, name );
-      
                        if (!reopen_logs()) {
                                /* We failed to reopen a log - continue using the old name. */
                                (void)rename(name, debugf);
                        }
+                       SAFE_FREE(name);
                }
        }
 
@@ -747,7 +788,7 @@ void check_log_size( void )
 
  int Debug1( const char *format_str, ... )
 {
-       va_list ap;  
+       va_list ap;
        int old_errno = errno;
 
        debug_count++;
@@ -758,13 +799,13 @@ void check_log_size( void )
                        (void)x_vfprintf( dbf, format_str, ap );
                va_end( ap );
                errno = old_errno;
-               return( 0 );
+               goto done;
        }
 
        /* prevent recursion by checking if reopen_logs() has temporaily
-          set the debugf string to "" */
-       if( debugf[0] == '\0')
-               return( 0 );
+          set the debugf string to NULL */
+       if( debugf == NULL)
+               goto done;
 
 #ifdef WITH_SYSLOG
        if( !lp_syslog_only() )
@@ -779,7 +820,7 @@ void check_log_size( void )
                                x_setbuf( dbf, NULL );
                        } else {
                                errno = old_errno;
-                               return(0);
+                               goto done;
                        }
                }
        }
@@ -789,29 +830,32 @@ void check_log_size( void )
                /* map debug levels to syslog() priorities
                 * note that not all DEBUG(0, ...) calls are
                 * necessarily errors */
-               static int priority_map[] = { 
+               static int priority_map[] = {
                        LOG_ERR,     /* 0 */
                        LOG_WARNING, /* 1 */
                        LOG_NOTICE,  /* 2 */
                        LOG_INFO,    /* 3 */
                };
                int     priority;
-               pstring msgbuf;
+               char *msgbuf = NULL;
+               int ret;
 
                if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) ) || syslog_level < 0)
                        priority = LOG_DEBUG;
                else
                        priority = priority_map[syslog_level];
 
-               va_start( ap, format_str );
-               vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
-               va_end( ap );
+               va_start(ap, format_str);
+               ret = vasprintf(&msgbuf, format_str, ap);
+               va_end(ap);
 
-               msgbuf[255] = '\0';
-               syslog( priority, "%s", msgbuf );
+               if (ret == -1) {
+                       syslog(priority, "%s", msgbuf);
+               }
+               SAFE_FREE(msgbuf);
        }
 #endif
-  
+
        check_log_size();
 
 #ifdef WITH_SYSLOG
@@ -826,6 +870,9 @@ void check_log_size( void )
                        (void)x_fflush( dbf );
        }
 
+ done:
+       TALLOC_FREE(tmp_debug_ctx);
+
        errno = old_errno;
 
        return( 0 );
@@ -866,6 +913,10 @@ static void format_debug_text( const char *msg )
        size_t i;
        bool timestamp = (!stdout_logging && (lp_timestamp_logs() || !(lp_loaded())));
 
+       if (!format_bufr) {
+               debug_init();
+       }
+
        for( i = 0; msg[i]; i++ ) {
                /* Indent two spaces at each new line. */
                if(timestamp && 0 == format_pos) {
@@ -989,12 +1040,14 @@ bool dbghdr(int level, int cls, const char *file, const char *func, int line)
                /* Print it all out at once to prevent split syslog output. */
                if( lp_debug_prefix_timestamp() ) {
                    (void)Debug1( "[%s, %2d%s] ",
-                       current_timestring(lp_debug_hires_timestamp()), level,
-                       header_str);
+                       current_timestring(debug_ctx(),
+                                          lp_debug_hires_timestamp()),
+                       level, header_str);
                } else {
                    (void)Debug1( "[%s, %2d%s] %s:%s(%d)\n",
-                       current_timestring(lp_debug_hires_timestamp()), level,
-                       header_str, file, func, line );
+                       current_timestring(debug_ctx(),
+                                          lp_debug_hires_timestamp()),
+                       level, header_str, file, func, line );
                }
        }
 
@@ -1018,13 +1071,30 @@ bool dbghdr(int level, int cls, const char *file, const char *func, int line)
  bool dbgtext( const char *format_str, ... )
 {
        va_list ap;
-       pstring msgbuf;
+       char *msgbuf = NULL;
+       bool ret = true;
+       int res;
 
-       va_start( ap, format_str ); 
-       vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
-       va_end( ap );
+       va_start(ap, format_str);
+       res = vasprintf(&msgbuf, format_str, ap);
+       va_end(ap);
 
-       format_debug_text( msgbuf );
+       if (res != -1) {
+               format_debug_text(msgbuf);
+       } else {
+               ret = false;
+       }
+       SAFE_FREE(msgbuf);
+       return ret;
+}
 
-  return( True );
+/*
+ * Get us a temporary talloc context usable just for DEBUG arguments
+ */
+TALLOC_CTX *debug_ctx(void)
+{
+        if (tmp_debug_ctx == NULL) {
+                tmp_debug_ctx = talloc_named_const(NULL, 0, "debug_ctx");
+        }
+        return tmp_debug_ctx;
 }