From e7be81dd66bc4d19ff8552b81aa38821eeb9f457 Mon Sep 17 00:00:00 2001 From: yaworsky Date: Mon, 28 Nov 2005 14:03:41 +0000 Subject: Implemented charset conversion in each log path. Fixed bugs in configuration reader. --- daemon/conf.c | 72 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 22 deletions(-) (limited to 'daemon/conf.c') diff --git a/daemon/conf.c b/daemon/conf.c index 383673c..2255369 100644 --- a/daemon/conf.c +++ b/daemon/conf.c @@ -36,8 +36,6 @@ static char syslog_conf_dir[] = SYSLOG_CONF_DIR; /* options and their default values */ gboolean use_dns = TRUE; -gchar *source_encoding = NULL; -gchar *destination_encoding = NULL; int mark_interval = 0; gchar *mark_message = "-- MARK --"; int hold = 3; @@ -108,6 +106,8 @@ static void create_source( int line_number, } else if( strcmp( aname, "port" ) == 0 ) source->udp.sin_port = htons( strtoul( aval, NULL, 0 ) ); + else if( strcmp( aname, "encoding" ) == 0 ) + source->encoding = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); } if( !source->name ) @@ -255,29 +255,30 @@ static void create_destination( int line_number, const gchar** attribute_values ) { gboolean r = FALSE; + const gchar **attr_names; + const gchar **attr_values; const gchar *aname; struct destination *dest = g_malloc0( sizeof(struct destination) ); /* at first, we must determine destination type for selection of type-specific structure that we'll fill later; - also, look for 'name' attribute and set the name of destination */ + also, look for 'name' and 'encoding' attributes and set corresponding fields + in destination structure */ dest->type = DT_UNDEFINED; - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) + attr_names = attribute_names; + attr_values = attribute_values; + for( ; (aname = *attr_names) != NULL; attr_names++, attr_values++ ) { - const gchar *aval = *attribute_values; + const gchar *aval = *attr_values; if( strcmp( aname, "name" ) == 0 ) dest->name = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "encoding" ) == 0 ) + dest->encoding = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); else if( strcmp( aname, "file" ) == 0 ) - { dest->type = DT_FILE; - break; - } else if( strcmp( aname, "collector" ) == 0 ) - { dest->type = DT_RELAY; - break; - } } if( !dest->name ) { @@ -500,10 +501,6 @@ static void read_options( int line_number, else ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", aval, aname, line_number ); } - else if( strcmp( aname, "source_encoding" ) == 0 ) - source_encoding = g_strdup( aval ); - else if( strcmp( aname, "destination_encoding" ) == 0 ) - destination_encoding = g_strdup( aval ); else if( strcmp( aname, "mark_interval" ) == 0 ) mark_interval = strtoul( aval, NULL, 0 ); else if( strcmp( aname, "mark_message" ) == 0 ) @@ -697,6 +694,8 @@ static void resolve_logpaths() g_free( logpath ); logpath = g_malloc( sizeof(struct logpath) ); + logpath->message_cd = (GIConv) -1; + /* find source */ for( item = sources; item; item = item->next ) { @@ -741,6 +740,32 @@ static void resolve_logpaths() else 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 ); + } + } + } + /* add item to paths */ paths = g_list_append( paths, logpath ); logpath = NULL; @@ -774,9 +799,10 @@ static void dump_configuration() for( item = sources; item; item = item->next ) { struct source *s = item->data; - TRACE( "\tname=%s\ttype=%s\tinterface=%d:%d:%d:%d\tport=%d\n", + TRACE( "\tname=%s\ttype=%s\tencoding=%s\tinterface=%d:%d:%d:%d\tport=%d\n", s->name, (s->type == ST_INTERNAL)? "internal" : ((s->type == ST_UDP)? "udp" : "undefined"), + s->encoding? s->encoding : "UTF-8", s->udp.sin_addr.S_un.S_un_b.s_b1, s->udp.sin_addr.S_un.S_un_b.s_b2, s->udp.sin_addr.S_un.S_un_b.s_b3, s->udp.sin_addr.S_un.S_un_b.s_b4, ntohs( s->udp.sin_port ) ); @@ -788,10 +814,12 @@ static void dump_configuration() switch( d->type ) { case DT_FILE: - TRACE( "\tname=%s\tfile=%s\n" + TRACE( "\tname=%s\tencoding=%s\tfile=%s\n" "\t\trotate=%s size=%d backlogs=%d ifempty=%s\n" "\t\tolddir=%s compresscmd=%s\n", - d->name, d->u.file.name_pattern, + d->name, + d->encoding? d->encoding : "UTF-8", + d->u.file.name_pattern, (d->u.file.rotate == RP_DAILY)? "daily" : (d->u.file.rotate == RP_WEEKLY)? "weekly" : (d->u.file.rotate == RP_MONTHLY)? "monthly" @@ -801,9 +829,11 @@ static void dump_configuration() d->u.file.compresscmd? d->u.file.compresscmd : "NULL" ); break; case DT_RELAY: - TRACE( "\tname=%s\tcollector=%s\n" + TRACE( "\tname=%s\tencoding=%s\tcollector=%s\n" "\t\tomit_hostname=%s\n", - d->name, d->u.file.name_pattern, + d->name, + d->encoding? d->encoding : "UTF-8", + d->u.relay.collector, d->u.relay.omit_hostname? "yes" : "no" ); break; default: @@ -840,8 +870,6 @@ static void dump_configuration() } TRACE( "Options:\n" ); TRACE( "\tuse_dns=%d\n", (int) use_dns ); - TRACE( "\tsource_encoding=%s\n", source_encoding? source_encoding : "NULL" ); - TRACE( "\tdestination_encoding=%s\n", destination_encoding? destination_encoding : "NULL" ); TRACE( "\tmark_interval=%d\n", mark_interval ); TRACE( "\tmark_message=%s\n", mark_message ); TRACE( "\thold=%d\n", hold ); -- cgit v1.2.3