merge changes from 2.2 branch to prevent smb.conf from changing debug level
[ira/wip.git] / source3 / lib / debug.c
index 934110a4d77c2e6d7afdea3ddc50bc103e1b6cc8..f3b0f2be124cec70dd349492c3c680d3683485f2 100644 (file)
@@ -26,7 +26,7 @@
  *
  *  FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
  *                    format_bufr[FORMAT_BUFR_MAX] should always be reserved
- *                    for a terminating nul byte.
+ *                    for a terminating null byte.
  */
 
 #define FORMAT_BUFR_MAX ( sizeof( format_bufr ) - 1 )
  *                  levels higher than DEBUGLEVEL will not be processed.
  */
 
-FILE   *dbf        = NULL;
+XFILE   *dbf        = NULL;
 pstring debugf     = "";
 BOOL    append_log = False;
 
 int     DEBUGLEVEL_CLASS[DBGC_LAST];
+BOOL    DEBUGLEVEL_CLASS_ISSET[DBGC_LAST];
 int     DEBUGLEVEL = DEBUGLEVEL_CLASS;
+BOOL   AllowDebugChange = True;
 
 
 /* -------------------------------------------------------------------------- **
@@ -124,18 +126,19 @@ static size_t     format_pos     = 0;
 static BOOL    log_overflow   = False;
 
 /*
-* Define all the debug class selection names here. Names *MUST NOT* contain 
-* white space. There must be one name for each DBGC_<class name>, and they 
-* must be in the table in the order of DBGC_<class name>.. 
-*/
+ * Define all the debug class selection names here. Names *MUST NOT* contain 
+ * white space. There must be one name for each DBGC_<class name>, and they 
+ * must be in the table in the order of DBGC_<class name>.. 
+ */
 char *classname_table[] = {
-       "all",               /* DBGC_ALL; index references traditional DEBUGLEVEL */
-       "tdb",               /* DBGC_TDB        */
+       "all",               /* DBGC_ALL; index refs traditional DEBUGLEVEL */
+       "tdb",               /* DBGC_TDB          */
        "printdrivers",      /* DBGC_PRINTDRIVERS */
-       "lanman",            /* DBGC_LANMAN */
-       "smb",               /* DBGC_SMB */
-       "rpc",               /* DBGC_RPC */
-       "rpc_hdr",           /* DBGC_RPC_HDR */
+       "lanman",            /* DBGC_LANMAN       */
+       "smb",               /* DBGC_SMB          */
+       "rpc",               /* DBGC_RPC          */
+       "rpc_hdr",           /* DBGC_RPC_HDR      */
+       "bdc",               /* DBGC_BDC          */
 };
 
 
@@ -171,7 +174,8 @@ int debug_lookup_classname(char* classname)
 parse the debug levels from smbcontrol. Example debug level parameter:
   printdrivers:7
 ****************************************************************************/
