1998-08-01 00:17:36 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-01 00:17:36 +04:00
Samba utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
2002-07-15 14:35:28 +04:00
Copyright ( C ) Elrond 2002
Copyright ( C ) Simo Sorce 2002
1998-08-01 00:17:36 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-08-01 00:17:36 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-08-01 00:17:36 +04:00
*/
# include "includes.h"
2011-02-24 08:14:03 +03:00
# include "system/filesys.h"
# include "system/syslog.h"
# include "lib/util/time.h"
/* define what facility to use for syslog */
# ifndef SYSLOG_FACILITY
# define SYSLOG_FACILITY LOG_DAEMON
# endif
1998-08-01 00:17:36 +04:00
1998-08-21 23:57:59 +04:00
/* -------------------------------------------------------------------------- **
* Defines . . .
*
* FORMAT_BUFR_MAX - Index of the last byte of the format buffer ;
* format_bufr [ FORMAT_BUFR_MAX ] should always be reserved
2001-10-29 11:26:45 +03:00
* for a terminating null byte .
1998-08-21 23:57:59 +04:00
*/
2007-11-16 01:19:52 +03:00
# define FORMAT_BUFR_SIZE 1024
# define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)
1998-08-21 23:57:59 +04:00
1998-08-01 00:17:36 +04:00
/* -------------------------------------------------------------------------- **
* This module implements Samba ' s debugging utility .
*
* The syntax of a debugging log file is represented as :
*
* < debugfile > : = = { < debugmsg > }
*
* < debugmsg > : = = < debughdr > ' \n ' < debugtext >
*
* < debughdr > : = = ' [ ' TIME ' , ' LEVEL ' ] ' [ [ FILENAME ' : ' ] [ FUNCTION ' ( ) ' ] ]
*
* < debugtext > : = = { < debugline > }
*
* < debugline > : = = TEXT ' \n '
*
* TEXT is a string of characters excluding the newline character .
* LEVEL is the DEBUG level of the message ( an integer in the range 0. .10 ) .
* TIME is a timestamp .
* FILENAME is the name of the file from which the debug message was generated .
* FUNCTION is the function from which the debug message was generated .
*
* Basically , what that all means is :
*
* - A debugging log file is made up of debug messages .
*
* - Each debug message is made up of a header and text . The header is
* separated from the text by a newline .
*
* - The header begins with the timestamp and debug level of the message
* enclosed in brackets . The filename and function from which the
* message was generated may follow . The filename is terminated by a
* colon , and the function name is terminated by parenthesis .
*
* - The message text is made up of zero or more lines , each terminated by
* a newline .
*/
2010-10-29 07:19:32 +04:00
/* state variables for the debug system */
static struct {
2011-02-24 08:14:03 +03:00
bool initialized ;
2010-10-29 09:20:22 +04:00
int fd ; /* The log file handle */
2010-10-29 07:19:32 +04:00
enum debug_logtype logtype ; /* The type of logging we are doing: eg stdout, file, stderr */
const char * prog_name ;
bool reopening_logs ;
2011-02-24 08:14:03 +03:00
bool schedule_reopen_logs ;
struct debug_settings settings ;
char * debugf ;
2012-03-08 05:21:26 +04:00
debug_callback_fn callback ;
void * callback_private ;
2011-02-24 08:14:03 +03:00
} state = {
. settings = {
. timestamp_logs = true
2011-04-01 07:55:37 +04:00
} ,
. fd = 2 /* stderr by default */
2011-02-24 08:14:03 +03:00
} ;
2010-10-29 07:19:32 +04:00
1998-08-01 00:17:36 +04:00
/* -------------------------------------------------------------------------- **
* External variables .
*
* debugf - Debug file name .
* DEBUGLEVEL - System - wide debug message limit . Messages with message -
* levels higher than DEBUGLEVEL will not be processed .
*/
2007-11-16 01:19:52 +03:00
/*
used to check if the user specified a
logfile on the command line
2004-03-26 18:40:06 +03:00
*/
2007-11-16 01:19:52 +03:00
bool override_logfile ;
2004-03-26 18:40:06 +03:00
2002-07-15 14:35:28 +04:00
/*
2011-02-24 08:14:03 +03:00
* This is to allow reading of DEBUGLEVEL_CLASS before the debug
2008-08-13 00:35:15 +04:00
* system has been initialized .
2002-07-15 14:35:28 +04:00
*/
2011-02-24 08:14:03 +03:00
static const int debug_class_list_initial [ DBGC_MAX_FIXED + 1 ] ;
2002-07-15 14:35:28 +04:00
static int debug_num_classes = 0 ;
2011-02-24 08:14:03 +03:00
int * DEBUGLEVEL_CLASS = discard_const_p ( int , debug_class_list_initial ) ;
1998-08-01 00:17:36 +04:00
/* -------------------------------------------------------------------------- **
* Internal variables .
*
* debug_count - Number of debug messages that have been output .
* Used to check log size .
*
2012-03-08 05:21:26 +04:00
* current_msg_level - Internal copy of the message debug level . Written by
1998-08-01 00:17:36 +04:00
* dbghdr ( ) and read by Debug1 ( ) .
*
* format_bufr - Used to format debug messages . The dbgtext ( ) function
* prints debug messages to a string , and then passes the
* string to format_debug_text ( ) , which uses format_bufr
* to build the formatted output .
*
* format_pos - Marks the first free byte of the format_bufr .
2011-02-24 08:14:03 +03:00
*
2001-03-27 05:19:54 +04:00
*
2011-03-01 00:52:25 +03:00
* log_overflow - When this variable is true , never attempt to check the
2001-03-27 05:19:54 +04:00
* size of the log . This is a hack , so that we can write
* a message using DEBUG , from open_logs ( ) when we
* are unable to open a new log file for some reason .
1998-08-01 00:17:36 +04:00
*/
static int debug_count = 0 ;
2012-03-08 05:21:26 +04:00
static int current_msg_level = 0 ;
2007-11-16 01:19:52 +03:00
static char * format_bufr = NULL ;
1999-12-13 16:27:58 +03:00
static size_t format_pos = 0 ;
2011-03-01 00:52:25 +03:00
static bool log_overflow = false ;
1998-08-01 00:17:36 +04:00
2001-02-12 19:18:02 +03:00
/*
2011-02-24 08:14:03 +03:00
* 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 > . .
2001-10-29 11:26:45 +03:00
*/
2002-07-15 14:35:28 +04:00
static const char * default_classname_table [ ] = {
2001-06-01 16:04:44 +04:00
" all " , /* DBGC_ALL; index refs traditional DEBUGLEVEL */
" tdb " , /* DBGC_TDB */
2001-02-12 19:18:02 +03:00
" printdrivers " , /* DBGC_PRINTDRIVERS */
2001-06-01 16:04:44 +04:00
" lanman " , /* DBGC_LANMAN */
" smb " , /* DBGC_SMB */
2002-07-15 14:35:28 +04:00
" rpc_parse " , /* DBGC_RPC_PARSE */
" rpc_srv " , /* DBGC_RPC_SRV */
" rpc_cli " , /* DBGC_RPC_CLI */
" passdb " , /* DBGC_PASSDB */
2002-09-25 19:19:00 +04:00
" sam " , /* DBGC_SAM */
2002-07-15 14:35:28 +04:00
" auth " , /* DBGC_AUTH */
" winbind " , /* DBGC_WINBIND */
2002-09-25 19:19:00 +04:00
" vfs " , /* DBGC_VFS */
2003-05-12 22:12:31 +04:00
" idmap " , /* DBGC_IDMAP */
2004-01-15 11:49:30 +03:00
" quota " , /* DBGC_QUOTA */
2004-05-18 21:24:59 +04:00
" acls " , /* DBGC_ACLS */
2005-04-27 22:32:37 +04:00
" locking " , /* DBGC_LOCKING */
2005-06-28 23:25:48 +04:00
" msdfs " , /* DBGC_MSDFS */
2006-03-23 02:49:09 +03:00
" dmapi " , /* DBGC_DMAPI */
2007-09-29 03:03:08 +04:00
" registry " , /* DBGC_REGISTRY */
2002-07-15 14:35:28 +04:00
NULL
2001-02-12 19:18:02 +03:00
} ;
2002-07-15 14:35:28 +04:00
static char * * classname_table = NULL ;
1998-08-01 00:17:36 +04:00
/* -------------------------------------------------------------------------- **
* Functions . . .
*/
2011-02-24 08:14:03 +03:00
static void debug_init ( void ) ;
2006-04-08 21:25:31 +04:00
/***************************************************************************
Free memory pointed to by global pointers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void gfree_debugsyms ( void )
{
2011-02-24 08:14:03 +03:00
TALLOC_FREE ( classname_table ) ;
2006-04-08 21:25:31 +04:00
2011-02-24 08:14:03 +03:00
if ( DEBUGLEVEL_CLASS ! = debug_class_list_initial ) {
TALLOC_FREE ( DEBUGLEVEL_CLASS ) ;
DEBUGLEVEL_CLASS = discard_const_p ( int , debug_class_list_initial ) ;
2008-08-13 00:35:15 +04:00
}
2008-01-07 14:41:18 +03:00
2011-02-24 08:14:03 +03:00
TALLOC_FREE ( format_bufr ) ;
2008-08-13 00:35:15 +04:00
2011-05-09 19:43:45 +04:00
debug_num_classes = 0 ;
2008-08-13 00:35:15 +04:00
2011-02-24 08:14:03 +03:00
state . initialized = false ;
2006-04-08 21:25:31 +04:00
}
2002-07-15 14:35:28 +04:00
/****************************************************************************
utility lists registered debug class names ' s
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-02-24 08:14:03 +03:00
char * debug_list_class_names_and_levels ( void )
2002-07-15 14:35:28 +04:00
{
char * buf = NULL ;
2011-02-24 08:14:03 +03:00
unsigned int i ;
2002-07-15 14:35:28 +04:00
/* prepare strings */
2006-03-14 23:37:24 +03:00
for ( i = 0 ; i < debug_num_classes ; i + + ) {
2011-02-24 08:14:03 +03:00
buf = talloc_asprintf_append ( buf ,
" %s:%d%s " ,
classname_table [ i ] ,
DEBUGLEVEL_CLASS [ i ] ,
i = = ( debug_num_classes - 1 ) ? " \n " : " " ) ;
if ( buf = = NULL ) {
return NULL ;
}
2002-07-15 14:35:28 +04:00
}
2011-02-24 08:14:03 +03:00
return buf ;
2001-02-12 19:18:02 +03:00
}
/****************************************************************************
2004-07-10 00:49:43 +04:00
Utility to translate names to debug class index ' s ( internal version ) .
2001-02-12 19:18:02 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2002-07-15 14:35:28 +04:00
static int debug_lookup_classname_int ( const char * classname )
2001-02-12 19:18:02 +03:00
{
int i ;
if ( ! classname ) return - 1 ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < debug_num_classes ; i + + ) {
2001-02-12 19:18:02 +03:00
if ( strcmp ( classname , classname_table [ i ] ) = = 0 )
return i ;
}
return - 1 ;
}
2002-07-15 14:35:28 +04:00
/****************************************************************************
2004-07-10 00:49:43 +04:00
Add a new debug class to the system .
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2002-07-15 14:35:28 +04:00
int debug_add_class ( const char * classname )
{
int ndx ;
2011-02-24 08:14:03 +03:00
int * new_class_list ;
char * * new_name_list ;
2011-03-04 04:23:16 +03:00
int default_level ;
2002-07-15 14:35:28 +04:00
if ( ! classname )
return - 1 ;
/* check the init has yet been called */
debug_init ( ) ;
ndx = debug_lookup_classname_int ( classname ) ;
if ( ndx > = 0 )
return ndx ;
ndx = debug_num_classes ;
2011-02-24 08:14:03 +03:00
if ( DEBUGLEVEL_CLASS = = debug_class_list_initial ) {
2002-07-15 14:35:28 +04:00
/* Initial loading... */
2011-02-24 08:14:03 +03:00
new_class_list = NULL ;
} else {
new_class_list = DEBUGLEVEL_CLASS ;
2002-07-15 14:35:28 +04:00
}
2011-03-04 04:23:16 +03:00
default_level = DEBUGLEVEL_CLASS [ DBGC_ALL ] ;
2011-02-24 08:14:03 +03:00
new_class_list = talloc_realloc ( NULL , new_class_list , int , ndx + 1 ) ;
if ( ! new_class_list )
2002-07-15 14:35:28 +04:00
return - 1 ;
2011-02-24 08:14:03 +03:00
DEBUGLEVEL_CLASS = new_class_list ;
2002-07-15 14:35:28 +04:00
2011-03-04 04:23:16 +03:00
DEBUGLEVEL_CLASS [ ndx ] = default_level ;
2011-02-24 08:14:03 +03:00
new_name_list = talloc_realloc ( NULL , classname_table , char * , ndx + 1 ) ;
if ( ! new_name_list )
2002-07-15 14:35:28 +04:00
return - 1 ;
2011-02-24 08:14:03 +03:00
classname_table = new_name_list ;
2002-07-15 14:35:28 +04:00
2011-02-24 08:14:03 +03:00
classname_table [ ndx ] = talloc_strdup ( classname_table , classname ) ;
2002-07-15 14:35:28 +04:00
if ( ! classname_table [ ndx ] )
return - 1 ;
2011-02-24 08:14:03 +03:00
debug_num_classes = ndx + 1 ;
2002-07-15 14:35:28 +04:00
return ndx ;
}
/****************************************************************************
2004-07-10 00:49:43 +04:00
Utility to translate names to debug class index ' s ( public version ) .
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2002-07-15 14:35:28 +04:00
int debug_lookup_classname ( const char * classname )
{
int ndx ;
2011-02-24 08:14:03 +03:00
2004-07-10 00:49:43 +04:00
if ( ! classname | | ! * classname )
return - 1 ;
2002-07-15 14:35:28 +04:00
ndx = debug_lookup_classname_int ( classname ) ;
if ( ndx ! = - 1 )
return ndx ;
2011-02-24 08:14:03 +03:00
DEBUG ( 0 , ( " debug_lookup_classname(%s): Unknown class \n " ,
classname ) ) ;
return debug_add_class ( classname ) ;
2002-07-15 14:35:28 +04:00
}
/****************************************************************************
2004-07-10 00:49:43 +04:00
Dump the current registered debug levels .
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2002-07-15 14:35:28 +04:00
static void debug_dump_status ( int level )
{
int q ;
DEBUG ( level , ( " INFO: Current debug levels: \n " ) ) ;
2004-07-10 00:49:43 +04:00
for ( q = 0 ; q < debug_num_classes ; q + + ) {
2011-02-24 08:14:03 +03:00
const char * classname = classname_table [ q ] ;
DEBUGADD ( level , ( " %s: %d \n " ,
classname ,
2002-07-15 14:35:28 +04:00
DEBUGLEVEL_CLASS [ q ] ) ) ;
}
}
2001-02-12 19:18:02 +03:00
/****************************************************************************
2004-07-10 00:49:43 +04:00
parse the debug levels from smbcontrol . Example debug level parameter :
printdrivers : 7
2001-02-12 19:18:02 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2007-10-19 04:40:25 +04:00
static bool debug_parse_params ( char * * params )
2001-02-12 19:18:02 +03:00
{
2001-02-13 19:28:48 +03:00
int i , ndx ;
2001-02-12 19:18:02 +03:00
char * class_name ;
char * class_level ;
2002-07-15 14:35:28 +04:00
if ( ! params )
2011-03-01 00:52:25 +03:00
return false ;
2001-02-12 19:18:02 +03:00
2011-02-24 08:14:03 +03:00
/* 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
2001-02-12 19:18:02 +03:00
*/
2001-04-28 02:02:23 +04:00
if ( isdigit ( ( int ) params [ 0 ] [ 0 ] ) ) {
2002-09-25 19:19:00 +04:00
DEBUGLEVEL_CLASS [ DBGC_ALL ] = atoi ( params [ 0 ] ) ;
2001-02-12 19:18:02 +03:00
i = 1 ; /* start processing at the next params */
2004-07-10 00:49:43 +04:00
} else {
2011-02-24 08:14:03 +03:00
DEBUGLEVEL_CLASS [ DBGC_ALL ] = 0 ;
2001-10-29 11:26:45 +03:00
i = 0 ; /* DBGC_ALL not specified OR class name was included */
2004-07-10 00:49:43 +04:00
}
2001-02-12 19:18:02 +03:00
2011-02-24 08:14:03 +03:00
/* Array is debug_num_classes long */
for ( ndx = DBGC_ALL ; ndx < debug_num_classes ; ndx + + ) {
DEBUGLEVEL_CLASS [ ndx ] = DEBUGLEVEL_CLASS [ DBGC_ALL ] ;
}
2001-02-12 19:18:02 +03:00
/* Fill in new debug class levels */
2002-07-15 14:35:28 +04:00
for ( ; i < debug_num_classes & & params [ i ] ; i + + ) {
2008-01-23 13:04:10 +03:00
char * saveptr ;
if ( ( class_name = strtok_r ( params [ i ] , " : " , & saveptr ) ) & &
( class_level = strtok_r ( NULL , " \0 " , & saveptr ) ) & &
2001-02-13 19:28:48 +03:00
( ( ndx = debug_lookup_classname ( class_name ) ) ! = - 1 ) ) {
2002-09-25 19:19:00 +04:00
DEBUGLEVEL_CLASS [ ndx ] = atoi ( class_level ) ;
2001-02-12 19:18:02 +03:00
} else {
DEBUG ( 0 , ( " debug_parse_params: unrecognized debug class name or format [%s] \n " , params [ i ] ) ) ;
2011-03-01 00:52:25 +03:00
return false ;
2001-02-12 19:18:02 +03:00
}
}
2011-03-01 00:52:25 +03:00
return true ;
2001-02-12 19:18:02 +03:00
}
/****************************************************************************
2004-07-10 00:49:43 +04:00
Parse the debug levels from smb . conf . Example debug level string :
2001-02-12 19:18:02 +03:00
3 tdb : 5 printdrivers : 7
2004-07-10 00:49:43 +04:00
Note : the 1 st param has no " name: " preceeding it .
2001-02-12 19:18:02 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2007-10-19 04:40:25 +04:00
bool debug_parse_levels ( const char * params_str )
2001-02-12 19:18:02 +03:00
{
2002-07-15 14:35:28 +04:00
char * * params ;
/* Just in case */
debug_init ( ) ;
2001-02-12 19:18:02 +03:00
2011-02-24 08:14:03 +03:00
params = str_list_make ( NULL , params_str , NULL ) ;
2001-06-01 16:04:44 +04:00
2004-07-10 00:49:43 +04:00
if ( debug_parse_params ( params ) ) {
2002-07-15 14:35:28 +04:00
debug_dump_status ( 5 ) ;
2008-02-04 22:57:35 +03:00
TALLOC_FREE ( params ) ;
2011-03-01 00:52:25 +03:00
return true ;
2002-07-15 14:35:28 +04:00
} else {
2008-02-04 22:57:35 +03:00
TALLOC_FREE ( params ) ;
2011-03-01 00:52:25 +03:00
return false ;
2002-07-15 14:35:28 +04:00
}
2001-02-12 19:18:02 +03:00
}
2011-02-24 08:14:03 +03:00
/* setup for logging of talloc warnings */
static void talloc_log_fn ( const char * msg )
2000-09-11 11:02:43 +04:00
{
2011-02-24 08:14:03 +03:00
DEBUG ( 0 , ( " %s " , msg ) ) ;
2000-09-11 11:02:43 +04:00
}
2011-02-24 08:14:03 +03:00
void debug_setup_talloc_log ( void )
2002-07-15 14:35:28 +04:00
{
2011-02-24 08:14:03 +03:00
talloc_set_log_fn ( talloc_log_fn ) ;
2002-07-15 14:35:28 +04:00
}
2011-02-24 08:14:03 +03:00
2002-07-15 14:35:28 +04:00
/****************************************************************************
Init debugging ( one time stuff )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-07-10 00:49:43 +04:00
2011-02-24 08:14:03 +03:00
static void debug_init ( void )
2000-09-11 11:02:43 +04:00
{
2002-07-15 14:35:28 +04:00
const char * * p ;
2011-02-24 08:14:03 +03:00
if ( state . initialized )
2002-07-15 14:35:28 +04:00
return ;
2006-04-08 21:25:31 +04:00
2011-02-24 08:14:03 +03:00
state . initialized = true ;
debug_setup_talloc_log ( ) ;
2002-07-15 14:35:28 +04:00
2004-07-10 00:49:43 +04:00
for ( p = default_classname_table ; * p ; p + + ) {
2002-07-15 14:35:28 +04:00
debug_add_class ( * p ) ;
}
2011-02-24 08:14:03 +03:00
format_bufr = talloc_array ( NULL , char , FORMAT_BUFR_SIZE ) ;
2007-11-16 01:19:52 +03:00
if ( ! format_bufr ) {
smb_panic ( " debug_init: unable to create buffer " ) ;
}
2000-09-11 11:02:43 +04:00
}
1998-08-01 00:17:36 +04:00
2011-02-24 08:14:03 +03:00
/* This forces in some smb.conf derived values into the debug system.
* There are no pointers in this structure , so we can just
* structure - assign it in */
void debug_set_settings ( struct debug_settings * settings )
2007-05-15 19:14:32 +04:00
{
2011-02-24 08:14:03 +03:00
state . settings = * settings ;
2007-05-15 19:14:32 +04:00
}
2010-10-29 07:19:32 +04:00
/**
control the name of the logfile and whether logging will be to stdout , stderr
or a file , and set up syslog
2010-11-01 10:42:36 +03:00
new_log indicates the destination for the debug log ( an enum in
order of precedence - once set to DEBUG_FILE , it is not possible to
reset to DEBUG_STDOUT for example . This makes it easy to override
for debug to stderr on the command line , as the smb . conf cannot
reset it back to file - based logging
2010-10-29 07:19:32 +04:00
*/
void setup_logging ( const char * prog_name , enum debug_logtype new_logtype )
2000-09-12 04:47:11 +04:00
{
2002-07-15 14:35:28 +04:00
debug_init ( ) ;
2010-10-29 07:19:32 +04:00
if ( state . logtype < new_logtype ) {
state . logtype = new_logtype ;
2004-07-10 00:49:43 +04:00
}
2010-10-29 07:19:32 +04:00
if ( prog_name ) {
state . prog_name = prog_name ;
2000-09-12 04:47:11 +04:00
}
2011-02-24 08:14:03 +03:00
reopen_logs_internal ( ) ;
2010-10-29 07:19:32 +04:00
if ( state . logtype = = DEBUG_FILE ) {
2000-09-12 04:47:11 +04:00
# ifdef WITH_SYSLOG
2010-10-29 07:19:32 +04:00
const char * p = strrchr_m ( prog_name , ' / ' ) ;
2000-09-12 04:47:11 +04:00
if ( p )
2010-10-29 07:19:32 +04:00
prog_name = p + 1 ;
1998-08-01 00:17:36 +04:00
# ifdef LOG_DAEMON
2010-10-29 07:19:32 +04:00
openlog ( prog_name , LOG_PID , SYSLOG_FACILITY ) ;
2001-10-29 11:26:45 +03:00
# else
/* for old systems that have no facility codes. */
2010-10-29 07:19:32 +04:00
openlog ( prog_name , LOG_PID ) ;
1998-08-01 00:17:36 +04:00
# endif
# endif
2010-10-29 07:19:32 +04:00
}
2004-07-10 00:49:43 +04:00
}
2007-11-16 01:19:52 +03:00
/***************************************************************************
Set the logfile name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void debug_set_logfile ( const char * name )
{
2011-03-29 07:41:58 +04:00
if ( name = = NULL | | * name = = 0 ) {
/* this copes with calls when smb.conf is not loaded yet */
return ;
}
2011-02-24 08:14:03 +03:00
TALLOC_FREE ( state . debugf ) ;
state . debugf = talloc_strdup ( NULL , name ) ;
2007-11-16 01:19:52 +03:00
}
2010-10-29 09:20:22 +04:00
static void debug_close_fd ( int fd )
2010-10-29 07:19:32 +04:00
{
2010-10-29 09:20:22 +04:00
if ( fd > 2 ) {
close ( fd ) ;
2010-10-29 07:19:32 +04:00
}
}
2010-11-01 12:55:04 +03:00
bool debug_get_output_is_stderr ( void )
{
return ( state . logtype = = DEBUG_DEFAULT_STDERR ) | | ( state . logtype = = DEBUG_STDERR ) ;
}
2011-07-18 11:07:25 +04:00
bool debug_get_output_is_stdout ( void )
{
return ( state . logtype = = DEBUG_DEFAULT_STDOUT ) | | ( state . logtype = = DEBUG_STDOUT ) ;
}
2012-03-08 05:21:26 +04:00
void debug_set_callback ( void * private_ptr , debug_callback_fn fn )
{
debug_init ( ) ;
if ( fn ) {
state . logtype = DEBUG_CALLBACK ;
state . callback_private = private_ptr ;
state . callback = fn ;
} else {
state . logtype = DEBUG_DEFAULT_STDERR ;
state . callback_private = NULL ;
state . callback = NULL ;
}
}
2004-07-10 00:49:43 +04:00
/**************************************************************************
reopen the log files
note that we now do this unconditionally
We attempt to open the new debug fp before closing the old . This means
if we run out of fd ' s we just keep using the old fd rather than aborting .
Fix from dgibson @ linuxcare . com .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-27 05:19:54 +04:00
2010-10-29 07:19:32 +04:00
/**
reopen the log file ( usually called because the log file name might have changed )
*/
2011-02-24 08:14:03 +03:00
bool reopen_logs_internal ( void )
2000-08-28 07:17:22 +04:00
{
mode_t oldumask ;
2010-10-29 09:20:22 +04:00
int new_fd = 0 ;
int old_fd = 0 ;
2011-03-01 00:52:25 +03:00
bool ret = true ;
2000-08-28 07:17:22 +04:00
2010-10-29 07:19:32 +04:00
if ( state . reopening_logs ) {
return true ;
}
2011-02-24 08:14:03 +03:00
/* Now clear the SIGHUP induced flag */
state . schedule_reopen_logs = false ;
2010-10-29 07:19:32 +04:00
switch ( state . logtype ) {
2012-03-08 05:21:26 +04:00
case DEBUG_CALLBACK :
return true ;
2010-10-29 07:19:32 +04:00
case DEBUG_STDOUT :
2011-07-18 11:07:25 +04:00
case DEBUG_DEFAULT_STDOUT :
2010-10-29 14:12:12 +04:00
debug_close_fd ( state . fd ) ;
2010-10-29 09:20:22 +04:00
state . fd = 1 ;
2010-10-29 07:19:32 +04:00
return true ;
case DEBUG_DEFAULT_STDERR :
case DEBUG_STDERR :
2010-10-29 09:20:22 +04:00
debug_close_fd ( state . fd ) ;
state . fd = 2 ;
2010-10-29 07:19:32 +04:00
return true ;
case DEBUG_FILE :
break ;
}
2001-05-08 03:46:48 +04:00
2000-08-28 07:17:22 +04:00
oldumask = umask ( 022 ) ;
2007-11-16 01:19:52 +03:00
2012-06-01 03:06:17 +04:00
if ( ! state . debugf ) {
2007-11-16 01:19:52 +03:00
return false ;
}
2001-10-02 10:57:18 +04:00
2011-02-24 08:14:03 +03:00
state . reopening_logs = true ;
2000-08-28 07:17:22 +04:00
2011-02-24 08:14:03 +03:00
new_fd = open ( state . debugf , O_WRONLY | O_APPEND | O_CREAT , 0644 ) ;
2001-03-27 05:19:54 +04:00
2010-10-29 09:20:22 +04:00
if ( new_fd = = - 1 ) {
2011-03-01 00:52:25 +03:00
log_overflow = true ;
2011-03-29 07:41:58 +04:00
DEBUG ( 0 , ( " Unable to open new log file '%s': %s \n " , state . debugf , strerror ( errno ) ) ) ;
2011-03-01 00:52:25 +03:00
log_overflow = false ;
ret = false ;
2001-03-27 05:19:54 +04:00
} else {
2010-10-29 09:20:22 +04:00
old_fd = state . fd ;
state . fd = new_fd ;
debug_close_fd ( old_fd ) ;
2001-03-27 05:19:54 +04:00
}
2000-08-28 07:17:22 +04:00
/* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
* to fix problem where smbd ' s that generate less
* than 100 messages keep growing the log .
*/
force_check_log_size ( ) ;
( void ) umask ( oldumask ) ;
2008-11-01 05:58:14 +03:00
/* Take over stderr to catch output into logs */
2012-03-02 12:32:56 +04:00
if ( state . fd > 0 ) {
if ( dup2 ( state . fd , 2 ) = = - 1 ) {
/* Close stderr too, if dup2 can't point it -
at the logfile . There really isn ' t much
that can be done on such a fundemental
failure . . . */
close_low_fds ( false , false , true ) ;
}
2002-08-17 21:00:51 +04:00
}
2011-02-24 08:14:03 +03:00
state . reopening_logs = false ;
2001-03-27 05:19:54 +04:00
return ret ;
}
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
/**************************************************************************
Force a check of the log size .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-01 00:17:36 +04:00
void force_check_log_size ( void )
2000-04-15 04:31:56 +04:00
{
2004-07-10 00:49:43 +04:00
debug_count = 100 ;
2000-04-15 04:31:56 +04:00
}
2011-02-24 08:14:03 +03:00
_PUBLIC_ void debug_schedule_reopen_logs ( void )
{
state . schedule_reopen_logs = true ;
}
2000-04-15 04:31:56 +04:00
/***************************************************************************
Check to see if there is any need to check if the logfile has grown too big .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool need_to_check_log_size ( void )
2000-04-15 04:31:56 +04:00
{
int maxlog ;
2011-02-24 08:14:03 +03:00
if ( debug_count < 100 )
2011-03-01 00:52:25 +03:00
return ( false ) ;
2000-04-15 04:31:56 +04:00
2011-02-24 08:14:03 +03:00
maxlog = state . settings . max_log_size * 1024 ;
if ( state . fd < = 2 | | maxlog < = 0 ) {
2000-04-15 04:31:56 +04:00
debug_count = 0 ;
2011-03-01 00:52:25 +03:00
return ( false ) ;
2000-04-15 04:31:56 +04:00
}
2011-03-01 00:52:25 +03:00
return ( true ) ;
2000-04-15 04:31:56 +04:00
}
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
/**************************************************************************
Check to see if the log has grown to be too big .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-15 04:31:56 +04:00
void check_log_size ( void )
1999-12-13 16:27:58 +03:00
{
2001-03-27 05:19:54 +04:00
int maxlog ;
2011-02-24 08:14:03 +03:00
struct stat st ;
2001-03-27 05:19:54 +04:00
2007-04-14 10:40:47 +04:00
/*
* We need to be root to check / change log - file , skip this and let the main
* loop check do a new check as root .
*/
2011-03-31 19:02:27 +04:00
# if _SAMBA_BUILD_ == 3
if ( geteuid ( ) ! = sec_initial_uid ( ) )
# else
if ( geteuid ( ) ! = 0 )
# endif
{
2011-02-24 08:14:03 +03:00
/* We don't check sec_initial_uid() here as it isn't
* available in common code and we don ' t generally
* want to rotate and the possibly lose logs in
* make test or the build farm */
2007-04-14 10:40:47 +04:00
return ;
2011-02-24 08:14:03 +03:00
}
2007-04-14 10:40:47 +04:00
2011-02-24 08:14:03 +03:00
if ( log_overflow | | ( ! state . schedule_reopen_logs & & ! need_to_check_log_size ( ) ) ) {
2001-03-27 05:19:54 +04:00
return ;
2011-02-24 08:14:03 +03:00
}
2000-04-15 04:31:56 +04:00
2011-02-24 08:14:03 +03:00
maxlog = state . settings . max_log_size * 1024 ;
2012-06-11 07:22:42 +04:00
if ( state . schedule_reopen_logs ) {
( void ) reopen_logs_internal ( ) ;
}
if ( maxlog & & ( fstat ( state . fd , & st ) = = 0
2011-02-24 08:14:03 +03:00
& & st . st_size > maxlog ) ) {
( void ) reopen_logs_internal ( ) ;
2012-06-11 07:22:42 +04:00
if ( state . fd > 2 & & ( fstat ( state . fd , & st ) = = 0
& & st . st_size > maxlog ) ) {
char * name = NULL ;
if ( asprintf ( & name , " %s.old " , state . debugf ) < 0 ) {
return ;
}
( void ) rename ( state . debugf , name ) ;
if ( ! reopen_logs_internal ( ) ) {
/* We failed to reopen a log - continue using the old name. */
( void ) rename ( name , state . debugf ) ;
2001-03-27 05:19:54 +04:00
}
2012-06-11 07:22:42 +04:00
SAFE_FREE ( name ) ;
2001-03-27 05:19:54 +04:00
}
}
1998-08-01 00:17:36 +04:00
2001-03-27 05:19:54 +04:00
/*
2010-10-29 14:12:12 +04:00
* Here ' s where we need to panic if state . fd = = 0 or - 1 ( invalid values )
2001-03-27 05:19:54 +04:00
*/
2000-04-15 04:31:56 +04:00
2010-10-29 14:12:12 +04:00
if ( state . fd < = 0 ) {
2001-03-27 05:19:54 +04:00
/* This code should only be reached in very strange
2001-10-29 11:26:45 +03:00
* 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
*/
2010-10-29 09:20:22 +04:00
int fd = open ( " /dev/console " , O_WRONLY , 0 ) ;
2010-10-29 14:12:12 +04:00
if ( fd ! = - 1 ) {
2010-10-29 09:20:22 +04:00
state . fd = fd ;
2001-03-27 05:19:54 +04:00
DEBUG ( 0 , ( " check_log_size: open of debug file %s failed - using console. \n " ,
2011-02-24 08:14:03 +03:00
state . debugf ) ) ;
2001-03-27 05:19:54 +04:00
} else {
/*
* We cannot continue without a debug file handle .
*/
abort ( ) ;
}
}
debug_count = 0 ;
2004-07-10 00:49:43 +04:00
}
/*************************************************************************
Write an debug message on the debugfile .
This is called by dbghdr ( ) and format_debug_text ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-01 00:17:36 +04:00
2002-11-15 17:06:35 +03:00
int Debug1 ( const char * format_str , . . . )
1998-08-01 00:17:36 +04:00
{
2007-11-16 01:19:52 +03:00
va_list ap ;
2004-07-10 00:49:43 +04:00
int old_errno = errno ;
debug_count + + ;
2012-03-08 05:21:26 +04:00
if ( state . logtype = = DEBUG_CALLBACK ) {
char * msg ;
int ret ;
va_start ( ap , format_str ) ;
ret = vasprintf ( & msg , format_str , ap ) ;
if ( ret ! = - 1 ) {
if ( msg [ ret - 1 ] = = ' \n ' ) {
msg [ ret - 1 ] = ' \0 ' ;
}
state . callback ( state . callback_private , current_msg_level , msg ) ;
free ( msg ) ;
}
va_end ( ap ) ;
goto done ;
} else if ( state . logtype ! = DEBUG_FILE ) {
2004-07-10 00:49:43 +04:00
va_start ( ap , format_str ) ;
2010-10-29 14:12:12 +04:00
if ( state . fd > 0 )
2010-10-29 09:20:22 +04:00
( void ) vdprintf ( state . fd , format_str , ap ) ;
2004-07-10 00:49:43 +04:00
va_end ( ap ) ;
errno = old_errno ;
2007-12-27 01:44:24 +03:00
goto done ;
2004-07-10 00:49:43 +04:00
}
2004-08-16 19:30:17 +04:00
1998-08-03 07:22:42 +04:00
# ifdef WITH_SYSLOG
2011-02-24 08:14:03 +03:00
if ( ! state . settings . syslog_only )
1998-08-01 00:17:36 +04:00
# endif
2004-07-10 00:49:43 +04:00
{
2010-10-29 14:12:12 +04:00
if ( state . fd < = 0 ) {
2004-07-10 00:49:43 +04:00
mode_t oldumask = umask ( 022 ) ;
2011-02-24 08:14:03 +03:00
int fd = open ( state . debugf , O_WRONLY | O_APPEND | O_CREAT , 0644 ) ;
2004-07-10 00:49:43 +04:00
( void ) umask ( oldumask ) ;
2010-10-29 09:20:22 +04:00
if ( fd = = - 1 ) {
2004-07-10 00:49:43 +04:00
errno = old_errno ;
2007-12-27 01:44:24 +03:00
goto done ;
2004-07-10 00:49:43 +04:00
}
2010-10-29 09:20:22 +04:00
state . fd = fd ;
2004-07-10 00:49:43 +04:00
}
}
1998-08-01 00:17:36 +04:00
2012-03-08 05:21:26 +04:00
1998-08-03 07:22:42 +04:00
# ifdef WITH_SYSLOG
2012-03-08 05:21:26 +04:00
if ( current_msg_level < state . settings . syslog ) {
2004-07-10 00:49:43 +04:00
/* map debug levels to syslog() priorities
* note that not all DEBUG ( 0 , . . . ) calls are
* necessarily errors */
2008-12-14 15:18:22 +03:00
static const int priority_map [ 4 ] = {
2004-07-10 00:49:43 +04:00
LOG_ERR , /* 0 */
LOG_WARNING , /* 1 */
LOG_NOTICE , /* 2 */
LOG_INFO , /* 3 */
} ;
int priority ;
2007-11-16 01:19:52 +03:00
char * msgbuf = NULL ;
2008-02-25 17:24:49 +03:00
int ret ;
2004-07-10 00:49:43 +04:00
2012-03-08 05:21:26 +04:00
if ( current_msg_level > = ARRAY_SIZE ( priority_map ) | | current_msg_level < 0 )
2004-07-10 00:49:43 +04:00
priority = LOG_DEBUG ;
else
2012-03-08 05:21:26 +04:00
priority = priority_map [ current_msg_level ] ;
2004-07-10 00:49:43 +04:00
2009-08-26 05:38:14 +04:00
/*
* Specify the facility to interoperate with other syslog
* callers ( vfs_full_audit for example ) .
*/
priority | = SYSLOG_FACILITY ;
2007-11-16 01:19:52 +03:00
va_start ( ap , format_str ) ;
2008-02-25 17:24:49 +03:00
ret = vasprintf ( & msgbuf , format_str , ap ) ;
2007-11-16 01:19:52 +03:00
va_end ( ap ) ;
2004-07-10 00:49:43 +04:00
2008-12-06 04:29:38 +03:00
if ( ret ! = - 1 ) {
2007-11-16 01:19:52 +03:00
syslog ( priority , " %s " , msgbuf ) ;
}
SAFE_FREE ( msgbuf ) ;
2004-07-10 00:49:43 +04:00
}
1998-08-01 00:17:36 +04:00
# endif
2007-11-16 01:19:52 +03:00
2004-07-10 00:49:43 +04:00
check_log_size ( ) ;
1999-12-13 16:27:58 +03:00
1998-08-03 07:22:42 +04:00
# ifdef WITH_SYSLOG
2011-02-24 08:14:03 +03:00
if ( ! state . settings . syslog_only )
1998-08-01 00:17:36 +04:00
# endif
2004-07-10 00:49:43 +04:00
{
va_start ( ap , format_str ) ;
2010-10-29 14:12:12 +04:00
if ( state . fd > 0 )
2010-10-29 09:20:22 +04:00
( void ) vdprintf ( state . fd , format_str , ap ) ;
2004-07-10 00:49:43 +04:00
va_end ( ap ) ;
}
1998-08-01 00:17:36 +04:00
2007-12-27 01:44:24 +03:00
done :
errno = old_errno ;
2004-07-10 00:49:43 +04:00
return ( 0 ) ;
}
1998-08-01 00:17:36 +04:00
1998-08-12 18:51:17 +04:00
2004-07-10 00:49:43 +04:00
/**************************************************************************
Print the buffer content via Debug1 ( ) , then reset the buffer .
Input : none
Output : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-12 18:51:17 +04:00
static void bufr_print ( void )
2004-07-10 00:49:43 +04:00
{
format_bufr [ format_pos ] = ' \0 ' ;
( void ) Debug1 ( " %s " , format_bufr ) ;
format_pos = 0 ;
}
/***************************************************************************
Format the debug message text .
Input : msg - Text to be added to the " current " debug message text .
Output : none .
Notes : The purpose of this is two - fold . First , each call to syslog ( )
( used by Debug1 ( ) , see above ) generates a new line of syslog
output . This is fixed by storing the partial lines until the
newline character is encountered . Second , printing the debug
message lines when a newline is encountered allows us to add
spaces , thus indenting the body of the message and making it
more readable .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void format_debug_text ( const char * msg )
{
size_t i ;
2011-02-24 08:14:03 +03:00
bool timestamp = ( state . logtype = = DEBUG_FILE & & ( state . settings . timestamp_logs ) ) ;
2004-07-10 00:49:43 +04:00
2007-12-14 10:21:59 +03:00
if ( ! format_bufr ) {
debug_init ( ) ;
}
2004-07-10 00:49:43 +04:00
for ( i = 0 ; msg [ i ] ; i + + ) {
/* Indent two spaces at each new line. */
if ( timestamp & & 0 = = format_pos ) {
format_bufr [ 0 ] = format_bufr [ 1 ] = ' ' ;
format_pos = 2 ;
}
/* If there's room, copy the character to the format buffer. */
if ( format_pos < FORMAT_BUFR_MAX )
format_bufr [ format_pos + + ] = msg [ i ] ;
/* If a newline is encountered, print & restart. */
if ( ' \n ' = = msg [ i ] )
bufr_print ( ) ;
/* If the buffer is full dump it out, reset it, and put out a line
* continuation indicator .
*/
if ( format_pos > = FORMAT_BUFR_MAX ) {
bufr_print ( ) ;
( void ) Debug1 ( " +> \n " ) ;
}
}
/* Just to be safe... */
format_bufr [ format_pos ] = ' \0 ' ;
}
/***************************************************************************
Flush debug output , including the format buffer content .
Input : none
Output : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-12 18:51:17 +04:00
void dbgflush ( void )
2004-07-10 00:49:43 +04:00
{
bufr_print ( ) ;
}
/***************************************************************************
Print a Debug Header .
Input : level - Debug level of the message ( not the system - wide debug
level . )
2007-09-30 12:07:06 +04:00
cls - Debuglevel class of the calling module .
2004-07-10 00:49:43 +04:00
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 .
func - Pointer to a string containing the name of the function
from which this function was called , or an empty string
if the __FUNCTION__ macro is not implemented .
line - line number of the call to dbghdr , assuming __LINE__
works .
2011-03-01 00:52:25 +03:00
Output : Always true . This makes it easy to fudge a call to dbghdr ( )
2004-07-10 00:49:43 +04:00
in a macro , since the function can be called as part of a test .
Eg : ( ( level < = DEBUGLEVEL ) & & ( dbghdr ( level , " " , line ) ) )
2012-03-08 05:21:26 +04:00
Notes : This function takes care of setting current_msg_level .
2004-07-10 00:49:43 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2008-10-11 22:44:19 +04:00
bool dbghdrclass ( int level , int cls , const char * location , const char * func )
1999-12-13 16:27:58 +03:00
{
2004-07-10 00:49:43 +04:00
/* Ensure we don't lose any real errno value. */
int old_errno = errno ;
if ( format_pos ) {
/* This is a fudge. If there is stuff sitting in the format_bufr, then
* the * right * thing to do is to call
* format_debug_text ( " \n " ) ;
* to write the remainder , and then proceed with the new header .
* Unfortunately , there are several places in the code at which
* the DEBUG ( ) macro is used to build partial lines . That in mind ,
* we ' ll work under the assumption that an incomplete line indicates
* that a new header is * not * desired .
*/
2011-03-01 00:52:25 +03:00
return ( true ) ;
2004-07-10 00:49:43 +04:00
}
1998-08-01 00:17:36 +04:00
2012-03-08 05:21:26 +04:00
/* Set current_msg_level. */
current_msg_level = level ;
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
/* Don't print a header if we're logging to stdout. */
2010-10-29 07:19:32 +04:00
if ( state . logtype ! = DEBUG_FILE ) {
2011-03-01 00:52:25 +03:00
return ( true ) ;
2010-10-29 07:19:32 +04:00
}
1998-08-03 07:22:42 +04:00
2004-07-10 00:49:43 +04:00
/* Print the header if timestamps are turned on. If parameters are
* not yet loaded , then default to timestamps on .
*/
2011-02-24 08:14:03 +03:00
if ( state . settings . timestamp_logs | | state . settings . debug_prefix_timestamp ) {
2011-11-16 00:50:54 +04:00
bool verbose = false ;
2004-07-10 00:49:43 +04:00
char header_str [ 200 ] ;
1999-12-13 16:27:58 +03:00
2004-07-10 00:49:43 +04:00
header_str [ 0 ] = ' \0 ' ;
1999-12-13 16:27:58 +03:00
2011-11-16 00:50:54 +04:00
if ( unlikely ( DEBUGLEVEL_CLASS [ cls ] > = 10 ) ) {
verbose = true ;
}
if ( verbose | | state . settings . debug_pid )
2011-02-24 08:14:03 +03:00
slprintf ( header_str , sizeof ( header_str ) - 1 , " , pid=%u " , ( unsigned int ) getpid ( ) ) ;
1999-12-13 16:27:58 +03:00
2011-11-16 00:50:54 +04:00
if ( verbose | | state . settings . debug_uid ) {
2004-07-10 00:49:43 +04:00
size_t hs_len = strlen ( header_str ) ;
slprintf ( header_str + hs_len ,
sizeof ( header_str ) - 1 - hs_len ,
" , effective(%u, %u), real(%u, %u) " ,
( unsigned int ) geteuid ( ) , ( unsigned int ) getegid ( ) ,
2011-02-24 08:14:03 +03:00
( unsigned int ) getuid ( ) , ( unsigned int ) getgid ( ) ) ;
2004-07-10 00:49:43 +04:00
}
2007-09-30 12:07:06 +04:00
2011-11-16 00:50:54 +04:00
if ( ( verbose | | state . settings . debug_class )
& & ( cls ! = DBGC_ALL ) ) {
2007-09-30 12:07:06 +04:00
size_t hs_len = strlen ( header_str ) ;
slprintf ( header_str + hs_len ,
sizeof ( header_str ) - 1 - hs_len ,
" , class=%s " ,
default_classname_table [ cls ] ) ;
}
2011-02-24 08:14:03 +03:00
2004-07-10 00:49:43 +04:00
/* Print it all out at once to prevent split syslog output. */
2011-02-24 08:14:03 +03:00
if ( state . settings . debug_prefix_timestamp ) {
char * time_str = current_timestring ( NULL ,
state . settings . debug_hires_timestamp ) ;
( void ) Debug1 ( " [%s, %2d%s] " ,
time_str ,
level , header_str ) ;
talloc_free ( time_str ) ;
2007-03-13 20:39:06 +03:00
} else {
2011-02-24 08:14:03 +03:00
char * time_str = current_timestring ( NULL ,
state . settings . debug_hires_timestamp ) ;
( void ) Debug1 ( " [%s, %2d%s] %s(%s) \n " ,
time_str ,
level , header_str , location , func ) ;
talloc_free ( time_str ) ;
2007-03-13 20:39:06 +03:00
}
2004-07-10 00:49:43 +04:00
}
1998-08-11 19:47:26 +04:00
2004-07-10 00:49:43 +04:00
errno = old_errno ;
2011-03-01 00:52:25 +03:00
return ( true ) ;
1999-12-13 16:27:58 +03:00
}
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
/***************************************************************************
Add text to the body of the " current " debug message via the format buffer .
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
Input : format_str - Format string , as used in printf ( ) , et . al .
. . . - Variable argument list .
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
. . or . . va_alist - Old style variable parameter list starting point .
1998-08-01 00:17:36 +04:00
2011-03-01 00:52:25 +03:00
Output : Always true . See dbghdr ( ) for more info , though this is not
2004-07-10 00:49:43 +04:00
likely to be used in the same way .
1998-08-01 00:17:36 +04:00
2004-07-10 00:49:43 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-01 00:17:36 +04:00
2007-10-19 04:40:25 +04:00
bool dbgtext ( const char * format_str , . . . )
2004-07-10 00:49:43 +04:00
{
va_list ap ;
2007-11-16 01:19:52 +03:00
char * msgbuf = NULL ;
bool ret = true ;
2008-02-25 17:24:49 +03:00
int res ;
2004-07-10 00:49:43 +04:00
2007-11-16 01:19:52 +03:00
va_start ( ap , format_str ) ;
2008-02-25 17:24:49 +03:00
res = vasprintf ( & msgbuf , format_str , ap ) ;
2007-11-16 01:19:52 +03:00
va_end ( ap ) ;
2004-07-10 00:49:43 +04:00
2008-02-25 17:24:49 +03:00
if ( res ! = - 1 ) {
2007-11-16 01:19:52 +03:00
format_debug_text ( msgbuf ) ;
} else {
ret = false ;
}
SAFE_FREE ( msgbuf ) ;
return ret ;
2004-07-10 00:49:43 +04:00
}
2011-02-24 08:14:03 +03:00
/* the registered mutex handlers */
static struct {
const char * name ;
struct debug_ops ops ;
} debug_handlers ;
/**
log suspicious usage - print comments and backtrace
*/
_PUBLIC_ void log_suspicious_usage ( const char * from , const char * info )
{
if ( ! debug_handlers . ops . log_suspicious_usage ) return ;
debug_handlers . ops . log_suspicious_usage ( from , info ) ;
}
/**
print suspicious usage - print comments and backtrace
*/
_PUBLIC_ void print_suspicious_usage ( const char * from , const char * info )
{
if ( ! debug_handlers . ops . print_suspicious_usage ) return ;
debug_handlers . ops . print_suspicious_usage ( from , info ) ;
}
_PUBLIC_ uint32_t get_task_id ( void )
{
if ( debug_handlers . ops . get_task_id ) {
return debug_handlers . ops . get_task_id ( ) ;
}
return getpid ( ) ;
}
_PUBLIC_ void log_task_id ( void )
{
if ( ! debug_handlers . ops . log_task_id ) return ;
if ( ! reopen_logs_internal ( ) ) return ;
debug_handlers . ops . log_task_id ( state . fd ) ;
}
/**
register a set of debug handlers .
*/
_PUBLIC_ void register_debug_handlers ( const char * name , struct debug_ops * ops )
{
debug_handlers . name = name ;
debug_handlers . ops = * ops ;
}