2015-07-06 19:30:18 +03:00
/*
* Copyright ( C ) 2011 - 2012 Red Hat , Inc .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v .2 .1 .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2015-07-06 19:30:18 +03:00
*/
# define _REENTRANT
# include "tool.h"
2012-08-08 11:41:01 +04:00
# include "daemon-server.h"
# include "daemon-log.h"
2015-07-06 19:30:18 +03:00
2012-08-08 11:41:01 +04:00
# include <syslog.h>
struct backend {
int id ;
void ( * log ) ( log_state * s , void * * state , int type , const char * message ) ;
} ;
2017-10-18 17:57:46 +03:00
static void _log_syslog ( log_state * s , void * * state , int type , const char * message )
2012-08-08 11:41:01 +04:00
{
2012-10-12 12:15:30 +04:00
int prio ;
2012-08-08 11:41:01 +04:00
if ( ! * state ) { /* initialize */
* state = ( void * ) 1 ;
openlog ( s - > name , LOG_PID , LOG_DAEMON ) ;
}
2012-10-12 12:15:30 +04:00
2012-08-08 11:41:01 +04:00
switch ( type ) {
case DAEMON_LOG_INFO : prio = LOG_INFO ; break ;
case DAEMON_LOG_WARN : prio = LOG_WARNING ; break ;
2015-03-10 16:35:29 +03:00
case DAEMON_LOG_ERROR : prio = LOG_ERR ; break ;
2012-08-08 11:41:01 +04:00
case DAEMON_LOG_FATAL : prio = LOG_CRIT ; break ;
2012-10-12 12:15:30 +04:00
default : prio = LOG_DEBUG ; break ;
2012-08-08 11:41:01 +04:00
}
syslog ( prio , " %s " , message ) ;
}
2017-10-18 17:57:46 +03:00
static void _log_stderr ( log_state * s , void * * state , int type , const char * message )
2012-08-08 11:41:01 +04:00
{
2012-10-12 12:15:30 +04:00
const char * prefix ;
2012-08-08 11:41:01 +04:00
switch ( type ) {
case DAEMON_LOG_INFO : prefix = " I: " ; break ;
case DAEMON_LOG_WARN : prefix = " W: " ; break ;
2012-10-12 12:15:30 +04:00
case DAEMON_LOG_ERROR : /* fall through */
2012-08-08 11:41:01 +04:00
case DAEMON_LOG_FATAL : prefix = " E: " ; break ;
2012-10-12 12:15:30 +04:00
default : prefix = " " ; break ;
2012-08-08 11:41:01 +04:00
}
fprintf ( stderr , " %s%s \n " , prefix , message ) ;
}
struct backend backend [ ] = {
2017-10-18 17:57:46 +03:00
{ DAEMON_LOG_OUTLET_SYSLOG , _log_syslog } ,
{ DAEMON_LOG_OUTLET_STDERR , _log_stderr } ,
2012-08-08 11:41:01 +04:00
{ 0 , 0 }
} ;
void daemon_log ( log_state * s , int type , const char * message ) {
int i = 0 ;
while ( backend [ i ] . id ) {
2013-11-25 16:42:30 +04:00
if ( ( int ) ( s - > log_config [ type ] & backend [ i ] . id ) = = backend [ i ] . id )
2012-08-08 11:41:01 +04:00
backend [ i ] . log ( s , & s - > backend_state [ i ] , type , message ) ;
+ + i ;
}
}
2012-10-08 20:34:33 +04:00
static int _type_interesting ( log_state * s , int type ) {
int i = 0 ;
while ( backend [ i ] . id ) {
2013-11-25 16:42:30 +04:00
if ( ( int ) ( s - > log_config [ type ] & backend [ i ] . id ) = = backend [ i ] . id )
2012-10-08 20:34:33 +04:00
return 1 ;
+ + i ;
}
return 0 ;
}
2012-08-08 11:41:01 +04:00
void daemon_logf ( log_state * s , int type , const char * fmt , . . . ) {
2012-08-17 02:46:00 +04:00
char * buf ;
2012-08-08 11:41:01 +04:00
va_list ap ;
2012-08-17 02:46:00 +04:00
2012-08-08 11:41:01 +04:00
va_start ( ap , fmt ) ;
2012-08-17 02:46:00 +04:00
if ( dm_vasprintf ( & buf , fmt , ap ) > = 0 ) {
daemon_log ( s , type , buf ) ;
dm_free ( buf ) ;
} /* else return_0 */
va_end ( ap ) ;
2012-08-08 11:41:01 +04:00
}
struct log_line_baton {
log_state * s ;
int type ;
const char * prefix ;
} ;
static int _log_line ( const char * line , void * baton ) {
struct log_line_baton * b = baton ;
daemon_logf ( b - > s , b - > type , " %s%s " , b - > prefix , line ) ;
return 0 ;
}
void daemon_log_cft ( log_state * s , int type , const char * prefix , const struct dm_config_node * n )
{
2012-10-12 12:15:30 +04:00
struct log_line_baton b = { . s = s , . type = type , . prefix = prefix } ;
2012-10-08 20:34:33 +04:00
if ( ! _type_interesting ( s , type ) )
return ;
2012-12-13 22:55:33 +04:00
( void ) dm_config_write_node ( n , & _log_line , & b ) ;
2012-08-08 11:41:01 +04:00
}
void daemon_log_multi ( log_state * s , int type , const char * prefix , const char * msg )
{
2012-10-12 12:15:30 +04:00
struct log_line_baton b = { . s = s , . type = type , . prefix = prefix } ;
char * buf ;
char * pos ;
2012-10-08 20:34:33 +04:00
if ( ! _type_interesting ( s , type ) )
return ;
2012-10-12 12:15:30 +04:00
buf = dm_strdup ( msg ) ;
pos = buf ;
2012-08-08 11:41:01 +04:00
if ( ! buf )
return ; /* _0 */
while ( pos ) {
char * next = strchr ( pos , ' \n ' ) ;
if ( next )
* next = 0 ;
_log_line ( pos , & b ) ;
pos = next ? next + 1 : 0 ;
}
2012-10-08 19:11:43 +04:00
dm_free ( buf ) ;
2012-08-08 11:41:01 +04:00
}
void daemon_log_enable ( log_state * s , int outlet , int type , int enable )
{
2015-03-05 23:00:44 +03:00
if ( type > = 32 )
return ;
2012-08-08 11:41:01 +04:00
if ( enable )
s - > log_config [ type ] | = outlet ;
else
s - > log_config [ type ] & = ~ outlet ;
}
static int _parse_one ( log_state * s , int outlet , const char * type , int enable )
{
int i ;
if ( ! strcmp ( type , " all " ) )
for ( i = 0 ; i < 32 ; + + i )
daemon_log_enable ( s , outlet , i , enable ) ;
2015-10-21 19:16:59 +03:00
else if ( ! strcmp ( type , " fatal " ) )
daemon_log_enable ( s , outlet , DAEMON_LOG_FATAL , enable ) ;
else if ( ! strcmp ( type , " error " ) )
daemon_log_enable ( s , outlet , DAEMON_LOG_ERROR , enable ) ;
else if ( ! strcmp ( type , " warn " ) )
daemon_log_enable ( s , outlet , DAEMON_LOG_WARN , enable ) ;
2015-10-21 19:22:22 +03:00
else if ( ! strcmp ( type , " info " ) )
2015-10-21 19:16:59 +03:00
daemon_log_enable ( s , outlet , DAEMON_LOG_INFO , enable ) ;
2012-08-08 11:41:01 +04:00
else if ( ! strcmp ( type , " wire " ) )
daemon_log_enable ( s , outlet , DAEMON_LOG_WIRE , enable ) ;
else if ( ! strcmp ( type , " debug " ) )
daemon_log_enable ( s , outlet , DAEMON_LOG_DEBUG , enable ) ;
return 1 ;
}
int daemon_log_parse ( log_state * s , int outlet , const char * types , int enable )
{
2012-10-15 13:02:15 +04:00
char * buf ;
char * pos ;
2012-08-08 11:41:01 +04:00
2012-10-15 13:02:15 +04:00
if ( ! types | | ! types [ 0 ] )
return 1 ;
if ( ! ( buf = dm_strdup ( types ) ) )
2012-08-08 11:41:01 +04:00
return 0 ;
2012-10-15 13:02:15 +04:00
pos = buf ;
2012-08-08 11:41:01 +04:00
while ( pos ) {
char * next = strchr ( pos , ' , ' ) ;
if ( next )
* next = 0 ;
2012-08-16 22:10:35 +04:00
if ( ! _parse_one ( s , outlet , pos , enable ) ) {
dm_free ( buf ) ;
2012-08-08 11:41:01 +04:00
return 0 ;
2012-08-16 22:10:35 +04:00
}
2012-08-08 11:41:01 +04:00
pos = next ? next + 1 : 0 ;
}
2012-08-16 22:10:35 +04:00
dm_free ( buf ) ;
2012-08-08 11:41:01 +04:00
return 1 ;
}