diff options
-rw-r--r-- | daemon/conf.c | 84 | ||||
-rw-r--r-- | daemon/syslogd.c | 53 | ||||
-rw-r--r-- | daemon/syslogd.h | 3 | ||||
-rw-r--r-- | doc/src/configuration.xml | 2 |
4 files changed, 103 insertions, 39 deletions
diff --git a/daemon/conf.c b/daemon/conf.c index 2255369..78f95c2 100644 --- a/daemon/conf.c +++ b/daemon/conf.c @@ -676,6 +676,64 @@ parsed: } /****************************************************************************** + * create_conversion_descriptors + * + * helper function for resolve_logpaths; + * creates charset conversion descriptors for message and program name + */ +static void create_conversion_descriptors( struct logpath* logpath ) +{ + /* create message charset conversion descriptor */ + if( logpath->source->encoding || logpath->destination->encoding ) + { + char *source_encoding = logpath->source->encoding? + logpath->source->encoding : "UTF-8"; + char *destination_encoding = logpath->destination->encoding? + logpath->destination->encoding : "UTF-8"; + + if( strcasecmp( source_encoding, destination_encoding ) != 0 ) + { + logpath->message_cd = g_iconv_open( destination_encoding, source_encoding ); + if( logpath->message_cd == (GIConv) -1 ) + { + ERR( "Cannot convert messages from %s to %s\n", + source_encoding, destination_encoding ); + } + else + { + TRACE( "Log path %s-%s: converting messages from %s to %s\n", + logpath->source->name, logpath->destination->name, + source_encoding, destination_encoding ); + } + } + } + + /* create charset conversion descriptor for program name */ + if( logpath->source->encoding ) + { + const gchar *destination_encoding; + + g_get_charset( &destination_encoding ); + + if( strcasecmp( logpath->source->encoding, destination_encoding ) != 0 ) + { + logpath->program_cd = g_iconv_open( destination_encoding, logpath->source->encoding ); + if( logpath->program_cd == (GIConv) -1 ) + { + ERR( "Cannot convert program names from %s to %s\n", + logpath->source->encoding, destination_encoding ); + } + else + { + TRACE( "Log path %s-%s: converting program name from %s to %s\n", + logpath->source->name, logpath->destination->name, + logpath->source->encoding, destination_encoding ); + } + } + } +} + +/****************************************************************************** * resolve_logpaths * * replace logpath_names structures @@ -695,6 +753,7 @@ static void resolve_logpaths() logpath = g_malloc( sizeof(struct logpath) ); logpath->message_cd = (GIConv) -1; + logpath->program_cd = (GIConv) -1; /* find source */ for( item = sources; item; item = item->next ) @@ -741,30 +800,7 @@ static void resolve_logpaths() logpath->filter = NULL; } - /* create message charset conversion descriptor */ - if( logpath->source->encoding || logpath->destination->encoding ) - { - char *source_encoding = logpath->source->encoding? - logpath->source->encoding : "UTF-8"; - char *destination_encoding = logpath->destination->encoding? - logpath->destination->encoding : "UTF-8"; - - if( strcasecmp( source_encoding, destination_encoding ) != 0 ) - { - logpath->message_cd = g_iconv_open( destination_encoding, source_encoding ); - if( logpath->message_cd == (GIConv) -1 ) - { - ERR( "Cannot convert messages from %s to %s\n", - source_encoding, destination_encoding ); - } - else - { - TRACE( "Log path %s-%s: converting messages from %s to %s\n", - logpath->source->name, logpath->destination->name, - source_encoding, destination_encoding ); - } - } - } + create_conversion_descriptors( logpath ); /* add item to paths */ paths = g_list_append( paths, logpath ); diff --git a/daemon/syslogd.c b/daemon/syslogd.c index e4467b3..0a3b2b6 100644 --- a/daemon/syslogd.c +++ b/daemon/syslogd.c @@ -180,6 +180,30 @@ done: } /****************************************************************************** + * try_convert_string + * + * helper function for mux_message; + * try to convert encoding, return reference to the original string in case + * of failure + */ +static struct string* try_convert_string( struct string* s, GIConv cd ) +{ + struct string *ret; + gchar *converted_str; + + converted_str = g_convert_with_iconv( s->gstr->str, -1, cd, NULL, NULL, NULL ); + if( !converted_str ) + { + TRACE( "conversion error\n" ); + return string_addref( s ); + } + + ret = string_new( converted_str ); + g_free( converted_str ); + return ret; +} + +/****************************************************************************** * mux_message * * filter and multiplex message to destinations; @@ -194,6 +218,7 @@ static void mux_message( struct message* msg ) for( item = logpaths; item; item = item->next ) { struct logpath *logpath = item->data; + gboolean need_message_iconv, need_program_iconv; struct message *converted_msg; if( logpath->source != msg->source ) @@ -202,27 +227,29 @@ static void mux_message( struct message* msg ) if( !filter_message( msg, logpath->filter ) ) continue; - /* convert message encoding if needed */ - if( logpath->message_cd == (GIConv) -1 ) + /* convert encoding if needed */ + need_message_iconv = logpath->message_cd != (GIConv) -1; + need_program_iconv = logpath->program_cd != (GIConv) -1; + + if( (!need_message_iconv) && (!need_program_iconv) ) { converted_msg = msg; reference_message( msg ); } else { - gchar *c_message = g_convert_with_iconv( msg->message->gstr->str, -1, - logpath->message_cd, - NULL, NULL, NULL ); - if( !c_message ) + converted_msg = duplicate_message( msg ); + + if( need_message_iconv ) { - TRACE( "conversion error\n" ); - c_message = g_strdup( msg->message->gstr->str ); + string_release( converted_msg->message ); + converted_msg->message = try_convert_string( msg->message, logpath->message_cd ); + } + if( need_program_iconv ) + { + string_release( converted_msg->program ); + converted_msg->program = try_convert_string( msg->program, logpath->program_cd ); } - - converted_msg = duplicate_message( msg ); - string_release( converted_msg->message ); - converted_msg->message = string_new( c_message ); - g_free( c_message ); } /* put message to destination */ diff --git a/daemon/syslogd.h b/daemon/syslogd.h index d2bb056..97b02ea 100644 --- a/daemon/syslogd.h +++ b/daemon/syslogd.h @@ -197,7 +197,8 @@ struct logpath struct source *source; struct filter *filter; struct destination *destination; - GIConv message_cd; + GIConv message_cd; /* charset conversion descriptor for message */ + GIConv program_cd; /* charset conversion descriptor for program name */ }; extern GList *sources; diff --git a/doc/src/configuration.xml b/doc/src/configuration.xml index dc99510..f88059b 100644 --- a/doc/src/configuration.xml +++ b/doc/src/configuration.xml @@ -172,7 +172,7 @@ It may contain the following format characters: <seglistitem><seg>%l</seg><seg>priority level in numeric form</seg></seglistitem> <seglistitem><seg>%H</seg><seg>source host name (a <quote>device</quote>, according to <ulink url="http://www.ietf.org/rfc/rfc3164.txt">RFC 3164</ulink>)</seg></seglistitem> <seglistitem><seg>%h</seg><seg>sender host name (datagram sender, which may be device or relay)</seg></seglistitem> - <seglistitem><seg>%P</seg><seg>program name</seg></seglistitem> + <seglistitem><seg>%P</seg><seg>program name; this is taken from the MSG part of message and converted to locale encoding if source encoding is specified</seg></seglistitem> <seglistitem><seg>%%</seg><seg>% character</seg></seglistitem> </segmentedlist> </para> |