-BOOL debug_parse_params(char **params, int *debuglevel_class)
+BOOL debug_parse_params(char **params, int *debuglevel_class,
+                       BOOL *debuglevel_class_isset)
 {
        int   i, ndx;
        char *class_name;
@@ -180,15 +184,16 @@ BOOL debug_parse_params(char **params, int *debuglevel_class)
        /* Set the new debug level array to the current DEBUGLEVEL array */
        memcpy(debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
 
-       /* Allow DBGC_ALL to be specifies w/o requiring its class name e.g."10"  
+       /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"  
         * v.s. "all:10", this is the traditional way to set DEBUGLEVEL 
         */
        if (isdigit((int)params[0][0])) {
                debuglevel_class[DBGC_ALL] = atoi(params[0]);
+               debuglevel_class_isset[DBGC_ALL] = True;
                i = 1; /* start processing at the next params */
        }
        else
-               i = 0; /* DBGC_ALL not specified  OR calss name was included */
+               i = 0; /* DBGC_ALL not specified OR class name was included */
 
        /* Fill in new debug class levels */
        for (; i < DBGC_LAST && params[i]; i++) {
@@ -196,6 +201,7 @@ BOOL debug_parse_params(char **params, int *debuglevel_class)
                        (class_level=strtok(NULL, "\0")) &&
             ((ndx = debug_lookup_classname(class_name)) != -1)) {
                                debuglevel_class[ndx] = atoi(class_level);
+                               debuglevel_class_isset[ndx] = True;
                } else {
                        DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
                        return False;
@@ -215,9 +221,13 @@ BOOL debug_parse_levels(char *params_str)
        int  i;
        char *params[DBGC_LAST];
        int  debuglevel_class[DBGC_LAST];       
+       BOOL debuglevel_class_isset[DBGC_LAST];
 
+       if (AllowDebugChange == False)
+               return True;
        ZERO_ARRAY(params);
        ZERO_ARRAY(debuglevel_class);
+       ZERO_ARRAY(debuglevel_class_isset);
 
        if ((params[0]=strtok(params_str," ,"))) {
                for (i=1; i<DBGC_LAST;i++) {
@@ -228,13 +238,26 @@ BOOL debug_parse_levels(char *params_str)
        else
                return False;
 
-       if (debug_parse_params(params, debuglevel_class)) {
+       if (debug_parse_params(params, debuglevel_class, 
+                              debuglevel_class_isset)) {
                debug_message(0, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
 
-#if 0
                memcpy(DEBUGLEVEL_CLASS, debuglevel_class, 
                       sizeof(debuglevel_class));
-#endif
+
+               memcpy(DEBUGLEVEL_CLASS_ISSET, debuglevel_class_isset,
+                      sizeof(debuglevel_class_isset));
+
+               {
+                       int q;
+
+                       for (q = 0; q < DBGC_LAST; q++)
+                               DEBUG(5, ("%s: %d/%d\n",
+                                         classname_table[q],
+                                         DEBUGLEVEL_CLASS[q],
+                                         DEBUGLEVEL_CLASS_ISSET[q]));
+               }
+
                return True;
        } else
                return False;
@@ -245,18 +268,20 @@ receive a "set debug level" message
 ****************************************************************************/
 void debug_message(int msg_type, pid_t src, void *buf, size_t len)
 {
+       struct debuglevel_message *dm = (struct debuglevel_message *)buf;
        int i;
 
-       /* Set the new DEBUGLEVEL_CLASS array from the pased array */
-       memcpy(DEBUGLEVEL_CLASS, buf, sizeof(DEBUGLEVEL_CLASS));
-       
-       DEBUG(1,("INFO: Debug class %s level = %d   (pid %u from pid %u)\n",
+       /* Set the new DEBUGLEVEL_CLASS array from the passed message */
+       memcpy(DEBUGLEVEL_CLASS, dm->debuglevel_class, sizeof(dm->debuglevel_class));
+       memcpy(DEBUGLEVEL_CLASS_ISSET, dm->debuglevel_class_isset, sizeof(dm->debuglevel_class_isset));
+
+       DEBUG(3,("INFO: Debug class %s level = %d   (pid %u from pid %u)\n",
                        classname_table[DBGC_ALL],
                        DEBUGLEVEL_CLASS[DBGC_ALL], (unsigned int)getpid(), (unsigned int)src));
 
        for (i=1; i<DBGC_LAST; i++) {
                if (DEBUGLEVEL_CLASS[i])
-                        DEBUGADD(1,("INFO: Debug class %s level = %d\n", 
+                        DEBUGADD(3,("INFO: Debug class %s level = %d\n", 
                                                classname_table[i], DEBUGLEVEL_CLASS[i]));
        }
 }
@@ -286,16 +311,17 @@ void setup_logging(char *pname, BOOL interactive)
 
        if (interactive) {
                stdout_logging = True;
-               dbf = stdout;
+               dbf = x_stdout;
        }
 #ifdef WITH_SYSLOG
        else {
-               char *p = strrchr( pname,'/' );
+               char *p = strrchr_m( pname,'/' );
                if (p)
                        pname = p + 1;
 #ifdef LOG_DAEMON
                openlog( pname, LOG_PID, SYSLOG_FACILITY );
-#else /* for old systems that have no facility codes. */
+#else
+               /* for old systems that have no facility codes. */
                openlog( pname, LOG_PID );
 #endif
        }
@@ -315,42 +341,41 @@ BOOL reopen_logs( void )
 {
        pstring fname;
        mode_t oldumask;
-       FILE *new_dbf = NULL;
+       XFILE *new_dbf = NULL;
        BOOL ret = True;
 
        if (stdout_logging)
                return True;
 
-       if (DEBUGLEVEL_CLASS[ DBGC_ALL ] <= 0) {
-               if (dbf) {
-                       (void)fclose(dbf);
-                       dbf = NULL;
-               }
-               return True;
-       }
-
        oldumask = umask( 022 );
   
        pstrcpy(fname, debugf );
-       if (lp_loaded() && (*lp_logfile()))
-               pstrcpy(fname, lp_logfile());
+
+       if (lp_loaded()) {
+               char *logfname;
+
+               logfname = lp_logfile();
+               if (*logfname)
+                       pstrcpy(fname, logfname);
+       }
 
        pstrcpy( debugf, fname );
        if (append_log)
-               new_dbf = sys_fopen( debugf, "a" );
+               new_dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644);
        else
-               new_dbf = sys_fopen( debugf, "w" );
+               new_dbf = x_fopen( debugf, O_WRONLY|O_CREAT|O_TRUNC, 0644 );
 
        if (!new_dbf) {
                log_overflow = True;
                DEBUG(0, ("Unable to open new log file %s: %s\n", debugf, strerror(errno)));
                log_overflow = False;
-               fflush(dbf);
+               if (dbf)
+                       x_fflush(dbf);
                ret = False;
        } else {
-               setbuf(new_dbf, NULL);
+               x_setbuf(new_dbf, NULL);
                if (dbf)
-                       (void) fclose(dbf);
+                       (void) x_fclose(dbf);
                dbf = new_dbf;
        }
 
@@ -415,7 +440,7 @@ void check_log_size( void )
 
        maxlog = lp_max_log_size() * 1024;
 
-       if( sys_fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
+       if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) {
                (void)reopen_logs();
                if( dbf && get_file_size( debugf ) > maxlog ) {
                        pstring name;
@@ -436,13 +461,13 @@ void check_log_size( void )
 
        if(dbf == NULL) {
                /* This code should only be reached in very strange
-                       circumstances. If we merely fail to open the new log we
-                       should stick with the old one. ergo this should only be
-                       reached when opening the logs for the first time: at
-                       startup or when the log level is increased from zero.
-                       -dwg 6 June 2000
-               */
-               dbf = sys_fopen( "/dev/console", "w" );
+                * circumstances. If we merely fail to open the new log we
+                * should stick with the old one. ergo this should only be
+                * reached when opening the logs for the first time: at
+                * startup or when the log level is increased from zero.
+                * -dwg 6 June 2000
+                */
+               dbf = x_fopen( "/dev/console", O_WRONLY, 0);
                if(dbf) {
                        DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
                                        debugf ));
@@ -470,7 +495,7 @@ void check_log_size( void )
     {
     va_start( ap, format_str );
     if(dbf)
-      (void)vfprintf( dbf, format_str, ap );
+      (void)x_vfprintf( dbf, format_str, ap );
     va_end( ap );
     errno = old_errno;
     return( 0 );
@@ -485,13 +510,13 @@ void check_log_size( void )
       mode_t oldumask = umask( 022 );
 
       if( append_log )
-        dbf = sys_fopen( debugf, "a" );
+        dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
       else
-        dbf = sys_fopen( debugf, "w" );
+        dbf = x_fopen( debugf, O_WRONLY|O_CREAT|O_TRUNC, 0644 );
       (void)umask( oldumask );
       if( dbf )
         {
-        setbuf( dbf, NULL );
+        x_setbuf( dbf, NULL );
         }
       else
         {
@@ -540,10 +565,10 @@ void check_log_size( void )
     {
     va_start( ap, format_str );
     if(dbf)
-      (void)vfprintf( dbf, format_str, ap );
+      (void)x_vfprintf( dbf, format_str, ap );
     va_end( ap );
     if(dbf)
-      (void)fflush( dbf );
+      (void)x_fflush( dbf );
     }
 
   errno = old_errno;
@@ -633,14 +658,14 @@ void dbgflush( void )
   {
   bufr_print();
   if(dbf)
-    (void)fflush( dbf );
+    (void)x_fflush( dbf );
   } /* dbgflush */
 
 /* ************************************************************************** **
  * Print a Debug Header.
  *
  *  Input:  level - Debug level of the message (not the system-wide debug
- *                  level.
+ *                  level. )
  *          file  - Pointer to a string containing the name of the file
  *                  from which this function was called, or an empty string
  *                  if the __FILE__ macro is not implemented.