From ffe303d7937f478fccbb302c04e63e0cbfd7867e Mon Sep 17 00:00:00 2001 From: yaworsky Date: Tue, 29 Nov 2005 10:12:45 +0000 Subject: Convert TAG (program name) from source encoding to locale encoding if source encoding is specified and other than locale encoding. --- daemon/conf.c | 84 +++++++++++++++++++++++++++++++++-------------- daemon/syslogd.c | 53 ++++++++++++++++++++++-------- daemon/syslogd.h | 3 +- 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 @@ -675,6 +675,64 @@ parsed: prolog_expected = FALSE; } +/****************************************************************************** + * 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 * @@ -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 @@ -179,6 +179,30 @@ done: return ret; } +/****************************************************************************** + * 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 * @@ -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: %lpriority level in numeric form %Hsource host name (a device, according to RFC 3164) %hsender host name (datagram sender, which may be device or relay) - %Pprogram name + %Pprogram name; this is taken from the MSG part of message and converted to locale encoding if source encoding is specified %%% character -- cgit v1.2.3